Before this commit, the calendar UX was not good enough. The look and feel was not modern. This commit improves a lot of small details, remove unneeded or not mature features (like the videocall location url). Counted recurrence now brings a better experience. When weekly or montly recurrences are created, occurences in the past are dismissed but before this commit their number was not adapted. User would end up with less occurences than the provided number without explanations. Taskid: 2484335 Part-of: odoo/odoo#68700
449 lines
26 KiB
XML
449 lines
26 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; padding: 16px 0px 16px 0px;">
|
|
% if not is_online or object.state != 'accepted':
|
|
<a href="/calendar/meeting/accept?token=${object.access_token}&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}&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}&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&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
|
|
<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>Meeting URL: <a href="${object.event_id.videocall_location}" target="_blank">${object.event_id.videocall_location}</a></li>
|
|
% endif
|
|
% if not is_html_empty(object.event_id.description):
|
|
<li>Description of the event:
|
|
${object.event_id.description | safe}</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; padding: 16px 0px 16px 0px;">
|
|
<a href="/calendar/meeting/accept?token=${object.access_token}&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}&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}&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&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
|
|
<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>Meeting URL: <a href="${object.event_id.videocall_location}" target="_blank">${object.event_id.videocall_location}</a></li>
|
|
% endif
|
|
% if not is_html_empty(object.event_id.description):
|
|
<li>Description of the event:
|
|
${object.event_id.description | safe}</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; padding: 16px 0px 16px 0px;">
|
|
<a href="/calendar/${'recurrence' if recurrent else 'meeting'}/accept?token=${object.access_token}&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}&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}&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&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
|
|
<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>Meeting URL: <a href="${object.event_id.videocall_location}" target="_blank">${object.event_id.videocall_location}</a></li>
|
|
% endif
|
|
% if not is_html_empty(object.event_id.description):
|
|
<li>Description of the event:
|
|
${object.event_id.description | safe}</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_update" model="mail.template">
|
|
<field name="name">Calendar: Event Update</field>
|
|
<field name="model_id" ref="calendar.model_calendar_event"/>
|
|
<field name="subject">${object.name}: Event update</field>
|
|
<field name="email_from">${(object.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="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 and object.appointment_type_id
|
|
% set target_responsible = object.partner_id == object.partner_id
|
|
% set target_customer = object.partner_id == customer
|
|
% set recurrent = object.recurrence_id and not ctx.get('calendar_template_ignore_recurrence')
|
|
% set mail_tz = ctx.get('mail_tz')
|
|
<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.start, tz=mail_tz if not object.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;">
|
|
${format_datetime(dt=object.start, tz=mail_tz if not object.allday else None, dt_format="d", lang_code=object.env.lang)}
|
|
</div>
|
|
<div style='font-size: 12px; text-align: center; font-weight: bold; color: #ffffff; background-color: #875A7B;'>
|
|
${format_datetime(dt=object.start, tz=mail_tz if not object.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.allday
|
|
<div>
|
|
${format_time(time=object.start, tz=mail_tz, time_format="short", lang_code=object.env.lang)}
|
|
</div>
|
|
% if mail_tz
|
|
<div style="font-size: 10px; font-weight: normal">
|
|
(${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 not is_online and object.display_description :
|
|
<li>Description: ${object.description}</li>
|
|
% elif is_online and object.description:
|
|
% set splitted_description = object.description_to_html_lines()
|
|
<li>Description:
|
|
<ul>
|
|
% for description_line in splitted_description:
|
|
<li>${description_line | safe}</li>
|
|
% endfor
|
|
</ul>
|
|
</li>
|
|
% endif
|
|
% if object.videocall_location:
|
|
<li>Meeting URL:
|
|
<a href="${object.videocall_location}" target="_blank">
|
|
${object.videocall_location}
|
|
</a>
|
|
</li>
|
|
% endif
|
|
% if object.location:
|
|
<li>Location: ${object.location}
|
|
(<a target="_blank"
|
|
href="http://maps.google.com/maps?oi=map&q=${object.location}">View Map</a>)
|
|
</li>
|
|
% endif
|
|
% if recurrent:
|
|
<li>When: ${object.recurrence_id.name}</li>
|
|
% endif
|
|
% if not object.allday and object.duration
|
|
<li>Duration:
|
|
${('%dH%02d' % (object.duration,round(object.duration*60)%60))}
|
|
</li>
|
|
% endif
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="user_input">
|
|
<hr/>
|
|
<p placeholder="Enter your message here"><br/></p>
|
|
|
|
</div>
|
|
</div>
|
|
</field>
|
|
</record>
|
|
</data>
|
|
</odoo>
|