[IMP] mail: support email_layout_xmlid on template
RATIONALE Currently email layout choice is done in code and is not controllable through any user interface. In this commit we prepare improvements in template management by allowing to choose the email layout directly from a given mail template. As number of layouts is going to grow better be able to choose the right one. SPECIFICATIONS Add a field on template to propagate email layout choice directly on template and propagate it to the composer, then post/notify process. We can now choose directly on a template which notification layout should be used in conjunction with this template. Composer model already holds a field 'email_layout_xmlid', used in various places in code to give a specific layout to use when sending notifications emails e.g. SO email layout. This can now be specified directly from the template itself. It allows to customize the look and feel of notifications without having to do it explicitly in a given code flow. Computation is coming either from template, either reset. When having a template with a value set, set it on composer. When removing the template reset it. Currently no standard template uses it as this task targets mainly a code cleaning that began with the composer code cleaning. It targets the near freeze to have the base code updated once, then functional templates will make use of it (hopefully). Note that currently notification layout is still not supported at composer level for mailings. It is simply ignored when generating outgoing mail records. This will be improved soon. Global followup of odoo/odoo#107356 / Task-2088884 (Mail: Use editable computed stored fields in composer). Prepares code for Task-3046371 (Mail: Better Language Support in Composer) see odoo/odoo#106177 . Task-3186426 (Mail: Support notification layout in template / email composer) closes odoo/odoo#114462 Related: odoo/upgrade#4404 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
@@ -71,6 +71,7 @@ class MailTemplate(models.Model):
|
||||
column2='ir_actions_report_id',
|
||||
string='Dynamic Reports',
|
||||
domain="[('model', '=', model)]")
|
||||
email_layout_xmlid = fields.Char('Email Notification Layout', copy=False)
|
||||
# options
|
||||
mail_server_id = fields.Many2one('ir.mail_server', 'Outgoing Mail Server', readonly=False,
|
||||
help="Optional preferred server for outgoing mails. If not set, the highest "
|
||||
@@ -424,6 +425,8 @@ class MailTemplate(models.Model):
|
||||
# technical settings
|
||||
if 'auto_delete' in render_fields:
|
||||
values['auto_delete'] = self.auto_delete
|
||||
if 'email_layout_xmlid' in render_fields:
|
||||
values['email_layout_xmlid'] = self.email_layout_xmlid
|
||||
if 'mail_server_id' in render_fields:
|
||||
values['mail_server_id'] = self.mail_server_id.id
|
||||
if 'model' in render_fields:
|
||||
@@ -461,6 +464,7 @@ class MailTemplate(models.Model):
|
||||
'scheduled_date', # specific
|
||||
# not rendered (static)
|
||||
'auto_delete',
|
||||
'email_layout_xmlid',
|
||||
'mail_server_id',
|
||||
'model',
|
||||
'res_id',
|
||||
@@ -569,6 +573,7 @@ class MailTemplate(models.Model):
|
||||
if 'email_from' in values and not values.get('email_from'):
|
||||
values.pop('email_from')
|
||||
# encapsulate body
|
||||
email_layout_xmlid = email_layout_xmlid or self.email_layout_xmlid
|
||||
if email_layout_xmlid and values['body_html']:
|
||||
record = self.env[self.model].browse(res_id)
|
||||
model = self.env['ir.model']._get(record._name)
|
||||
|
||||
@@ -92,7 +92,10 @@ class MailComposer(models.TransientModel):
|
||||
'ir.attachment', 'mail_compose_message_ir_attachments_rel',
|
||||
'wizard_id', 'attachment_id', string='Attachments',
|
||||
compute='_compute_attachment_ids', readonly=False, store=True)
|
||||
email_layout_xmlid = fields.Char('Email Notification Layout', copy=False)
|
||||
email_layout_xmlid = fields.Char(
|
||||
'Email Notification Layout',
|
||||
compute='_compute_email_layout_xmlid', readonly=False, store=True,
|
||||
copy=False)
|
||||
email_add_signature = fields.Boolean(
|
||||
'Add signature',
|
||||
compute='_compute_email_add_signature', readonly=False, store=True)
|
||||
@@ -275,6 +278,17 @@ class MailComposer(models.TransientModel):
|
||||
else:
|
||||
composer.email_add_signature = not bool(composer.template_id)
|
||||
|
||||
@api.depends('template_id')
|
||||
def _compute_email_layout_xmlid(self):
|
||||
""" Computation is coming either from template, either reset. When
|
||||
having a template with a value set, set it on composer.When removing
|
||||
the template, reset it. """
|
||||
for composer in self:
|
||||
if composer.template_id.email_layout_xmlid:
|
||||
composer.email_layout_xmlid = composer.template_id.email_layout_xmlid
|
||||
if not composer.template_id:
|
||||
composer.email_layout_xmlid = False
|
||||
|
||||
@api.depends('composition_mode', 'email_from', 'model',
|
||||
'res_domain', 'res_ids', 'template_id')
|
||||
def _compute_authorship(self):
|
||||
|
||||
@@ -95,6 +95,13 @@ class TestMailComposer(TestMailCommon, TestRecipients):
|
||||
'scheduled_date': '{{ (object.create_date or datetime.datetime(2022, 12, 26, 18, 0, 0)) + datetime.timedelta(days=2) }}',
|
||||
})
|
||||
|
||||
# activate translations
|
||||
cls._activate_multi_lang(
|
||||
layout_arch_db=None, # use default mail.test_layout
|
||||
test_record=cls.test_records,
|
||||
test_template=cls.template,
|
||||
)
|
||||
|
||||
def _get_web_context(self, records, add_web=True, **values):
|
||||
""" Helper to generate composer context. Will make tests a bit less
|
||||
verbose.
|
||||
@@ -1332,13 +1339,17 @@ class TestComposerResultsComment(TestMailComposer, CronMixinCase):
|
||||
attachs = self.env['ir.attachment'].search([('name', 'in', [a['name'] for a in attachment_data])])
|
||||
self.assertEqual(len(attachs), 2)
|
||||
|
||||
for batch_mode, scheduled_date in product(
|
||||
for batch_mode, scheduled_date, email_layout_xmlid in product(
|
||||
(False, True, 'domain'),
|
||||
(False, '{{ (object.create_date or datetime.datetime(2022, 12, 26, 18, 0, 0)) + datetime.timedelta(days=2) }}')
|
||||
(False, '{{ (object.create_date or datetime.datetime(2022, 12, 26, 18, 0, 0)) + datetime.timedelta(days=2) }}'),
|
||||
(False, 'mail.test_layout'),
|
||||
):
|
||||
with self.subTest(batch_mode=batch_mode, scheduled_date=scheduled_date):
|
||||
batch = bool(batch_mode)
|
||||
self.template.write({'scheduled_date': scheduled_date})
|
||||
self.template.write({
|
||||
'scheduled_date': scheduled_date,
|
||||
'email_layout_xmlid': email_layout_xmlid,
|
||||
})
|
||||
test_records = self.test_records if batch else self.test_record
|
||||
|
||||
# ensure initial data
|
||||
@@ -1361,6 +1372,7 @@ class TestComposerResultsComment(TestMailComposer, CronMixinCase):
|
||||
# open a composer and run it in comment mode
|
||||
composer_form = Form(self.env['mail.compose.message'].with_context(ctx))
|
||||
composer = composer_form.save()
|
||||
self.assertEqual(composer.email_layout_xmlid, email_layout_xmlid)
|
||||
|
||||
# ensure some parameters used afterwards
|
||||
if batch:
|
||||
|
||||
Reference in New Issue
Block a user