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.

185 lines
6.5 KiB

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