From 5c146ec219bf57788495c4989d531a961fd5a391 Mon Sep 17 00:00:00 2001 From: Renaud Thiry Date: Tue, 7 Mar 2023 21:02:18 +0000 Subject: [PATCH] [FIX] mail: compute resource_ref Before this, the resource_ref field is computed once in the default_get. This means if the cache is invalidated, its value is unrecoverable. Notably, the cache is invalidated when an attachment is generated (triggering a commit). So calling _generate_template could invalidate resource_ref, which we use as a key to retrieve its result. This results in a traceback for the user when trying to preview a template where the first record hasn't yet generated its attachment. As an example, trying to preview `Sales: Send Quotation` on fresh installs. task-3162320 X-original-commit: b4bd93c9b61736a7f41d70afe5db977a6e4b35e0 Part-of: odoo/odoo#118710 --- addons/mail/wizard/mail_template_preview.py | 27 ++++++++++--------- .../tests/test_mail_template_preview.py | 25 +++++++++++++++++ 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/addons/mail/wizard/mail_template_preview.py b/addons/mail/wizard/mail_template_preview.py index aea4beddcc3..0f9708aa554 100644 --- a/addons/mail/wizard/mail_template_preview.py +++ b/addons/mail/wizard/mail_template_preview.py @@ -28,21 +28,16 @@ class MailTemplatePreview(models.TransientModel): def _selection_languages(self): return self.env['res.lang'].get_installed() - @api.model - def default_get(self, fields): - result = super(MailTemplatePreview, self).default_get(fields) - if not result.get('mail_template_id') or 'resource_ref' not in fields: - return result - mail_template = self.env['mail.template'].browse(result['mail_template_id']).sudo() - model = mail_template.model - res = self.env[model].search([], limit=1) - if res: - result['resource_ref'] = '%s,%s' % (model, res.id) - return result mail_template_id = fields.Many2one('mail.template', string='Related Mail Template', required=True) model_id = fields.Many2one('ir.model', string='Targeted model', related="mail_template_id.model_id") - resource_ref = fields.Reference(string='Record', selection='_selection_target_model') + resource_ref = fields.Reference( + string='Record', + compute='_compute_resource_ref', + compute_sudo=False, readonly=False, + selection='_selection_target_model', + store=True + ) lang = fields.Selection(_selection_languages, string='Template Preview Language') no_record = fields.Boolean('No Record', compute='_compute_no_record') error_msg = fields.Char('Error Message', compute='_compute_mail_template_fields') @@ -88,6 +83,14 @@ class MailTemplatePreview(models.TransientModel): error_msg = user_error.args[0] self.error_msg = error_msg + @api.depends('mail_template_id') + def _compute_resource_ref(self): + for preview in self: + mail_template = preview.mail_template_id.sudo() + model = mail_template.model + res = self.env[model].search([], limit=1) + preview.resource_ref = f'{model},{res.id}' if res else False + def _set_mail_attributes(self, values=None): for field in self._MAIL_TEMPLATE_FIELDS: if field in ('partner_to', 'report_template_ids'): diff --git a/addons/test_mail/tests/test_mail_template_preview.py b/addons/test_mail/tests/test_mail_template_preview.py index df223d6fd97..9bac5987e89 100644 --- a/addons/test_mail/tests/test_mail_template_preview.py +++ b/addons/test_mail/tests/test_mail_template_preview.py @@ -34,6 +34,31 @@ class TestMailTemplateTools(TestMailTemplateCommon): continue self.assertEqual(test_template[field], preview[field]) + def test_mail_template_preview_dynamic_attachment(self): + """Check behaviour with templates that use reports.""" + test_record = self.env['mail.test.lang'].browse(self.test_record.ids) + test_report = self.env['ir.actions.report'].sudo().create({ + 'name': 'Test Report', + 'model': test_record._name, + 'print_report_name': "'TestReport for %s' % object.name", + 'report_type': 'qweb-pdf', + 'report_name': 'test_mail.mail_test_ticket_test_template', + }) + self.test_template.write({ + 'report_template_ids': test_report.ids, + 'attachment_ids': False, + }) + + preview = self.env['mail.template.preview'].with_context({ + 'force_report_rendering': False, # this also invalidates the test records... + }).create({ + 'mail_template_id': self.test_template.id, + 'resource_ref': test_record, + }) + + self.assertEqual(preview.body_html, f'

EnglishBody for {test_record.name}

') + self.assertFalse(preview.attachment_ids, 'Reports should not be listed in attachments') + def test_mail_template_preview_force_lang(self): test_record = self.env['mail.test.lang'].browse(self.test_record.ids) test_record.write({