Example #1
0
    def _qweb_render_context(self, record):
        """Compute variables to render Qweb templates.

        Some vars are added to ease porting of Jinja templates.
        """
        res = {
            "object": record,
            "email_template": self,
        }
        ctx = dict(self.env.context)
        if record._name == "mail.message":
            partner_model = self.env["res.partner"]  # pragma: no cover
            # These variables are usually loaded when the notification is sent.
            # It normally happens on `partner._notify` call,
            # hence - due to the call here - is going to happen twice.
            # Nevertheless there are some important values
            # that can be mandatory for your templates
            # especially if you load them
            # from the mail composer. In this case
            # the template will be rendered but it will miss many params.
            # NOTE: some keys related to partner-specific permissions
            # such as `actions` or `button_follow` won't be available
            # until the final rendering happens.
            # Check the variable `recipient_template_values`
            # that comes from `_message_notification_recipients`
            # in `partner._notify`.
            ctx.update(partner_model._notify_prepare_template_context(
                record))  # pragma: no cover
        res.update({
            # Same as for Jinja rendering,
            # taken from `mail_template.render_template`.
            # These ease porting of old Jinja templates to qweb ones.
            # fmt: off
            "format_date":
            lambda date, format=False, context=self._context: format_date(
                self.env, date, format),
            "format_tz":
            lambda dt, tz=False, format=False, context=self._context:
            format_datetime(self.env, dt, tz, format),
            "format_amount":
            lambda amount, currency, context=self._context: format_amount(
                self.env, amount, currency),
            # fmt: on
            "user":
            self.env.user,
            # keep it for Jinja template compatibility
            "ctx":
            ctx,
        })
        # Alias `record` to be always the main record needed by the template.
        # Imagine a template for sale.order: when you load it in the composer
        # the current `object` is the SO you are looking at,
        # BUT when you send the message, the `object` is the message
        # and not the SO anymore.
        # Hence, stick the main record to `record` to make templates robust.
        res["record"] = ctx.get("record", record)
        res["record_name"] = ctx.get("record_name", record.display_name)
        return res
    def get_payment_mode_display(self):
        self.ensure_one()

        payment_mode = self.of_payment_mode_id
        result = False

        if payment_mode.config_affichage:
            affichage = self.env['mail.template'].render_template(payment_mode.config_affichage, 'account.payment', self.id, post_process=False)
            result = affichage

        if not result:
            result = _('Paid on %s') % format_date(self.env, self.payment_date)

        return result
Example #3
0
    def render_template(self,
                        template_txt,
                        model,
                        res_ids,
                        post_process=False):
        """ Render the given template text, replace mako expressions
        ``${expr}`` with the result of evaluating these expressions
        with an evaluation context containing:

         - ``user``: browse_record of the current user
         - ``object``: record of the document record this mail is related to
         - ``context``: the context passed to the mail composition wizard

        :param str template_txt: the template text to render
        :param str model: model name of the document record
            this mail is related to.
        :param int res_ids: list of ids of document records
            those mails are related to.
        """
        multi_mode = True
        if isinstance(res_ids, (int, long)):
            multi_mode = False
            res_ids = [res_ids]

        results = dict.fromkeys(res_ids, u"")

        # try to load the template
        try:
            mako_env = mako_safe_template_env if self.env.context.get('safe') \
                else mako_template_env
            template = mako_env.from_string(tools.ustr(template_txt))
        except Exception:
            _logger.info("Failed to load template %r",
                         template_txt,
                         exc_info=True)
            return multi_mode and results or results[res_ids[0]]

        # prepare template variables
        # filter to avoid browsing [None]
        records = self.env[model].browse(list(filter(None, res_ids)))
        res_to_rec = dict.fromkeys(res_ids, None)
        for record in records:
            res_to_rec[record.id] = record
        variables = {
            'format_date':
            lambda date, format=False, context=self._context: format_date(
                self.env, date, format),
            'format_datetime':
            lambda dt, tz=False, format=False, context=self._context: tools.
            format_datetime(self.env, dt, tz, format),
            'format_amount':
            lambda amount, currency, context=self._context: tools.
            format_amount(self.env, amount, currency),
            'format_numeric':
            lambda value, column, options=None: self.format_numeric(
                value, column, options),  # Added by Smile
            'user':
            self.env.user,
            'ctx':
            self._context,  # context kw would clash with mako internals
        }
        for res_id, record in res_to_rec.items():
            variables['object'] = record
            try:
                render_result = template.render(variables)
            except Exception:
                _logger.info("Failed to render template %r using values %r" %
                             (template, variables),
                             exc_info=True)
                raise UserError(
                    _("Failed to render template %r using values %r") %
                    (template, variables))
            if render_result == u"False":
                render_result = u""
            results[res_id] = render_result

        if post_process:
            for res_id, result in results.items():
                results[res_id] = self.render_post_process(result)

        return multi_mode and results or results[res_ids[0]]
Example #4
0
    def _render_template(self, template_txt, model, res_ids, post_process=False):
        """Override to add website to context"""
        multi_mode = True
        if isinstance(res_ids, pycompat.integer_types):
            multi_mode = False
            res_ids = [res_ids]

        results = dict.fromkeys(res_ids, u"")

        # try to load the template
        try:
            mako_env = mako_safe_template_env if self.env.context.get('safe') else mako_template_env
            template = mako_env.from_string(tools.ustr(template_txt))
        except Exception:
            _logger.info("Failed to load template %r", template_txt, exc_info=True)
            return multi_mode and results or results[res_ids[0]]

        # prepare template variables
        records = self.env[model].browse(it for it in res_ids if it)  # filter to avoid browsing [None]
        res_to_rec = dict.fromkeys(res_ids, None)
        for record in records:
            res_to_rec[record.id] = record

        variables = {
            'format_date': lambda date, format=False, context=self._context: format_date(self.env, date, format),
            'format_tz': lambda dt, tz=False, format=False, context=self._context: format_tz(self.env, dt, tz, format),
            'format_amount': lambda amount, currency, context=self._context: format_amount(self.env, amount, currency),
            'user': self.env.user,
            'ctx': self._context,  # context kw would clash with mako internals
        }

        # [NEW] Check website and company context
        company = self.env['res.company']  # empty value

        company_id = self.env.context.get('force_company')
        if company_id:
            company = self.env['res.company'].sudo().browse(company_id)

        if self.env.context.get('website_id'):
            website = self.env['website'].browse(self.env.context.get('website_id'))
        else:
            website = self.env.user.backend_website_id

        for res_id, record in res_to_rec.items():
            record_company = company
            if not record_company:
                if hasattr(record, 'company_id') and record.company_id:
                    record_company = record.company_id

            record_website = website
            if hasattr(record, 'website_id') and record.website_id:
                record_website = record.website_id

            if record_company and record_website \
               and record_website.company_id != company:
                # company and website are incompatible, so keep only company
                record_website = self.env['website']  # empty value

            record_context = dict(force_company=record_company.id, website_id=record_website.id)
            variables['object'] = record.with_context(**record_context)
            variables['website'] = record_website

            try:
                render_result = template.render(variables)
            except Exception:
                _logger.info("Failed to render template %r using values %r" % (template, variables), exc_info=True)
                raise UserError(_("Failed to render template %r using values %r") % (template, variables))
            if render_result == u"False":
                render_result = u""

            if post_process:
                render_result = self.with_context(**record_context).render_post_process(render_result)

            results[res_id] = render_result

        return multi_mode and results or results[res_ids[0]]
Example #5
0
    def _get_dict_values(self, o, objects):
        if not o:
            return {}
        lang_obj = self.env['res.lang']

        order = objects['order']
        invoice = objects['invoice']
        partner = objects['partner']
        address = objects['address']
        address_pose = objects['address_pose']
        cal_event = objects['cal_event']

        lang_code = self._context.get('lang', partner.lang)
        lang = lang_obj.search([('code', '=', lang_code or 'fr_FR')])

        values = (
            ('amount_total', o, ''),
            ('origin', o, ''),
            ('date_order', order or o, ''),
            ('confirmation_date', order or o, ''),
            ('date_invoice', invoice or o, ''),
            ('residual', invoice or o, ''),
            ('number', invoice, ''),
            ('user_id', o, ''),
            ('objet', o, ''),
        )

        res = {
            key: getattr(obj, key, default) or default
            for key, obj, default in values
        }

        res['date_confirm_order'] = res['confirmation_date']
        del res['confirmation_date']
        res['user_name'] = res['user_id'] and res['user_id'].name
        del res['user_id']

        if cal_event:
            date_event = fields.Datetime.from_string(cal_event.start)
            date_event = fields.Datetime.context_timestamp(self, date_event)

        date_format = lang.date_format.encode('utf-8')
        res.update({
            'c_title':
            address.title.name or 'Madame, Monsieur',
            'c_name':
            address.name or (address.parent_id and address.parent_id.name)
            or '',
            'c_note':
            partner.comment,
            'c_street':
            address.street or '',
            'c_street2':
            address.street2 or '',
            'c_zip':
            address.zip or '',
            'c_city':
            address.city or '',
            'c_phone':
            address.phone or '',
            'c_mobile':
            address.mobile or '',
            'c_fax':
            address.fax or '',
            'c_email':
            address.email or '',
            'c_adr_intervention_name':
            address_pose.name or address_pose.parent_id.name or '',
            'c_adr_intervention_street':
            address_pose.street or '',
            'c_adr_intervention_street2':
            address_pose.street2 or '',
            'c_adr_intervention_city':
            address_pose.city or '',
            'c_adr_intervention_zip':
            address_pose.zip or '',
            'c_rdv_date':
            cal_event and date_event.strftime(date_format) or '',
            'c_rdv_heure':
            cal_event and date_event.strftime('%H:%M') or '',
            'date':
            time.strftime(date_format),
            'order_name':
            order and order.name or '',
        })

        for date_field in ('date_order', 'date_confirm_order', 'date_invoice'):
            if not res[date_field]:
                continue

            date = fields.Datetime.from_string(res[date_field])
            date = date.strftime(date_format)
            res[date_field] = date

        # Pour rétrocompatibilité
        res.update({
            'c_adr_pose_name': res['c_adr_intervention_name'],
            'c_adr_pose_street': res['c_adr_intervention_street'],
            'c_adr_pose_street2': res['c_adr_intervention_street2'],
            'c_adr_pose_city': res['c_adr_intervention_city'],
            'c_adr_pose_zip': res['c_adr_intervention_zip'],
        })

        res.update(objects)
        res.update({
            'o':
            o,
            'format_date':
            lambda date, format=False, context=self._context: format_date(
                self.env, date, format),
            'format_tz':
            lambda dt, tz=False, format=False, context=self._context:
            format_tz(self.env, dt, tz, format),
            'format_amount':
            lambda amount, currency, context=self._context: format_amount(
                self.env, amount, currency),
            'user':
            self.env.user,
            'ctx':
            self._context,  # context kw would clash with mako internals
        })
        return res