You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
6.0 KiB

  1. # Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
  2. # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
  3. import logging
  4. from odoo import models, fields, api, tools, _
  5. from odoo.exceptions import UserError
  6. from odoo.tools import pycompat
  7. from odoo.addons.mail.models.mail_template import format_date, format_tz, format_amount
  8. _logger = logging.getLogger(__name__)
  9. FIELDS = ['body_html', 'mail_server_id', 'report_template']
  10. try:
  11. from odoo.addons.mail.models.mail_template import mako_safe_template_env, mako_template_env
  12. except ImportError:
  13. _logger.warning("jinja2 not available, templating features will not work!")
  14. class MailTemplate(models.Model):
  15. _inherit = ['mail.template', 'website_dependent.mixin']
  16. _name = 'mail.template'
  17. body_html = fields.Html(company_dependent=True, website_dependent=True)
  18. mail_server_id = fields.Many2one(string='Outgoing Mail Server (Multi-Website)', company_dependent=True, website_dependent=True)
  19. report_template = fields.Many2one(string='Optional report to print and attach (Multi-Website)', company_dependent=True, website_dependent=True)
  20. @api.multi
  21. def generate_email(self, res_ids, fields=None):
  22. """Remove mail_server_id when not set to recompute in _default_mail_server_id in mail.message"""
  23. multi_mode = True
  24. if isinstance(res_ids, pycompat.integer_types):
  25. multi_mode = False
  26. res = super(MailTemplate, self).generate_email(res_ids, fields=fields)
  27. if not multi_mode:
  28. list_of_dict = {0: res}
  29. else:
  30. list_of_dict = res
  31. for _unused, data in list_of_dict.items():
  32. if 'mail_server_id' in data and not data.get('mail_server_id'):
  33. del data['mail_server_id']
  34. return res
  35. @api.model
  36. def _render_template(self, template_txt, model, res_ids, post_process=False):
  37. """Override to add website to context"""
  38. multi_mode = True
  39. if isinstance(res_ids, pycompat.integer_types):
  40. multi_mode = False
  41. res_ids = [res_ids]
  42. results = dict.fromkeys(res_ids, u"")
  43. # try to load the template
  44. try:
  45. mako_env = mako_safe_template_env if self.env.context.get('safe') else mako_template_env
  46. template = mako_env.from_string(tools.ustr(template_txt))
  47. except Exception:
  48. _logger.info("Failed to load template %r", template_txt, exc_info=True)
  49. return multi_mode and results or results[res_ids[0]]
  50. # prepare template variables
  51. records = self.env[model].browse(it for it in res_ids if it) # filter to avoid browsing [None]
  52. res_to_rec = dict.fromkeys(res_ids, None)
  53. for record in records:
  54. res_to_rec[record.id] = record
  55. variables = {
  56. 'format_date': lambda date, format=False, context=self._context: format_date(self.env, date, format),
  57. 'format_tz': lambda dt, tz=False, format=False, context=self._context: format_tz(self.env, dt, tz, format),
  58. 'format_amount': lambda amount, currency, context=self._context: format_amount(self.env, amount, currency),
  59. 'user': self.env.user,
  60. 'ctx': self._context, # context kw would clash with mako internals
  61. }
  62. # [NEW] Check website and company context
  63. company = self.env['res.company'] # empty value
  64. company_id = self.env.context.get('force_company')
  65. if company_id:
  66. company = self.env['res.company'].sudo().browse(company_id)
  67. if self.env.context.get('website_id'):
  68. website = self.env['website'].browse(self.env.context.get('website_id'))
  69. else:
  70. website = self.env.user.backend_website_id
  71. for res_id, record in res_to_rec.items():
  72. record_company = company
  73. if not record_company:
  74. if hasattr(record, 'company_id') and record.company_id:
  75. record_company = record.company_id
  76. record_website = website
  77. if hasattr(record, 'website_id') and record.website_id:
  78. record_website = record.website_id
  79. if record_company and record_website \
  80. and record_website.company_id != company:
  81. # company and website are incompatible, so keep only company
  82. record_website = self.env['website'] # empty value
  83. record_context = dict(force_company=record_company.id, website_id=record_website.id)
  84. variables['object'] = record.with_context(**record_context)
  85. variables['website'] = record_website
  86. try:
  87. render_result = template.render(variables)
  88. except Exception:
  89. _logger.info("Failed to render template %r using values %r" % (template, variables), exc_info=True)
  90. raise UserError(_("Failed to render template %r using values %r") % (template, variables))
  91. if render_result == u"False":
  92. render_result = u""
  93. if post_process:
  94. render_result = self.with_context(**record_context).render_post_process(render_result)
  95. results[res_id] = render_result
  96. return multi_mode and results or results[res_ids[0]]
  97. @api.model
  98. def create(self, vals):
  99. res = super(MailTemplate, self).create(vals)
  100. # make value company independent
  101. for f in FIELDS:
  102. res._force_default(f, vals.get(f))
  103. return res
  104. @api.multi
  105. def write(self, vals):
  106. res = super(MailTemplate, self).write(vals)
  107. # TODO: will it work with OCA's partner_firstname module?
  108. if 'name' in vals:
  109. fields_to_update = FIELDS
  110. else:
  111. fields_to_update = [
  112. f for f in FIELDS
  113. if f in vals
  114. ]
  115. for f in fields_to_update:
  116. self._update_properties_label(f)
  117. return res
  118. def _auto_init(self):
  119. for f in FIELDS:
  120. self._auto_init_website_dependent(f)
  121. return super(MailTemplate, self)._auto_init()