[MERGE] mail, various: improve notification layout buttons and usage

PURPOSE

Display "View document" link on notification emails using the 'light' layout
as done in standard layout.

Cleanup layout xml id propagation through composer or email sending in
mail and various applications.

SPECIFICATIONS: LAYOUT XML ID USAGE

Get rid of context usage and use a real field on mail.compose.message model.
Support old context key in composer for backward compatibility, working like
a default value for the field itself.

On template model: rename ``notif_layout`` parameter of ``send_mail`` to
``email_layout_xmlid`` to be coherent with naming used in other parts of the
code. Moreover it better indicates we expect an xml id.

On rating model: rename ``notif_layout`` parameter of ``rating_send_request``
to ``email_layout_xmlid``, for the same reasons as above.

In various wizards: support ``email_layout_xmlid`` context key when no field
is available, notably because this is still done manually in some wizards
like survey invite. Keep a fallback on ``notif_layout`` but remove support of
``custom_layout`` deprecated since quite a long time.

SPECIFICATIONS: ACCESS LINK

Light template is used is several notification processes as an alternate
layout to the classic one. It currently lacks any link to the document that
generated the notifications.

We add this behavior in this commit. Behavior is the same as the classic
notification email, aka a link to mail/view that chooses what to do based
on access rights and user status (internal, portal, ...).

SPECIFICATIONS: MISC

Remove ``mail_notification_borders`` as it is not used anymore.

LINKS

Task-2621326 (Mail: add 'view' button in 'light notification template')
Task-2647302 (Mail: add layout field in composer

closes odoo/odoo#76418

Related: odoo/enterprise#20903
Related: odoo/upgrade#2829
Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com>
This commit is contained in:
Odoo's Mergebot
2021-11-10 10:58:11 +01:00
committed by GitHub
33 changed files with 172 additions and 200 deletions
+2 -2
View File
@@ -3091,6 +3091,7 @@ class AccountMove(models.Model):
'res_model': 'account.invoice.send',
'view_mode': 'form',
'context': {
'default_email_layout_xmlid': 'mail.mail_notification_paynow',
'default_template_id': self.env.ref(self._get_mail_template()).id,
'mark_invoice_as_sent': True,
'active_model': 'account.move',
@@ -3098,7 +3099,6 @@ class AccountMove(models.Model):
# ir.actions.act_window works
'active_id': self.ids[0],
'active_ids': self.ids,
'custom_layout': 'mail.mail_notification_paynow',
},
'target': 'new',
'type': 'ir.actions.act_window',
@@ -3127,7 +3127,7 @@ class AccountMove(models.Model):
default_template_id=template and template.id or False,
default_composition_mode='comment',
mark_invoice_as_sent=True,
custom_layout="mail.mail_notification_paynow",
default_email_layout_xmlid="mail.mail_notification_paynow",
model_description=self.with_context(lang=lang).type_name,
force_email=True,
wizard_opened=True
@@ -409,7 +409,7 @@
'default_composition_mode': 'comment',
'default_use_template': True,
'default_template_id': ref('account.mail_template_data_payment_receipt'),
'custom_layout': 'mail.mail_notification_light',
'default_email_layout_xmlid': 'mail.mail_notification_light',
}"/>
<field name="binding_model_id" ref="model_account_payment"/>
<field name="binding_view_types">form</field>
@@ -426,7 +426,7 @@
'default_composition_mode': 'mass_mail',
'default_use_template': True,
'default_template_id': ref('account.mail_template_data_payment_receipt'),
'custom_layout': 'mail.mail_notification_light',
'default_email_layout_xmlid': 'mail.mail_notification_light',
}"/>
<field name="binding_model_id" ref="model_account_payment"/>
<field name="binding_view_types">list</field>
+1 -1
View File
@@ -221,7 +221,7 @@ class ResUsers(models.Model):
# For sending mail to all the invitors about their invited users
for user in invited_users:
template = self.env.ref('auth_signup.mail_template_data_unregistered_users').with_context(dbname=self._cr.dbname, invited_users=invited_users[user])
template.send_mail(user, notif_layout='mail.mail_notification_light', force_send=False)
template.send_mail(user, email_layout_xmlid='mail.mail_notification_light', force_send=False)
@api.model
def web_create_users(self, emails):
+1 -1
View File
@@ -29,7 +29,7 @@ class Users(models.Model):
'author_id': self.env.user.partner_id.id,
}
invite_template.send_mail(user.id, force_send=True, email_values=email_values,
notif_layout='mail.mail_notification_light')
email_layout_xmlid='mail.mail_notification_light')
# Display a confirmation toaster
return {
+1 -1
View File
@@ -65,7 +65,7 @@ class Coupon(models.Model):
default_use_template=bool(default_template),
default_template_id=default_template and default_template.id,
default_composition_mode='comment',
custom_layout='mail.mail_notification_light',
default_email_layout_xmlid='mail.mail_notification_light',
mark_coupon_as_sent=True,
force_email=True,
)
+1 -1
View File
@@ -39,7 +39,7 @@ class CouponGenerate(models.TransientModel):
del context
if self.template_id:
email_values = {'email_from': self.env.user.email or '', 'subject': subject}
self.template_id.send_mail(coupon.id, email_values=email_values, notif_layout='mail.mail_notification_light')
self.template_id.send_mail(coupon.id, email_values=email_values, email_layout_xmlid='mail.mail_notification_light')
@api.depends('partners_domain')
def _compute_has_partner_email(self):
+1 -1
View File
@@ -237,7 +237,7 @@ class EventRegistration(models.Model):
default_use_template=bool(template),
default_template_id=template.id,
default_composition_mode='comment',
custom_layout="mail.mail_notification_light",
default_email_layout_xmlid="mail.mail_notification_light",
)
return {
'name': _('Compose Email'),
+1 -1
View File
@@ -184,7 +184,7 @@ WHERE sub.user_id IN %%s""" % {
if template:
for u in self:
if u.rank_id.karma_min > 0:
template.send_mail(u.id, force_send=False, notif_layout='mail.mail_notification_light')
template.send_mail(u.id, force_send=False, email_layout_xmlid='mail.mail_notification_light')
def _recompute_rank(self):
"""
+1 -1
View File
@@ -186,7 +186,7 @@ Do not hesitate to contact your manager or the human resource department.""")
default_template_id=template.id,
default_composition_mode='comment',
default_is_log=True,
custom_layout='mail.mail_notification_light',
default_email_layout_xmlid='mail.mail_notification_light',
)
return {
'name': _('Compose Email'),
+3 -2
View File
@@ -2,7 +2,7 @@
{
'name': 'Discuss',
'version': '1.5',
'version': '1.6',
'category': 'Productivity/Discuss',
'sequence': 145,
'summary': 'Chat, mail gateway and private channels',
@@ -32,7 +32,8 @@
'views/res_config_settings_views.xml',
'data/res_partner_data.xml',
'data/mail_message_subtype_data.xml',
'data/mail_templates.xml',
'data/mail_templates_chatter.xml',
'data/mail_templates_email_layouts.xml',
'data/mail_channel_data.xml',
'data/mail_activity_data.xml',
'data/ir_cron_data.xml',
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- Discuss utility templates for notifications -->
<template id="message_user_assigned">
<p style="margin: 0px;">
<span>Dear <t t-esc="object.user_id.sudo().name"/>,</span><br />
<span style="margin-top: 8px;">You have been assigned to the <t t-esc="model_description or 'document'"/> <t t-esc="object.display_name"/>.</span>
</p>
<p style="padding-top: 24px; padding-bottom: 16px;">
<a t-att-href="access_link" t-att-data-oe-model="object._name" t-att-data-oe-id="object.id" style="background-color:#875A7B; padding: 10px; text-decoration: none; color: #fff; border-radius: 5px;">
View <t t-esc="model_description or 'document'"/>
</a>
</p>
</template>
<template id="message_activity_done">
<div>
<p>
<span t-attf-class="fa #{activity.activity_type_id.icon} fa-fw"/><span t-field="activity.activity_type_id.name"/> done
<t t-if="display_assignee"> (originally assigned to <span t-field="activity.user_id.name"/>)</t>
<span t-if="activity.summary">: </span><span t-if="activity.summary" t-field="activity.summary"/>
</p>
<div t-if="feedback">
<t t-foreach="feedback.split('\n')" t-as="feedback_line">
<t t-esc="feedback_line"/>
<br t-if="not feedback_line_last"/>
</t>
</div>
<t t-if="activity.note and activity.note != '&lt;p&gt;&lt;br&gt;&lt;/p&gt;'"><!-- <p></br></p> -->
<div class="o_mail_note_title"><strong>Original note:</strong></div>
<div t-field="activity.note"/>
</t>
</div>
</template>
<template id="message_activity_assigned">
<div style="margin: 0px; padding: 0px; font-size: 13px;">
<span t-field="activity.create_uid.name"/> assigned you an activity <span t-field="activity.activity_type_id.name"/>
<t t-if="activity.summary">(<span t-field="activity.summary"/>)</t>
on <span t-field="activity.res_name"/>
to close for <span t-field="activity.date_deadline"/>.<br />
<p style="padding: 16px 0px 16px 0px;">
<a t-att-href="access_link" t-att-data-oe-model="activity.res_model" t-att-data-oe-id="activity.res_id"
style="background-color:#875A7B; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px;">
View <t t-esc="model_description or 'document'"/>
</a>
</p>
<div t-if="activity.note" style="margin-top: 8px;" t-field="activity.note"/>
</div>
</template>
<template id="message_origin_link">
<p>
<t t-if="edit">This <t t-esc="self.env['ir.model']._get(self._name).name.lower()"/> has been modified from:</t>
<t t-else="">This <t t-esc="self.env['ir.model']._get(self._name).name.lower()"/> has been created from:</t>
<t t-foreach="origin" t-as="o">
<a href="#" t-att-data-oe-model="o._name" t-att-data-oe-id="o.id"> <t t-esc="o.display_name"/></a><span t-if="origin.ids[-1:] != o.ids">, </span>
</t>
</p>
</template>
<!-- Mail gateway templates -->
<template id="mail_bounce_catchall">
<div>
<p>Hello <t t-esc="message['email_from']"/>,</p>
<p>The email sent to <t t-esc="message['to']"/> cannot be processed. This address
is used to collect replies and should not be used to directly contact <t t-esc="res_company.name"/>.</p>
<p>Please contact us instead using <a t-att-href="'mailto:%s' % res_company.email"><t t-esc="res_company.email"/></a></p>
<p>Regards,</p>
<p>The <t t-esc="res_company.name"/> team.</p>
</div>
<blockquote><t t-esc="message['body']"/></blockquote>
</template>
<!-- Mail bounce alias mail template -->
<template id="mail_bounce_alias_security">
<div><t t-out="body"/></div>
<blockquote><t t-out="message['body']"/></blockquote>
</template>
</data>
</odoo>
@@ -65,64 +65,6 @@
</div>
</template>
<template id="mail_notification_borders">
<div>
<table border="0" width="100%" cellpadding="0" bgcolor="#ededed" style="padding: 20px; background-color: #ededed; border-collapse:separate;" summary="o_mail_notification">
<tbody>
<!-- HEADER -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" bgcolor="#875A7B" style="min-width: 590px; background-color: rgb(135,90,123); padding: 20px; border-collapse:separate;">
<tr><td valign="middle">
<span style="font-size:20px; color:white; font-weight: bold;">
<t t-esc="message.record_name"/>
</span>
</td><td valign="middle" align="right">
<img t-att-src="'/logo.png?company=%s' % (company.id or 0)" style="padding: 0px; margin: 0px; height: auto; width: 80px;" t-att-alt="'%s' % company.name"/>
</td></tr>
</table>
</td>
</tr>
<!-- CONTENT -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" bgcolor="#ffffff" style="min-width: 590px; background-color: rgb(255, 255, 255); padding: 20px; border-collapse:separate;">
<tbody><td valign="top" style="font-family:Arial,Helvetica,sans-serif; color: #555; font-size: 14px;">
<t t-out="message.body"/>
</td></tbody>
</table>
</td>
</tr>
<!-- FOOTER -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" bgcolor="#875A7B" style="min-width: 590px; background-color: rgb(135,90,123); padding: 20px; border-collapse:separate;">
<tr><td valign="middle" align="left" style="color: #fff; padding-top: 10px; padding-bottom: 10px; font-size: 12px;">
<t t-esc="company.name"/><br/>
<t t-esc="company.phone"/>
</td><td valign="middle" align="right" style="color: #fff; padding-top: 10px; padding-bottom: 10px; font-size: 12px;">
<t t-if="company.email">
<a t-att-href="'mailto:%s' % company.email" style="text-decoration:none; color: white;"><t t-esc="company.email"/></a><br/>
</t>
<t t-if="company.website">
<a t-att-href="'%s' % company.website" style="text-decoration:none; color: white;">
<t t-esc="company.website"/>
</a>
</t>
</td></tr>
</table>
</td>
</tr>
<tr>
<td align="center" style="padding: 8px; font-size:11px;">
Powered by <a target="_blank" href="https://www.odoo.com?utm_source=db&amp;utm_medium=email">Odoo</a>.
</td>
</tr>
</tbody>
</table>
</div>
</template>
<template id="mail_notification_light">
<table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #F1F1F1; font-family:Verdana, Arial,sans-serif; color: #454748; width: 100%; border-collapse:separate;"><tr><td align="center">
<table border="0" cellpadding="0" cellspacing="0" width="590" style="padding: 24px; background-color: white; color: #454748; border-collapse:separate;">
@@ -132,10 +74,20 @@
<td align="center" style="min-width: 590px;">
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: white; padding: 0; border-collapse:separate;">
<tr><td valign="middle">
<span style="font-size: 10px;">Your <t t-esc="model_description or 'document'"/></span><br/>
<span style="font-size: 20px; font-weight: bold;">
<t t-esc="message.record_name and message.record_name.replace('/','-') or ''"/>
</span>
<span style="font-size: 10px;">Your <t t-esc="model_description or 'document'"/></span>
<br/>
<t t-if="has_button_access">
<a t-att-href="button_access['url']">
<span style="font-size: 20px; font-weight: bold;">
<t t-esc="message.record_name and message.record_name.replace('/','-') or ''"/>
</span>
</a>
</t>
<t t-else="">
<span style="font-size: 20px; font-weight: bold;">
<t t-esc="message.record_name and message.record_name.replace('/','-') or ''"/>
</span>
</t>
</td><td valign="middle" align="right">
<img t-att-src="'/logo.png?company=%s' % (company.id or 0)" style="padding: 0px; margin: 0px; height: 48px;" t-att-alt="'%s' % company.name"/>
</td></tr>
@@ -263,83 +215,5 @@
</td></tr>
</table>
</template>
<!-- Discuss utility templates for notifications -->
<template id="message_user_assigned">
<p style="margin: 0px;">
<span>Dear <t t-esc="object.user_id.sudo().name"/>,</span><br />
<span style="margin-top: 8px;">You have been assigned to the <t t-esc="model_description or 'document'"/> <t t-esc="object.display_name"/>.</span>
</p>
<p style="padding-top: 24px; padding-bottom: 16px;">
<a t-att-href="access_link" t-att-data-oe-model="object._name" t-att-data-oe-id="object.id" style="background-color:#875A7B; padding: 10px; text-decoration: none; color: #fff; border-radius: 5px;">
View <t t-esc="model_description or 'document'"/>
</a>
</p>
</template>
<template id="message_activity_done">
<div>
<p>
<span t-attf-class="fa #{activity.activity_type_id.icon} fa-fw"/><span t-field="activity.activity_type_id.name"/> done
<t t-if="display_assignee"> (originally assigned to <span t-field="activity.user_id.name"/>)</t>
<span t-if="activity.summary">: </span><span t-if="activity.summary" t-field="activity.summary"/>
</p>
<div t-if="feedback">
<t t-foreach="feedback.split('\n')" t-as="feedback_line">
<t t-esc="feedback_line"/>
<br t-if="not feedback_line_last"/>
</t>
</div>
<t t-if="activity.note and activity.note != '&lt;p&gt;&lt;br&gt;&lt;/p&gt;'"><!-- <p></br></p> -->
<div class="o_mail_note_title"><strong>Original note:</strong></div>
<div t-field="activity.note"/>
</t>
</div>
</template>
<template id="message_activity_assigned">
<div style="margin: 0px; padding: 0px; font-size: 13px;">
<span t-field="activity.create_uid.name"/> assigned you an activity <span t-field="activity.activity_type_id.name"/>
<t t-if="activity.summary">(<span t-field="activity.summary"/>)</t>
on <span t-field="activity.res_name"/>
to close for <span t-field="activity.date_deadline"/>.<br />
<p style="padding: 16px 0px 16px 0px;">
<a t-att-href="access_link" t-att-data-oe-model="activity.res_model" t-att-data-oe-id="activity.res_id"
style="background-color:#875A7B; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px;">
View <t t-esc="model_description or 'document'"/>
</a>
</p>
<div t-if="activity.note" style="margin-top: 8px;" t-field="activity.note"/>
</div>
</template>
<template id="message_origin_link">
<p>
<t t-if="edit">This <t t-esc="self.env['ir.model']._get(self._name).name.lower()"/> has been modified from:</t>
<t t-else="">This <t t-esc="self.env['ir.model']._get(self._name).name.lower()"/> has been created from:</t>
<t t-foreach="origin" t-as="o">
<a href="#" t-att-data-oe-model="o._name" t-att-data-oe-id="o.id"> <t t-esc="o.display_name"/></a><span t-if="origin.ids[-1:] != o.ids">, </span>
</t>
</p>
</template>
<!-- Mail gateway templates -->
<template id="mail_bounce_catchall">
<div>
<p>Hello <t t-esc="message['email_from']"/>,</p>
<p>The email sent to <t t-esc="message['to']"/> cannot be processed. This address
is used to collect replies and should not be used to directly contact <t t-esc="res_company.name"/>.</p>
<p>Please contact us instead using <a t-att-href="'mailto:%s' % res_company.email"><t t-esc="res_company.email"/></a></p>
<p>Regards,</p>
<p>The <t t-esc="res_company.name"/> team.</p>
</div>
<blockquote><t t-esc="message['body']"/></blockquote>
</template>
<!-- Mail bounce alias mail template -->
<template id="mail_bounce_alias_security">
<div><t t-out="body"/></div>
<blockquote><t t-out="message['body']"/></blockquote>
</template>
</data>
</odoo>
+10 -5
View File
@@ -236,7 +236,8 @@ class MailTemplate(models.Model):
records.check_access_rights('read')
records.check_access_rule('read')
def send_mail(self, res_id, force_send=False, raise_exception=False, email_values=None, notif_layout=False):
def send_mail(self, res_id, force_send=False, raise_exception=False, email_values=None,
email_layout_xmlid=False):
""" Generates a new mail.mail. Template is rendered on record given by
res_id and model coming from template.
@@ -245,7 +246,7 @@ class MailTemplate(models.Model):
queue (recommended);
:param dict email_values: update generated mail with those values to further
customize the mail;
:param str notif_layout: optional notification layout to encapsulate the
:param str email_layout_xmlid: optional notification layout to encapsulate the
generated email;
:returns: id of the mail.mail that was created """
@@ -266,11 +267,15 @@ class MailTemplate(models.Model):
if 'email_from' in values and not values.get('email_from'):
values.pop('email_from')
# encapsulate body
if notif_layout and values['body_html']:
if email_layout_xmlid and values['body_html']:
try:
template = self.env.ref(notif_layout, raise_if_not_found=True)
template = self.env.ref(email_layout_xmlid, raise_if_not_found=True)
except ValueError:
_logger.warning('QWeb template %s not found when sending template %s. Sending without layouting.' % (notif_layout, self.name))
_logger.warning(
'QWeb template %s not found when sending template %s. Sending without layout.',
email_layout_xmlid,
self.name
)
else:
record = self.env[self.model].browse(res_id)
model = self.env['ir.model']._get(record._name)
+1 -1
View File
@@ -1890,10 +1890,10 @@ class MailThread(models.AbstractModel):
active_ids=res_ids,
active_model=kwargs.get('model', self._name),
default_composition_mode=kwargs['composition_mode'],
default_email_layout_xmlid=email_layout_xmlid,
default_model=kwargs.get('model', self._name),
default_res_id=res_id,
default_template_id=template_id,
custom_layout=email_layout_xmlid,
).create(kwargs)
# Simulate the onchange (like trigger in form the view) only
# when having a template in single-email mode
+8 -2
View File
@@ -49,6 +49,11 @@ class MailComposer(models.TransientModel):
- active_ids: record IDs
- default_model or active_model
"""
# backward compatibility of context before addition of
# email_layout_xmlid field: to remove in 15.1+
if self._context.get('custom_layout') and 'default_email_layout_xmlid' not in self._context:
self = self.with_context(default_email_layout_xmlid=self._context['custom_layout'])
result = super(MailComposer, self).default_get(fields)
# author
@@ -94,6 +99,7 @@ class MailComposer(models.TransientModel):
attachment_ids = fields.Many2many(
'ir.attachment', 'mail_compose_message_ir_attachments_rel',
'wizard_id', 'attachment_id', 'Attachments')
email_layout_xmlid = fields.Char('Email Notification Layout', copy=False)
layout = fields.Char('Layout', copy=False) # xml id of layout
add_sign = fields.Boolean(default=True)
# origin
@@ -241,7 +247,6 @@ class MailComposer(models.TransientModel):
def _action_send_mail(self, auto_commit=False):
""" Process the wizard content and proceed with sending the related
email(s), rendering any template patterns on the fly if needed. """
notif_layout = self._context.get('custom_layout')
# Several custom layouts make use of the model description at rendering, e.g. in the
# 'View <document>' button. Some models are used for different business concepts, such as
# 'purchase.order' which is used for a RFQ and and PO. To avoid confusion, we must use a
@@ -249,6 +254,7 @@ class MailComposer(models.TransientModel):
# Therefore, we can set the description in the context from the beginning to avoid falling
# back on the regular display_name retrieved in '_notify_prepare_template_context'.
model_description = self._context.get('model_description')
for wizard in self:
# Duplicate attachments linked to the email.template.
# Indeed, basic mail.compose.message wizard duplicates attachments in mass
@@ -304,7 +310,7 @@ class MailComposer(models.TransientModel):
post_params = dict(
message_type=wizard.message_type,
subtype_id=subtype_id,
email_layout_xmlid=notif_layout,
email_layout_xmlid=wizard.email_layout_xmlid,
add_sign=not bool(wizard.template_id),
mail_auto_delete=wizard.template_id.auto_delete if wizard.template_id else self._context.get('mail_auto_delete', True),
model_description=model_description)
@@ -10,6 +10,7 @@
<group>
<!-- truly invisible fields for control and options -->
<field name="composition_mode" invisible="1"/>
<field name="email_layout_xmlid" invisible="1"/>
<field name="model" invisible="1"/>
<field name="res_id" invisible="1"/>
<field name="is_log" invisible="1"/>
+4 -4
View File
@@ -589,7 +589,7 @@ class MailGroup(models.Model):
template = self.env.ref('mail_group.mail_template_list_subscribe')
template.with_context(token_url=confirm_action_url).send_mail(
self.id,
force_send=True,
email_layout_xmlid='mail.mail_notification_light',
email_values={
'author_id': self.create_uid.partner_id.id,
'auto_delete': True,
@@ -597,7 +597,7 @@ class MailGroup(models.Model):
'email_to': email,
'message_type': 'user_notification',
},
notif_layout='mail.mail_notification_light',
force_send=True,
)
_logger.info('Subscription email sent to %s.', email)
@@ -609,7 +609,7 @@ class MailGroup(models.Model):
template = self.env.ref('mail_group.mail_template_list_unsubscribe')
template.with_context(token_url=confirm_action_url).send_mail(
self.id,
force_send=True,
email_layout_xmlid='mail.mail_notification_light',
email_values={
'author_id': self.create_uid.partner_id.id,
'auto_delete': True,
@@ -617,7 +617,7 @@ class MailGroup(models.Model):
'email_to': email,
'message_type': 'user_notification',
},
notif_layout='mail.mail_notification_light',
force_send=True,
)
_logger.info('Unsubscription email sent to %s.', email)
+4 -3
View File
@@ -372,7 +372,7 @@ class PurchaseOrder(models.Model):
'default_use_template': bool(template_id),
'default_template_id': template_id,
'default_composition_mode': 'comment',
'custom_layout': "mail.mail_notification_paynow",
'default_email_layout_xmlid': "mail.mail_notification_paynow",
'force_email': True,
'mark_rfq_as_sent': True,
})
@@ -716,8 +716,9 @@ class PurchaseOrder(models.Model):
self.id,
force_send=True,
raise_exception=False,
email_layout_xmlid="mail.mail_notification_paynow",
email_values={'email_to': self.env.user.email, 'recipient_ids': []},
notif_layout="mail.mail_notification_paynow")
)
return {'toast_message': escape(_("A sample email has been sent to %s.", self.env.user.email))}
def _send_reminder_open_composer(self,template_id):
@@ -735,7 +736,7 @@ class PurchaseOrder(models.Model):
'default_use_template': bool(template_id),
'default_template_id': template_id,
'default_composition_mode': 'comment',
'custom_layout': "mail.mail_notification_paynow",
'default_email_layout_xmlid': "mail.mail_notification_paynow",
'force_email': True,
'mark_rfq_as_sent': True,
})
+9 -8
View File
@@ -166,19 +166,20 @@ class RatingMixin(models.AbstractModel):
rating = ratings[0]
return rating.access_token
def rating_send_request(self, template, lang=False, subtype_id=False, force_send=True, composition_mode='comment', notif_layout=None):
def rating_send_request(self, template, lang=False, subtype_id=False, force_send=True, composition_mode='comment',
email_layout_xmlid=None):
""" This method send rating request by email, using a template given
in parameter.
:param template: a mail.template record used to compute the message body;
:param lang: optional lang; it can also be specified directly on the template
:param record template: a mail.template record used to compute the message body;
:param str lang: optional lang; it can also be specified directly on the template
itself in the lang field;
:param subtype_id: optional subtype to use when creating the message; is
:param int subtype_id: optional subtype to use when creating the message; is
a note by default to avoid spamming followers;
:param force_send: whether to send the request directly or use the mail
:param bool force_send: whether to send the request directly or use the mail
queue cron (preferred option);
:param composition_mode: comment (message_post) or mass_mail (template.send_mail);
:param notif_layout: layout used to encapsulate the content when sending email;
:param str composition_mode: comment (message_post) or mass_mail (template.send_mail);
:param str email_layout_xmlid: layout used to encapsulate the content when sending email;
"""
if lang:
template = template.with_context(lang=lang)
@@ -190,7 +191,7 @@ class RatingMixin(models.AbstractModel):
record.message_post_with_template(
template.id,
composition_mode=composition_mode,
email_layout_xmlid=notif_layout if notif_layout is not None else 'mail.mail_notification_light',
email_layout_xmlid=email_layout_xmlid if email_layout_xmlid is not None else 'mail.mail_notification_light',
subtype_id=subtype_id
)
+1 -1
View File
@@ -292,7 +292,7 @@ class Repair(models.Model):
'default_use_template': bool(template_id),
'default_template_id': template_id,
'default_composition_mode': 'comment',
'custom_layout': 'mail.mail_notification_light',
'default_email_layout_xmlid': 'mail.mail_notification_light',
}
return {
'type': 'ir.actions.act_window',
+1 -1
View File
@@ -81,7 +81,7 @@ class ResCompany(models.Model):
message_composer = self.env['mail.compose.message'].with_context(
default_use_template=bool(template),
mark_so_as_sent=True,
custom_layout='mail.mail_notification_paynow',
default_email_layout_xmlid='mail.mail_notification_paynow',
proforma=self.env.context.get('proforma', False),
force_email=True, mail_notify_author=True
).create({
+1 -1
View File
@@ -900,7 +900,7 @@ class SaleOrder(models.Model):
'default_template_id': template_id,
'default_composition_mode': 'comment',
'mark_so_as_sent': True,
'custom_layout': "mail.mail_notification_paynow",
'default_email_layout_xmlid': "mail.mail_notification_paynow",
'proforma': self.env.context.get('proforma', False),
'force_email': True,
'model_description': self.with_context(lang=lang).type_name,
+1 -1
View File
@@ -54,7 +54,7 @@ class SaleOrder(models.Model):
template = self.env.ref('sale_gift_card.mail_template_gift_card', raise_if_not_found=False)
if template and self.gift_card_count:
for gift in self.order_line.mapped("generated_gift_card_ids"):
template.send_mail(gift.id, force_send=True, notif_layout='mail.mail_notification_light')
template.send_mail(gift.id, force_send=True, email_layout_xmlid='mail.mail_notification_light')
def _recompute_gift_card_lines(self):
for record in self:
+1 -1
View File
@@ -846,7 +846,7 @@ class Survey(models.Model):
default_survey_id=self.id,
default_use_template=bool(template),
default_template_id=template and template.id or False,
notif_layout='mail.mail_notification_light',
default_email_layout_xmlid='mail.mail_notification_light',
)
return {
'type': 'ir.actions.act_window',
+1 -1
View File
@@ -216,7 +216,7 @@ class SurveyUserInput(models.Model):
for user_input in self:
if user_input.survey_id.certification and user_input.scoring_success:
if user_input.survey_id.certification_mail_template_id and not user_input.test_entry:
user_input.survey_id.certification_mail_template_id.send_mail(user_input.id, notif_layout="mail.mail_notification_light")
user_input.survey_id.certification_mail_template_id.send_mail(user_input.id, email_layout_xmlid="mail.mail_notification_light")
if user_input.survey_id.certification_give_badge:
badge_ids.append(user_input.survey_id.certification_badge_id.id)
+5 -5
View File
@@ -212,13 +212,13 @@ class SurveyInvite(models.TransientModel):
else:
mail_values['email_to'] = answer.email
# optional support of notif_layout in context
notif_layout = self.env.context.get('notif_layout', self.env.context.get('custom_layout'))
if notif_layout:
# optional support of default_email_layout_xmlid in context
email_layout_xmlid = self.env.context.get('default_email_layout_xmlid', self.env.context.get('notif_layout'))
if email_layout_xmlid:
try:
template = self.env.ref(notif_layout, raise_if_not_found=True)
template = self.env.ref(email_layout_xmlid, raise_if_not_found=True)
except ValueError:
_logger.warning('QWeb template %s not found when sending survey mails. Sending without layouting.' % (notif_layout))
_logger.warning('QWeb template %s not found when sending survey mails. Sending without layout', email_layout_xmlid)
else:
template_ctx = {
'message': self.env['mail.message'].sudo().new(dict(body=mail_values['body_html'], record_name=self.survey_id.title)),
+2 -2
View File
@@ -137,7 +137,7 @@ class TestMailTemplate(TestMailCommon, TestRecipients):
})
test_template = self.env['mail.template'].browse(self.test_template.ids)
mail_id = test_template.send_mail(test_record.id, notif_layout='test_mail.test_layout')
mail_id = test_template.send_mail(test_record.id, email_layout_xmlid='test_mail.test_layout')
mail = self.env['mail.mail'].sudo().browse(mail_id)
self.assertEqual(mail.body_html,
'<body><p>Spanish Body for %s</p> Spanish Layout Spanish description</body>' % self.test_record.name)
@@ -156,7 +156,7 @@ class TestMailTemplate(TestMailCommon, TestRecipients):
})
test_template = self.env['mail.template'].browse(self.test_template.ids)
mail_id = test_template.send_mail(test_record.id, notif_layout='test_mail.test_layout')
mail_id = test_template.send_mail(test_record.id, email_layout_xmlid='test_mail.test_layout')
mail = self.env['mail.mail'].sudo().browse(mail_id)
self.assertEqual(mail.body_html,
'<body><p>Spanish Body for %s</p> Spanish Layout Spanish description</body>' % self.test_record.name)
@@ -51,7 +51,6 @@ class TestMessagePost(TestMailCommon, TestRecipients):
recipients_data = self._generate_notify_recipients(self.partner_1 + self.partner_2 + self.partner_employee)
for email_xmlid in ['mail.message_notification_email',
'mail.mail_notification_borders',
'mail.mail_notification_light',
'mail.mail_notification_paynow']:
test_message.write({'email_layout_xmlid': email_xmlid})
@@ -33,8 +33,8 @@ class PaymentTransaction(models.Model):
'comment': comment,
}, engine='ir.qweb', minimal_qcontext=True)
self.env.ref('website_payment.mail_template_donation').send_mail(
self.id, notif_layout="mail.mail_notification_light",
force_send=True,
self.id,
email_layout_xmlid="mail.mail_notification_light",
email_values={
'email_to': recipient_email if is_internal_notification else self.partner_email,
'email_from': self.company_id.email_formatted,
@@ -42,4 +42,5 @@ class PaymentTransaction(models.Model):
'subject': subject,
'body_html': body,
},
force_send=True,
)
@@ -559,7 +559,7 @@ class Channel(models.Model):
default_channel_id=self.id,
default_use_template=bool(template),
default_template_id=template and template.id or False,
notif_layout='website_slides.mail_notification_channel_invite',
default_email_layout_xmlid='website_slides.mail_notification_channel_invite',
)
return {
'type': 'ir.actions.act_window',
+1 -1
View File
@@ -548,7 +548,7 @@ class Slide(models.Model):
template = template.sudo()
email_values['email_from'] = self.env.company.catchall_formatted or self.env.company.email_formatted
mail_ids.append(template.send_mail(record.id, notif_layout='mail.mail_notification_light', email_values=email_values))
mail_ids.append(template.send_mail(record.id, email_layout_xmlid='mail.mail_notification_light', email_values=email_values))
return mail_ids
def action_like(self):
@@ -91,13 +91,13 @@ class SlideChannelInvite(models.TransientModel):
'recipient_ids': [(4, slide_channel_partner.partner_id.id)]
}
# optional support of notif_layout in context
notif_layout = self.env.context.get('notif_layout', self.env.context.get('custom_layout'))
if notif_layout:
# optional support of default_email_layout_xmlid in context
email_layout_xmlid = self.env.context.get('default_email_layout_xmlid', self.env.context.get('notif_layout'))
if email_layout_xmlid:
try:
template = self.env.ref(notif_layout, raise_if_not_found=True)
template = self.env.ref(email_layout_xmlid, raise_if_not_found=True)
except ValueError:
_logger.warning('QWeb template %s not found when sending slide channel mails. Sending without layouting.' % (notif_layout))
_logger.warning('QWeb template %s not found when sending slide channel mails. Sending without layout.', email_layout_xmlid)
else:
# could be great to use _notify_prepare_template_context someday
template_ctx = {
@@ -50,7 +50,7 @@ class SurveyUserInput(models.Model):
continue
self.env.ref('website_slides_survey.mail_template_user_input_certification_failed').send_mail(
user_input.id, notif_layout="mail.mail_notification_light"
user_input.id, email_layout_xmlid="mail.mail_notification_light"
)
removed_memberships = removed_memberships_per_partner.get(