[MERGE] mail, various: make (some) templates bioutifoul

Purpose of this commit is to enhance quality of templates proposed by Odoo
and make them use notification layout when send by emails. Those emails
are cleaner and more up to date compared to other emails.

Main work of this merge is to ease the propagation of setting the
notification layout specification through various layers of mail.thread
post processing and to improve the various templates proposed in several
applications.

Impacted modules in this merge: event and event track, project (including
rating), gamification, product email template.

This merge is linked to task 51122. Closes #24052.
This commit is contained in:
Thibault Delavallée
2018-06-08 17:27:25 +02:00
19 changed files with 594 additions and 457 deletions
+283 -227
View File
@@ -5,113 +5,130 @@
<record id="event_registration_mail_template_badge" model="mail.template">
<field name="name">Event: Registration Badge</field>
<field name="model_id" ref="event.model_event_registration"/>
<field name="email_from">${(object.event_id.organizer_id.email or object.event_id.user_id.email or '')|safe}</field>
<field name="email_to" >${object.partner_id.email or object.email|safe}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="subject">Your badge for ${object.event_id.name}</field>
<field name="auto_delete" eval="True"/>
<field name="email_from">${(object.event_id.organizer_id.email or object.event_id.user_id.email or '')|safe}</field>
<field name="email_to">${('"%s" &lt;%s&gt;' % (object.partner_id.name or object.name, object.partner_id.email or object.email)) | safe}</field>
<field name="body_html" type="html">
<div>
Dear ${object.name},<br/>
Thank you for your inquiry.<br/>
Here is your badge for the event ${object.event_id.name}.<br/>
If you have any questions, please let us know.
<br/><br/>
Thank you,<br/>
% if object.event_id.user_id and object.event_id.user_id.signature:
${object.event_id.user_id.signature | safe}
% endif
</div></field>
<field name="report_template" ref="report_event_registration_badge"/>
<field name="report_name">badge_of_${(object.event_id.name or '').replace('/','_')}</field>
<field name="body_html"><![CDATA[
<p>Dear ${object.name},</p>
<p>Thank you for your inquiry.</p>
<p>Here is your badge for the event ${object.event_id.name}.</p>
<p>If you have any questions, please let us know.</p>
<p>Best regards,</p>]]></field>
<field name="lang">${object.partner_id.lang}</field>
<field name="auto_delete" eval="True"/>
</record>
<record id="event_subscription" model="mail.template">
<field name="name">Event: Registration</field>
<field name="model_id" ref="event.model_event_registration"/>
<field name="email_from">${(object.event_id.organizer_id.email or object.event_id.user_id.email or '')|safe}</field>
<field name="email_to" >${object.partner_id.email or object.email|safe}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="reply_to" eval="False"/>
<field name="subject">Your registration at ${object.event_id.name}</field>
<field name="body_html"><![CDATA[
<div style="background:#F3F5F6;color:#515166;padding:25px 0px;font-family:Arial,Helvetica,sans-serif;font-size:14px;">
<field name="email_from">${(object.event_id.organizer_id.email or object.event_id.user_id.email or '')|safe}</field>
<field name="email_to">${('"%s" &lt;%s&gt;' % (object.partner_id.name or object.name, object.partner_id.email or object.email)) | safe}</field>
<field name="reply_to" eval="False"/>
<field name="body_html" type="html">
<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">
% set date_begin = format_tz(object.event_id.date_begin, tz='UTC', format='%Y%m%dT%H%M%SZ')
% set date_end = format_tz(object.event_id.date_end, tz='UTC', format='%Y%m%dT%H%M%SZ')
<table style="width:600px;margin:5px auto;">
<tbody>
<tr>
<td>
<a href="/">
<img src="/logo" alt="${object.company_id.name}" style="vertical-align:baseline;max-width:100px;" />
</a>
</td>
<td style="text-align:right;vertical-align:middle;">
% if 'website_url' in object.event_id and object.event_id.website_url:
<a href="${object.event_id.website_url}" style="background-color: #1abc9c; padding: 12px; font-weight: 12px; text-decoration: none; color: #fff; border-radius: 5px; font-size:16px;">View Event</a>
% endif
</td>
</tr>
</tbody>
</table>
<table style="width:600px;margin:0px auto;background:white;border:1px solid #e1e1e1;">
<tbody>
<tr>
<td style="padding:15px 20px 0px 20px; font-size:16px; font-weight:300;">
<p style="font-size:16px;">
Hi,
</p><p style="font-size:16px;">
We are happy to confirm your registration to the event:
</p>
<ul>
<li>Event:
<table border="0" cellpadding="0" cellspacing="0" width="590" style="padding: 16px; background-color: white; color: #454748; border-collapse:separate;">
<tbody>
<!-- HEADER -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" cellspacing="0" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="middle">
<span style="font-size: 10px;">Your registration</span><br/>
<span style="font-size: 20px; font-weight: bold;">
${object.name}
</span>
</td><td valign="middle" align="right">
<img src="${'/logo.png?company=%s' % object.company_id.id}" style="padding: 0px; margin: 0px; height: auto; width: 80px;" alt="${'%s' % object.company_id.name}"/>
</td></tr>
<tr><td colspan="2" style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin:16px 0px 16px 0px;"/>
</td></tr>
</table>
</td>
</tr>
<!-- EVENT DESCRIPTION -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" cellspacing="0" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="top" style="font-size: 14px;">
<div>
Hello ${object.name or ''},<br/>
We are happy to confirm your registration to the event
% if 'website_url' in object.event_id and object.event_id.website_url:
<a href="${object.event_id.website_url}" style="color:#875A7B;text-decoration:none;">${object.event_id.name}</a>
% else:
<strong>${object.event_id.name}</strong>
% endif
</li>
<li>Attendee: ${object.name}</li>
</ul>
<p style="font-size:16px;">
See you soon,
</p>
<p style="font-size:16px; margin-bottom: 30px">
<i>
-- <br/>
for attendee ${object.name}.
</div>
% if 'website_url' in object.event_id and object.event_id.website_url:
<div style="margin: 16px 0px 16px 0px;">
<a href="${object.event_id.website_url}"
style="background-color: #875A7B; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px; font-size:16px;">View Event</a><br />
</div>
% endif
<div>
See you soon,<br/>
<span style="color: #454748;">
-- <br/>
% if object.event_id.organizer_id:
${object.event_id.organizer_id.name}
% else:
The organizers.
% endif
</i>
</p>
</td>
</tr>
<tr>
<td style="padding:15px 20px 0px 20px;">
<table style="width:100%;border-top:1px solid #e1e1e1;">
</span>
</div>
</td></tr>
<tr><td style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>
</td></tr>
</table>
</td>
</tr>
<!-- DETAILS -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" cellspacing="0" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="top" style="font-size: 14px;">
<table style="width:100%;">
<tr>
<td style="padding:25px 0px;vertical-align:top;">
<img src="/web_editor/font_to_img/61555/rgb(81,81,102)/34" style="padding:4px;max-width:inherit;" height="34">
<td style="vertical-align:top;">
<img src="/web_editor/font_to_img/61555/rgb(81,81,102)/34" style="padding:4px;max-width:inherit;" height="34"/>
</td>
<td style="padding:25px 10px 25px 10px;width:50%;line-height:20px;vertical-align:top;">
<td style="padding: 0px 10px 0px 10px;width:50%;line-height:20px;vertical-align:top;">
<div><strong>From</strong> ${object.event_id.date_begin_located}</div>
<div><strong>To</strong> ${object.event_id.date_end_located}</div>
<div style="font-size:12px;color:#9e9e9e"><i><strong>TZ</strong> ${object.event_id.date_tz}</i></div>
</td>
% if object.event_id.address_id.country_id.name:
<td style="padding:25px 0px;vertical-align:top;">
<img src="/web_editor/font_to_img/61505/rgb(81,81,102)/34" style="padding:4px;max-width:inherit;" height="34">
<td style="vertical-align:top;">
<img src="/web_editor/font_to_img/61505/rgb(81,81,102)/34" style="padding:4px;max-width:inherit;" height="34"/>
</td>
<td style="padding:30px 10px 25px 10px;width:50%;vertical-align:top;">
<td style="padding: 0px 10px 0px 10px;width:50%;vertical-align:top;">
% set location = ''
% if object.event_id.address_id.name:
<p style="margin:0px 0px 0px 0px;">${object.event_id.address_id.name}</p>
<div>${object.event_id.address_id.name}</div>
% endif
% if object.event_id.address_id.street:
<p style="margin:0px 0px 0px 0px;">${object.event_id.address_id.street}</p>
<div>${object.event_id.address_id.street}</div>
% set location = object.event_id.address_id.street
% endif
% if object.event_id.address_id.street2:
<p style="margin:0px 0px 0px 0px;">${object.event_id.address_id.street2}</p>
<div>${object.event_id.address_id.street2}</div>
% set location = '%s, %s' % (location, object.event_id.address_id.street2)
% endif
<p style="margin:0px 0px 0px 0px;">
<div>
% if object.event_id.address_id.city:
${object.event_id.address_id.city},
% set location = '%s, %s' % (location, object.event_id.address_id.city)
@@ -124,163 +141,189 @@
${object.event_id.address_id.zip}
% set location = '%s, %s' % (location, object.event_id.address_id.zip)
% endif
</p>
</div>
% if object.event_id.address_id.country_id.name:
<p style="margin:0px 0px 0px 0px;">${object.event_id.address_id.country_id.name}</p>
<div>${object.event_id.address_id.country_id.name}</div>
% set location = '%s, %s' % (location, object.event_id.address_id.country_id.name)
% endif
</td>
% endif
</tr>
</table>
% if object.event_id.organizer_id:
<table style="width:100%;border-top:1px solid #e1e1e1;">
<tr>
<td style="padding:10px 0px 25px 0px;">
<h2 style="font-weight:300;margin:10px 0px">Questions about this event?</h2>
<p>Please contact the organizer:</p>
<ul>
<li>${object.event_id.organizer_id.name}</li>
% if object.event_id.organizer_id.email
<li>Mail: <a href="mailto:${object.event_id.organizer_id.email}" style="text-decoration:none;color:#875A7B;">${object.event_id.organizer_id.email}</a></li>
% endif
% if object.event_id.organizer_id.phone
<li>Phone: ${object.event_id.organizer_id.phone}</li>
% endif
</ul>
</td>
</tr>
</table>
% endif
</td></tr>
<tr><td style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>
</td></tr>
% if object.event_id.organizer_id:
<tr><td valign="top" style="font-size: 14px;">
<div>
<span style="font-weight:300;margin:10px 0px">Questions about this event?</span>
<div>Please contact the organizer:</div>
<ul>
<li>${object.event_id.organizer_id.name}</li>
% if object.event_id.organizer_id.email
<li>Mail: <a href="mailto:${object.event_id.organizer_id.email}" style="text-decoration:none;color:#875A7B;">${object.event_id.organizer_id.email}</a></li>
% endif
% if object.event_id.organizer_id.phone
<li>Phone: ${object.event_id.organizer_id.phone}</li>
% endif
</ul>
</div>
</td></tr>
% endif
<tr><td valign="top" style="font-size: 14px;">
<table style="width:100%;border-top:1px solid #e1e1e1;">
<tr>
<td style="padding:25px 0px;">
<strong>Add this event to your calendar</strong>
<a href="https://www.google.com/calendar/render?action=TEMPLATE&text=${object.event_id.name}&dates=${date_begin}/${date_end}&location=${location}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16"> Google</a>
<a href="https://bay02.calendar.live.com/calendar/calendar.aspx?rru=addevent&summary=${object.event_id.name}&dtstart=${date_begin}&dtend=${date_end}&location=${location}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16"> Outlook</a>
<a href="https://calendar.yahoo.com/?v=60&view=d&type=20&title=${object.event_id.name}&in_loc=${location}&st=${format_tz(object.event_id.date_begin, tz='UTC', format='%Y%m%dT%H%M%S')}&et=${format_tz(object.event_id.date_end, tz='UTC', format='%Y%m%dT%H%M%S')}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16"> Yahoo</a>
<a href="https://www.google.com/calendar/render?action=TEMPLATE&amp;text=${object.event_id.name}&amp;dates=${date_begin}/${date_end}&amp;location=${location}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16"/> Google</a>
<a href="https://bay02.calendar.live.com/calendar/calendar.aspx?rru=addevent&amp;summary=${object.event_id.name}&amp;dtstart=${date_begin}&amp;dtend=${date_end}&amp;location=${location}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16"/> Outlook</a>
<a href="https://calendar.yahoo.com/?v=60&amp;view=d&amp;type=20&amp;title=${object.event_id.name}&amp;in_loc=${location}&amp;st=${format_tz(object.event_id.date_begin, tz='UTC', format='%Y%m%dT%H%M%S')}&amp;et=${format_tz(object.event_id.date_end, tz='UTC', format='%Y%m%dT%H%M%S')}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new">
<img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16"/> Yahoo</a>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</td></tr>
<tr><td style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>
</td></tr>
% if object.event_id.address_id:
<tr><td valign="top" style="font-size: 14px;">
<table style="width:100%;"><tr><td>
<div>
<a href="https://maps.google.com/maps?q=${location}" target="new">
<img src="http://maps.googleapis.com/maps/api/staticmap?autoscale=1&amp;size=598x200&amp;maptype=roadmap&amp;format=png&amp;visual_refresh=true&amp;markers=size:mid%7Ccolor:0xa5117d%7Clabel:%7C${location}" style="vertical-align:bottom; width: 100%;"/>
</a>
</div>
</td></tr></table>
</td></tr>
% endif
</table>
</td>
</tr>
</tbody>
</table>
</td></tr>
<!-- FOOTER BY -->
<tr><td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" cellspacing="0" style="min-width: 590px; background-color: #F1F1F1; color: #454748; padding: 8px; border-collapse:separate;">
<tr><td style="text-align: center; font-size: 14px;">
Sent by <a target="_blank" href="object.company_id.website" style="color: #875A7B;">${object.company_id.name}</a>
% if 'website_url' in object.event_id and object.event_id.website_url:
<br />
Discover <a href="/event" style="text-decoration:none;color:#717188;">all our events</a>.
% endif
</td></tr>
</table>
% if object.event_id.address_id:
<div style="width:598px;margin:0px auto;border-left:1px solid #dddddd;border-right:1px solid #dddddd;border-bottom:1px solid #dddddd;">
<a href="https://maps.google.com/maps?q=${location}" target="new">
<img src="http://maps.googleapis.com/maps/api/staticmap?autoscale=1&size=598x200&maptype=roadmap&format=png&visual_refresh=true&markers=size:mid%7Ccolor:0xa5117d%7Clabel:%7C${location}" style="vertical-align:bottom;" />
</a>
</div>
% endif
<table style="width:600px;margin:0px auto;text-align:center;">
<tbody>
<tr>
<td style="padding-top:10px;font-size: 12px;">
<div>Sent by ${object.company_id.name}</div>
% if 'website_url' in object.event_id and object.event_id.website_url:
<div>
Discover <a href="/event" style="text-decoration:none;color:#717188;">all our events</a>.
</div>
% endif
</td>
</tr>
</tbody>
</table>
</div>
]]></field>
</td></tr>
</table>
</field>
<field name="lang">${object.partner_id.lang}</field>
</record>
<record id="event_reminder" model="mail.template">
<field name="name">Event: Reminder</field>
<field name="model_id" ref="event.model_event_registration"/>
<field name="email_from">${(object.event_id.organizer_id.email or object.event_id.user_id.email or '')|safe}</field>
<field name="email_to" >${object.partner_id.email or object.email|safe}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="reply_to" eval="False"/>
<field name="subject">${object.event_id.name}: ${object.get_date_range_str()}</field>
<field name="body_html"><![CDATA[
<div style="background:#F3F5F6;color:#515166;padding:25px 0px;font-family:Arial,Helvetica,sans-serif;font-size:14px;">
<field name="email_from">${(object.event_id.organizer_id.email or object.event_id.user_id.email or '')|safe}</field>
<field name="email_to">${('"%s" &lt;%s&gt;' % (object.partner_id.name or object.name, object.partner_id.email or object.email)) | safe}</field>
<field name="reply_to" eval="False"/>
<field name="body_html" type="html">
<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">
% set date_begin = format_tz(object.event_id.date_begin, tz='UTC', format='%Y%m%dT%H%M%SZ')
% set date_end = format_tz(object.event_id.date_end, tz='UTC', format='%Y%m%dT%H%M%SZ')
<table style="width:600px;margin:5px auto;">
<tbody>
<tr>
<td>
<a href="/">
<img src="/logo" alt="${object.company_id.name}" style="vertical-align:baseline;max-width:100px;" />
</a>
</td>
<td style="text-align:right;vertical-align:middle;">
% if 'website_url' in object.event_id and object.event_id.website_url:
<a href="${object.event_id.website_url}" style="background-color: #1abc9c; padding: 12px; font-weight: 12px; text-decoration: none; color: #fff; border-radius: 5px; font-size:16px;">View Event</a>
% endif
</td>
</tr>
</tbody>
</table>
<table style="width:600px;margin:0px auto;background:white;border:1px solid #e1e1e1;">
<tbody>
<tr>
<td style="padding:15px 20px 0px 20px; font-size:16px;">
<p style="font-size:16px;">
Hello,
</p>
<p style="font-size:16px;">
<table border="0" cellpadding="0" cellspacing="0" width="590" style="padding: 16px; background-color: white; color: #454748; border-collapse:separate;">
<tbody>
<!-- HEADER -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" cellspacing="0" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="middle">
<span style="font-size: 10px;">Your registration</span><br/>
<span style="font-size: 20px; font-weight: bold;">
${object.name}
</span>
</td><td valign="middle" align="right">
<img src="${'/logo.png?company=%s' % object.company_id.id}" style="padding: 0px; margin: 0px; height: auto; width: 80px;" alt="${'%s' % object.company_id.name}"/>
</td></tr>
<tr><td colspan="2" style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin:16px 0px 16px 0px;"/>
</td></tr>
</table>
</td>
</tr>
<!-- EVENT DESCRIPTION -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" cellspacing="0" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="top" style="font-size: 14px;">
<div>
Hello ${object.name},<br/>
We are excited to remind you that the event
% if 'website_url' in object.event_id and object.event_id.website_url:
<a href="${object.event_id.website_url}" style="color:#875A7B;text-decoration:none;">${object.event_id.name}</a>
% else:
${object.event_id.name}
<strong>${object.event_id.name}</strong>
% endif
is starting
<strong>${object.get_date_range_str()}</strong>.
</p><p style="font-size:16px;">
We confirm your registration and hope to meet you there,
</p><p style="font-size:16px; margin-bottom: 30px">
<i>
-- <br/>
is starting <strong>${object.get_date_range_str()}</strong>.
</div>
% if 'website_url' in object.event_id and object.event_id.website_url:
<div style="margin: 16px 0px 16px 0px;">
<a href="${object.event_id.website_url}"
style="background-color: #875A7B; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px; font-size:16px;">View Event</a><br />
</div>
% endif
<div>
We confirm your registration and hope to meet you there,<br/>
<span style="color: #454748;">
-- <br/>
% if object.event_id.organizer_id:
${object.event_id.organizer_id.name}
% else:
The organizers.
% endif
</i>
</p>
</td>
</tr>
<tr>
<td style="padding:15px 20px 0px 20px;">
<table style="width:100%;border-top:1px solid #e1e1e1;">
</span>
</div>
</td></tr>
<tr><td style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>
</td></tr>
</table>
</td>
</tr>
<!-- DETAILS -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" cellspacing="0" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="top" style="font-size: 14px;">
<table style="width:100%;">
<tr>
<td style="padding:25px 0px;vertical-align:top;">
<img src="/web_editor/font_to_img/61555/rgb(81,81,102)/34" style="padding:4px;max-width:inherit;" height="34">
<td style="vertical-align:top;">
<img src="/web_editor/font_to_img/61555/rgb(81,81,102)/34" style="padding:4px;max-width:inherit;" height="34"/>
</td>
<td style="padding:25px 10px 25px 10px;width:50%;line-height:20px;vertical-align:top;">
<td style="padding: 0px 10px 0px 10px;width:50%;line-height:20px;vertical-align:top;">
<div><strong>From</strong> ${object.event_id.date_begin_located}</div>
<div><strong>To</strong> ${object.event_id.date_end_located}</div>
<div style="font-size:12px;color:#9e9e9e"><i><strong>TZ</strong> ${object.event_id.date_tz}</i></div>
</td>
% if object.event_id.address_id:
<td style="padding:25px 0px;vertical-align:top;">
<img src="/web_editor/font_to_img/61505/rgb(81,81,102)/34" style="padding:4px;max-width:inherit;" height="34">
% if object.event_id.address_id.country_id.name:
<td style="vertical-align:top;">
<img src="/web_editor/font_to_img/61505/rgb(81,81,102)/34" style="padding:4px;max-width:inherit;" height="34"/>
</td>
<td style="padding:30px 10px 25px 10px;width:50%;vertical-align:top;">
<td style="padding: 0px 10px 0px 10px;width:50%;vertical-align:top;">
% set location = ''
% if object.event_id.address_id.name:
<p style="margin:0px 0px 0px 0px;">${object.event_id.address_id.name}</p>
<div>${object.event_id.address_id.name}</div>
% endif
% if object.event_id.address_id.street:
<p style="margin:0px 0px 0px 0px;">${object.event_id.address_id.street}</p>
<div>${object.event_id.address_id.street}</div>
% set location = object.event_id.address_id.street
% endif
% if object.event_id.address_id.street2:
<p style="margin:0px 0px 0px 0px;">${object.event_id.address_id.street2}</p>
<div>${object.event_id.address_id.street2}</div>
% set location = '%s, %s' % (location, object.event_id.address_id.street2)
% endif
<p style="margin:0px 0px 0px 0px;">
<div>
% if object.event_id.address_id.city:
${object.event_id.address_id.city},
% set location = '%s, %s' % (location, object.event_id.address_id.city)
@@ -293,71 +336,84 @@
${object.event_id.address_id.zip}
% set location = '%s, %s' % (location, object.event_id.address_id.zip)
% endif
</p>
</div>
% if object.event_id.address_id.country_id.name:
<p style="margin:0px 0px 0px 0px;">${object.event_id.address_id.country_id.name}</p>
<div>${object.event_id.address_id.country_id.name}</div>
% set location = '%s, %s' % (location, object.event_id.address_id.country_id.name)
% endif
</td>
% endif
</tr>
</table>
% if object.event_id.organizer_id.email:
<table style="width:100%;border-top:1px solid #e1e1e1;">
<tr>
<td style="padding:10px 0px 25px 0px;">
<h2 style="font-weight:300;margin:10px 0px">Questions about this event?</h2>
<p>Please contact the organizer:</p>
<ul>
<li>${object.event_id.organizer_id.name}</li>
% if object.event_id.organizer_id.email
<li>Mail: <a href="mailto:${object.event_id.organizer_id.email}" style="text-decoration:none;color:#875A7B;">${object.event_id.organizer_id.email}</a></li>
% endif
% if object.event_id.organizer_id.phone
<li>Phone: ${object.event_id.organizer_id.phone}</li>
% endif
</ul>
</td>
</tr>
</table>
% endif
</td></tr>
<tr><td style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>
</td></tr>
% if object.event_id.organizer_id:
<tr><td valign="top" style="font-size: 14px;">
<div>
<span style="font-weight:300;margin:10px 0px">Questions about this event?</span>
<div>Please contact the organizer:</div>
<ul>
<li>${object.event_id.organizer_id.name}</li>
% if object.event_id.organizer_id.email
<li>Mail: <a href="mailto:${object.event_id.organizer_id.email}" style="text-decoration:none;color:#875A7B;">${object.event_id.organizer_id.email}</a></li>
% endif
% if object.event_id.organizer_id.phone
<li>Phone: ${object.event_id.organizer_id.phone}</li>
% endif
</ul>
</div>
</td></tr>
% endif
<tr><td valign="top" style="font-size: 14px;">
<table style="width:100%;border-top:1px solid #e1e1e1;">
<tr>
<td style="padding:25px 0px;">
<strong>Add this event to your calendar</strong>
<a href="https://www.google.com/calendar/render?action=TEMPLATE&text=${object.event_id.name}&dates=${date_begin}/${date_end}&location=${location}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16"> Google</a>
<a href="https://bay02.calendar.live.com/calendar/calendar.aspx?rru=addevent&summary=${object.event_id.name}&dtstart=${date_begin}&dtend=${date_end}&location=${location}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16"> Outlook</a>
<a href="https://calendar.yahoo.com/?v=60&view=d&type=20&title=${object.event_id.name}&in_loc=${location}&st=${format_tz(object.event_id.date_begin, tz='UTC', format='%Y%m%dT%H%M%S')}&et=${format_tz(object.event_id.date_end, tz='UTC', format='%Y%m%dT%H%M%S')}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16"> Yahoo</a>
<a href="https://www.google.com/calendar/render?action=TEMPLATE&amp;text=${object.event_id.name}&amp;dates=${date_begin}/${date_end}&amp;location=${location}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16"/> Google</a>
<a href="https://bay02.calendar.live.com/calendar/calendar.aspx?rru=addevent&amp;summary=${object.event_id.name}&amp;dtstart=${date_begin}&amp;dtend=${date_end}&amp;location=${location}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16"/> Outlook</a>
<a href="https://calendar.yahoo.com/?v=60&amp;view=d&amp;type=20&amp;title=${object.event_id.name}&amp;in_loc=${location}&amp;st=${format_tz(object.event_id.date_begin, tz='UTC', format='%Y%m%dT%H%M%S')}&amp;et=${format_tz(object.event_id.date_end, tz='UTC', format='%Y%m%dT%H%M%S')}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new">
<img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16"/> Yahoo</a>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</td></tr>
<tr><td style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>
</td></tr>
% if object.event_id.address_id:
<tr><td valign="top" style="font-size: 14px;">
<table style="width:100%;"><tr><td>
<div>
<a href="https://maps.google.com/maps?q=${location}" target="new">
<img src="http://maps.googleapis.com/maps/api/staticmap?autoscale=1&amp;size=598x200&amp;maptype=roadmap&amp;format=png&amp;visual_refresh=true&amp;markers=size:mid%7Ccolor:0xa5117d%7Clabel:%7C${location}" style="vertical-align:bottom; width: 100%;"/>
</a>
</div>
</td></tr></table>
</td></tr>
% endif
</table>
</td>
</tr>
</tbody>
</table>
</td></tr>
<!-- FOOTER BY -->
<tr><td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" cellspacing="0" style="min-width: 590px; background-color: #F1F1F1; color: #454748; padding: 8px; border-collapse:separate;">
<tr><td style="text-align: center; font-size: 14px;">
Sent by <a target="_blank" href="object.company_id.website" style="color: #875A7B;">${object.company_id.name}</a>
% if 'website_url' in object.event_id and object.event_id.website_url:
<br />
Discover <a href="/event" style="text-decoration:none;color:#717188;">all our events</a>.
% endif
</td></tr>
</table>
% if object.event_id.address_id:
<div style="width:598px;margin:0px auto;border-left:1px solid #dddddd;border-right:1px solid #dddddd;border-bottom:1px solid #dddddd;">
<a href="https://maps.google.com/maps?q=${location}" target="new">
<img src="http://maps.googleapis.com/maps/api/staticmap?autoscale=1&size=598x200&maptype=roadmap&format=png&visual_refresh=true&markers=size:mid%7Ccolor:0xa5117d%7Clabel:%7C${location}" style="vertical-align:bottom;" />
</a>
</div>
% endif
<table style="width:600px;margin:0px auto;text-align:center;">
<tbody>
<tr>
<td style="padding-top:10px;font-size: 12px;">
<p style="margin:0px 0px 9px 0px;padding-top:10px;">Sent by ${object.company_id.name}</p>
% if 'website_url' in object.event_id and object.event_id.website_url:
<div>
Discover <a href="/event" style="text-decoration:none;color:#717188;">all our events</a>.
</div>
% endif
</td>
</tr>
</tbody>
</table>
</div>
]]></field>
</td></tr>
</table>
</field>
<field name="lang">${object.partner_id.lang}</field>
</record>
</data>
+1
View File
@@ -482,6 +482,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",
)
return {
'name': _('Compose Email'),
+98 -29
View File
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="badge_good_job" model="gamification.badge">
@@ -47,36 +48,104 @@
<field name="partner_to">${object.user_id.partner_id.id}</field>
<field name="lang">${object.user_id.lang}</field>
<field name="body_html" type="xml">
<div>
<p>Congratulations ${object.user_id.name} !</p>
<p>You just received badge <strong>${object.badge_id.name}</strong> !</p>
</div>
<div>
% if object.badge_id.description
<table cellspacing="0" cellpadding="0" border="0" style="width: 600px; margin-top: 5px;">
<tbody><tr>
<td valign="center">
<img src="/web/image/gamification.badge/${object.badge_id.id}/image/80x80" style="padding: 0px; margin: 0px; height: auto; width: 80px;" alt="${user.company_id.name}"/>
</td>
<td valign="center">
<cite>${object.badge_id.description}</cite>
</td>
</tr></tbody>
<table border="0" cellpadding="0" style="padding-top: 16px; background-color: #F1F1F1; color: #454748; width: 100%; border-collapse:separate;"><tr><td align="center">
<table border="0" width="590" cellpadding="0" style="padding: 16px; background-color: white; color: #454748; border-collapse:separate;" summary="o_mail_notification">
<tbody>
<!-- HEADER -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="middle">
<span style="font-size: 10px;">Your Badge</span><br/>
<span style="font-size: 20px; font-weight: bold;">
${object.badge_id.name}
</span>
</td><td valign="middle" align="right">
<img src="/logo.png?company=${object.user_id.company_id.id}" style="padding: 0px; margin: 0px; height: auto; width: 80px;" alt="${object.user_id.company_id.name}"/>
</td></tr>
<tr><td colspan="2" style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>
</td></tr>
</table>
</td>
</tr>
<!-- CONTENT -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="top" style="font-size: 14px;">
<div>
Congratulations ${object.user_id.name} !<br/>
You just received badge <strong>${object.badge_id.name}</strong> !<br/>
% if object.badge_id.description
<table cellspacing="0" cellpadding="0" border="0" style="width: 560px; margin-top: 5px;">
<tbody><tr>
<td valign="center">
<img src="/web/image/gamification.badge/${object.badge_id.id}/image/80x80" style="padding: 0px; margin: 0px; height: auto; width: 80px;" alt="${user.company_id.name}"/>
</td>
<td valign="center">
<cite>${object.badge_id.description}</cite>
</td>
</tr></tbody>
</table>
% endif
<br/>
% if object.sender_id
This badge was granted by <strong>${object.sender_id.name}</strong>.
% endif
<br/>
% if object.comment
${object.comment}
% endif
<br/><br/>
Thank you,
<br/>
% if object.sender_id and object.sender_id.signature:
${object.sender_id.signature | safe}
% endif
</div>
</td></tr>
<tr><td style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>
</td></tr>
</table>
</td>
</tr>
<!-- FOOTER -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" style="min-width: 590px; background-color: white; font-size: 12px; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="middle" align="left">
${object.user_id.company_id.name}
</td></tr>
<tr><td valign="middle" align="left" style="opacity: 0.7;">
${object.user_id.company_id.phone}
% if object.user_id.company_id.email
| <a href="'mailto:%s' % ${object.user_id.company_id.email}" style="text-decoration:none; color: #454748;">${object.user_id.company_id.email}</a>
% endif
% if object.user_id.company_id.website
| <a href="'%s' % ${object.user_id.company_id.website}" style="text-decoration:none; color: #454748;">
${object.user_id.company_id.website}
</a>
% endif
</td></tr>
</table>
</td>
</tr>
</tbody>
</table>
% endif
</div>
<div>
<p>
% if object.sender_id
This badge was granted by <strong>${object.sender_id.name}</strong>.
% endif
</p>
<p>
% if object.comment
<em>${object.comment}</em>
% endif
</p>
</div>
</td></tr>
<!-- POWERED BY -->
<tr><td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" style="min-width: 590px; background-color: #F1F1F1; color: #454748; padding: 8px; border-collapse:separate;">
<tr><td style="text-align: center; font-size: 14px;">
Powered by <a target="_blank" href="https://www.odoo.com" style="color: #875A7B;">Odoo</a>
</td></tr>
</table>
</td></tr>
</table>
</field>
</record>
</data>
+36 -71
View File
@@ -8,38 +8,40 @@
<field name="name">Reminder for Goal Update</field>
<field name="model_id" ref="gamification.model_gamification_goal"/>
<field name="lang">${object.user_id.lang}</field>
<field name="body_html"><![CDATA[
<p>
<strong>Reminder ${object.name}</strong>
</p>
<p>You have not updated your progress for the goal ${object.definition_id.name} (currently reached at ${object.completeness}%) for at least ${object.remind_update_delay} days. Do not forget to do it.</p>
]]></field>
<field name="body_html" type="html">
<div>
<strong>Reminder ${object.name}</strong><br/>
You have not updated your progress for the goal ${object.definition_id.name} (currently reached at ${object.completeness}%) for at least ${object.remind_update_delay} days. Do not forget to do it.
<br/><br/>
Thank you,
<br/>
% if object.challenge_id.manager_id and object.challenge_id.manager_id.signature:
${object.challenge_id.manager_id.signature | safe}
% endif
</div></field>
</record>
<record id="simple_report_template" model="mail.template">
<field name="name">Simple Challenge Report Progress</field>
<field name="model_id" ref="gamification.model_gamification_challenge"/>
<field name="body_html">
<![CDATA[
% set record = ctx.get('record')
% set company = record and record.company_id or user.company_id
% set challenge_lines = ctx.get('challenge_lines', [])
<table cellspacing="0" cellpadding="0" width="100%" style="font-family: 'Helvetica'; background-color: #EEE; border-collapse: collapse;">
<field name="body_html" type="html">
<table cellspacing="0" cellpadding="0" width="100%" style="background-color: #EEE; border-collapse: collapse;">
<tr>
<td valign="top" align="center">
<table cellspacing="0" cellpadding="0" width="600" style="margin: 0 auto; width: 600px;">
% set record = ctx.get('record')
% set company = record and record.company_id or user.company_id
% set challenge_lines = ctx.get('challenge_lines', [])
<table cellspacing="0" cellpadding="0" width="600" style="margin: 0 auto; width: 570px;">
<tr><td>
<table cellspacing="0" cellpadding="0" width="100%">
<tr>
<td valign="middle" align="left" style="padding:30px 15px;">
<img width="90" src="/logo.png?company=${user.company_id.id}" style="width:80px;"/>
</td>
% if object.visibility_mode == 'ranking':
<td style="padding:15px;">
<p style="font-size:20px;color:#666666;" align="right">Leaderboard</p>
</td>
% endif
<div>
% if object.visibility_mode == 'ranking':
<td style="padding:15px;">
<p style="font-size:20px;color:#666666;" align="center">Leaderboard</p>
</td>
% endif
</div>
</tr>
</table>
<table cellspacing="0" cellpadding="0" width="100%" bgcolor="#fff" style="background-color:#fff;">
@@ -49,7 +51,7 @@
<table cellspacing="0" cellpadding="0" width="100%" style="margin-top:20px;">
<tr>
<td align="center">
<p style="font-size:27px;color:#666666;">Personal Performance</p>
<div>Personal Performance</div>
</td>
</tr>
</table>
@@ -67,11 +69,7 @@
</thead>
<tbody>
% for line in challenge_lines:
<tr
% if line['completeness'] >= 100:
style="font-weight:bold;"
% endif
>
<tr style="font-weight:bold;">
<td style="padding: 20px 0;" align="left">
${line['name']}
% if line['suffix'] or line['monetary']:
@@ -102,15 +100,15 @@
</span>
% for line in challenge_lines:
<!-- Header + Button table -->
<table cellspacing="0" cellpadding="0" width="100%"style="margin-top:35px;">
<table cellspacing="0" cellpadding="0" width="100%" style="margin-top:35px;">
<tr>
<td width="50%">
<p style="font-size:22px;color:#666666;">Top Achievers for goal <strong>${line['name']}</strong></p>
<div>Top Achievers for goal <strong>${line['name']}</strong></div>
</td>
</tr>
</table>
<!-- Podium -->
% if len(line['goals'])>2:
% if len(line['goals']) == 2:
<table cellspacing="0" cellpadding="0" width="100%" style="margin-top:10px;">
<tr><td style="padding:0 30px;">
<table cellspacing="0" cellpadding="0" width="100%" style="table-layout: fixed;">
@@ -149,18 +147,16 @@
</div>
<div align="center" style ="color:${bgColor};height:20px">
${goal['name']}
</div
</div>
</div>
<div style="background-color:${bgColor | safe};height:${heightB}px;">
<strong><span style="color:#fff;font-size:${fontSize}px;">${podiumPosition | safe}</span></strong>
</div>
<div style="height:30px;">
<p style="color:#9A6C8E;font-size:20px;margin-top:10px;">
${"%.2f" % goal['current']}
% if line['suffix'] or line['monetary']:
${line['full_suffix']}
% endif
</p>
${"%.2f" % goal['current']}
% if line['suffix'] or line['monetary']:
${line['full_suffix']}
% endif
</div>
</div>
</td>
@@ -187,7 +183,7 @@
(${company.currency_id.symbol})
% endif
</th>
<th style="width:30%;text-align:right;"">Completeness</th>
<th style="width:30%;text-align:right;">Completeness</th>
</tr>
<tr>
<td colspan="5" style="height:1px;background-color:#9A6C8E;"></td>
@@ -220,43 +216,12 @@
% endif
</td></tr>
</table>
<table cellspacing="0" cellpadding="0" width="100%" style="padding: 15px; color: #666666;margin-bottom: 5px;">
<tr>
<td align="center" style="min-width: 590px;">
<table width="580" border="0" cellpadding="0" style="min-width: 580px; font-size: 12px;">
<tr>
<td valign="middle" align="left" style="padding-top: 10px; padding-bottom: 10px;">
${company.name}<br/>
${company.phone or ''}
</td>
<td valign="middle" align="right" style="padding-top: 10px; padding-bottom: 10px;">
% if company.email:
<a href="mailto:${company.email}" style="text-decoration:none; color: #666666;">${company.email}</a><br/>
% endif
% if company.website:
<a href="${company.website}" style="text-decoration:none; color: #666666;">
${company.website}
</a>
% endif
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="center">
Powered by <a target="_blank" href="https://www.odoo.com">Odoo</a>.
</td>
</tr>
</table>
</td></tr>
</table>
</td>
</tr>
</table>
]]>
</field>
</field>
</record>
<!-- goal definitions -->
+18 -4
View File
@@ -551,7 +551,12 @@ class Challenge(models.Model):
challenge.message_post(
body=body_html,
partner_ids=challenge.mapped('user_ids.partner_id.id'),
subtype='mail.mt_comment')
subtype='mail.mt_comment',
notif_layout='mail.mail_notification_light',
notif_values={
'model_description': challenge._description.lower(),
}
)
if challenge.report_message_group_id:
challenge.report_message_group_id.message_post(
body=body_html,
@@ -573,12 +578,21 @@ class Challenge(models.Model):
self.env['gamification.challenge'].message_post(
body=body_html,
partner_ids=[(4, user.partner_id.id)],
subtype='mail.mt_comment'
subtype='mail.mt_comment',
notif_layout='mail.mail_notification_light',
notif_values={
'model_description': self._description.lower(),
}
)
if challenge.report_message_group_id:
challenge.report_message_group_id.message_post(
body=body_html,
subtype='mail.mt_comment')
body=body_html,
subtype='mail.mt_comment',
notif_layout='mail.mail_notification_light',
notif_values={
'model_description': self._description.lower(),
}
)
return challenge.write({'last_report_date': fields.Date.today()})
##### Challenges #####
+5 -1
View File
@@ -225,7 +225,11 @@ class Goal(models.Model):
self.env['mail.thread'].message_post(
body=body_html,
partner_ids=[ self.user_id.partner_id.id],
subtype='mail.mt_comment'
subtype='mail.mt_comment',
notif_layout='mail.mail_notification_light',
notif_values={
'model_description': self._description.lower(),
}
)
return {'to_update': True}
+7 -7
View File
@@ -158,20 +158,20 @@
</template>
<template id="mail_notification_light">
<table border="0" cellpadding="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" width="590" cellpadding="0" style="padding: 16px; background-color: white; color: #454748; border-collapse:separate;" summary="o_mail_notification">
<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: 16px; background-color: white; color: #454748; border-collapse:separate;">
<tbody>
<!-- HEADER -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="middle">
<span style="font-size: 10px;">Your <t t-esc="'%s' % model_description or 'document'"/></span><br/>
<span style="font-size: 20px; 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" style="padding: 0px; margin: 0px; height: auto; width: 40px;" t-att-alt="'%s' % company.name"/>
<img t-att-src="'/logo.png?company=%s' % company.id" style="padding: 0px; margin: 0px; height: auto; width: 80px;" t-att-alt="'%s' % company.name"/>
</td></tr>
<tr><td colspan="2" style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin:16px 0px 16px 0px;"/>
@@ -182,7 +182,7 @@
<!-- CONTENT -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="top" style="font-size: 14px;">
<t t-raw="message.body"/>
</td></tr>
@@ -195,7 +195,7 @@
<!-- FOOTER -->
<tr>
<td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" style="min-width: 590px; background-color: white; font-size: 12px; padding: 0px 8px 0px 8px; border-collapse:separate;">
<table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; font-size: 12px; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="middle" align="left">
<t t-esc="company.name"/>
</td></tr>
@@ -218,7 +218,7 @@
</td></tr>
<!-- POWERED BY -->
<tr><td align="center" style="min-width: 590px;">
<table width="590" border="0" cellpadding="0" style="min-width: 590px; background-color: #F1F1F1; color: #454748; padding: 8px; border-collapse:separate;">
<table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: #F1F1F1; color: #454748; padding: 8px; border-collapse:separate;">
<tr><td style="text-align: center; font-size: 14px;">
Powered by <a target="_blank" href="https://www.odoo.com" style="color: #875A7B;">Odoo</a>
</td></tr>
+2
View File
@@ -2076,6 +2076,7 @@ class MailThread(models.AbstractModel):
kwargs['message_type'] = 'notification'
res_id = kwargs.get('res_id', self.ids and self.ids[0] or 0)
res_ids = kwargs.get('res_id') and [kwargs['res_id']] or self.ids
notif_layout = kwargs.pop('notif_layout', None)
# Create the composer
composer = self.env['mail.compose.message'].with_context(
@@ -2086,6 +2087,7 @@ class MailThread(models.AbstractModel):
default_model=kwargs.get('model', self._name),
default_res_id=res_id,
default_template_id=template_id,
custom_layout=notif_layout,
).create(kwargs)
# Simulate the onchange (like trigger in form the view) only
# when having a template in single-email mode
+1 -1
View File
@@ -85,7 +85,7 @@ class Partner(models.Model):
'signature': signature,
'website_url': website_url,
'company': company,
'model_name': model_name,
'model_description': model_name,
'record': record,
'record_name': record_name,
'tracking_values': tracking,
+6 -4
View File
@@ -198,6 +198,7 @@ class MailComposer(models.TransientModel):
""" 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')
ctx_notif_values = self._context.get('notif_values', {})
for wizard in self:
# Duplicate attachments linked to the email.template.
# Indeed, basic mail.compose.message wizard duplicates attachments in mass
@@ -246,14 +247,15 @@ class MailComposer(models.TransientModel):
if wizard.composition_mode == 'mass_mail':
batch_mails |= Mail.create(mail_values)
else:
notif_values = dict(
add_sign=not bool(wizard.template_id),
mail_auto_delete=wizard.template_id.auto_delete if wizard.template_id else False,
**ctx_notif_values)
post_params = dict(
message_type=wizard.message_type,
subtype_id=subtype_id,
notif_layout=notif_layout,
notif_values={
'add_sign': not bool(wizard.template_id),
'mail_auto_delete': wizard.template_id.auto_delete if wizard.template_id else False,
},
notif_values=notif_values,
**mail_values)
if ActiveModel._name == 'mail.thread' and wizard.model:
post_params['model'] = wizard.model
@@ -14,7 +14,7 @@ class AccountInvoice(models.Model):
invoice.message_subscribe([invoice.partner_id.id])
for line in invoice.invoice_line_ids:
if line.product_id.email_template_id:
invoice.message_post_with_template(line.product_id.email_template_id.id, composition_mode='comment')
invoice.message_post_with_template(line.product_id.email_template_id.id, composition_mode='comment', custom_layout='mail.mail_notification_light')
return True
@api.multi
-14
View File
@@ -21,20 +21,6 @@
<field name="name">Usability</field>
</record>
<!-- Email templates -->
<record id="mail_template_data_project_task" model="mail.template">
<field name="name">Task: Reception Acknowledgment</field>
<field name="subject">Reception of ${object.name}</field>
<field name="model_id" ref="project.model_project_task"/>
<field name="use_default_to" eval="True"/>
<field name="body_html"><![CDATA[
<p>Dear ${object.partner_id.name or 'customer'},</p>
<p>Thank you for your enquiry.<br /></p>
<p>If you have any questions, please let us know.</p>
<p>Best regards,</p>]]></field>
<field name="auto_delete" eval="True"/>
</record>
<!-- Stages -->
<record id="project_stage_0" model="project.task.type">
<field name="sequence">1</field>
@@ -3,7 +3,7 @@
<data noupdate="1">
<!-- notify to admin of module installation -->
<record id="mail_template_data_module_install_project" model="mail.template">
<field name="name">project module install then send email</field>
<field name="name">Project: Spam admin after install</field>
<field name="subject">Your Odoo Project application</field>
<field name="email_from">help@odoo.com</field>
<field name="email_to">${user.email|safe}</field>
@@ -113,87 +113,92 @@
name="send_mail"
eval="[ref('mail_template_data_module_install_project'), ref('base.module_project')]"/>
<!-- Sample stage-related template -->
<record id="mail_template_data_project_task" model="mail.template">
<field name="name">Task: Reception Acknowledgment</field>
<field name="model_id" ref="project.model_project_task"/>
<field name="subject">Reception of ${object.name}</field>
<field name="use_default_to" eval="True"/>
<field name="body_html" type="html">
<div>
Dear ${object.partner_id.name or 'customer'},<br/>
Thank you for your enquiry.<br />
If you have any questions, please let us know.
<br/><br/>
Thank you,
<br/>
</div>
</field>
<field name="auto_delete" eval="True"/>
<field name="user_signature" eval="True"/>
</record>
<!-- Mail sent to request a rating for a task -->
<record id="rating_project_request_email_template" model="mail.template">
<field name="name">Task: Rating Request</field>
<field name="email_from">${object.rating_get_rated_partner_id().email or '' | safe}</field>
<field name="subject">${object.project_id.company_id.name}: Service Rating Request</field>
<field name="model_id" ref="project.model_project_task"/>
<field name="subject">${object.project_id.company_id.name}: Satisfaction Survey</field>
<field name="email_from">${('"%s" &lt;%s&gt;' % (object.rating_get_rated_partner_id().name, object.rating_get_rated_partner_id().email) if object.rating_get_rated_partner_id().email else '') | safe}</field>
<field name="partner_to" >${object.rating_get_partner_id().id}</field>
<field name="auto_delete" eval="True"/>
<field name="body_html"><![CDATA[
<div style="background:#F0F0F0;color:#515166;padding:10px 0px;font-family:Arial,Helvetica,sans-serif;font-size:14px;">
<field name="body_html" type="html">
<div>
% set access_token = object.rating_get_access_token()
<table style="width:600px;margin:5px auto;">
<tbody>
<tr><td>
<a href="/"><img src="/web/binary/company_logo" style="vertical-align:baseline;max-width:100px;" /></a>
</td><td style="text-align:right;vertical-align:middle;">
Satisfaction Survey
</td></tr>
</tbody>
</table>
<table style="width:600px;margin:0px auto;background:white;border:1px solid #e1e1e1;">
<tbody>
<tr><td style="padding:15px 20px 10px 20px;">
<p>Hello,</p>
<p>Please take a moment to rate our services related to the task "<strong>${object.name}</strong>"
assigned to <strong>${object.rating_get_rated_partner_id().name}</strong>.</p>
<p>We appreciate your feedback. It helps us to improve continuously.</p>
</td></tr>
<tr><td style="padding:10px 20px">
<table summary="o_mail_notification" style="width:100%;border-top:1px solid #e1e1e1;">
<tr>
<td style="text-align:center;">
<h2 style="font-weight:300;font-size:18px;">
Tell us how you feel about our service:
</h2>
<div style="text-color: #888888">(click on one of these smileys)</div>
</td>
</tr>
<tr>
<td style="padding:10px 10px;">
<table style="width:100%;text-align:center;">
<tr>
<td>
<a href="/rating/${access_token}/10">
<img alt="Satisfied" src="/rating/static/src/img/rating_10.png" title="Satisfied"/>
</a>
</td>
<td>
<a href="/rating/${access_token}/5">
<img alt="Not satisfied" src="/rating/static/src/img/rating_5.png" title="Not satisfied"/>
</a>
</td>
<td>
<a href="/rating/${access_token}/1">
<img alt="Highly Dissatisfied" src="/rating/static/src/img/rating_1.png" title="Highly Dissatisfied"/>
</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td></tr>
<tr><td style="padding:15px 20px 10px 20px;">${(object.user_id.signature or '')| safe}</td></tr>
</tbody>
</table>
<table style="width:600px;margin:auto;text-align:center;font-size:12px;">
<tbody>
<tr><td style="padding-top:10px;color:#afafaf;">
% if object.project_id.rating_status == 'stage':
<p>This customer survey has been sent because your task has been moved to the stage <b>${object.stage_id.name}</b></p>
% endif
% if object.project_id.rating_status == 'periodic':
<p>This customer survey is sent <b>${object.project_id.rating_status_period}</b> as long as the task is in the <b>${object.stage_id.name}</b> stage.</p>
% endif
<p>Email automatically sent by <a target="_blank" href="https://www.odoo.com/page/project-management" style="color:#875A7B;text-decoration:none;">Odoo Project</a> for <a href="${object.project_id.company_id.website}" style="color:#875A7B;text-decoration:none;">${object.project_id.company_id.name}</a></p>
</td></tr>
</tbody>
% set partner = object.rating_get_partner_id()
<table border="0" cellpadding="0" cellspacing="0" width="590" style="width:100%; margin:0px auto;">
<tbody>
<tr><td valign="top" style="font-size: 14px;">
Hello ${partner.name},<br/>
Please take a moment to rate our services related to the task "<strong>${object.name}</strong>"
% if object.rating_get_rated_partner_id().name:
assigned to <strong>${object.rating_get_rated_partner_id().name}</strong>.<br/>
% else:
.<br/>
% endif
</td></tr>
<tr><td style="text-align: center;">
<table border="0" cellpadding="0" cellspacing="0" width="590" summary="o_mail_notification" style="width:100%; margin: 32px 0px 32px 0px;">
<tr><td style="font-size: 14px;">
<strong>Tell us how you feel about our service</strong><br/>
<span style="text-color: #888888">(click on one of these smileys)</span>
</td></tr>
<tr><td style="font-size: 14px;">
<table style="width:100%;text-align:center;">
<tr>
<td>
<a href="/rating/${access_token}/10">
<img alt="Satisfied" src="/rating/static/src/img/rating_10.png" title="Satisfied"/>
</a>
</td>
<td>
<a href="/rating/${access_token}/5">
<img alt="Not satisfied" src="/rating/static/src/img/rating_5.png" title="Not satisfied"/>
</a>
</td>
<td>
<a href="/rating/${access_token}/1">
<img alt="Highly Dissatisfied" src="/rating/static/src/img/rating_1.png" title="Highly Dissatisfied"/>
</a>
</td>
</tr>
</table>
</td></tr>
</table>
</td></tr>
<tr><td valign="top" style="font-size: 14px;">
We appreciate your feedback. It helps us to improve continuously.
% if object.project_id.rating_status == 'stage':
<br/><span style="margin: 0px 0px 0px 0px; font-size: 12px; opacity: 0.5; color: #454748;">This customer survey has been sent because your task has been moved to the stage <b>${object.stage_id.name}</b></span>
% endif
% if object.project_id.rating_status == 'periodic':
<br/><span style="margin: 0px 0px 0px 0px; font-size: 12px; opacity: 0.5; color: #454748;">This customer survey is sent <b>${object.project_id.rating_status_period}</b> as long as the task is in the <b>${object.stage_id.name}</b> stage.</span>
% endif
</td></tr>
</tbody>
</table>
</div>
]]></field>
</field>
<field name="auto_delete" eval="True"/>
<field name="user_signature" eval="False"/>
</record>
</data>
</odoo>
+5 -1
View File
@@ -833,7 +833,11 @@ class Task(models.Model):
test_task = self[0]
changes, tracking_value_ids = tracking[test_task.id]
if 'stage_id' in changes and test_task.stage_id.mail_template_id:
res['stage_id'] = (test_task.stage_id.mail_template_id, {'composition_mode': 'mass_mail'})
res['stage_id'] = (test_task.stage_id.mail_template_id, {
'auto_delete_message': True,
'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'),
'notif_layout': 'mail.mail_notification_light'
})
return res
@api.multi
+25 -4
View File
@@ -213,12 +213,33 @@ class RatingMixin(models.AbstractModel):
return rating.access_token
@api.multi
def rating_send_request(self, template, lang=False, force_send=True):
def rating_send_request(self, template, lang=False, subtype_id=False, force_send=True, composition_mode='comment', notif_layout=None):
""" This method send rating request by email, using a template given
in parameter. """
lang = lang or 'en_US'
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
itself in the lang field;
:param 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
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;
"""
if lang:
template = template.with_context(lang=lang)
if subtype_id is False:
subtype_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note')
if force_send:
self = self.with_context(mail_notify_force_send=True)
for record in self:
template.with_context(lang=lang).send_mail(record.id, force_send=force_send)
record.message_post_with_template(
template.id,
composition_mode=composition_mode,
notif_layout=notif_layout if notif_layout is not None else 'mail.mail_notification_light',
subtype_id=subtype_id
)
@api.multi
def rating_apply(self, rate, token=None, feedback=None, subtype=None):
@@ -4,9 +4,11 @@
from email.utils import formataddr
from odoo.tests.common import TransactionCase, users, warmup
from odoo.tests import tagged
from odoo.tools import mute_logger
@tagged('mail_performance')
class TestMailPerformance(TransactionCase):
def setUp(self):
@@ -113,6 +115,7 @@ class TestMailPerformance(TransactionCase):
})
@tagged('mail_performance')
class TestAdvMailPerformance(TransactionCase):
def setUp(self):
@@ -295,6 +298,7 @@ class TestAdvMailPerformance(TransactionCase):
record.message_subscribe(partner_ids=self.user_test.partner_id.ids, subtype_ids=subtype_ids)
@tagged('mail_performance')
class TestHeavyMailPerformance(TransactionCase):
def setUp(self):
@@ -4,27 +4,26 @@
<!-- Email templates -->
<record id="mail_template_data_track_confirmation" model="mail.template">
<field name="name">Track: Confirmation</field>
<field name="subject">Confirmation of ${object.name}</field>
<field name="model_id" ref="website_event_track.model_event_track"/>
<field name="subject">Confirmation of ${object.name}</field>
<field name="use_default_to" eval="True"/>
<field name="body_html" type="xml">
<div>
<p>
Dear <t t-esc="object.partner_name"/>
</p><p>
We are pleased to inform you that your proposal ${object.name} has been accepted and confirmed for the event ${object.event_id.name}.
</p><p>
You will find more details here:
<div style="margin-top: 16px;">
<a href="/event/${object.event_id.id}/"
style="padding: 8px 12px; font-size: 12px; color: #FFFFFF; text-decoration: none !important; font-weight: 400; background-color: #875A7B; border: 0px solid #875A7B; border-radius:3px">
View Event
</a>
</div>
</p>
<p>Sincerely,</p>
Dear ${object.partner_name or ''}<br/>
We are pleased to inform you that your proposal ${object.name} has been accepted and confirmed for the event ${object.event_id.name}.
<br/>
You will find more details here:
<div style="margin: 16px 0px 16px 0px;">
<a href="/event/${object.event_id.id}/"
style="padding: 8px 16px 8px 16px; font-size: 14px; color: #FFFFFF; text-decoration: none !important; background-color: #875A7B; border: 0px solid #875A7B; border-radius:3px">
View Event
</a>
</div>
<br/><br/>
Thank you,
</div>
</field>
<field name="user_signature" eval="True"/>
<field name="auto_delete" eval="True"/>
</record>
@@ -139,7 +139,12 @@ class Track(models.Model):
track = self[0]
changes, tracking_value_ids = tracking[track.id]
if 'stage_id' in changes and track.stage_id.mail_template_id:
res['stage_id'] = (track.stage_id.mail_template_id, {'composition_mode': 'mass_mail'})
res['stage_id'] = (track.stage_id.mail_template_id, {
'composition_mode': 'comment',
'auto_delete_message': True,
'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'),
'notif_layout': 'mail.mail_notification_light'
})
return res
@api.multi
+3 -3
View File
@@ -44,13 +44,13 @@ class _Cleaner(clean.Cleaner):
_style_whitelist = [
'font-size', 'font-family', 'font-weight', 'background-color', 'color', 'text-align',
'line-height', 'letter-spacing', 'text-transform', 'text-decoration',
'line-height', 'letter-spacing', 'text-transform', 'text-decoration', 'opacity',
'float', 'vertical-align',
'padding', 'padding-top', 'padding-left', 'padding-bottom', 'padding-right',
'margin', 'margin-top', 'margin-left', 'margin-bottom', 'margin-right',
# box model
'border', 'border-color', 'border-radius', 'border-style', 'border-width',
'height', 'margin', 'padding', 'width', 'max-width', 'min-width',
'border', 'border-color', 'border-radius', 'border-style', 'border-width', 'border-top',
'height', 'width', 'max-width', 'min-width', 'min-height',
# tables
'border-collapse', 'border-spacing', 'caption-side', 'empty-cells', 'table-layout']