[IMP] mail: support layouting in composer mailing mode
RATIONALE
Naming conventions
* content = core message / subject (+ other fields);
* email layout = layouting applied to messages when sent to recipients who
receive notifications by email e.g. access button, ...;
* comment mode / mailing mode: composer main composition mode: posting on
record(s) / sending a mailing on records;
Content situation when using a template to post on a composer
* comment, monorecord mode: choose a template, content is rendered directly
from template side according to 'lang' field definition -> ok;
* comment, multirecord mode / mailing mode: choose a template, content is
the raw content. At post / send, content is rendered and translated if
matching template content -> ok;
Email layout situation when posting / mailing
* comment: layout translated based on recipient lang or fallback on template
'lang' field definition, or current user's lang;
* mailing: no layout supported;
PURPOSE
Make those the two composer modes less different by supporting layouting in
mailing mode of composer. Consider it a bit experimental.
SPECIFICATIONS
When using the composer in mailing mode, render email layout if given. This
layout is used to encapsulate body.
To simplify rendering and sending, consider all recipients to be 'customer'
as defined in '_notify_get_recipients'. This means all recipients receive the
same basic layouting currently as a first attempt to improve this situation.
Considered lang is the one coming from the template 'lang' field, or fallback
on current user's lang.
Task-3186426 (Mail: Support notification layout in template / email composer)
Part-of: odoo/odoo#106177
This commit is contained in:
@@ -877,7 +877,7 @@ class MailComposer(models.TransientModel):
|
||||
|
||||
# langs, used currently only to propagate in comment mode for notification
|
||||
# layout translation
|
||||
langs = self._render_field('lang', res_ids) if not email_mode else {}
|
||||
langs = self._render_field('lang', res_ids)
|
||||
subjects = self._render_field('subject', res_ids, compute_lang=True)
|
||||
bodies = self._render_field(
|
||||
'body', res_ids, compute_lang=True,
|
||||
@@ -979,7 +979,7 @@ class MailComposer(models.TransientModel):
|
||||
# recipients: transform partner_ids (field used in mail_message) into
|
||||
# recipient_ids, used by mail_mail
|
||||
if email_mode:
|
||||
recipient_ids_all = mail_values.pop('partner_ids', []) + self.partner_ids.ids
|
||||
recipient_ids_all = set(mail_values.pop('partner_ids', [])) | set(self.partner_ids.ids)
|
||||
mail_values['recipient_ids'] = [(4, pid) for pid in recipient_ids_all]
|
||||
|
||||
# when having no specific reply_to -> fetch rendered email_from
|
||||
@@ -989,6 +989,42 @@ class MailComposer(models.TransientModel):
|
||||
reply_to = mail_values.get('email_from', False)
|
||||
mail_values['reply_to'] = reply_to
|
||||
|
||||
# body: render layout in email mode (comment mode is managed by the
|
||||
# notification process, see @_notify_thread_by_email)
|
||||
if email_mode and self.email_layout_xmlid and mail_values['recipient_ids']:
|
||||
lang = langs[res_id]
|
||||
recipient_ids = [command[1] for command in mail_values['recipient_ids']]
|
||||
msg_vals = {
|
||||
'email_layout_xmlid': self.email_layout_xmlid,
|
||||
'model': self.model,
|
||||
'res_id': res_id,
|
||||
}
|
||||
message_inmem = self.env['mail.message'].new({
|
||||
'body': mail_values['body'],
|
||||
})
|
||||
for _lang, render_values, recipients_group_data in record._notify_get_classified_recipients_iterator(
|
||||
message_inmem,
|
||||
[{
|
||||
'active': True,
|
||||
'id': pid,
|
||||
'lang': lang,
|
||||
'notif': 'email',
|
||||
'share': True,
|
||||
'type': 'customer',
|
||||
'ushare': False,
|
||||
} for pid in recipient_ids],
|
||||
msg_vals=msg_vals,
|
||||
model_description=False, # force dynamic computation
|
||||
force_email_lang=lang,
|
||||
):
|
||||
mail_body = record._notify_by_email_render_layout(
|
||||
message_inmem,
|
||||
recipients_group_data,
|
||||
msg_vals=msg_vals,
|
||||
render_values=render_values,
|
||||
)
|
||||
mail_values['body_html'] = mail_body
|
||||
|
||||
return mail_values_all
|
||||
|
||||
def _prepare_mail_values_rendered(self, res_ids):
|
||||
|
||||
@@ -2039,30 +2039,23 @@ class TestComposerResultsMass(TestMailComposer):
|
||||
email = self._find_sent_email(self.partner_employee_2.email_formatted, [record.customer_id.email_formatted])
|
||||
self.assertTrue(bool(email), 'Email not found, check recipients')
|
||||
|
||||
# Currently layouting in mailing mode is not supported.
|
||||
# Hence no translations.
|
||||
self.assertEqual(
|
||||
email['body'],
|
||||
f'<p>{exp_body}</p>'
|
||||
)
|
||||
# exp_layout_content_en = 'English Layout for Ticket-like model'
|
||||
# exp_layout_content_es = 'Spanish Layout para Spanish Model Description'
|
||||
# exp_button_en = 'View Ticket-like model'
|
||||
# exp_button_es = 'zefView Ticket-like model'
|
||||
# if email_layout_xmlid:
|
||||
# if exp_lang == 'es_ES':
|
||||
# self.assertIn(exp_layout_content_es, email['body'])
|
||||
# self.assertIn(exp_button_en, email['body'])
|
||||
# else:
|
||||
# self.assertIn(exp_layout_content_en, email['body'])
|
||||
# # self.assertIn(exp_button_es, email['body'])
|
||||
# self.assertIn(exp_button_en, email['body'])
|
||||
# else:
|
||||
# # check default layouting applies
|
||||
# if exp_lang == 'es_ES':
|
||||
# self.assertIn('html lang="es_ES"', email['body'])
|
||||
# else:
|
||||
# self.assertIn('html lang="en_US"', email['body'])
|
||||
if not email_layout_xmlid:
|
||||
self.assertEqual(
|
||||
email['body'],
|
||||
f'<p>{exp_body}</p>'
|
||||
)
|
||||
else:
|
||||
exp_layout_content_en = 'English Layout for Ticket-like model'
|
||||
exp_layout_content_es = 'Spanish Layout para Spanish Model Description'
|
||||
exp_button_en = 'View Ticket-like model'
|
||||
exp_button_es = 'Spanish Layout para Spanish Model Description'
|
||||
if exp_lang == 'es_ES':
|
||||
self.assertIn(exp_layout_content_es, email['body'])
|
||||
self.assertIn(exp_button_es, email['body'])
|
||||
else:
|
||||
self.assertIn(exp_layout_content_en, email['body'])
|
||||
# self.assertIn(exp_button_es, email['body'])
|
||||
self.assertIn(exp_button_en, email['body'])
|
||||
|
||||
@users('employee')
|
||||
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
|
||||
|
||||
Reference in New Issue
Block a user