邮件集成是odoo最重要的特性。我们可以通过odoo收发邮件。我们甚至可以管理业务文档上的电子邮件,如潜在客户、销售订单和项目。本章,我们将探讨在odoo中处理邮件的方式。
在收发邮件前,我们需要配置邮件服务器。
本节,并不需要进行代码开发,我们需要邮件服务器的相关信息。比如,服务器url,端口,服务器类型,用户名,密码。
小贴士
如果你使用Odoo Online或者Odoo.sh,你无需配置邮件服务器。
配置传入和传出的电子邮件服务器涉及到传入和传出服务器流程中常见的几个步骤,以及每种服务器特有的几个步骤。因此,首先我们将看到常见的配置步骤,然后我们将分别配置传入和传出的电子邮件服务器。以下是输入和输出邮件服务器都需要的步骤:
在Settins|General Settins的form视图下打开General Settins
在Discuss区域打开External Email Servers,如下:
在Alias Domain字段,输入我们的邮件服务器domain名。
打开General Settings,点击Incoming Email Servers链接,将打开收邮件服务器的列表视图
。
点击新建,将打开form视图。输入相关内容如下:
点击Test & Confirm验证配置。
打开General Settings,使能External Email Servers,点击Outgoing Email Servers链接。
点击新建,将打开form视图。输入服务器细节如下:
点击Test Connection验证配置。
The steps given in this recipe are self-explanatory and do not require further explanation.But the outoging and incoming email records have several fields, so let`s see their purpose.
Here is a list of the fields used to configure the incoming eamil server:
如下是配置发送邮件服务器:
默认邮件服务器每5分钟更新一次。你可以修改该配置:
本节,我们将了解如何在文档中管理沟通记录。
本节,我们使用my_library模块,我们新增library.book.rent模型。
...
‘depends‘: [‘base‘, ‘mail‘],
...
class LibraryBookRent(models.Model):
_name = ‘library.book.rent‘
_inherit = [‘mail.thread‘]
...
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_
followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
为了确保模型中的chatter可用,我们需要安装mail模块。
与chatter相关的字段及方法定义在mail.thread模型中。mail.thread模型是虚拟类仅用作继承。步骤2,我们继承了mail.thread模型,可以为library.book.rent模型添加必要的字段及方法。
在前两个步骤中,我们添加了chatter所需的所有字段和方法。步骤3,我们添加了message thread及follower widget。其中message_follower_ids及message_ids字段自定义mail.thread中。
当我们在chatter中发送了消息,odoo将会自动给followers发送邮件。在我们本节的例子中,借阅人并不是图书记录的follower,因此他们并不会受到消息。如果需要给他们发邮件提醒,我们需要将他们添加到借阅列表中。我们可以通过 message_subscribe() 函数实现自动添加。如下:
@api.model
def create(self, vals):
res = super(LibraryBookRent, self).create(vals)
res.message_subscribe(partner_ids=[res.borrower_id.id])
return res
同样,我们可以通过 message_unsubscribe() 移除follower。
当使用chatter时,还可以添加活动
。类似于代做列表清单的东西。本节,我们将学习如何激活活动
。
为library.book.rent模型添加活动:
class LibraryBookRent(models.Model):
_name = ‘library.book.rent‘
_inherit = [‘mail.thread‘, ‘mail.activity.mixin‘]
...
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_
followers"/>
<field name="activity_ids" widget="mail_activity"/>
<field name="message_ids" widget="mail_thread"/>
</div>
活动
是mail模块中的一部分,我们可通过继承mail.activity.mixin实现在chatter中选择性的启用该功能。与mail.thread模型类似,mail.activity.mixin也是抽象模型。
步骤1,我们在library.book.rent中继承了mail.activity.mixin,因此library.book.rent获得了管理活动所必须的方法及字段。
步骤2,我们添加了mail_activity小部件,用于展示活动的相关内容,通过继承,我们在library.book.rent模型中添加了activity_ids字段。
活动有不同的类型。默认我们可以创建诸如Email、Call、Meeting和To-Do。我们可以在Settings | Technical | Email | Activity Types添加新的活动类型。
如果你想实现自动关联活动,我们可以通过mail.activity.mixin模型中的activity_schedule()方法实现。如下:
@api.model
def create(self, vals):
res = super(LibraryBookRent, self).create(vals)
if res.return_date:
res.activity_schedule(‘mail.mail_activity_data_call‘, date_deadline=res.return_date)
return res
如上例子可以在图书被借用的时候可自动实现添加一个提醒活动。可以在借阅截止日期的时候,管理员提醒下借阅人。
odoo支持通过Jinja模板创建动态邮件。Jinja是基于文本的模板引擎,用于解析HTML内容。本节,我们将创建Jinja邮件模板并发送邮件。
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<record id="book_return_reminder" model="mail. template">
<field name="name">Book Return Reminder</field>
<field name="email_from">${object.book_id.create_ uid.email}</field>
<field name="email_to">${object.borrower_ id.email}</field>
<field name="subject">Reminder for book return</field>
<field name="model_id" ref="my_library.model_ library_book_rent"/>
<field name="body_html">
<![CDATA[
<p>Dear ${object.borrower_id.name},</p> <p>You had rented the
<b>${object.book_id.name}</b> book on ${format_date(object.rent_date)}
<br/>
The due date of book is <b style="color:red;">${format_date(object.return_date)}.</b>
</p> <br/>
<p>Best regards,
<br/> Librarian</p>
]]>
</field>
</record>
‘data‘:[
...
‘data/mail_template.xml‘
]
<header>
<button name="book_return" string="Return the Book" states="ongoing" type="object"/>
<button name="book_return_reminder" string="Send reminder" states="ongoing" type="object"/>
<field name="state" widget="statusbar"/>
</header>
def book_return_reminder(self):
template_id = self.env.ref(‘my_library.book_return_
reminder‘) self.message_post_with_template(template_id.id)
更新模块,展示如下:
步骤1,我们创建了基于数据的动态生成的Jinja模板。邮件模板存储在mail.template模型中。主要字段如下:
信息
我们可以使用${}来设置动态值,比如email_form, email_to, email_cc, subject, scheduled_date和lang。
在body_html字段中,我们使用了${object.borrower_id.name}。此处的object就是library.book.rent的记录。在渲染的时候,${object.borrower_id.name}将被替换为借阅者的姓名。还有几个类似于Object的变量或函数,如下:
小贴士
我们可以在开发这模式下,点击Settings | Technical | Email | Templates菜单查看到邮件模板列表。form视图下还提供了预览模板的功能。
步骤2,在manifest文件中注册模板。
步骤3,添加激活book_return_reminder()方法的按钮,可用于给关注者发送邮件。
步骤4,message_post_with_template()方法用于发送邮件模板。该方法是通过继承模型mail.thread实现的。为了发送邮件,我们需要将模板的ID作为参数传递给函数。
message_post_with_tempalte()函数用于发送Jinja格式的邮件。如果我们想发送纯文本的邮件,可如下:
self.message_post(body="Please return your book on time")
所有的关注者都将收到Please return your book on time的消息。如果我们想记录该信息,可在调用函数的时候添加subtype_id参数。
本节,我们将学习发送QWeb样式的邮件。
<template id="book_return_reminder_qweb">
<p>Dear <span t-field="object.borrower_id.name"/>,</p>
<p>You had rented the<b><span t-field="object.book_id.name"/></b> book on <span t-field="object.rent_date"/>
<br/>
The due date of book is <b style="color:red;">
<span t-field="object.return_date"/>
</b>
</p>
<br/>
<p>Best regards, <br/>
Librarian
</p>
</template>
<header>
<button name="book_return" string="Return the Book" states="ongoing" type="object"/>
<button name="book_return_reminder" string="Send reminder" states="ongoing" type="object"/>
<button name="book_return_reminder_qweb" string="Send reminder(QWeb)" states="ongoing" type="object"/>
<field name="state" widget="statusbar"/>
</header>
def book_return_reminder_qweb(self):
self.message_post_with_view(‘my_library.book_return_reminder_qweb‘)
步骤1,我们创建了ID为book_return_reminder_qweb的QWeb模板。在模板中,我们并没有使用format_date()方法,这是因为QWeb渲染引擎将会自动根据用户的语言处理时间。同样的情况还有format_amount()方法。
步骤2,我们添加了可触发book_return_reminder_qweb()的按钮。
步骤3,message_post_with_view()用于发送邮件,该方法定义在mai.thread模型中。
QWeb模板与Jinja模板有如下几点不同:
self.message_post_with_view(
‘my_library.book_return_reminder_qweb‘, values={‘extra_data‘: ‘test‘}
)
在Jinja模板中,我们需要使用format_date、format_tz、format_amount方法管理日期、时区及货币的格式化。但在QWeb模板中,渲染器将自动转化。
在Jinja中,是不能修改已有的Jinja模板的。而在QWeb中,我们可以通过继承实现对模板的修改。详细内容可在第14章中学习。
您可以直接从消息生成器中选择和使用Jinja模板。在下面的屏幕截图中,右下角的下拉菜单用于选择Jinja模板:
但在我们无法直接在消息生成器中使用QWeb模板。
message_post、message_post_with_template及message_post_with_view均可在用户配置中实现。当用户在配置页面修改了通知方式,用户将无法收到邮件,而是在odoo的通知系统中收到消息提醒。此外,Odoo消息线程遵循一个称为子类型的概念。
子类型仅用于接收您感兴趣的信息的电子邮件。您可以在message_post_*方法中传递额外的参数subtype_id,以根据子类型发送电子邮件。通常,用户将从Follow按钮的下拉列表中管理其子类型。假设用户将其子类型设置为:
本节我们将继续使用my_library模块。我们将创建邮件地址为rent@yourdomain.com的邮件别名。如果你发邮件给这个地址,邮件主题为图书的名字,那么odoo将会自动创建一个library.book.rent的记录。
<record id="mail_alias_rent" model="mail.alias">
<field name="alias_name">rent</field>
<field name="alias_model_id" ref="model_library_book_prent"/>
<field name="alias_user_id" ref="base.user_admin"/>
<field name="alias_contact">partners</field>
</record>
import re
from odoo.tools import email_split, email_escape_char
@api.model
def message_new(self, msg_dict, custom_values=None):
self = self.with_content(default_user_id=False)
if custom_values is None:
custom_values = {}
regex = re.compile("^\[(.*)\]")
match = regex.match(msg_dict.get(‘subject‘)).group(1)
book_id = self.env[‘library.book‘].search([
(‘name‘, ‘=‘, match),
(‘state‘, ‘=‘, ‘available‘)
], limit=1)
custom_values[‘book_id‘] = book_id.id
email_from = email_escape_char(email_split(msg_dict.get(‘from‘))[0])
custom_values[‘borrower_id‘] = self._search_on_partner(email_from)
return super(LibraryBookRent, self).message_new(msg_dict, custom_values)
更新my_library模块,给rent@yourdomain.com发送邮件。确保邮件的主题符合要求,比如[Odoo 14 Development Cookbook] Request to borrow this book
。这将会创建一条新的借阅记录,如下:
步骤1,我们创建了mail.alias记录。这个别名将会处理rent@yourdomain.com邮件地址的内容。如果我们给这个地址发送邮件,odoo将会在Library.book.rent模型中创建一条新的记录。我们可以在Settings | Technical | Email | Aliases查看邮件别名列表。
步骤2,添加必要的引用。
步骤3,重写message_new()方法。该方法将在接收到新邮件的时候自动触发。该方法有两个参数:
一些业务模型有时需要针对每一条记录进行区分别名。比如,在销售团队模型中,针对不同的团队创建不同的别名。比如,为印度的团队创建sale-in@example.com,为比利时的团队创建sale-be@example.com。如果我们打算在模型中管理别名,我们可以在我们的模型中继承mail.alias.mixin。
class Team(models.Model):
_name = ‘crm.team‘
_inherit = [‘mail.alias.mixin‘, ‘mail.thread‘]
现在,我们可以在form视图中添加alias_name字段了,这用终端用户可以自行添加别名内容了。
Odoo框架提供了一个内置的工具来记录chatter中的字段更改。本节我们将启用邮件日志功能,用于记录某些字段的修改。
调整某些字段的定义,这样可以在改变字段内容的时候实现自动记录日志。如下:
class LibraryBookRent(models.Model):
_name = ‘library.book.rent‘
_inherit = [‘mail.thread‘, ‘mail.activity.mixin‘]
book_id = fields.Many2one(‘library.book‘, ‘Book‘, required=True)
borrower_id = fields.Many2one(‘res.partner‘, ‘Borrower‘, required=True)
state = fields.Selection([(‘ongoing‘, ‘Ongoing‘),(‘returned‘,‘Returned‘)],‘State‘, default=‘ongoing‘, required=True, tracking=True)
rent_date = fields.Date(default.fields.Date.today, tracking=True)
return_date = fields.Date(tracking=True)
更新模块,创建一条新的记录并修改,可如下内容:
当我们修改state, rent_date, return_date时,都可以清晰的看到修改的内容。
当您设置tracking=True属性时,每当您更新字段值时,Odoo将添加一个在chatter中更改的日志。如果对多个记录启用跟踪,并且希望在跟踪值中提供序列,还可以在跟踪参数中传递如下数字:tracking=20。当传递tracking=True时,将使用默认序列,即100。
track_visibility特性相关的代码定义在mail.thread模型中。
odoo框架内置了定期发送摘要邮件的功能。通过摘要邮件,我们可以发送商业KPI的相关内容。本节,我们将给管理员发送已借阅的图书。
class Digest(models.Model):
_inherit = ‘digest.digest‘
kpi_book_rent = fields.Boolean(‘Book Rent‘)
kpi_book_rent_value = fields.Integer(compute=‘_compute_kpi_book_rent_value‘)
def _compute_kpi_book_rent_value(self):
for record in self:
start, end, company = record._get_kpi_compute_parameters()
record.kpi_book_rent_value = self.env[‘library.book.rent‘].search_count([
(‘create_date‘, ‘>=‘, start),
(‘create_date‘, ‘<‘, end)
])
<?xml version=‘1.0‘ encoding=‘utf-8‘?>
<odoo>
<record id="digest_digest_view_form" model="ir. ui.view">
<field name="name">digest.digest.view.form. inherit.library</field>
<field name="model">digest.digest</field>
<field name="inherit_id" ref="digest.digest_ digest_view_form"/>
<field name="arch" type="xml">
<xpath expr="//group[@name=‘kpi_general‘]" position="after">
<group name="kpi_library" string="Library">
<field name="kpi_book_rent"/>
</group>
</xpath>
</field>
</record>
</odoo>
更新模块,可在Settings | Technical | Emails | Digest Emails中查看如下内容:
但我们启用了该功能并订阅了摘要邮件后,我们将收到相关提醒邮件喽。
为了创建自定义的摘要邮件,我们需要Boolean字段(用于启停KPI功能)及compute字段(用于获取KPI的值)。我们compute字段中使用了_get_kpi_compute_parameters()函数。这个函数由三个返回值,开始日期、结束日期以及公司记录。我们可以使用这三个值生成KPI。在本例中,我们返回了特定周期内借阅图书的数量。如果我们的KPI是多站点的,那么我们还需要使用company参数。
步骤2,我们在digest form视图添加了用于启停摘要邮件的字段。如果启用了该功能,则可以收到摘要邮件了。
原文:https://www.cnblogs.com/xushuotec/p/14587849.html