[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
This commit is contained in:
Renaud Thiry
2023-04-17 11:47:11 +02:00
parent 20fe457377
commit 5c146ec219
2 changed files with 40 additions and 12 deletions
+15 -12
View File
@@ -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'):
@@ -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'<p>EnglishBody for {test_record.name}</p>')
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({