Files
odoo_source/addons/calendar/data/mail_template_data.xml
T
nounoubensebia ad602bba0c [FIX] calendar_event, tools: appointment time mismatch
add mail_tz to calendar_attendee model in order to make it easier to change the
timezone displayed in the mail template so that we can use it to make the
appointment time shown on the email reminder sent to the attendees consistent
with the time shown on the website page.

Change the invitation mail template and use the mail_tz field to display time
field instead of using the partner's timezone in order to make the time shown
in the invitation consistent with the time shown on the website page.

Remove the get_interval method in the calendar_event model and use standard
formatting tools instead, as this is more conveniant than having a custom
method for formatting dates, For this reason the format_time function located
in tools/misc.py has been modified to be capable of handling timezones in
order to be able to display time in the correct timezone, furthermore, this
function has been added to the rendering context provided in the
mail_render_mixin file to be used in email templates.

see: https://github.com/odoo/enterprise/pull/16204

Task-2451154

closes odoo/odoo#65729

Related: odoo/enterprise#16204
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2021-03-30 13:17:07 +00:00

379 lines
22 KiB
XML

<?xml version="1.0"?>
<odoo>
<data noupdate="1">
<record id="calendar_template_meeting_invitation" model="mail.template">
<field name="name">Calendar: Meeting Invitation</field>
<field name="model_id" ref="calendar.model_calendar_attendee"/>
<field name="subject">Invitation to ${object.event_id.name}</field>
<field name="email_from">${(object.event_id.user_id.email_formatted or user.email_formatted or '') | safe}</field>
<field name="email_to">${('' if object.partner_id.email and object.partner_id.email == object.email else object.email) | safe}</field>
<field name="partner_to">${object.partner_id.id if object.partner_id.email and object.partner_id.email == object.email else False}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="body_html" type="html">
<div>
% set colors = {'needsAction': 'grey', 'accepted': 'green', 'tentative': '#FFFF00', 'declined': 'red'}
% set is_online = 'appointment_type_id' in object.event_id and object.event_id.appointment_type_id
% set customer = object.event_id.find_partner_customer()
% set target_responsible = object.partner_id == object.event_id.partner_id
% set target_customer = object.partner_id == customer
<p>
Hello ${object.common_name},<br/><br/>
% if is_online and target_customer:
Your appointment <strong>${object.event_id.appointment_type_id.name}</strong> with ${object.event_id.user_id.name} has been booked.
% elif is_online and target_responsible:
% if customer
${customer.name} scheduled the following appointment <strong>${object.event_id.appointment_type_id.name}</strong> with you.
% else
Your appointment <strong>${object.event_id.appointment_type_id.name}</strong> has been booked.
% endif
% elif not target_responsible:
${object.event_id.user_id.partner_id.name} invited you for the <strong>${object.event_id.name}</strong> meeting.
% else:
Your meeting <strong>${object.event_id.name}</strong> has been booked.
% endif
</p>
<div style="text-align: center; margin: 16px 0px 16px 0px;">
% if not is_online or object.state != 'accepted':
<a href="/calendar/meeting/accept?token=${object.access_token}&amp;id=${object.event_id.id}"
style="padding: 5px 10px; color: #FFFFFF; text-decoration: none; background-color: #875A7B; border: 1px solid #875A7B; border-radius: 3px">
Accept</a>
<a href="/calendar/meeting/decline?token=${object.access_token}&amp;id=${object.event_id.id}"
style="padding: 5px 10px; color: #FFFFFF; text-decoration: none; background-color: #875A7B; border: 1px solid #875A7B; border-radius: 3px">
Decline</a>
% endif
<a href="/calendar/meeting/view?token=${object.access_token}&amp;id=${object.event_id.id}"
style="padding: 5px 10px; color: #FFFFFF; text-decoration: none; background-color: #875A7B; border: 1px solid #875A7B; border-radius: 3px">
${'Reschedule' if is_online and target_customer else 'View'}
</a>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tr>
<td width="130px;">
<div style="border-top-left-radius: 3px; border-top-right-radius: 3px; font-size: 12px; border-collapse: separate; text-align: center; font-weight: bold; color: #ffffff; min-height: 18px; background-color: #875A7B; border: 1px solid #875A7B;">
${format_datetime(dt=object.event_id.start, tz=object.mail_tz if not object.event_id.allday else None, dt_format="EEEE", lang_code=object.env.lang)}
</div>
<div style="font-size: 48px; min-height: auto; font-weight: bold; text-align: center; color: #5F5F5F; background-color: #F8F8F8; border: 1px solid #875A7B;">
${str(object.event_id.start.day)}
</div>
<div style='font-size: 12px; text-align: center; font-weight: bold; color: #ffffff; background-color: #875A7B;'>
${format_datetime(dt=object.event_id.start, tz=object.mail_tz if not object.event_id.allday else None, dt_format="MMMM y", lang_code=object.env.lang)}
</div>
<div style="border-collapse: separate; color: #5F5F5F; text-align: center; font-size: 12px; border-bottom-right-radius: 3px; font-weight: bold ; border: 1px solid #875A7B; border-bottom-left-radius: 3px;">
% if not object.event_id.allday
<div>
${format_time(time=object.event_id.start, tz=object.mail_tz, time_format="short", lang_code=object.env.lang)}
</div>
% if object.mail_tz
<div style="font-size: 10px; font-weight: normal">
(${object.mail_tz})
</div>
% endif
%endif
</div>
</td>
<td width="20px;"/>
<td style="padding-top: 5px;">
<p><strong>Details of the event</strong></p>
<ul>
% if is_online:
<li>Appointment Type: ${object.event_id.appointment_type_id.name}</li>
% endif
% if object.event_id.location:
<li>Location: ${object.event_id.location}
(<a target="_blank" href="http://maps.google.com/maps?oi=map&amp;q=${object.event_id.location}">View Map</a>)
</li>
% endif
% if recurrent:
<li>When: ${object.recurrence_id.name}</li>
% endif
% if not object.event_id.allday and object.event_id.duration
<li>Duration: ${('%dH%02d' % (object.event_id.duration,round(object.event_id.duration*60)%60))}</li>
% endif
% if not is_online and object.event_id.description :
<li>Description: ${object.event_id.description}</li>
% elif is_online and object.event_id.description:
% set splitted_description = object.event_id.description_to_html_lines()
<li>Description:
<ul>
% for description_line in splitted_description:
<li>${description_line | safe}</li>
% endfor
</ul>
</li>
% endif
<li>Attendees
<ul>
% for attendee in object.event_id.attendee_ids:
<li>
<div style="display: inline-block; border-radius: 50%; width: 10px; height: 10px; background:${colors[attendee.state] or 'white'};"> </div>
% if attendee.common_name != object.common_name:
<span style="margin-left:5px">${attendee.common_name}</span>
% else:
<span style="margin-left:5px">You</span>
% endif
</li>
% endfor
</ul></li>
% if object.event_id.videocall_location:
<li>Join Video Call: <a href="${object.event_id.videocall_location}" target="_blank">${object.event_id.videocall_location}</a></li>
% endif
</ul>
</td>
</tr></table>
<br/>
Thank you,
% if object.event_id.user_id.signature:
<br />
${object.event_id.user_id.signature | safe}
% endif
</div>
</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="auto_delete" eval="True"/>
</record>
<record id="calendar_template_meeting_changedate" model="mail.template">
<field name="name">Calendar: Date updated</field>
<field name="model_id" ref="calendar.model_calendar_attendee"/>
<field name="subject">${object.event_id.name}: Date updated</field>
<field name="email_from">${(object.event_id.user_id.email_formatted or user.email_formatted or '') | safe}</field>
<field name="email_to">${('' if object.partner_id.email and object.partner_id.email == object.email else object.email) | safe}</field>
<field name="partner_to">${object.partner_id.id if object.partner_id.email and object.partner_id.email == object.email else False}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="body_html" type="html">
<div>
% set colors = {'needsAction': 'grey', 'accepted': 'green', 'tentative': '#FFFF00', 'declined': 'red'}
% set is_online = 'appointment_type_id' in object.event_id and object.event_id.appointment_type_id
% set customer = object.event_id.find_partner_customer()
% set target_responsible = object.partner_id == object.event_id.partner_id
% set target_customer = object.partner_id == customer
<p>
Hello ${object.common_name},<br/><br/>
% if is_online and target_responsible:
% if customer:
The date of your appointment with ${customer.name} has been updated.
% else
Your appointment has been updated.
% endif
The appointment <strong>${object.event_id.appointment_type_id.name}</strong> is now scheduled for
${object.event_id.get_display_time_tz(tz=object.partner_id.tz)}.
% elif is_online and target_customer:
The date of your appointment with ${object.event_id.user_id.partner_id.name} has been updated.
The appointment <strong>${object.event_id.appointment_type_id.name}</strong> is now scheduled for
${object.event_id.get_display_time_tz(tz=object.partner_id.tz)}.
% else:
The date of the meeting has been updated.
The meeting <strong>${object.event_id.name}</strong> created by ${object.event_id.user_id.partner_id.name} is now scheduled for
${object.event_id.get_display_time_tz(tz=object.partner_id.tz)}.
% endif
</p>
<div style="text-align: center; margin: 16px 0px 16px 0px;">
<a href="/calendar/meeting/accept?token=${object.access_token}&amp;id=${object.event_id.id}"
style="padding: 5px 10px; color: #FFFFFF; text-decoration: none; background-color: #875A7B; border: 1px solid #875A7B; border-radius: 3px">
Accept</a>
<a href="/calendar/meeting/decline?token=${object.access_token}&amp;id=${object.event_id.id}"
style="padding: 5px 10px; color: #FFFFFF; text-decoration: none; background-color: #875A7B; border: 1px solid #875A7B; border-radius: 3px">
Decline</a>
<a href="/calendar/meeting/view?token=${object.access_token}&amp;id=${object.event_id.id}"
style="padding: 5px 10px; color: #FFFFFF; text-decoration: none; background-color: #875A7B; border: 1px solid #875A7B; border-radius: 3px">
View</a>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tr>
<td width="130px;">
<div style="border-top-left-radius: 3px; border-top-right-radius: 3px; font-size: 12px; border-collapse: separate; text-align: center; font-weight: bold; color: #ffffff; min-height: 18px; background-color: #875A7B; border: 1px solid #875A7B;">
${format_datetime(dt=object.event_id.start, tz=object.mail_tz if not object.event_id.allday else None, dt_format="EEEE", lang_code=object.env.lang)}
</div>
<div style="font-size: 48px; min-height: auto; font-weight: bold; text-align: center; color: #5F5F5F; background-color: #F8F8F8; border: 1px solid #875A7B;">
${str(object.event_id.start.day)}
</div>
<div style='font-size: 12px; text-align: center; font-weight: bold; color: #ffffff; background-color: #875A7B;'>
${format_datetime(dt=object.event_id.start, tz=object.mail_tz if not object.event_id.allday else None, dt_format="MMMM y", lang_code=object.env.lang)}
</div>
<div style="border-collapse: separate; color: #5F5F5F; text-align: center; font-size: 12px; border-bottom-right-radius: 3px; font-weight: bold; border: 1px solid #875A7B; border-bottom-left-radius: 3px;">
% if not object.event_id.allday
<div>
${format_time(time=object.event_id.start, tz=object.mail_tz, time_format="short", lang_code=object.env.lang)}
</div>
% if object.mail_tz
<div style="font-size: 10px; font-weight: normal">
(${object.mail_tz})
</div>
% endif
%endif
</div>
</td>
<td width="20px;"/>
<td style="padding-top: 5px;">
<p><strong>Details of the event</strong></p>
<ul>
% if object.event_id.location:
<li>Location: ${object.event_id.location}
(<a target="_blank" href="http://maps.google.com/maps?oi=map&amp;q=${object.event_id.location}">View Map</a>)
</li>
% endif
% if recurrent:
<li>When: ${object.recurrence_id.name}</li>
% endif
% if not object.event_id.allday and object.event_id.duration
<li>Duration: ${('%dH%02d' % (object.event_id.duration,round(object.event_id.duration*60)%60))}</li>
% endif
% if not is_online and object.event_id.description :
<li>Description: ${object.event_id.description}</li>
% elif is_online and object.event_id.description:
% set splitted_description = object.event_id.description_to_html_lines()
<li>Description:
<ul>
% for description_line in splitted_description:
<li>${description_line | safe}</li>
% endfor
</ul>
</li>
% endif
<li>Attendees
<ul>
% for attendee in object.event_id.attendee_ids:
<li>
<div style="display: inline-block; border-radius: 50%; width: 10px; height: 10px; background: ${colors[attendee.state] or 'white'};"> </div>
% if attendee.common_name != object.common_name:
<span style="margin-left:5px">${attendee.common_name}</span>
% else:
<span style="margin-left:5px">You</span>
% endif
</li>
% endfor
</ul></li>
% if object.event_id.videocall_location:
<li>Join Video Call: <a href="${object.event_id.videocall_location}" target="_blank">${object.event_id.videocall_location}</a></li>
% endif
</ul>
</td>
</tr></table>
<br/>
Thank you,
% if object.event_id.user_id.signature:
<br />
${object.event_id.user_id.signature | safe}
% endif
</div>
</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="auto_delete" eval="True"/>
</record>
<record id="calendar_template_meeting_reminder" model="mail.template">
<field name="name">Calendar: Reminder</field>
<field name="model_id" ref="calendar.model_calendar_attendee"/>
<field name="subject">${object.event_id.name} - Reminder</field>
<field name="email_from">${(object.event_id.user_id.email_formatted or user.email_formatted or '') | safe}</field>
<field name="email_to">${('' if object.partner_id.email and object.partner_id.email == object.email else object.email) | safe}</field>
<field name="partner_to">${object.partner_id.id if object.partner_id.email and object.partner_id.email == object.email else False}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="body_html" type="html">
<div>
% set colors = {'needsAction': 'grey', 'accepted': 'green', 'tentative': '#FFFF00', 'declined': 'red'}
% set is_online = 'appointment_type_id' in object.event_id and object.event_id.appointment_type_id
% set recurrent = object.recurrence_id and not ctx.get('calendar_template_ignore_recurrence')
<p>
Hello ${object.common_name},<br/><br/>
This is a reminder for the below event :
</p>
<div style="text-align: center; margin: 16px 0px 16px 0px;">
<a href="/calendar/${'recurrence' if recurrent else 'meeting'}/accept?token=${object.access_token}&amp;id=${object.event_id.id}"
style="padding: 5px 10px; color: #FFFFFF; text-decoration: none; background-color: #875A7B; border: 1px solid #875A7B; border-radius: 3px">
Accept</a>
<a href="/calendar/${'recurrence' if recurrent else 'meeting'}/decline?token=${object.access_token}&amp;id=${object.event_id.id}"
style="padding: 5px 10px; color: #FFFFFF; text-decoration: none; background-color: #875A7B; border: 1px solid #875A7B; border-radius: 3px">
Decline</a>
<a href="/calendar/meeting/view?token=${object.access_token}&amp;id=${object.event_id.id}"
style="padding: 5px 10px; color: #FFFFFF; text-decoration: none; background-color: #875A7B; border: 1px solid #875A7B; border-radius: 3px">
View</a>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tr>
<td width="130px;">
<div style="border-top-left-radius: 3px; border-top-right-radius: 3px; font-size: 12px; border-collapse: separate; text-align: center; font-weight: bold; color: #ffffff; min-height: 18px; background-color: #875A7B; border: 1px solid #875A7B;">
${format_datetime(dt=object.event_id.start, tz=object.mail_tz if not object.event_id.allday else None, dt_format="EEEE", lang_code=object.env.lang)}
</div>
<div style="font-size: 48px; min-height: auto; font-weight: bold; text-align: center; color: #5F5F5F; background-color: #F8F8F8; border: 1px solid #875A7B;">
${str(object.event_id.start.day)}
</div>
<div style='font-size: 12px; text-align: center; font-weight: bold; color: #ffffff; background-color: #875A7B;'>
${format_datetime(dt=object.event_id.start, tz=object.mail_tz if not object.event_id.allday else None, dt_format="MMMM y", lang_code=object.env.lang)}
</div>
<div style="border-collapse: separate; color: #5F5F5F; text-align: center; font-size: 12px; border-bottom-right-radius: 3px; font-weight: bold; border: 1px solid #875A7B; border-bottom-left-radius: 3px;">
% if not object.event_id.allday
<div>
${format_time(time=object.event_id.start, tz=object.mail_tz, time_format="short", lang_code=object.env.lang)}
</div>
% if object.mail_tz
<div style="font-size: 10px; font-weight: normal">
(${object.mail_tz})
</div>
% endif
%endif
</div>
</td>
<td width="20px;"/>
<td style="padding-top: 5px;">
<p><strong>Details of the event</strong></p>
<ul>
% if object.event_id.location:
<li>Location: ${object.event_id.location}
(<a target="_blank" href="http://maps.google.com/maps?oi=map&amp;q=${object.event_id.location}">View Map</a>)
</li>
% endif
% if recurrent:
<li>When: ${object.recurrence_id.name}</li>
% endif
% if not object.event_id.allday and object.event_id.duration
<li>Duration: ${('%dH%02d' % (object.event_id.duration,round(object.event_id.duration*60)%60))}</li>
% endif
% if not is_online and object.event_id.description :
<li>Description: ${object.event_id.description}</li>
% elif is_online and object.event_id.description:
% set splitted_description = object.event_id.description_to_html_lines()
<li>Description:
<ul>
% for description_line in splitted_description:
<li>${description_line | safe}</li>
% endfor
</ul>
</li>
% endif
<li>Attendees
<ul>
% for attendee in object.event_id.attendee_ids:
<li>
<div style="display: inline-block; border-radius: 50%; width: 10px; height: 10px; background:${colors[attendee.state] or 'white'};"> </div>
% if attendee.common_name != object.common_name:
<span style="margin-left:5px">${attendee.common_name}</span>
% else:
<span style="margin-left:5px">You</span>
% endif
</li>
% endfor
</ul></li>
% if object.event_id.videocall_location:
<li>Join Video Call: <a href="${object.event_id.videocall_location}" target="_blank">${object.event_id.videocall_location}</a></li>
% endif
</ul>
</td>
</tr></table>
<br/>
Thank you,
% if object.event_id.user_id.signature:
<br />
${object.event_id.user_id.signature | safe}
% endif
</div>
</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="auto_delete" eval="True"/>
</record>
</data>
</odoo>