Пример #1
0
    def remove(self, ids, **kwargs):
        """ Removes a web-based image attachment if it is used by no view (template)

        Returns a dict mapping attachments which would not be removed (if any)
        mapped to the views preventing their removal
        """
        Attachment = attachments_to_remove = request.env['ir.attachment']
        Views = request.env['ir.ui.view']

        # views blocking removal of the attachment
        removal_blocked_by = {}

        for attachment in Attachment.browse(ids):
            # in-document URLs are html-escaped, a straight search will not
            # find them
            url = tools.html_escape(attachment.local_url)
            views = Views.search([
                "|",
                ('arch_db', 'like', '"%s"' % url),
                ('arch_db', 'like', "'%s'" % url)
            ])

            if views:
                removal_blocked_by[attachment.id] = views.read(['name'])
            else:
                attachments_to_remove += attachment
        if attachments_to_remove:
            attachments_to_remove.unlink()
        return removal_blocked_by
Пример #2
0
 def _check_contents(self, values):
     mimetype = values['mimetype'] = self._compute_mimetype(values)
     needs_escape = 'htm' in mimetype or '/ht' in mimetype # hta, html, xhtml, etc.
     if needs_escape and not self.env.user._is_admin():
         if 'datas' in values:
             values['datas'] = html_escape(values['datas'].decode('base64')).encode('base64')
         else:
             values['mimetype'] = 'text/plain'
     return values
Пример #3
0
Файл: main.py Проект: befks/odoo
    def report_download(self, data, token):
        """This function is used by 'qwebactionmanager.js' in order to trigger the download of
        a pdf/controller report.

        :param data: a javascript array JSON.stringified containg report internal url ([0]) and
        type [1]
        :returns: Response with a filetoken cookie and an attachment header
        """
        requestcontent = json.loads(data)
        url, type = requestcontent[0], requestcontent[1]
        try:
            if type == 'qweb-pdf':
                reportname = url.split('/report/pdf/')[1].split('?')[0]

                docids = None
                if '/' in reportname:
                    reportname, docids = reportname.split('/')

                if docids:
                    # Generic report:
                    response = self.report_routes(reportname, docids=docids, converter='pdf')
                else:
                    # Particular report:
                    data = url_decode(url.split('?')[1]).items()  # decoding the args represented in JSON
                    response = self.report_routes(reportname, converter='pdf', **dict(data))

                report = request.env['report']._get_report_from_name(reportname)
                filename = "%s.%s" % (report.name, "pdf")
                if docids:
                    ids = [int(x) for x in docids.split(",")]
                    obj = request.env[report.model].browse(ids)
                    if report.print_report_name and not len(obj) > 1:
                        report_name = safe_eval(report.print_report_name, {'object': obj, 'time': time})
                        filename = "%s.%s" % (report_name, "pdf")
                response.headers.add('Content-Disposition', content_disposition(filename))
                response.set_cookie('fileToken', token)
                return response
            elif type == 'controller':
                reqheaders = Headers(request.httprequest.headers)
                response = Client(request.httprequest.app, BaseResponse).get(url, headers=reqheaders, follow_redirects=True)
                response.set_cookie('fileToken', token)
                return response
            else:
                return
        except Exception as e:
            se = _serialize_exception(e)
            error = {
                'code': 200,
                'message': "Odoo Server Error",
                'data': se
            }
            return request.make_response(html_escape(json.dumps(error)))
Пример #4
0
 def report(self, output_format, report_name, token, report_id=False, **kw):
     uid = request.session.uid
     coa = request.env['account.open.chart'].sudo(uid).browse(report_id)
     try:
         if output_format == 'pdf':
             response = request.make_response(
                 coa.with_context(active_id=report_id).get_pdf(report_id),
                 headers=[
                     ('Content-Type', 'application/pdf'),
                     ('Content-Disposition', 'attachment; filename=coa_report.pdf;')
                 ]
             )
             response.set_cookie('fileToken', token)
             return response
     except Exception as e:
         se = serialize_exception(e)
         error = {
             'code': 200,
             'message': 'Odoo Server Error',
             'data': se
         }
         return request.make_response(html_escape(json.dumps(error)))
Пример #5
0
    def report_download(self, data, token):
        """This function is used by 'qwebactionmanager.js' in order to trigger
        the download of a py3o/controller report.

        :param data: a javascript array JSON.stringified containg report
        internal url ([0]) and type [1]
        :returns: Response with a filetoken cookie and an attachment header
        """
        requestcontent = json.loads(data)
        url, report_type = requestcontent[0], requestcontent[1]
        if 'py3o' not in report_type:
            return super(ReportController, self).report_download(data, token)
        try:
            reportname = url.split('/report/py3o/')[1].split('?')[0]
            docids = None
            if '/' in reportname:
                reportname, docids = reportname.split('/')

            if docids:
                # Generic report:
                response = self.report_routes(
                    reportname, docids=docids, converter='py3o')
            else:
                # Particular report:
                # decoding the args represented in JSON
                data = list(url_decode(url.split('?')[1]).items())
                response = self.report_routes(
                    reportname, converter='py3o', **dict(data))
            response.set_cookie('fileToken', token)
            return response
        except Exception as e:
            exc_info = sys.exc_info()
            se = traceback.format_exception(*exc_info)
            error = {
                'code': 200,
                'message': "Odoo Server Error",
                'data': se
            }
            return request.make_response(html_escape(json.dumps(error)))
Пример #6
0
 def download_report_xlsx(self, model, options, output_format, token,
                          report_name, **kw):
     uid = request.session.uid
     report_obj = request.env[model].with_user(uid)
     options = json.loads(options)
     try:
         if output_format == 'xlsx':
             response = request.make_response(
                 None,
                 headers=[('Content-Type', 'application/vnd.ms-excel'),
                          ('Content-Disposition',
                           content_disposition(report_name + '.xlsx'))])
             report_obj.get_xlsx_report(options, response)
         response.set_cookie('fileToken', token)
         return response
     except Exception as e:
         error = {
             'code': 200,
             'message': 'Odoo Server Error',
             'data': str(e)
         }
         return request.make_response(html_escape(json.dumps(error)))
Пример #7
0
    def partner_desinterested(self, comment=False, contacted=False, spam=False):
        if contacted:
            message = '<p>%s</p>' % _('I am not interested by this lead. I contacted the lead.')
        else:
            message = '<p>%s</p>' % _('I am not interested by this lead. I have not contacted the lead.')
        partner_ids = self.env['res.partner'].search(
            [('id', 'child_of', self.env.user.partner_id.commercial_partner_id.id)])
        self.message_unsubscribe(partner_ids=partner_ids.ids)
        if comment:
            message += '<p>%s</p>' % html_escape(comment)
        self.message_post(body=message)
        values = {
            'partner_assigned_id': False,
        }

        if spam:
            tag_spam = self.env.ref('website_crm_partner_assign.tag_portal_lead_is_spam', False)
            if tag_spam and tag_spam not in self.tag_ids:
                values['tag_ids'] = [(4, tag_spam.id, False)]
        if partner_ids:
            values['partner_declined_ids'] = [(4, p, 0) for p in partner_ids.ids]
        self.sudo().write(values)
Пример #8
0
    def _get_lead_days(self, product):
        """Returns the cumulative delay and its description encountered by a
        procurement going through the rules in `self`.

        :param product: the product of the procurement
        :type product: :class:`~odoo.addons.product.models.product.ProductProduct`
        :return: the cumulative delay and cumulative delay's description
        :rtype: tuple
        """
        delay = sum(
            self.filtered(lambda r: r.action in ['pull', 'pull_push']).mapped(
                'delay'))
        if self.env.context.get('bypass_delay_description'):
            delay_description = ""
        else:
            delay_description = ''.join([
                '<tr><td>%s %s</td><td class="text-right">+ %d %s</td></tr>' %
                (_('Delay on'), html_escape(
                    rule.name), rule.delay, _('day(s)')) for rule in self
                if rule.action in ['pull', 'pull_push'] and rule.delay
            ])
        return delay, delay_description
Пример #9
0
    def report_download(self, data, token, context=None):
        """ print reports on report_download
        """
        user = request.env.user
        if not user.has_group(SECURITY_GROUP) \
                or not user.company_id.printnode_enabled or not user.printnode_enabled:
            return super(ReportControllerProxy, self).report_download(data, token, context)

        requestcontent = json.loads(data)

        if requestcontent[1] not in PDF + RAW:
            return super(ReportControllerProxy, self).report_download(data, token, context)

        ext = requestcontent[1].split('-')[1]
        report_name, object_ids = requestcontent[0].\
            split('/report/{}/'.format(ext))[1].split('?')[0].split('/')

        report_id = request.env['ir.actions.report']._get_report_from_name(report_name)
        printer_id = user._get_report_printer(report_id.id)

        if not printer_id:
            return super(ReportControllerProxy, self).report_download(data, token, context)

        try:
            ids = [int(x) for x in object_ids.split(',')]
            obj = request.env[report_id.model].browse(ids)

            super(ReportControllerProxy, self).printnode_print(printer_id, report_id, obj)

        except Exception as e:
            return request.make_response(html_escape(json.dumps({
                'code': 200,
                'message': 'Odoo Server Error',
                'data': _serialize_exception(e),
            })))

        index = user.company_id.im_a_teapot
        raise PrintNodeSuccess(['', _('Sent to PrintNode')][index])
Пример #10
0
 def followup(self, partners, token, **kw):
     uid = request.session.uid
     try:
         context_obj = request.env['account.report.context.followup']
         partners = request.env['res.partner'].browse([int(i) for i in partners.split(',')])
         context_ids = context_obj.search([('partner_id', 'in', partners.ids), ('create_uid', '=', uid)])
         response = request.make_response(
             context_ids.with_context(public=True).get_pdf(log=True),
             headers=[
                 ('Content-Type', 'application/pdf'),
                 ('Content-Disposition', 'attachment; filename=payment_reminder.pdf;')
             ]
         )
         response.set_cookie('fileToken', token)
         return response
     except Exception, e:
         se = _serialize_exception(e)
         error = {
             'code': 200,
             'message': 'Odoo Server Error',
             'data': se
         }
         return request.make_response(html_escape(json.dumps(error)))
Пример #11
0
    def report_download(self, data, token, context=None):
        """This function is used by 'qwebactionmanager.js' in order to trigger
        the download of a py3o/controller report.

        :param data: a javascript array JSON.stringified containg report
        internal url ([0]) and type [1]
        :returns: Response with a filetoken cookie and an attachment header
        """
        requestcontent = json.loads(data)
        url, report_type = requestcontent[0], requestcontent[1]
        if "py3o" not in report_type:
            return super(ReportController,
                         self).report_download(data, token, context)
        try:
            reportname = url.split("/report/py3o/")[1].split("?")[0]
            docids = None
            if "/" in reportname:
                reportname, docids = reportname.split("/")

            if docids:
                # Generic report:
                response = self.report_routes(reportname,
                                              docids=docids,
                                              converter="py3o")
            else:
                # Particular report:
                # decoding the args represented in JSON
                data = list(url_decode(url.split("?")[1]).items())
                response = self.report_routes(reportname,
                                              converter="py3o",
                                              **dict(data))
            response.set_cookie("fileToken", token)
            return response
        except Exception as e:
            se = _serialize_exception(e)
            error = {"code": 200, "message": "Odoo Server Error", "data": se}
            return request.make_response(html_escape(json.dumps(error)))
Пример #12
0
 def get_statement_report_custom(self, model, **kw):
     if not request.env.user.partner_id.allow_print_statement_portal:
         return request.redirect("/")
     if kw.get('report_type') == 'excel':
         uid = request.session.uid
         account_report_model = request.env['account.report']
         options = self._get_statement_report_options_custom(**kw)
         cids = request.httprequest.cookies.get(
             'cids',
             str(request.website.company_id.id
                 or request.env.user.company_id.id))
         allowed_company_ids = [int(cid) for cid in cids.split(',')]
         report_obj = request.env[model].with_user(uid).with_context(
             allowed_company_ids=allowed_company_ids).sudo()
         report_name = report_obj.get_report_filename(options)
         try:
             response = request.make_response(
                 report_obj.get_xlsx(options),
                 headers=[
                     ('Content-Type',
                      account_report_model.get_export_mime_type('xlsx')),
                     ('Content-Disposition',
                      content_disposition(report_name + '.xlsx'))
                 ])
             return response
         except Exception as e:
             se = _serialize_exception(e)
             error = {
                 'code': 200,
                 'message': 'Odoo Server Error',
                 'data': se
             }
             return request.make_response(html_escape(json.dumps(error)))
     else:
         return super(CustomerPortal,
                      self).get_statement_report_custom(model, **kw)
Пример #13
0
 def get_report(self,
                model,
                options,
                output_format,
                token,
                financial_id=None,
                **kw):
     uid = request.session.uid
     account_report_model = request.env['account.report']
     options = json.loads(options)
     cids = request.httprequest.cookies.get(
         'cids', str(request.env.user.company_id.id))
     allowed_company_ids = [int(cid) for cid in cids.split(',')]
     report_obj = request.env[model].with_user(uid).with_context(
         allowed_company_ids=allowed_company_ids)
     if financial_id and financial_id != 'null':
         report_obj = report_obj.browse(int(financial_id))
     report_name = report_obj.get_report_filename(options)
     try:
         response = None
         if output_format == 'xlsx':
             response = request.make_response(
                 None,
                 headers=[
                     ('Content-Type',
                      account_report_model.get_export_mime_type('xlsx')),
                     ('Content-Disposition',
                      content_disposition(report_name + '.xlsx'))
                 ])
             response.stream.write(report_obj.advanced_get_xlsx(options))
         response.set_cookie('fileToken', token)
         return response
     except Exception as e:
         se = _serialize_exception(e)
         error = {'code': 200, 'message': 'Odoo Server Error', 'data': se}
         return request.make_response(html_escape(json.dumps(error)))
Пример #14
0
Файл: main.py Проект: 10537/odoo
 def report(self, output_format, report_name, token, report_id=False, **kw):
     uid = request.session.uid
     domain = [('create_uid', '=', uid)]
     stock_traceability = request.env['stock.traceability.report'].sudo(uid).search(domain, limit=1)
     line_data = json.loads(kw['data'])
     try:
         if output_format == 'pdf':
             response = request.make_response(
                 stock_traceability.with_context(active_id=report_id).get_pdf(line_data),
                 headers=[
                     ('Content-Type', 'application/pdf'),
                     ('Content-Disposition', 'attachment; filename=' + 'stock_traceability' + '.pdf;')
                 ]
             )
             response.set_cookie('fileToken', token)
             return response
     except Exception as e:
         se = _serialize_exception(e)
         error = {
             'code': 200,
             'message': 'Odoo Server Error',
             'data': se
         }
         return request.make_response(html_escape(json.dumps(error)))
Пример #15
0
 def report(self, output_format, report_name, token, report_id=False, **kw):
     uid = request.session.uid
     domain = [('create_uid', '=', uid)]
     stock_traceability = request.env['stock.traceability.report'].sudo(uid).search(domain, limit=1)
     line_data = json.loads(kw['data'])
     try:
         if output_format == 'pdf':
             response = request.make_response(
                 stock_traceability.with_context(active_id=report_id).get_pdf(line_data),
                 headers=[
                     ('Content-Type', 'application/pdf'),
                     ('Content-Disposition', 'attachment; filename=' + 'stock_traceability' + '.pdf;')
                 ]
             )
             response.set_cookie('fileToken', token)
             return response
     except Exception as e:
         se = _serialize_exception(e)
         error = {
             'code': 200,
             'message': 'QuikHR Server Error',
             'data': se
         }
         return request.make_response(html_escape(json.dumps(error)))
Пример #16
0
 def _format_error_message(self, error_title, errors):
     bullet_list_msg = ''.join('<li>%s</li>' % html_escape(msg)
                               for msg in errors)
     return '%s<ul>%s</ul>' % (error_title, bullet_list_msg)
Пример #17
0
 def _execute_command_lead(self, **kwargs):
     partner = self.env.user.partner_id
     key = kwargs['body']
     channel_partners = self.env['mail.channel.partner'].search([
         ('partner_id', '!=', partner.id),
         ('channel_id', '=', self.id)], limit=1
     )
     if key.strip() == '/lead':
         msg = self._define_command_lead()['help']
     else:
         lead = self._convert_visitor_to_lead(partner, channel_partners, key)
         msg = _('Created a new lead: <a href="#" data-oe-id="%s" data-oe-model="crm.lead">%s</a>') % (lead.id, html_escape(lead.name))
     self._send_transient_message(partner, msg)
Пример #18
0
Файл: main.py Проект: KKamaa/OCB
    def shape(self, module, filename, **kwargs):
        """
        Returns a color-customized svg (background shape or illustration).
        """
        svg = None
        if module == 'illustration':
            attachment = request.env['ir.attachment'].sudo().search(
                [('url', '=like', request.httprequest.path),
                 ('public', '=', True)],
                limit=1)
            if not attachment:
                raise werkzeug.exceptions.NotFound()
            svg = b64decode(attachment.datas).decode('utf-8')
        else:
            shape_path = get_resource_path(module, 'static', 'shapes',
                                           filename)
            if not shape_path:
                raise werkzeug.exceptions.NotFound()
            with tools.file_open(shape_path, 'r') as file:
                svg = file.read()

        user_colors = []
        for key, value in kwargs.items():
            colorMatch = re.match('^c([1-5])$', key)
            if colorMatch:
                # Check that color is hex or rgb(a) to prevent arbitrary injection
                if not re.match(
                        r'(?i)^#[0-9A-F]{6,8}$|^rgba?\(\d{1,3},\d{1,3},\d{1,3}(?:,[0-9.]{1,4})?\)$',
                        value.replace(' ', '')):
                    raise werkzeug.exceptions.BadRequest()
                user_colors.append(
                    [tools.html_escape(value),
                     colorMatch.group(1)])
            elif key == 'flip':
                if value == 'x':
                    svg = svg.replace('<svg ',
                                      '<svg style="transform: scaleX(-1);" ')
                elif value == 'y':
                    svg = svg.replace('<svg ',
                                      '<svg style="transform: scaleY(-1)" ')
                elif value == 'xy':
                    svg = svg.replace('<svg ',
                                      '<svg style="transform: scale(-1)" ')

        default_palette = {
            '1': '#3AADAA',
            '2': '#7C6576',
            '3': '#F6F6F6',
            '4': '#FFFFFF',
            '5': '#383E45',
        }
        color_mapping = {
            default_palette[palette_number]: color
            for color, palette_number in user_colors
        }
        # create a case-insensitive regex to match all the colors to replace, eg: '(?i)(#3AADAA)|(#7C6576)'
        regex = '(?i)%s' % '|'.join('(%s)' % color
                                    for color in color_mapping.keys())

        def subber(match):
            key = match.group().upper()
            return color_mapping[key] if key in color_mapping else key

        svg = re.sub(regex, subber, svg)

        return request.make_response(svg, [
            ('Content-type', 'image/svg+xml'),
            ('Cache-control', 'max-age=%s' % http.STATIC_CACHE_LONG),
        ])
Пример #19
0
    def report(self, output_format, report_name, token, report_id=False, **kw):
        accounts_hierarchy_obj = request.env['accounts.hierarchy'].sudo(
        ).browse(report_id)
        try:
            if output_format == 'pdf':
                response = request.make_response(
                    accounts_hierarchy_obj.with_context(
                        active_id=report_id).get_pdf(),
                    headers=[('Content-Type', 'application/pdf'),
                             ('Content-Disposition', 'attachment; filename=' +
                              'accounts_hierarchy' + '.pdf;')])
                response.set_cookie('fileToken', token)
                return response
            if output_format == "xls":
                wizard_obj = request.env['accounts.hierarchy'].sudo().browse(
                    report_id)
                heading = request.env['res.company'].browse(
                    wizard_obj.company_id.id).name
                lines = request.env['accounts.hierarchy'].with_context(
                    print_mode=True,
                    output_format=output_format).sudo().get_pdf_lines(
                        report_id)
                if lines:
                    if len(lines) > 65535:
                        raise UserError(
                            _('There are too many rows (%s rows, limit: 65535) to export as Excel 97-2003 (.xls) format.'
                              ) % len(lines))
                    workbook = xlwt.Workbook()
                    sheet = workbook.add_sheet('Chart of Account')

                    normal = xlwt.easyxf(
                        'font: name Times New Roman ;align: horiz left;',
                        num_format_str='#,##0.00')
                    bold = xlwt.easyxf(
                        'font: name Times New Roman bold ;align: horiz left;',
                        num_format_str='#,##0.00')
                    head = xlwt.easyxf(
                        'font: name Times New Roman bold ;align: horiz centre, vert centre;',
                        num_format_str='#,##0.00')
                    if heading:
                        sheet.write_merge(
                            0, 1, 0, 5,
                            'Chart of Account Hierarchy for ' + heading + '',
                            bold)
                    else:
                        sheet.write_merge(0, 1, 0, 5,
                                          'Chart of Account Hierarchy', head)

                    sheet.write(3, 0, 'Code', bold)
                    sheet.write(3, 1, 'Name', bold)
                    sheet.write(3, 2, 'Type', bold)
                    sheet.write(3, 3, 'Debit', bold)
                    sheet.write(3, 4, 'Credit', bold)
                    sheet.write(3, 5, 'Balance', bold)

                    i = 4

                    for line in lines:
                        sheet.write(i, 0, line['columns'][0] or '', normal)
                        sheet.write(i, 1, line['columns'][1] or '', normal)
                        sheet.write(i, 2, line['columns'][2] or '', normal)
                        sheet.write(i, 3,
                                    html2plaintext(line['columns'][3]) or '0',
                                    normal)
                        sheet.write(i, 4,
                                    html2plaintext(line['columns'][4]) or '0',
                                    normal)
                        sheet.write(i, 5,
                                    html2plaintext(line['columns'][5]) or '0',
                                    normal)
                        i += 1
                    fp = io.BytesIO()
                    workbook.save(fp)
                    data = fp.getvalue()
                    fp.close()

                response = request.make_response(
                    data,
                    headers=[('Content-Type', 'application/vnd.ms-excel'),
                             ('Content-Disposition',
                              'attachment; filename=coahiearchy.xls')],
                    cookies={'fileToken': token})
                return response

        except Exception as e:
            se = _serialize_exception(e)
            error = {'code': 200, 'message': 'Odoo Server Error', 'data': se}
            return request.make_response(html_escape(json.dumps(error)))
Пример #20
0
    def report_download(self, data, context=None, token=None):  # pylint: disable=unused-argument
        """This function is used by 'action_manager_report.js' in order to trigger the download of
        a pdf/controller report.

        :param data: a javascript array JSON.stringified containg report internal url ([0]) and
        type [1]
        :returns: Response with an attachment header

        """
        requestcontent = json.loads(data)
        url, type_ = requestcontent[0], requestcontent[1]
        reportname = '???'
        try:
            if type_ in ['qweb-pdf', 'qweb-text']:
                converter = 'pdf' if type_ == 'qweb-pdf' else 'text'
                extension = 'pdf' if type_ == 'qweb-pdf' else 'txt'

                pattern = '/report/pdf/' if type_ == 'qweb-pdf' else '/report/text/'
                reportname = url.split(pattern)[1].split('?')[0]

                docids = None
                if '/' in reportname:
                    reportname, docids = reportname.split('/')

                if docids:
                    # Generic report:
                    response = self.report_routes(reportname,
                                                  docids=docids,
                                                  converter=converter,
                                                  context=context)
                else:
                    # Particular report:
                    data = url_parse(url).decode_query(
                        cls=dict)  # decoding the args represented in JSON
                    if 'context' in data:
                        context, data_context = json.loads(
                            context or '{}'), json.loads(data.pop('context'))
                        context = json.dumps({**context, **data_context})
                    response = self.report_routes(reportname,
                                                  converter=converter,
                                                  context=context,
                                                  **data)

                report = request.env[
                    'ir.actions.report']._get_report_from_name(reportname)
                filename = "%s.%s" % (report.name, extension)

                if docids:
                    ids = [int(x) for x in docids.split(",")]
                    obj = request.env[report.model].browse(ids)
                    if report.print_report_name and not len(obj) > 1:
                        report_name = safe_eval(report.print_report_name, {
                            'object': obj,
                            'time': time
                        })
                        filename = "%s.%s" % (report_name, extension)
                response.headers.add('Content-Disposition',
                                     content_disposition(filename))
                return response
            else:
                return
        except Exception as e:
            _logger.exception("Error while generating report %s", reportname)
            se = http.serialize_exception(e)
            error = {'code': 200, 'message': "Odoo Server Error", 'data': se}
            return request.make_response(html_escape(json.dumps(error)))
Пример #21
0
def apply_inheritance_specs(source,
                            specs_tree,
                            inherit_branding=False,
                            pre_locate=lambda s: True):
    """ Apply an inheriting view (a descendant of the base view)

    Apply to a source architecture all the spec nodes (i.e. nodes
    describing where and what changes to apply to some parent
    architecture) given by an inheriting view.

    :param Element source: a parent architecture to modify
    :param Element specs_tree: a modifying architecture in an inheriting view
    :param bool inherit_branding:
    :param pre_locate: function that is executed before locating a node.
                        This function receives an arch as argument.
                        This is required by studio to properly handle group_ids.
    :return: a modified source where the specs are applied
    :rtype: Element
    """
    # Queue of specification nodes (i.e. nodes describing where and
    # changes to apply to some parent architecture).
    specs = specs_tree if isinstance(specs_tree, list) else [specs_tree]

    def extract(spec):
        """
        Utility function that locates a node given a specification, remove
        it from the source and returns it.
        """
        if len(spec):
            raise ValueError(
                _("Invalid specification for moved nodes: %r",
                  etree.tostring(spec, encoding='unicode')))
        pre_locate(spec)
        to_extract = locate_node(source, spec)
        if to_extract is not None:
            remove_element(to_extract)
            return to_extract
        else:
            raise ValueError(
                _("Element %r cannot be located in parent view",
                  etree.tostring(spec, encoding='unicode')))

    while len(specs):
        spec = specs.pop(0)
        if isinstance(spec, SKIPPED_ELEMENT_TYPES):
            continue
        if spec.tag == 'data':
            specs += [c for c in spec]
            continue
        pre_locate(spec)
        node = locate_node(source, spec)
        if node is not None:
            pos = spec.get('position', 'inside')
            if pos == 'replace':
                mode = spec.get('mode', 'outer')
                if mode == "outer":
                    for loc in spec.xpath(".//*[text()='$0']"):
                        loc.text = ''
                        loc.append(copy.deepcopy(node))
                    if node.getparent() is None:
                        spec_content = None
                        comment = None
                        for content in spec:
                            if content.tag is not etree.Comment:
                                spec_content = content
                                break
                            else:
                                comment = content
                        source = copy.deepcopy(spec_content)
                        # only keep the t-name of a template root node
                        t_name = node.get('t-name')
                        if t_name:
                            source.set('t-name', t_name)
                        if comment is not None:
                            text = source.text
                            source.text = None
                            comment.tail = text
                            source.insert(0, comment)
                    else:
                        replaced_node_tag = None
                        for child in spec:
                            if child.get('position') == 'move':
                                child = extract(child)
                            if inherit_branding and not replaced_node_tag and child.tag is not etree.Comment:
                                # To make a correct branding, we need to
                                # - know exactly which node has been replaced
                                # - store it before anything else has altered the Tree
                                # Do it exactly here :D
                                child.set('meta-oe-xpath-replacing', node.tag)
                                # We just store the replaced node tag on the first
                                # child of the xpath replacing it
                                replaced_node_tag = node.tag
                            node.addprevious(child)
                        node.getparent().remove(node)
                elif mode == "inner":
                    # Replace the entire content of an element
                    for child in node:
                        node.remove(child)
                    node.text = None

                    for child in spec:
                        node.append(copy.deepcopy(child))
                    node.text = spec.text

                else:
                    raise ValueError(
                        _("Invalid mode attribute:") + " '%s'" % mode)
            elif pos == 'attributes':
                for child in spec.getiterator('attribute'):
                    attribute = child.get('name')
                    value = child.text or ''
                    if child.get('add') or child.get('remove'):
                        assert not child.text
                        separator = child.get('separator', ',')
                        if separator == ' ':
                            separator = None  # squash spaces
                        to_add = (s for s in (
                            s.strip()
                            for s in child.get('add', '').split(separator))
                                  if s)
                        to_remove = {
                            s.strip()
                            for s in child.get('remove', '').split(separator)
                        }
                        values = (
                            s.strip()
                            for s in node.get(attribute, '').split(separator))
                        value = (separator or ' ').join(
                            itertools.chain(
                                (v for v in values if v not in to_remove),
                                to_add))
                    if value:
                        node.set(attribute, value)
                    elif attribute in node.attrib:
                        del node.attrib[attribute]
            elif pos == 'inside':
                # add a sentinel element at the end, insert content of spec
                # before the sentinel, then remove the sentinel element
                sentinel = E.sentinel()
                node.append(sentinel)
                add_stripped_items_before(sentinel, spec, extract)
                remove_element(sentinel)
            elif pos == 'after':
                # add a sentinel element right after node, insert content of
                # spec before the sentinel, then remove the sentinel element
                sentinel = E.sentinel()
                node.addnext(sentinel)
                add_stripped_items_before(sentinel, spec, extract)
                remove_element(sentinel)
            elif pos == 'before':
                add_stripped_items_before(node, spec, extract)

            else:
                raise ValueError(_("Invalid position attribute: '%s'") % pos)

        else:
            attrs = ''.join([
                ' %s="%s"' % (attr, html_escape(spec.get(attr)))
                for attr in spec.attrib if attr != 'position'
            ])
            tag = "<%s%s>" % (spec.tag, attrs)
            raise ValueError(
                _("Element '%s' cannot be located in parent view", tag))

    return source
Пример #22
0
    def report(self,
               output_format,
               report_name,
               token,
               report_id=None,
               aging_filter_cmp=False,
               aging_due_filter_cmp=False,
               filter_local_currency=False,
               filter_original_currency=False,
               **kw):

        aging_filter_cmp = eval(aging_filter_cmp.capitalize())
        aging_due_filter_cmp = eval(aging_due_filter_cmp.capitalize())
        filter_local_currency = eval(filter_local_currency.capitalize())
        filter_original_currency = eval(filter_original_currency.capitalize())

        uid = request.session.uid
        domain = [('create_uid', '=', uid)]
        report_model = request.env[
            'account.report.context.common'].get_full_report_name_by_report_name(
                report_name)
        report_obj = request.env[report_model].sudo(uid)
        if report_name == 'financial_report':
            report_id = int(report_id)
            domain.append(('report_id', '=', report_id))
            report_obj = report_obj.browse(report_id)
        context_obj = request.env[
            'account.report.context.common'].get_context_by_report_name(
                report_name)
        context_id = context_obj.sudo(uid).search(domain, limit=1)
        try:
            if output_format == 'xlsx':
                response = request.make_response(
                    None,
                    headers=[('Content-Type', 'application/vnd.ms-excel'),
                             ('Content-Disposition', 'attachment; filename=' +
                              report_obj.get_name() + '.xlsx;')])
                context_id.with_context(
                    aging_filter_cmp=aging_filter_cmp,
                    aging_due_filter_cmp=aging_due_filter_cmp,
                    filter_local_currency=filter_local_currency,
                    filter_original_currency=filter_original_currency
                ).get_xlsx(response)
                response.set_cookie('fileToken', token)
                return response
            if output_format == 'pdf':
                response = request.make_response(
                    context_id.with_context(
                        aging_filter_cmp=aging_filter_cmp,
                        aging_due_filter_cmp=aging_due_filter_cmp,
                        filter_local_currency=filter_local_currency,
                        filter_original_currency=filter_original_currency).
                    get_pdf(),
                    headers=[('Content-Type', 'application/pdf'),
                             ('Content-Disposition', 'attachment; filename=' +
                              report_obj.get_name() + '.pdf;')])
                response.set_cookie('fileToken', token)
                return response
            if output_format == 'xml':
                content = context_id.with_context(
                    aging_filter_cmp=aging_filter_cmp,
                    aging_due_filter_cmp=aging_due_filter_cmp,
                    filter_local_currency=filter_local_currency,
                    filter_original_currency=filter_original_currency).get_xml(
                    )
                response = request.make_response(
                    content,
                    headers=[('Content-Type',
                              'application/vnd.sun.xml.writer'),
                             ('Content-Disposition', 'attachment; filename=' +
                              report_obj.get_name() + '.xml;'),
                             ('Content-Length', len(content))])
                response.set_cookie('fileToken', token)
                return response
        except Exception, e:
            se = _serialize_exception(e)
            error = {'code': 200, 'message': 'Odoo Server Error', 'data': se}
            return request.make_response(html_escape(json.dumps(error)))
Пример #23
0
    def _l10n_es_edi_call_web_service_sign(self, invoices, info_list):
        company = invoices.company_id

        # All are sharing the same value, see '_get_batch_key'.
        csv_number = invoices.mapped('l10n_es_edi_csv')[0]

        # Set registration date
        invoices.filtered(lambda inv: not inv.l10n_es_registration_date).write(
            {
                'l10n_es_registration_date': fields.Date.context_today(self),
            })

        # === Call the web service ===

        # Get connection data.
        l10n_es_edi_tax_agency = company.mapped('l10n_es_edi_tax_agency')[0]
        connection_vals = getattr(
            self, f'_l10n_es_edi_web_service_{l10n_es_edi_tax_agency}_vals')(
                invoices)

        header = {
            'IDVersionSii': '1.1',
            'Titular': {
                'NombreRazon': company.name[:120],
                'NIF': company.vat[2:],
            },
            'TipoComunicacion': 'A1' if csv_number else 'A0',
        }

        session = requests.Session()
        session.cert = company.l10n_es_edi_certificate_id
        session.mount('https://', PatchedHTTPAdapter())

        transport = Transport(operation_timeout=60,
                              timeout=60,
                              session=session)
        client = zeep.Client(connection_vals['url'], transport=transport)

        if invoices[0].is_sale_document():
            service_name = 'SuministroFactEmitidas'
        else:
            service_name = 'SuministroFactRecibidas'
        if company.l10n_es_edi_test_env and not connection_vals.get(
                'test_url'):
            service_name += 'Pruebas'

        # Establish the connection.
        serv = client.bind('siiService', service_name)
        if company.l10n_es_edi_test_env and connection_vals.get('test_url'):
            serv._binding_options['address'] = connection_vals['test_url']

        msg = ''
        try:
            if invoices[0].is_sale_document():
                res = serv.SuministroLRFacturasEmitidas(header, info_list)
            else:
                res = serv.SuministroLRFacturasRecibidas(header, info_list)
        except requests.exceptions.SSLError as error:
            msg = _("The SSL certificate could not be validated.")
        except zeep.exceptions.Error as error:
            msg = _("Networking error:\n%s") % error
        except Exception as error:
            msg = str(error)
        finally:
            if msg:
                return {
                    inv: {
                        'error': msg,
                        'blocking_level': 'warning',
                    }
                    for inv in invoices
                }

        # Process response.

        if not res or not res.RespuestaLinea:
            return {
                inv: {
                    'error': _("The web service is not responding"),
                    'blocking_level': 'warning',
                }
                for inv in invoices
            }

        resp_state = res["EstadoEnvio"]
        l10n_es_edi_csv = res['CSV']

        if resp_state == 'Correcto':
            invoices.write({'l10n_es_edi_csv': l10n_es_edi_csv})
            return {inv: {'success': True} for inv in invoices}

        results = {}
        for respl in res.RespuestaLinea:
            invoice_number = respl.IDFactura.NumSerieFacturaEmisor

            # Retrieve the corresponding invoice.
            # Note: ref can be the same for different partners but there is no enough information on the response
            # to match the partner.

            # Note: Invoices are batched per move_type.
            if invoices[0].is_sale_document():
                inv = invoices.filtered(
                    lambda x: x.name[:60] == invoice_number)
            else:
                # 'ref' can be the same for different partners.
                candidates = invoices.filtered(
                    lambda x: x.ref[:60] == invoice_number)
                if len(candidates) >= 1:
                    respl_partner_info = respl.IDFactura.IDEmisorFactura
                    inv = None
                    for candidate in candidates:
                        partner_info = self._l10n_es_edi_get_partner_info(
                            candidate.commercial_partner_id)
                        if partner_info.get('NIF') and partner_info[
                                'NIF'] == respl_partner_info.NIF:
                            inv = candidate
                            break
                        if partner_info.get('IDOtro') and all(
                                getattr(respl_partner_info.IDOtro, k) == v
                                for k, v in partner_info['IDOtro'].items()):
                            inv = candidate
                            break

                    if not inv:
                        # This case shouldn't happen and means there is something wrong in this code. However, we can't
                        # raise anything since the document has already been approved by the government. The result
                        # will only be a badly logged message into the chatter so, not a big deal.
                        inv = candidates[0]
                else:
                    inv = candidates

            resp_line_state = respl.EstadoRegistro
            if resp_line_state in ('Correcto', 'AceptadoConErrores'):
                inv.l10n_es_edi_csv = l10n_es_edi_csv
                results[inv] = {'success': True}
                if resp_line_state == 'AceptadoConErrores':
                    inv.message_post(
                        body=_("This was accepted with errors: ") +
                        html_escape(respl.DescripcionErrorRegistro))
            elif respl.RegistroDuplicado:
                results[inv] = {'success': True}
                inv.message_post(body=_(
                    "We saw that this invoice was sent correctly before, but we did not treat "
                    "the response.  Make sure it is not because of a wrong configuration."
                ))
            else:
                results[inv] = {
                    'error':
                    _("[%s] %s", respl.CodigoErrorRegistro,
                      respl.DescripcionErrorRegistro),
                    'blocking_level':
                    'error',
                }

        return results
Пример #24
0
 def get_report(self,
                model,
                options,
                output_format,
                token,
                financial_id=None,
                **kw):
     uid = request.session.uid
     report_obj = request.env[model].sudo(uid)
     options = json.loads(options)
     if financial_id and financial_id != 'null':
         report_obj = report_obj.browse(int(financial_id))
     report_name = report_obj.get_report_filename(options)
     try:
         if output_format == 'xlsx':
             response = request.make_response(
                 None,
                 headers=[('Content-Type', 'application/vnd.ms-excel'),
                          ('Content-Disposition',
                           content_disposition(report_name + '.xlsx'))])
             report_obj.get_xlsx(options, response)
         if output_format == 'pdf':
             response = request.make_response(
                 report_obj.get_pdf(options),
                 headers=[('Content-Type', 'application/pdf'),
                          ('Content-Disposition',
                           content_disposition(report_name + '.pdf'))])
         if output_format == 'xml':
             content = report_obj.get_xml(options)
             response = request.make_response(
                 content,
                 headers=[('Content-Type',
                           'application/vnd.sun.xml.writer'),
                          ('Content-Disposition',
                           content_disposition(report_name + '.xml')),
                          ('Content-Length', len(content))])
         if output_format == 'xaf':
             content = report_obj.get_xaf(options)
             response = request.make_response(
                 content,
                 headers=[('Content-Type',
                           'application/vnd.sun.xml.writer'),
                          ('Content-Disposition',
                           content_disposition(report_name + '.xaf')),
                          ('Content-Length', len(content))])
         if output_format == 'txt':
             content = report_obj.get_txt(options)
             response = request.make_response(
                 content,
                 headers=[('Content-Type', 'text/plain'),
                          ('Content-Disposition',
                           content_disposition(report_name + '.txt')),
                          ('Content-Length', len(content))])
         if output_format == 'csv':
             content = report_obj.get_csv(options)
             response = request.make_response(
                 content,
                 headers=[('Content-Type', 'text/csv'),
                          ('Content-Disposition',
                           content_disposition(report_name + '.csv')),
                          ('Content-Length', len(content))])
         if output_format == 'zip':
             content = report_obj._get_zip(options)
             response = request.make_response(
                 content,
                 headers=[
                     ('Content-Type', 'application/zip'),
                     ('Content-Disposition',
                      content_disposition(report_name + '.zip')),
                 ])
             # Adding direct_passthrough to the response and giving it a file
             # as content means that we will stream the content of the file to the user
             # Which will prevent having the whole file in memory
             response.direct_passthrough = True
         response.set_cookie('fileToken', token)
         return response
     except Exception as e:
         se = _serialize_exception(e)
         error = {'code': 200, 'message': 'Odoo Server Error', 'data': se}
         return request.make_response(html_escape(json.dumps(error)))
Пример #25
0
 def get_report(self,
                model,
                options,
                output_format,
                token,
                financial_id=None,
                **kw):
     uid = request.session.uid
     account_report_model = request.env['account.report']
     options = json.loads(options)
     report_obj = request.env[model].with_user(uid)
     if not options.get('multi_company'):
         cids = request.httprequest.cookies.get(
             'cids', str(request.env.user.company_id.id))
         allowed_company_ids = [int(cid) for cid in cids.split(',')]
         report_obj = report_obj.with_context(
             allowed_company_ids=allowed_company_ids)
     if financial_id and financial_id != 'null':
         report_obj = report_obj.browse(int(financial_id))
     report_name = report_obj.get_report_filename(options)
     try:
         if output_format == 'xlsx':
             response = request.make_response(
                 None,
                 headers=[
                     ('Content-Type',
                      account_report_model.get_export_mime_type('xlsx')),
                     ('Content-Disposition',
                      content_disposition(report_name + '.xlsx'))
                 ])
             response.stream.write(report_obj.get_xlsx(options))
         if output_format == 'pdf':
             response = request.make_response(
                 report_obj.get_pdf(options),
                 headers=[
                     ('Content-Type',
                      account_report_model.get_export_mime_type('pdf')),
                     ('Content-Disposition',
                      content_disposition(report_name + '.pdf'))
                 ])
         if output_format == 'xml':
             content = report_obj.get_xml(options)
             response = request.make_response(
                 content,
                 headers=[
                     ('Content-Type',
                      account_report_model.get_export_mime_type('xml')),
                     ('Content-Disposition',
                      content_disposition(report_name + '.xml')),
                     ('Content-Length', len(content))
                 ])
         if output_format == 'xaf':
             content = report_obj.get_xaf(options)
             response = request.make_response(
                 content,
                 headers=[
                     ('Content-Type',
                      account_report_model.get_export_mime_type('xaf')),
                     ('Content-Disposition',
                      content_disposition(report_name + '.xaf')),
                     ('Content-Length', len(content))
                 ])
         if output_format == 'txt':
             content = report_obj.get_txt(options)
             response = request.make_response(
                 content,
                 headers=[
                     ('Content-Type',
                      account_report_model.get_export_mime_type('txt')),
                     ('Content-Disposition',
                      content_disposition(report_name + '.txt')),
                     ('Content-Length', len(content))
                 ])
         if output_format == 'csv':
             content = report_obj.get_csv(options)
             response = request.make_response(
                 content,
                 headers=[
                     ('Content-Type',
                      account_report_model.get_export_mime_type('csv')),
                     ('Content-Disposition',
                      content_disposition(report_name + '.csv')),
                     ('Content-Length', len(content))
                 ])
         if output_format == 'zip':
             content = report_obj.get_zip(options)
             response = request.make_response(
                 content,
                 headers=[
                     ('Content-Type',
                      account_report_model.get_export_mime_type('zip')),
                     ('Content-Disposition',
                      content_disposition(report_name + '.zip')),
                 ])
             # Adding direct_passthrough to the response and giving it a file
             # as content means that we will stream the content of the file to the user
             # Which will prevent having the whole file in memory
             response.direct_passthrough = True
         response.set_cookie('fileToken', token)
         return response
     except Exception as e:
         se = _serialize_exception(e)
         error = {'code': 200, 'message': 'Odoo Server Error', 'data': se}
         return request.make_response(html_escape(json.dumps(error)))
Пример #26
0
 def get_report(self,
                model,
                options,
                output_format,
                token,
                financial_id=None,
                **kw):
     uid = request.session.uid
     report_obj = request.env[model].sudo(uid)
     options = json.loads(options)
     if financial_id:
         report_obj = report_obj.browse(int(financial_id))
     report_name = report_obj.get_report_filename(options)
     try:
         if output_format == 'xlsx':
             response = request.make_response(
                 None,
                 headers=[('Content-Type', 'application/vnd.ms-excel'),
                          ('Content-Disposition',
                           content_disposition(report_name + '.xlsx'))])
             report_obj.get_xlsx(options, response)
         if output_format == 'pdf':
             response = request.make_response(
                 report_obj.get_pdf(options),
                 headers=[('Content-Type', 'application/pdf'),
                          ('Content-Disposition',
                           content_disposition(report_name + '.pdf'))])
         if output_format == 'xml':
             content = report_obj.get_xml(options)
             response = request.make_response(
                 content,
                 headers=[('Content-Type',
                           'application/vnd.sun.xml.writer'),
                          ('Content-Disposition',
                           content_disposition(report_name + '.xml')),
                          ('Content-Length', len(content))])
         if output_format == 'xaf':
             content = report_obj.get_xaf(options)
             response = request.make_response(
                 content,
                 headers=[('Content-Type',
                           'application/vnd.sun.xml.writer'),
                          ('Content-Disposition',
                           'attachment; filename=' + report_name + '.xaf;'),
                          ('Content-Length', len(content))])
         if output_format == 'txt':
             content = report_obj.get_txt(options)
             response = request.make_response(
                 content,
                 headers=[('Content-Type', 'text/plain'),
                          ('Content-Disposition',
                           content_disposition(report_name + '.txt')),
                          ('Content-Length', len(content))])
         if output_format == 'csv':
             content = report_obj.get_csv(options)
             response = request.make_response(
                 content,
                 headers=[('Content-Type', 'text/csv'),
                          ('Content-Disposition',
                           'attachment; filename=' + report_name + '.csv;'),
                          ('Content-Length', len(content))])
         response.set_cookie('fileToken', token)
         return response
     except Exception as e:
         se = _serialize_exception(e)
         error = {'code': 200, 'message': 'ERP Server Error', 'data': se}
         return request.make_response(html_escape(json.dumps(error)))
Пример #27
0
    def report_download(self, data, token):
        """This function is used by 'qwebactionmanager.js' in order to trigger the download of
        a pdf/controller report.

        :param data: a javascript array JSON.stringified containg report internal url ([0]) and
        type [1]
        :returns: Response with a filetoken cookie and an attachment header
        """
        requestcontent = json.loads(data)
        url, type = requestcontent[0], requestcontent[1]
        try:
            if type == 'qweb-pdf':
                reportname = url.split('/report/pdf/')[1].split('?')[0]

                docids = None
                if '/' in reportname:
                    reportname, docids = reportname.split('/')

                if docids:
                    # Generic report:
                    response = self.report_routes(reportname, docids=docids, converter='pdf')
                else:
                    # Particular report:
                    data = url_decode(url.split('?')[1]).items()  # decoding the args represented in JSON
                    response = self.report_routes(reportname, converter='pdf', **dict(data))

                report = request.env['report']._get_report_from_name(reportname)
                filename = "%s.%s" % (report.name, "pdf")
                #Sale Order
                if report.report_name == 'solum_sale.sol_quotation_report_template_id':
                    so_pool = request.env['sale.order']
                    lst_so = []
                    lst_so = docids.split(",")
                    for ele_inv in lst_so:
                        so_obj = so_pool.browse([int(ele_inv)])
                        filename = so_obj.name +'-'+'Sol Luminaire'
                if report.report_name == 'solum_sale.idesign_quotation_report_template_id':
                    so_pool = request.env['sale.order']
                    lst_so = []
                    lst_so = docids.split(",")
                    for ele_inv in lst_so:
                        so_obj = so_pool.browse([int(ele_inv)])
                        filename = so_obj.name +'-'+'iDesign'
                #Invoice
                if report.report_name == 'solum_invoice.sol_invoice_report_template_id':
                    inv_pool = request.env['account.invoice']
                    lst_inv = []
                    lst_inv = docids.split(",")
                    for ele_inv in lst_inv:
                        inv_obj = inv_pool.browse([int(ele_inv)])
                        if inv_obj.number:
                            filename = inv_obj.number +'-'+'Sol Luminaire Customer'
                        else:
                            filename = inv_obj.partner_id.name +'-'+'Sol Luminaire Customer'
                if report.report_name == 'solum_invoice.idesign_invoice_report_template_id':
                    inv_pool = request.env['account.invoice']
                    lst_inv = []
                    lst_inv = docids.split(",")
                    for ele_inv in lst_inv:
                        inv_obj = inv_pool.browse([int(ele_inv)])
                        if inv_obj.number:
                            filename = inv_obj.number +'-'+'iDesign'
                        else:
                            filename = inv_obj.partner_id.name +'-'+'iDesign'
                if report.report_name == 'solum_invoice.sol_commission_invoice_report_template_id':
                    inv_pool = request.env['account.invoice']
                    lst_inv = []
                    lst_inv = docids.split(",")
                    for ele_inv in lst_inv:
                        inv_obj = inv_pool.browse([int(ele_inv)])
                        if inv_obj.number:
                            filename = inv_obj.number +'-'+'Sol Luminaire Commission'
                        else:
                            filename = inv_obj.partner_id.name +'-'+'Sol Luminaire Commission'
                #Delivery Order
                if report.report_name == 'solum_delivery_order.sol_do_report_template_id':
                    picking_pool = request.env['stock.picking']
                    lst_picking = []
                    lst_picking = docids.split(",")
                    for ele_picking in lst_picking:
                        picking_obj = picking_pool.browse([int(ele_picking)])
                        filename = picking_obj.name +'-'+'Sol Luminaire'
                if report.report_name == 'solum_delivery_order.idesign_do_report_template_id':
                    picking_pool = request.env['stock.picking']
                    lst_picking = []
                    lst_picking = docids.split(",")
                    for ele_picking in lst_picking:
                        picking_obj = picking_pool.browse([int(ele_picking)])
                        filename = picking_obj.name +'-'+'iDesign'
                filename = "%s.%s" % (filename, "pdf")
                if docids:
                    ids = [int(x) for x in docids.split(",")]
                    obj = request.env[report.model].browse(ids)
                    if report.print_report_name and not len(obj) > 1:
                        filename = safe_eval(report.print_report_name, {'object': obj, 'time': time})
                response.headers.add('Content-Disposition', content_disposition(filename))
                response.set_cookie('fileToken', token)
                return response
            elif type == 'controller':
                reqheaders = Headers(request.httprequest.headers)
                response = Client(request.httprequest.app, BaseResponse).get(url, headers=reqheaders, follow_redirects=True)
                response.set_cookie('fileToken', token)
                return response
            else:
                return
        except Exception, e:
            se = _serialize_exception(e)
            error = {
                'code': 200,
                'message': "Odoo Server Error",
                'data': se
            }
            return request.make_response(html_escape(json.dumps(error)))
Пример #28
0
 def value_to_html(self, value, options):
     """
     Escapes the value and converts newlines to br. This is bullshit.
     """
     return nl2br(html_escape(value)) if value else ''
Пример #29
0
def apply_inheritance_specs(source,
                            specs_tree,
                            inherit_branding=False,
                            pre_locate=lambda s: True):
    """ Apply an inheriting view (a descendant of the base view)

    Apply to a source architecture all the spec nodes (i.e. nodes
    describing where and what changes to apply to some parent
    architecture) given by an inheriting view.

    :param Element source: a parent architecture to modify
    :param Element specs_tree: a modifying architecture in an inheriting view
    :param bool inherit_branding:
    :param pre_locate: function that is executed before locating a node.
                        This function receives an arch as argument.
                        This is required by studio to properly handle group_ids.
    :return: a modified source where the specs are applied
    :rtype: Element
    """
    # Queue of specification nodes (i.e. nodes describing where and
    # changes to apply to some parent architecture).
    specs = specs_tree if isinstance(specs_tree, list) else [specs_tree]

    def extract(spec):
        """
        Utility function that locates a node given a specification, remove
        it from the source and returns it.
        """
        if len(spec):
            raise ValueError(
                _("Invalid specification for moved nodes: %r",
                  etree.tostring(spec, encoding='unicode')))
        pre_locate(spec)
        to_extract = locate_node(source, spec)
        if to_extract is not None:
            remove_element(to_extract)
            return to_extract
        else:
            raise ValueError(
                _("Element %r cannot be located in parent view",
                  etree.tostring(spec, encoding='unicode')))

    while len(specs):
        spec = specs.pop(0)
        if isinstance(spec, SKIPPED_ELEMENT_TYPES):
            continue
        if spec.tag == 'data':
            specs += [c for c in spec]
            continue
        pre_locate(spec)
        node = locate_node(source, spec)
        if node is not None:
            pos = spec.get('position', 'inside')
            if pos == 'replace':
                mode = spec.get('mode', 'outer')
                if mode == "outer":
                    for loc in spec.xpath(".//*[text()='$0']"):
                        loc.text = ''
                        loc.append(copy.deepcopy(node))
                    if node.getparent() is None:
                        spec_content = None
                        comment = None
                        for content in spec:
                            if content.tag is not etree.Comment:
                                spec_content = content
                                break
                            else:
                                comment = content
                        source = copy.deepcopy(spec_content)
                        # only keep the t-name of a template root node
                        t_name = node.get('t-name')
                        if t_name:
                            source.set('t-name', t_name)
                        if comment is not None:
                            text = source.text
                            source.text = None
                            comment.tail = text
                            source.insert(0, comment)
                    else:
                        # TODO ideally the notion of 'inherit_branding' should
                        # not exist in this function. Given the current state of
                        # the code, it is however necessary to know where nodes
                        # were removed when distributing branding. As a stable
                        # fix, this solution was chosen: the location is marked
                        # with a "ProcessingInstruction" which will not impact
                        # the "Element" structure of the resulting tree.
                        # Exception: if we happen to replace a node that already
                        # has xpath branding (root level nodes), do not mark the
                        # location of the removal as it will mess up the branding
                        # of siblings elements coming from other views, after the
                        # branding is distributed (and those processing instructions
                        # removed).
                        if inherit_branding and not node.get('data-oe-xpath'):
                            node.addprevious(
                                etree.ProcessingInstruction(
                                    'apply-inheritance-specs-node-removal',
                                    node.tag))

                        for child in spec:
                            if child.get('position') == 'move':
                                child = extract(child)
                            node.addprevious(child)
                        node.getparent().remove(node)
                elif mode == "inner":
                    # Replace the entire content of an element
                    for child in node:
                        node.remove(child)
                    node.text = None

                    for child in spec:
                        node.append(copy.deepcopy(child))
                    node.text = spec.text

                else:
                    raise ValueError(
                        _("Invalid mode attribute:") + " '%s'" % mode)
            elif pos == 'attributes':
                for child in spec.getiterator('attribute'):
                    attribute = child.get('name')
                    value = child.text or ''
                    if child.get('add') or child.get('remove'):
                        assert not child.text
                        separator = child.get('separator', ',')
                        if separator == ' ':
                            separator = None  # squash spaces
                        to_add = (s for s in (
                            s.strip()
                            for s in child.get('add', '').split(separator))
                                  if s)
                        to_remove = {
                            s.strip()
                            for s in child.get('remove', '').split(separator)
                        }
                        values = (
                            s.strip()
                            for s in node.get(attribute, '').split(separator))
                        value = (separator or ' ').join(
                            itertools.chain(
                                (v for v in values if v not in to_remove),
                                to_add))
                    if value:
                        node.set(attribute, value)
                    elif attribute in node.attrib:
                        del node.attrib[attribute]
            elif pos == 'inside':
                # add a sentinel element at the end, insert content of spec
                # before the sentinel, then remove the sentinel element
                sentinel = E.sentinel()
                node.append(sentinel)
                add_stripped_items_before(sentinel, spec, extract)
                remove_element(sentinel)
            elif pos == 'after':
                # add a sentinel element right after node, insert content of
                # spec before the sentinel, then remove the sentinel element
                sentinel = E.sentinel()
                node.addnext(sentinel)
                add_stripped_items_before(sentinel, spec, extract)
                remove_element(sentinel)
            elif pos == 'before':
                add_stripped_items_before(node, spec, extract)

            else:
                raise ValueError(_("Invalid position attribute: '%s'") % pos)

        else:
            attrs = ''.join([
                ' %s="%s"' % (attr, html_escape(spec.get(attr)))
                for attr in spec.attrib if attr != 'position'
            ])
            tag = "<%s%s>" % (spec.tag, attrs)
            raise ValueError(
                _("Element '%s' cannot be located in parent view", tag))

    return source
Пример #30
0
    def report_download(self, data, token):
        """This function is used by 'qwebactionmanager.js' in order to trigger the download of
        a pdf/controller report.

        :param data: a javascript array JSON.stringified containg report internal url ([0]) and
        type [1]
        :returns: Response with a filetoken cookie and an attachment header
        """
        requestcontent = json.loads(data)
        url, type = requestcontent[0], requestcontent[1]
        try:
            if type == "qweb-pdf":
                reportname = url.split("/report/pdf/")[1].split("?")[0]

                docids = None
                active_model = ""
                NewReportName = ""
                if "/" in reportname:
                    reportname, docids = reportname.split("/")

                if docids:
                    # Generic report:
                    response = self.report_routes(reportname,
                                                  docids=docids,
                                                  converter="pdf")
                else:
                    # Particular report:
                    data = url_decode(
                        url.split("?")
                        [1]).items()  # decoding the args represented in JSON

                    dictData = dict(data)
                    active_model = json.loads(
                        dictData.get("context")).get("active_model")
                    NewReportName = (json.loads(
                        dictData.get("options")).get("form").get("name"))
                    response = self.report_routes(reportname,
                                                  converter="pdf",
                                                  **dictData)

                report = request.env[
                    "ir.actions.report"]._get_report_from_name(reportname)
                filename = "%s.%s" % (report.name, "pdf")

                if active_model == "payroll.register":
                    filename = "%s.%s" % (NewReportName, "pdf")

                if docids:
                    ids = [int(x) for x in docids.split(",")]
                    obj = request.env[report.model].browse(ids)
                    if report.print_report_name and not len(obj) > 1:
                        report_name = safe_eval(
                            report.print_report_name,
                            {
                                "object": obj,
                                "time": time
                            },
                        )
                        filename = "%s.%s" % (report_name, "pdf")
                    if report.model == "payroll.register":
                        filename = "%s.%s" % (obj.name, "pdf")
                response.headers.add("Content-Disposition",
                                     content_disposition(filename))
                response.set_cookie("fileToken", token)
                return response
            else:
                return
        except Exception as e:
            se = _serialize_exception(e)
            error = {"code": 200, "message": "Odoo Server Error", "data": se}
            return request.make_response(html_escape(json.dumps(error)))
Пример #31
0
    def report_download(self, data, token):

        # This method has been overwrite
        """This function is used by 'qwebactionmanager.js' in order to trigger the download of
        a pdf/controller report.

        :param data: a javascript array JSON.stringified containg report internal url ([0]) and
        type [1]
        :returns: Response with a filetoken cookie and an attachment header
        """
        requestcontent = json.loads(data)
        url, type = requestcontent[0], requestcontent[1]
        try:
            if type == 'qweb-pdf':
                reportname = url.split('/report/pdf/')[1].split('?')[0]

                docids = None
                if '/' in reportname:
                    reportname, docids = reportname.split('/')

                if docids:
                    # Generic report:
                    response = self.report_routes(reportname,
                                                  docids=docids,
                                                  converter='pdf')
                else:
                    # Particular report:
                    data = url_decode(
                        url.split('?')
                        [1]).items()  # decoding the args represented in JSON
                    response = self.report_routes(reportname,
                                                  converter='pdf',
                                                  **dict(data))

                report = request.env['report']._get_report_from_name(
                    reportname)
                filename = "%s.%s" % (report.name, "pdf")

                if docids:
                    ids = [int(x) for x in docids.split(",")]
                    obj = request.env[report.model].browse(ids)
                    # will search the model where reports will get printed
                    search_model = request.env['dynamic.reportname'].search([
                        ('model_id.model', '=', report.model)
                    ])
                    # Will bring the list of fields that belongs to the selected model
                    if search_model:
                        if search_model.field_id.ttype == 'many2one':
                            field = obj.read([
                                search_model.field_id.name
                            ])[0][search_model.field_id.name][1]
                        else:
                            field = obj.read([search_model.field_id.name
                                              ])[0][search_model.field_id.name]
                            # will print the dynamic names for pdf reports
                        filename = (str(field) or report.name) + '.pdf'

                    if report.print_report_name and not len(obj) > 1:
                        filename = safe_eval(report.print_report_name, {
                            'object': obj,
                            'time': time
                        })

                response.headers.add('Content-Disposition',
                                     content_disposition(filename))
                response.set_cookie('fileToken', token)
                return response
            elif type == 'controller':
                reqheaders = Headers(request.httprequest.headers)
                response = Client(request.httprequest.app,
                                  BaseResponse).get(url,
                                                    headers=reqheaders,
                                                    follow_redirects=True)
                response.set_cookie('fileToken', token)
                return response
            else:
                return
        except Exception, e:
            se = _serialize_exception(e)
            error = {'code': 200, 'message': "Odoo Server Error", 'data': se}
            return request.make_response(html_escape(json.dumps(error)))
Пример #32
0
 def value_to_html(self, value, options):
     if not value:
         return False
     text = ', '.join(value.sudo().mapped('display_name'))
     return nl2br(html_escape(text))
Пример #33
0
 def value_to_html(self, value, options):
     if not value:
         return ''
     return html_escape(
         pycompat.to_text(options['selection'][value]) or u'')
Пример #34
0
    def insert_record(self, request, model, values, custom, meta=None):
        if model.model != 'crm.lead':
            return super(ContactController,
                         self).insert_record(request, model, values, custom,
                                             meta)

        lead_model = request.env["crm.lead"]
        lead_id = lead_model.decode(request)

        # domain: leads that are still open:
        # NOT [ on_change AND (proba = 0 OR proba = 100) ]
        # the condition on the lead_id is prepended
        domain = [('id', '=', lead_id), '|',
                  ('stage_id.on_change', '=', False), '&',
                  ('stage_id.probability', '!=', 0),
                  ('stage_id.probability', '!=', 100)]
        lead_instance = lead_model.sudo().search(domain)

        if lead_instance:
            # a lead_id cookie exists and it has not been altered and the lead is not closed
            lead = lead_model.sudo().browse(lead_id)

            # NOTE: the following should be changed when dynamic forms exist
            changed_values = {}
            for fieldname, fieldvalue in values.items():
                if fieldname in lead and fieldvalue:
                    if lead[fieldname] and lead[fieldname] != fieldvalue:
                        changed_values[fieldname] = fieldvalue
                    else:
                        lead[fieldname] = fieldvalue
            # Post a message to indicate the updated field (if any)
            if changed_values:
                body = 'Other value given for field '
                for fieldname in changed_values.keys():
                    body += '<br/><b>%s</b>: <b>%s</b>' % (
                        fieldname, html_escape(changed_values[fieldname]))
                request.env['crm.lead'].browse(lead_id).sudo().message_post(
                    body=body, subject="Field value changed")

            return lead_id

        else:
            # either no lead_id cookie OR the lead_id doesn't exist in db OR the current one is closed -> a lead is created
            lang = request.context.get('lang', False)
            lang_id = request.env["res.lang"].sudo().search(
                [('code', '=', lang)], limit=1).id
            values['lang_id'] = lang_id
            body = None

            if 'pages_viewed' in request.session:
                score_pageview_ids = []
                url_list = []
                pages_viewed = request.session['pages_viewed']
                for url, date in pages_viewed.iteritems():
                    vals = {
                        'user_id': request.session.get('uid'),
                        'url': url,
                        'view_date': date
                    }
                    score_pageview_ids.append((0, 0, vals))
                    url_list.append(url)
                del request.session['pages_viewed']
                values['score_pageview_ids'] = score_pageview_ids
                urls = []
                for url in url_list:
                    url_encoded = html_escape(url)
                    urls.append('<a href="%s" target="_blank"><b>%s</b></a>' %
                                (url_encoded, url_encoded))
                body = '<br/>'.join(urls)

            new_lead_id = self.create_real_lead(request, model, values, custom,
                                                meta)

            # if pages were seen, a message is posted
            if body:
                request.env['crm.lead'].browse(
                    new_lead_id).sudo().message_post(body=body,
                                                     subject="Pages visited")

            return new_lead_id