[REF] digest: make digest template bioutifoul
PURPOSE
Make digest email and tips more appealing. The goals of these tips are
* to encourage the adoption of other apps (Did you know ?);
* to make Odoo look more fun (Fun tips and tricks, young and dynamic style);
* to show social proof and increase trust (emphasis on already existing
projects / customers to);
SPECIFICATIONS
Improve template according to FP specifications, aka
Header
Tip
KPIs
Preference text
Want to customize?
Mobile Tip
Footer
LINKS
Task ID 2197417
PR odoo/odoo#51619
Upgrade PR odoo/upgrade#1256
Co-Authored-By: Elisabeth Dickinson <edi@odoo.com>
Co-Authored-By: Thibault Delavallée <tde@odoo.com>
This commit is contained in:
co-authored by
Elisabeth Dickinson
parent
c329c618cf
commit
add1a04a94
@@ -7,7 +7,7 @@
|
||||
Send KPI Digests periodically
|
||||
=============================
|
||||
""",
|
||||
'version': '1.0',
|
||||
'version': '1.1',
|
||||
'depends': [
|
||||
'mail',
|
||||
'portal',
|
||||
@@ -15,8 +15,9 @@ Send KPI Digests periodically
|
||||
],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'data/digest_template_data.xml',
|
||||
'data/digest_data.xml',
|
||||
'data/digest_template_data.xml',
|
||||
'data/digest_tips_data.xml',
|
||||
'data/ir_cron_data.xml',
|
||||
'data/res_config_settings_data.xml',
|
||||
'views/digest_views.xml',
|
||||
|
||||
@@ -1,59 +1,56 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="digest_digest_default" model="digest.digest">
|
||||
<field name="name">Weekly Stats in Odoo</field>
|
||||
<field name="user_ids" eval="[(4, ref('base.user_admin'))]"/>
|
||||
<field name="next_run_date" eval="(DateTime.now() + timedelta(days=7)).strftime('%Y-%m-%d')"/>
|
||||
<field name="kpi_res_users_connected">True</field>
|
||||
<field name="kpi_mail_message_total">True</field>
|
||||
</record>
|
||||
</data>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo><data noupdate="1">
|
||||
|
||||
<data>
|
||||
<record id="digest_tip_mail_0" model="digest.tip">
|
||||
<field name="name">Mail: ping colleagues</field>
|
||||
<field name="sequence">1</field>
|
||||
<field name="tip_description" type="html">
|
||||
<div>
|
||||
% set users = object.env['res.users'].search([('share', '=' , False)], limit=10, order='id desc')
|
||||
% set channel_id = object.env.ref('mail.channel_all_employees').id
|
||||
<strong style="font-size: 16px;">Did you know...?</strong>
|
||||
<div style="font-size: 14px;">You can ping colleagues by tagging them in your messages using "@". They will be instantly notified.<br/>
|
||||
<div>
|
||||
<center>
|
||||
<img src="/digest/static/src/img/notification.png" width="70%" height="100%"/><br/>
|
||||
</center>
|
||||
${', '.join(users.mapped('name'))} signed up. Say hello in the <a href="/web#action=mail.action_discuss&active_id=${channel_id}" style="color: #006d6b;">company's discussion channel.</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
<record id="digest_tip_mail_1" model="digest.tip">
|
||||
<field name="name">Mail: get things done with activities</field>
|
||||
<field name="sequence">7</field>
|
||||
<field name="tip_description" type="html">
|
||||
<div>
|
||||
<strong style="font-size: 16px;">Get things done with activities</strong>
|
||||
<div style="font-size: 14px;">You don't have any activity scheduled. Use activities on any business document to schedule meetings, calls and todos.</div>
|
||||
<center>
|
||||
<img src="/digest/static/src/img/activity.png" width="70%" height="100%"/><br/>
|
||||
</center>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
<!-- Email layout: encapsulation when sending (not used in backend display) -->
|
||||
<template id="digest_mail_layout">
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta name="format-detection" content="telephone=no"/>
|
||||
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE" />
|
||||
|
||||
<record id="digest_tip_mail_2" model="digest.tip">
|
||||
<field name="name">Mail: apps videos tour</field>
|
||||
<field name="group_id" ref='base.group_system'/>
|
||||
<field name="sequence">0</field>
|
||||
<field name="tip_description" type="html">
|
||||
<div style="font-size: 14px;">
|
||||
To reach your full potential with Odoo, have a look at our <a href="https://www.odoo.com/page/tour">apps videos</a> and discover new tools to work better and faster.
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
<style type="text/css">
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
@media only screen and (max-width:650px) {
|
||||
.d-block{
|
||||
display: block !important;
|
||||
}
|
||||
.mobile-hide{
|
||||
display: none !important;
|
||||
}
|
||||
.mobile-w-75{
|
||||
width: 75% !important;
|
||||
}
|
||||
.mobile-w-33{
|
||||
width: 33% !important;
|
||||
}
|
||||
.font-25{
|
||||
font-size: 25px !important;
|
||||
line-height: 25px !important;
|
||||
}
|
||||
.font-18{
|
||||
font-size: 18px !important;
|
||||
line-height: 25px !important;
|
||||
}
|
||||
.font-16{
|
||||
font-size: 16px !important;
|
||||
line-height: 25px !important;
|
||||
}
|
||||
.font-12{
|
||||
font-size: 12px !important;
|
||||
line-height: 20px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<t t-raw="message.body"/>
|
||||
</body>
|
||||
</html>
|
||||
</template>
|
||||
</data></odoo>
|
||||
|
||||
@@ -6,103 +6,126 @@
|
||||
<field name="subject">${'%s: %s' % (ctx.get('user', user).company_id.name, object.name)}</field>
|
||||
<field name="email_from">${('%s' % (object.company_id.partner_id.email_formatted or user.email_formatted))|safe}</field>
|
||||
<field name="body_html" type="html">
|
||||
<table style="width: 100%; border-spacing: 0; font-family: Helvetica,Arial,Verdana,sans-serif;">
|
||||
<tr>
|
||||
<td align="center" valign="top" style="border-collapse: collapse; padding: 0">
|
||||
% set user = ctx.get('user', user)
|
||||
% set company = user.company_id
|
||||
% set data = object.compute_kpis(company, user)
|
||||
% set tips = object.compute_tips(company, user)
|
||||
% set kpi_actions = object.compute_kpis_actions(company, user)
|
||||
% set kpis = data.yesterday.keys()
|
||||
<table style="width: 100%; max-width: 600px; border-spacing: 0; border: 1px solid #e7e7e7; border-bottom: none; color: #6e7172; line-height: 23px; text-align: left;">
|
||||
<tr>
|
||||
<td style="border-collapse: collapse; padding: 10px 20px; text-align: left;">
|
||||
<strong style="color: #000000; font-size: 22px; line-height: 32px;">${object.name}</strong>
|
||||
<div style="color: #000000; font-size: 15px;">${datetime.date.today().strftime('%B %d, %Y')}</div>
|
||||
</td>
|
||||
<td style="text-align: right; padding: 10px 20px">
|
||||
<img style="padding: 0px; margin: 0px; height: auto; width: 80px;" src="/logo.png?company=${company.id}"/>
|
||||
<div style="padding-top: 5px;">
|
||||
<a href="/web/login" style="background-color: #875A7B; margin-left: 5px; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px; font-size:13px;">Connect</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td colspan="2" style="text-align: center;">
|
||||
<hr width="95%" 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 14px;"/>
|
||||
</td></tr>
|
||||
</table>
|
||||
% for kpi in kpis:
|
||||
<table style="border-spacing: 0; width: 100%; max-width: 600px;">
|
||||
<div style="margin:0; padding:0">
|
||||
% set user = ctx.get('user', user)
|
||||
% set company = user.company_id
|
||||
% set data = object.compute_kpis(company, user)
|
||||
% set tips = object.compute_tips(company, user, tips_count=ctx.get('tips_count', 1))
|
||||
% set kpi_actions = object.compute_kpis_actions(company, user)
|
||||
% set kpis = data.yesterday.keys()
|
||||
<table cellspacing="0" cellpadding="0" align="center" border="0" bgcolor="#eeeeee" style="width:100%; font-family: Arial,Helvetica,Verdana,sans-serif;">
|
||||
<tr class="mobile-hide" bgcolor="#875a7b"><td height="70"> </td></tr>
|
||||
<tr bgcolor="#875a7b">
|
||||
<td align="center" valign="top">
|
||||
<table bgcolor="#ffffff" cellspacing="0" cellpadding="0" width="650" align="center" border="0" style="border: 1px solid #eeeeee;width: 100%; max-width: 650px; padding: 30px 30px">
|
||||
<tr>
|
||||
<td style="border-collapse: collapse; background-color: #ffffff; border-left: 1px solid #e7e7e7; border-right: 1px solid #e7e7e7; line-height: 21px; padding: 0 20px 10px 20px; text-align: left;"><br/>
|
||||
<span style="color: #3d466e; font-size: 18px; font-weight: 500; line-height: 23px;">${object.fields_get()[kpi]['string']}</span>
|
||||
%if kpi in kpi_actions:
|
||||
<span style="float: right;">
|
||||
<a href="/web#action=${kpi_actions[kpi]}">View more</a>
|
||||
</span>
|
||||
%endif
|
||||
<td>
|
||||
<table cellspacing="0" cellpadding="0" border="0" width="580" align="center" style="width:100%; max-width:580px;">
|
||||
<tr>
|
||||
<td class="mobile-w-75" style="text-align: left;">
|
||||
<span class="font-16" style="color:#8F8F8F;font-weight:bold;font-size: 20px; line-height: 30px;">${company.name}</span>
|
||||
<br/>
|
||||
<span class="font-18" style="color:#282f33;font-weight:bold;font-size: 25px; line-height: 35px; margin-right: 5px;">${object.name}</span>
|
||||
<span class="d-block font-12" style="color:#8F8F8F;font-size: 15px;">${datetime.date.today().strftime('%B %d, %Y')}</span>
|
||||
</td>
|
||||
<td valign="top" style="text-align:right;">
|
||||
<a href="/web/login" target="_blank" style="display:block;background-color:#875a7b;line-height:40px;text-decoration: none;color: #ffffff;border-radius: 3px;font-size:13px;font-weight:bold;text-align:center;">Connect</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
% if tips:
|
||||
<table cellspacing="0" cellpadding="0" align="center" border="0" bgcolor="#eeeeee" style="width:100%; font-family: Arial,Helvetica,Verdana,sans-serif;">
|
||||
<tr>
|
||||
<td align="center" valign="top">
|
||||
<table bgcolor="#ffffff" cellspacing="0" cellpadding="0" width="650" align="center" border="0" style="border: 1px solid #eeeeee; border-bottom: none;width: 100%; max-width: 650px; padding:30px 30px">
|
||||
<tr>
|
||||
<td style="border-collapse: collapse; margin: 0; padding:0;">
|
||||
<table style="width: 100%; border-spacing: 0; background-color: #f9f9f9; border: 1px solid #e7e7e7; border-top: none;">
|
||||
<td>
|
||||
<table cellspacing="0" cellpadding="0" border="0" width="580" align="center" style="width:100%; max-width:580px;">
|
||||
<tr>
|
||||
<td style="border-collapse: collapse; margin: 0; padding: 0; display: block; border-top: 2px solid #56b3b5;">
|
||||
<table style="width: 100%; max-width: 199px; border-spacing: 0;">
|
||||
<tr>
|
||||
<td style="border-collapse: collapse; padding: 20px; text-align: center;">
|
||||
<span style="color: #56b3b5; font-size: 35px; font-weight: bold; text-decoration: none; line-height: 36px;">${data['yesterday'][kpi][kpi]}</span><br/>
|
||||
<span style="color: #888888; display: inline-block; font-size: 12px; line-height: 18px; text-transform: uppercase;">Yesterday</span>
|
||||
% if data['yesterday'][kpi]['margin'] != 0.0:
|
||||
<span style="color: #888888; display: block; font-size: 12px; line-height: 18px; text-transform: uppercase;">
|
||||
% if data['yesterday'][kpi]['margin'] is greaterthan(0.0):
|
||||
<span style="color: #0bbc22;">▲</span>${"%.2f" % data['yesterday'][kpi]['margin']} %
|
||||
% endif
|
||||
% if data['yesterday'][kpi]['margin'] is lessthan(0.0):
|
||||
<span style="color: #ff0000;">▼</span>${"%.2f" % data['yesterday'][kpi]['margin']} %
|
||||
% endif
|
||||
</span>
|
||||
% endif
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<td valign="top">
|
||||
${tip | safe}
|
||||
</td>
|
||||
<td style="border-collapse: collapse; margin: 0; padding: 0; border-top: 2px solid #9a5b82;">
|
||||
<table style="width: 100%; max-width: 199px; border-spacing: 0; margin: 0; padding: 0;">
|
||||
<tr>
|
||||
<td style="border-collapse: collapse; padding: 20px; text-align: center;">
|
||||
<span style="color: #9a5b82; font-size: 35px; font-weight: bold; text-decoration: none; line-height: 36px;">${data['lastweek'][kpi][kpi]}</span><br/>
|
||||
<span style="color: #888888; display: inline-block; font-size: 12px; line-height: 18px; text-transform: uppercase;">Last 7 Days</span>
|
||||
% if data['lastweek'][kpi]['margin'] != 0.0:
|
||||
<span style="color: #888888; display: block; font-size: 12px; line-height: 18px; text-transform: uppercase;">
|
||||
% if data['lastweek'][kpi]['margin'] is greaterthan(0.0):
|
||||
<span style="color: #0bbc22;">▲</span>${"%.2f" % data['lastweek'][kpi]['margin']} %
|
||||
% endif
|
||||
% if data['lastweek'][kpi]['margin'] is lessthan(0.0):
|
||||
<span style="color: #ff0000;">▼</span>${"%.2f" % data['lastweek'][kpi]['margin']} %
|
||||
%endif
|
||||
</span>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
% endif
|
||||
<table cellspacing="0" cellpadding="0" align="center" border="0" bgcolor="#eeeeee" style="width:100%; font-family: Arial,Helvetica,Verdana,sans-serif;">
|
||||
<tr>
|
||||
<td align="center" valign="top">
|
||||
% for kpi in kpis:
|
||||
<table bgcolor="#ffffff" cellspacing="0" cellpadding="0" width="650" align="center" border="0" style="border: 1px solid #eeeeee; border-bottom: none;width: 100%; max-width: 650px; padding:30px 30px">
|
||||
<tr>
|
||||
<td>
|
||||
<table cellspacing="0" cellpadding="0" border="0" width="580" align="center" style="width:100%; max-width:580px;">
|
||||
<tr>
|
||||
<td align="left" style="border-bottom: 1px solid #eeeeee;">
|
||||
<span style="color:#282f33;font-size: 15px; font-weight: bold; line-height: 30px">${object.fields_get()[kpi]['string']}</span>
|
||||
%if kpi in kpi_actions:
|
||||
<a href="/web#action=${kpi_actions[kpi]}" style=" float:right; background-color:#875A7B;margin-left: 5px; padding: 5px 12px 5px 12px; text-decoration: none; color: #ffffff; border-radius: 3px; font-size:13px; font-weight:bold; margin-bottom: 5px;">View</a>
|
||||
%endif
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table cellspacing="0" cellpadding="0" align="center" border="0" style="width:100%; padding: 20px 0;">
|
||||
<tr valign="top">
|
||||
<td class="mobile-w-33" width="196" style=" text-align: center;">
|
||||
<span class="font-25" style="color:#282f33;font-size: 35px; font-weight: bold; text-decoration: none; line-height: 36px;">${data['yesterday'][kpi][kpi]}</span><br/>
|
||||
<span style="color:#888888;display: inline-block; font-size: 12px; line-height: 18px; text-transform: uppercase;">Yesterday</span>
|
||||
% if data['yesterday'][kpi]['margin'] != 0.0:
|
||||
% if data['yesterday'][kpi]['margin'] is greaterthan(0.0):
|
||||
<div style="background-color:#d5f1e2; border: 1px solid #c4ecd7; margin: 10px auto;width: 67px; line-height:27px; text-decoration: none; color: #17613a; border-radius: 5px; font-size:13px;">
|
||||
▲ ${"%.2f" % data['yesterday'][kpi]['margin']}
|
||||
</div>
|
||||
%endif
|
||||
% if data['yesterday'][kpi]['margin'] is lessthan(0.0):
|
||||
<div style="background-color:#f7dddc; border: 1px solid #f4cfce; margin: 10px auto;width: 67px; line-height:27px; text-decoration: none; color: #712b29; border-radius: 5px; font-size:13px;">
|
||||
▼ ${"%.2f" % data['yesterday'][kpi]['margin']}
|
||||
</div>
|
||||
%endif
|
||||
%endif
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; margin: 0; padding: 15px; border-top: 2px solid #56b3b5;">
|
||||
<table style="width: 100%; max-width: 199px; border-spacing: 0; margin: 0; padding: 0;">
|
||||
<tr>
|
||||
<td style="border-collapse: collapse; margin: 0; text-align: center;">
|
||||
<span style="color: #56b3b5; font-size: 35px; font-weight: bold; text-decoration: none; line-height: 36px">${data['lastmonth'][kpi][kpi]}</span><br/>
|
||||
<span style="color: #888888; display: inline-block; font-size: 12px; line-height: 18px; text-transform: uppercase;">Last 30 Days</span>
|
||||
<td class="mobile-w-33" width="196" style=" text-align: center;">
|
||||
<span class="font-25" style="color:#282f33;font-size: 35px; font-weight: bold; text-decoration: none; line-height: 36px;">${data['lastweek'][kpi][kpi]}</span><br/>
|
||||
<span style="color:#888888;display: inline-block; font-size: 12px; line-height: 18px; text-transform: uppercase;">Last 7 Days</span>
|
||||
% if data['lastweek'][kpi]['margin'] != 0.0:
|
||||
% if data['lastweek'][kpi]['margin'] is greaterthan(0.0):
|
||||
<div style="background-color:#d5f1e2; border: 1px solid #c4ecd7; margin: 10px auto;width: 67px; line-height:27px; text-decoration: none; color: #17613a; border-radius: 5px; font-size:13px;">
|
||||
▲ ${"%.2f" % data['lastweek'][kpi]['margin']}
|
||||
</div>
|
||||
%endif
|
||||
% if data['lastweek'][kpi]['margin'] is lessthan(0.0):
|
||||
<div style="background-color:#f7dddc; border: 1px solid #f4cfce; margin: 10px auto;width: 67px; line-height:27px; text-decoration: none; color: #712b29; border-radius: 5px; font-size:13px;">
|
||||
▼ ${"%.2f" % data['lastweek'][kpi]['margin']}
|
||||
</div>
|
||||
%endif
|
||||
%endif
|
||||
</td>
|
||||
<td class="mobile-w-33" width="196" style=" text-align: center;">
|
||||
<span class="font-25" style="color:#282f33;font-size: 35px; font-weight: bold; text-decoration: none; line-height: 36px">${data['lastmonth'][kpi][kpi]}</span><br/>
|
||||
<span style="color:#888888;display: inline-block; font-size: 12px; line-height: 18px; text-transform: uppercase;">Last 30 Days</span>
|
||||
% if data['lastmonth'][kpi]['margin'] != 0.0:
|
||||
<span style="color: #888888; display: block; font-size: 12px; line-height: 18px; text-transform: uppercase;">
|
||||
% if data['lastmonth'][kpi]['margin'] is greaterthan(0.0):
|
||||
<span style="color: #0bbc22;">▲</span>${"%.2f" % data['lastmonth'][kpi]['margin']} %
|
||||
% endif
|
||||
% if data['lastmonth'][kpi]['margin'] is lessthan(0.0):
|
||||
<span style="color: #ff0000;">▼</span>${"%.2f" % data['lastmonth'][kpi]['margin']} %
|
||||
%endif
|
||||
</span>
|
||||
% if data['lastmonth'][kpi]['margin'] is greaterthan(0.0):
|
||||
<div style="background-color:#d5f1e2; border: 1px solid #c4ecd7; margin: 10px auto;width: 67px; line-height:27px; text-decoration: none; color: #17613a; border-radius: 5px; font-size:13px;">
|
||||
▲ ${"%.2f" % data['lastmonth'][kpi]['margin']}
|
||||
</div>
|
||||
%endif
|
||||
% if data['lastmonth'][kpi]['margin'] is lessthan(0.0):
|
||||
<div style="background-color:#f7dddc; border: 1px solid #f4cfce; margin: 10px auto;width: 67px; line-height:27px; text-decoration: none; color: #712b29; border-radius: 5px; font-size:13px;">
|
||||
▼ ${"%.2f" % data['lastmonth'][kpi]['margin']}
|
||||
</div>
|
||||
%endif
|
||||
%endif
|
||||
</td>
|
||||
</tr>
|
||||
@@ -113,52 +136,62 @@
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
% endfor
|
||||
% if tips:
|
||||
<table style="width: 100%; max-width: 600px; margin-top: 5px; border: 1px solid #e7e7e7;">
|
||||
% endfor
|
||||
% if user.has_group('base.group_system'):
|
||||
<table bgcolor="#ffffff" cellspacing="0" cellpadding="0" width="650" align="center" border="0" style="border-left: 1px solid #eeeeee; border-right: 1px solid #eeeeee; width: 100%; max-width: 650px; padding:30px 30px">
|
||||
<tr>
|
||||
<td style="border-collapse: collapse; background-color: #ffffff; line-height: 21px; padding: 0px 20px 20px;"><br/>
|
||||
<div style="color: #3d466e; line-height: 23px;">${tips | safe}</div>
|
||||
<td bgcolor="#fafafa" width="100%" height="50" align="center">
|
||||
<p class="font-12" style="font-size: 15px; color: #6b6d70">Want to customize this email?
|
||||
<a href="/web#view_type=form&model=digest.digest&id=${object.id}" target="_blank" style="color:#875A7B; font-weight: bold;">Choose the metrics you care about</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
% endif
|
||||
<table style="width: 100%; max-width: 600px; margin-top: 5px; border: 1px solid #e7e7e7;">
|
||||
<tr>
|
||||
<td style="border-collapse: collapse; background-color: #ffffff; line-height: 21px; padding: 0 20px 10px 20px; text-align: center;"><br/>
|
||||
<div style="color: #3d466e; font-size: 16px; font-weight: 600; line-height: 23px;">Run your business from anywhere with Odoo Mobile.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-bottom:20px;">
|
||||
<div style="text-align: center;"><a href="https://play.google.com/store/apps/details?id=com.odoo.mobile" target="_blank"><img src="/digest/static/src/img/google_play.png" style="display: inline-block; height: 30px; margin-left: auto; margin-right: 12px;"/></a><a href="https://itunes.apple.com/us/app/odoo/id1272543640" target="_blank"><img src="/digest/static/src/img/app_store.png" style="display: inline-block; height: 30px; margin-left: 12px; margin-right: auto;"/></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table style="margin-top: 5px; border: 1px solid #e7e7e7; font-size: 15px; width: 100%; max-width: 600px;">
|
||||
<tr>
|
||||
<td style="border-collapse: collapse; margin: 0; padding: 10px 20px;">
|
||||
% if user.has_group('base.group_system'):
|
||||
<div style="margin-top: 20px;">
|
||||
Want to customize this email?
|
||||
<a href="/web#view_type=form&model=digest.digest&id=${object.id}" target="_blank" style="color: #875A7B;">Choose the metrics you care about</a>
|
||||
</div>
|
||||
<br />
|
||||
% endif
|
||||
<p style="font-size: 11px; margin-top: 10px;">
|
||||
<strong>
|
||||
Sent by
|
||||
<a href="https://www.odoo.com" style="text-decoration: none; color: #875A7B;">Odoo</a> - <a href="/web#view_type=form&model=digest.digest&id=${object.id}" target="_blank" style="color: #888888;">Unsubscribe</a>
|
||||
</strong>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table></field>
|
||||
% endif
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top">
|
||||
<table bgcolor="#ffffff" cellspacing="0" cellpadding="0" width="650" align="center" border="0" style="border: 1px solid #eeeeee; width: 100%; max-width: 650px; padding:30px 30px">
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<table cellspacing="0" cellpadding="0" border="0" width="580" align="center" style="width:100%; max-width:580px;">
|
||||
<tr>
|
||||
<td valign="top" width="168">
|
||||
<img src="https://www.odoo.com/web/image/24717933/odoo-mobile.png" alt="Odoo Mobile" width="168"/>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<p class="font-16" style="color:#2d2a26;font-size: 18px;line-height: 23px; margin-top: 20px">Run your business from anywhere with <br class="mobile-hide" /><b>Odoo Mobile</b>.</p>
|
||||
<a href="https://play.google.com/store/apps/details?id=com.odoo.mobile" target="_blank"><img src="https://www.odoo.com/digest/static/src/img/google_play.png" style="display:inline-block;height: 40px; margin-bottom: 5px"/></a>
|
||||
<span class="mobile-hide"> </span>
|
||||
<a href="https://itunes.apple.com/us/app/odoo/id1272543640" target="_blank"><img src="https://www.odoo.com/digest/static/src/img/app_store.png" style="display:inline-block;height: 40px; margin-bottom: 5px"/></a>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top">
|
||||
<table bgcolor="#eeeeee" cellspacing="0" cellpadding="0" width="650" align="center" border="0" style="margin-top:30px;font-size: 15px; text-align:center; width: 100%; max-width: 650px;">
|
||||
<tr>
|
||||
<td style="color:#8F8F8F;font-weight:bold;font-size: 20px; line-height: 30px;">${company.name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="color:#8F8F8F;font-size: 12px; line-height: 30px;">Powered by <a href="https://www.odoo.com" target="_blank" style="color:#875A7B">Odoo</a>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td height="30"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</field>
|
||||
<field name="lang">${user.lang}</field>
|
||||
<field name="auto_delete" eval="True"/>
|
||||
<field name="auto_delete" eval="True" />
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="digest_digest_default" model="digest.digest">
|
||||
<field name="name">Weekly Stats in Odoo</field>
|
||||
<field name="user_ids" eval="[(4, ref('base.user_admin'))]"/>
|
||||
<field name="next_run_date" eval="(DateTime.now() + timedelta(days=7)).strftime('%Y-%m-%d')"/>
|
||||
<field name="kpi_res_users_connected">True</field>
|
||||
<field name="kpi_mail_message_total">True</field>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<data>
|
||||
<record id="digest_tip_mail_0" model="digest.tip">
|
||||
<field name="name">Mail: ping colleagues</field>
|
||||
<field name="sequence">1</field>
|
||||
<field name="tip_description" type="html">
|
||||
<div>
|
||||
% set users = object.env['res.users'].search([('share', '=' , False)], limit=10, order='id desc')
|
||||
% set channel_id = object.env.ref('mail.channel_all_employees').id
|
||||
<strong style="font-size: 16px;">Did you know...?</strong>
|
||||
<div style="font-size: 14px;">You can ping colleagues by tagging them in your messages using "@". They will be instantly notified.<br/>
|
||||
<div>
|
||||
<center>
|
||||
<img src="/digest/static/src/img/notification.png" width="70%" height="100%"/><br/>
|
||||
</center>
|
||||
${', '.join(users.mapped('name'))} signed up. Say hello in the <a href="/web#action=mail.action_discuss&active_id=${channel_id}" style="color: #006d6b;">company's discussion channel.</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
<record id="digest_tip_mail_1" model="digest.tip">
|
||||
<field name="name">Mail: get things done with activities</field>
|
||||
<field name="sequence">7</field>
|
||||
<field name="tip_description" type="html">
|
||||
<div>
|
||||
<strong style="font-size: 16px;">Get things done with activities</strong>
|
||||
<div style="font-size: 14px;">You don't have any activity scheduled. Use activities on any business document to schedule meetings, calls and todos.</div>
|
||||
<center>
|
||||
<img src="/digest/static/src/img/activity.png" width="70%" height="100%"/><br/>
|
||||
</center>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="digest_tip_mail_2" model="digest.tip">
|
||||
<field name="name">Mail: apps videos tour</field>
|
||||
<field name="group_id" ref='base.group_system'/>
|
||||
<field name="sequence">0</field>
|
||||
<field name="tip_description" type="html">
|
||||
<div style="font-size: 14px;">
|
||||
To reach your full potential with Odoo, have a look at our <a href="https://www.odoo.com/page/tour">apps videos</a> and discover new tools to work better and faster.
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -101,10 +101,20 @@ class Digest(models.Model):
|
||||
def action_send(self):
|
||||
for digest in self:
|
||||
for user in digest.user_ids:
|
||||
subject = '%s: %s' % (user.company_id.name, digest.name)
|
||||
digest.template_id.with_context(user=user).send_mail(digest.id, force_send=True, raise_exception=True, email_values={'email_to': user.email, 'subject': subject})
|
||||
digest._action_send_to_user(user, tips_count=1)
|
||||
digest.next_run_date = digest._get_next_run_date()
|
||||
|
||||
def _action_send_to_user(self, user, tips_count=1):
|
||||
subject = '%s: %s' % (user.company_id.name, self.name)
|
||||
self.template_id.with_context(user=user, tips_count=tips_count).send_mail(
|
||||
self.id,
|
||||
force_send=True,
|
||||
notif_layout="digest.digest_mail_layout",
|
||||
raise_exception=True,
|
||||
email_values={
|
||||
'email_to': user.email, 'subject': subject
|
||||
}
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _cron_send_digest_email(self):
|
||||
@@ -148,15 +158,17 @@ class Digest(models.Model):
|
||||
res.update({tf_name: kpis})
|
||||
return res
|
||||
|
||||
def compute_tips(self, company, user):
|
||||
tip = self.env['digest.tip'].search([('user_ids', '!=', user.id), '|', ('group_id', 'in', user.groups_id.ids), ('group_id', '=', False)], limit=1)
|
||||
if not tip:
|
||||
return False
|
||||
tip.user_ids += user
|
||||
body = tools.html_sanitize(tip.tip_description)
|
||||
# FIXME: sanitize ? links ?
|
||||
tip_description = self.env['mail.render.mixin']._render_template(body, 'digest.tip', self.ids)[self.id]
|
||||
return tip_description
|
||||
def compute_tips(self, company, user, tips_count=1):
|
||||
tips = self.env['digest.tip'].search([
|
||||
('user_ids', '!=', user.id),
|
||||
'|', ('group_id', 'in', user.groups_id.ids), ('group_id', '=', False)
|
||||
], limit=tips_count)
|
||||
tip_descriptions = [
|
||||
self.env['mail.render.mixin']._render_template(tools.html_sanitize(tip.tip_description), 'digest.tip', tip.ids, post_process=True)[tip.id]
|
||||
for tip in tips
|
||||
]
|
||||
# tip.user_ids += user
|
||||
return tip_descriptions
|
||||
|
||||
def compute_kpis_actions(self, company, user):
|
||||
""" Give an optional action to display in digest email linked to some KPIs.
|
||||
|
||||
Reference in New Issue
Block a user