[REF] mail: improve composer call to template values generation
Now that template generation methods have been cleaned we can cleanup calls done in composer. We notably * make methods private, improve their naming and docstrings; * better support input / output of asked fields; * be more coherent with composer fields and template fields usage; Task-2710804 (Mail: Clean MailThread Posting API) Prepares Task-2088884 (Mail: Composer Onchange to Editable Computed Stored) Part-of: odoo/odoo#99482
This commit is contained in:
@@ -203,12 +203,11 @@ class MailComposer(models.TransientModel):
|
||||
-> for x2many field, this onchange return command instead of ids
|
||||
"""
|
||||
if template_id and composition_mode == 'mass_mail':
|
||||
# copy raw template values (not rendered due to mass mode)
|
||||
template = self.env['mail.template'].browse(template_id)
|
||||
values = dict(
|
||||
(field, template[field])
|
||||
for field in ('body_html',
|
||||
'email_from',
|
||||
'mail_server_id',
|
||||
for field in ('email_from',
|
||||
'reply_to',
|
||||
'subject',
|
||||
)
|
||||
@@ -218,16 +217,20 @@ class MailComposer(models.TransientModel):
|
||||
values['attachment_ids'] = [att.id for att in template.attachment_ids]
|
||||
if template.mail_server_id:
|
||||
values['mail_server_id'] = template.mail_server_id.id
|
||||
if not tools.is_html_empty(template.body_html):
|
||||
values['body'] = template.body_html
|
||||
elif template_id:
|
||||
values = self._generate_email_for_composer(
|
||||
template_id, [res_id],
|
||||
# render template (mono record, comment mode) and set it as composer values
|
||||
values = self._generate_template_for_composer(
|
||||
self.env['mail.template'].browse(template_id),
|
||||
[res_id],
|
||||
('attachment_ids',
|
||||
'body_html',
|
||||
'email_cc',
|
||||
'email_from',
|
||||
'email_to',
|
||||
'mail_server_id',
|
||||
'partner_to',
|
||||
'partner_ids',
|
||||
'reply_to',
|
||||
'report_template',
|
||||
'subject',
|
||||
@@ -276,9 +279,6 @@ class MailComposer(models.TransientModel):
|
||||
'subject',
|
||||
) if key in default_values)
|
||||
|
||||
if values.get('body_html'):
|
||||
values['body'] = values.pop('body_html')
|
||||
|
||||
# This onchange should return command instead of ids for x2many field.
|
||||
values = self._convert_to_write(values)
|
||||
|
||||
@@ -642,13 +642,14 @@ class MailComposer(models.TransientModel):
|
||||
|
||||
# generate template-based values
|
||||
if self.template_id:
|
||||
template_values = self._generate_email_for_composer(
|
||||
self.template_id.id, res_ids,
|
||||
template_values = self._generate_template_for_composer(
|
||||
self.template_id,
|
||||
res_ids,
|
||||
('attachment_ids',
|
||||
'email_to',
|
||||
'email_cc',
|
||||
'mail_server_id',
|
||||
'partner_to',
|
||||
'partner_ids',
|
||||
'report_template',
|
||||
)
|
||||
)
|
||||
@@ -670,26 +671,55 @@ class MailComposer(models.TransientModel):
|
||||
|
||||
return template_values
|
||||
|
||||
@api.model
|
||||
def _generate_email_for_composer(self, template_id, res_ids, render_fields):
|
||||
""" Call email_template._generate_template(), get fields relevant for
|
||||
mail.compose.message, transform email_cc and email_to into partner_ids """
|
||||
returned_fields = list(render_fields) + ['partner_ids']
|
||||
if 'report_template' in render_fields:
|
||||
returned_fields.append('attachments')
|
||||
values = dict.fromkeys(res_ids, False)
|
||||
def _generate_template_for_composer(self, template, res_ids, render_fields,
|
||||
find_or_create_partners=True):
|
||||
""" Generate values based on template and relevant values for the
|
||||
mail.compose.message wizard.
|
||||
|
||||
template_values = self.env['mail.template'].browse(template_id)._generate_template(
|
||||
:param record template: a mail template, as during onchange mode it
|
||||
may not be set on self (to remove when removing the onchange);
|
||||
:param list res_ids: list of record IDs on which template is rendered;
|
||||
:param list render_fields: list of fields to render on template;
|
||||
:param boolean find_or_create_partners: transform emails into partners
|
||||
(see ``Template._generate_template_recipients``);
|
||||
|
||||
:returns: a dict containing all asked fields for each record ID given by
|
||||
res_ids. Note that
|
||||
|
||||
* 'body' comes from template 'body_html' generation;
|
||||
* 'attachments' is an additional key coming with 'attachment_ids' due
|
||||
to report generation (in the format [(report_name, data)] where data
|
||||
is base64 encoded);
|
||||
* 'partner_ids' is returned due to recipients generation that gives
|
||||
partner ids coming from default computation as well as from email
|
||||
to partner convert (see ``find_or_create_partners``);
|
||||
"""
|
||||
self.ensure_one()
|
||||
|
||||
# some fields behave / are named differently on template model
|
||||
mapping = {
|
||||
'attachments': 'report_template',
|
||||
'body': 'body_html',
|
||||
'partner_ids': 'partner_to',
|
||||
}
|
||||
template_fields = {mapping.get(fname, fname) for fname in render_fields}
|
||||
template_values = template._generate_template(
|
||||
res_ids,
|
||||
render_fields,
|
||||
template_fields,
|
||||
find_or_create_partners=True
|
||||
)
|
||||
for res_id in res_ids:
|
||||
res_id_values = dict((field, template_values[res_id][field]) for field in returned_fields if template_values[res_id].get(field))
|
||||
res_id_values['body'] = res_id_values.pop('body_html', '')
|
||||
values[res_id] = res_id_values
|
||||
|
||||
return values
|
||||
exclusion_list = ('email_cc', 'email_to') if find_or_create_partners else ()
|
||||
mapping = {'body_html': 'body'}
|
||||
render_results = {}
|
||||
for res_id in res_ids:
|
||||
render_results[res_id] = {
|
||||
mapping.get(fname, fname): value
|
||||
for fname, value in template_values[res_id].items()
|
||||
if fname not in exclusion_list and value
|
||||
}
|
||||
|
||||
return render_results
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# EMAIL MANAGEMENT
|
||||
|
||||
@@ -593,14 +593,13 @@ class TestComposerInternals(TestMailComposer):
|
||||
self.assertEqual(composer.subject, 'Back to my amazing subject for {{ record.name }}')
|
||||
|
||||
# update with template with void values: void value is not forced in
|
||||
# rendering mode as well as when copying template values, except for
|
||||
# body in rendering mode
|
||||
# rendering mode as well as when copying template values
|
||||
composer.write({'template_id': template_void.id})
|
||||
# currently onchange necessary
|
||||
composer._onchange_template_id_wrapper()
|
||||
|
||||
if composition_mode == 'comment':
|
||||
self.assertFalse(composer.body, 'Void template body resets while other fields not, maybe to fix')
|
||||
self.assertEqual(composer.body, 'Back to my amazing body')
|
||||
self.assertEqual(composer.mail_server_id, self.mail_server_global)
|
||||
self.assertEqual(composer.record_name, 'Manual update')
|
||||
self.assertEqual(composer.subject, 'Back to my amazing subject for {{ record.name }}')
|
||||
|
||||
Reference in New Issue
Block a user