【odoo14】【好書學習】第二十三章、管理郵件


老韓頭的開發日常【好書學習】系列
郵件集成是odoo最重要的特性。我們可以通過odoo收發郵件。我們甚至可以管理業務文檔上的電子郵件,如潛在客戶、銷售訂單和項目。本章,我們將探討在odoo中處理郵件的方式。

  • 配置郵件服務器
  • 管理文檔中的chatter
  • 管理文檔中的活動
  • 通過Jinja模板發送郵件
  • 通過QWeb模板發送郵件
  • 管理郵件別名
  • 記錄在聊天中用戶改變的內容
  • 定期發送摘要郵件

配置郵件服務器

在收發郵件前,我們需要配置郵件服務器。

准備

本節,並不需要進行代碼開發,我們需要郵件服務器的相關信息。比如,服務器url,端口,服務器類型,用戶名,密碼。

小貼士
如果你使用Odoo Online或者Odoo.sh,你無需配置郵件服務器。

步驟

配置傳入和傳出的電子郵件服務器涉及到傳入和傳出服務器流程中常見的幾個步驟,以及每種服務器特有的幾個步驟。因此,首先我們將看到常見的配置步驟,然后我們將分別配置傳入和傳出的電子郵件服務器。以下是輸入和輸出郵件服務器都需要的步驟:

  1. Settins|General Settins的form視圖下打開General Settins

  2. Discuss區域打開External Email Servers,如下:

  3. Alias Domain字段,輸入我們的郵件服務器domain名。

配置收郵件服務器

  1. 打開General Settings,點擊Incoming Email Servers鏈接,將打開收郵件服務器的列表視圖

  2. 點擊新建,將打開form視圖。輸入相關內容如下:

  3. 點擊Test & Confirm驗證配置。

配置發郵件服務器

  1. 打開General Settings,使能External Email Servers,點擊Outgoing Email Servers鏈接。

  2. 點擊新建,將打開form視圖。輸入服務器細節如下:

  3. 點擊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:

  • Name:服務器的名稱,在我們添加了多個收郵件服務器的時候,標識不同的服務器。
  • Server Type: 根據我們的郵件服務器選擇POP、IMAP、Local中的一個。
  • Server Name: 服務器的domain。
  • Port: 郵件服務器的端口。
  • SSL/TLS: 如果郵件服務器使用SSL/TLS加密,則選擇該項。
  • Username: 郵箱地址。
  • Password: 郵件密碼。
  • Active 標識是否啟用郵件服務器。
  • Keep Attachment: 如果你不想管理附件可關閉該項。
  • Keep Original: 如果你想保留原始郵件,可啟動該項。

如下是配置發送郵件服務器:

  • Description: 服務器的描述,用於區分不同的服務器。
  • Priority: 用於定義發送郵件服務器的優先級。數字越低,優先級越高。
  • SMTP Server: 服務器的domain。
  • SMTP Port: 服務器的端口。
  • Connection Security: 在發送郵件時使用的安全類型。
  • Username: 發送郵件的賬戶。
  • Password: 發送郵件的密碼。
  • Active: 啟停發送郵件服務器。

更多

默認郵件服務器每5分鍾更新一次。你可以修改該配置:

  1. 激活開發者模式。
  2. Settings | Technical | Automation | Scheduled | Actions,打開 Scheduled Actions
  3. 搜索名為Mail:Fetchmail的動作。
  4. 改變間隔(Execute Every)。

管理文檔中的chatter

本節,我們將了解如何在文檔中管理溝通記錄。

准備

本節,我們使用my_library模塊,我們新增library.book.rent模型。

步驟

  1. 在__manifest__.py中添加mail模型
...
'depends': ['base', 'mail'], 
...
  1. 在library.book.rent模型中繼承mail.thread
class LibraryBookRent(models.Model): 
	_name = 'library.book.rent' 
	_inherit = ['mail.thread']
	...
  1. 在library.book.rent模型的form視圖添加chatter小部件
</sheet>
	<div class="oe_chatter">
		<field name="message_follower_ids" widget="mail_
		followers"/>
		<field name="message_ids" widget="mail_thread"/>
	</div>
</form>
  1. 更新模塊,顯示如下:

原理

為了確保模型中的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模型添加活動:

  1. 在library.book.rent模型中添加繼承mail.activity.mixin。
class LibraryBookRent(models.Model):
	_name = 'library.book.rent'
	_inherit = ['mail.thread', 'mail.activity.mixin']
	...
  1. 在library.book.rent模型中添加mail_activity小部件
<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>
  1. 更新模塊,顯示如下:

原理

活動是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

如上例子可以在圖書被借用的時候可自動實現添加一個提醒活動。可以在借閱截止日期的時候,管理員提醒下借閱人。

通過Jinja模板發送郵件

odoo支持通過Jinja模板創建動態郵件。Jinja是基於文本的模板引擎,用於解析HTML內容。本節,我們將創建Jinja郵件模板並發送郵件。

准備

步驟

  1. 創建my_library/data/mail_template.xml文件如下:
<?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>
  1. 注冊文件
'data':[
	...
	'data/mail_template.xml'
]
  1. 在library.book.rent模型的form視圖添加Send reminder按鈕
<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>
  1. 添加book_return_reminder()方法:
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模型中。主要字段如下:

  • name: 模板的名稱
  • email_from: 郵件發送人
  • email_to: 收件人
  • email_cc: 抄送人
  • subject: 主題
  • model_id: 郵件模板所關聯的對象
  • body_html: 郵件的模板的正文。在正文中,我們可以使用基於Jinja語法的變量、循環、條件等。可在Jinja 詳細了解。通常我們使用CDATA標簽包裹正文,將其標記為字符數據。
  • auto_delete: 標識是否在郵件發送后自動刪除。默認為False。
  • scheduled_date: 郵件計划發送的時間。

信息
我們可以使用${}來設置動態值,比如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的變量或函數,如下:

  • object: 代表當前模型的記錄。
  • format_date: 代表格式化date-time的方法。
  • format_datetime: 代表將UTC時間轉化為另一個時區的方法。
  • format_amount: 將float類型轉化為帶有貨幣類型的字符串。
  • format_duration: 將float轉化為時間格式,比如,1.5=>01:30。
  • user: 代表當前用戶。
  • ctx: 代表環境上線文的字典。

小貼士
我們可以在開發這模式下,點擊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模板發送郵件

本節,我們將學習發送QWeb樣式的郵件。

准備

步驟

  1. 添加my_library/data/mail_template.xml 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>
  1. 添加按鈕:
<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>
  1. 在library.book.rent模型中添加book_return_reminder_qweb()方法:
def book_return_reminder_qweb(self): 
    self.message_post_with_view('my_library.book_return_reminder_qweb')
  1. 更新模塊,點擊按鈕后郵件如下:

原理

步驟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模板有如下幾點不同:

  • 在郵件模板中,我們可通過定義在Object變量獲取動態值。另一方面,在QWeb模板中,我們可以在渲染的時候在上下文通過values傳遞變量值。
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按鈕的下拉列表中管理其子類型。假設用戶將其子類型設置為:

  • 管理郵件別名
    郵件別名是odoo中的一個特性,可通過接收到的郵件創建記錄。最簡單的例子是銷售團隊。我們只需要發郵件給sale@yourdomain.com,odoo就會在銷售團隊的crm.lead模型中創建一條新的記錄。本節,我們將創建一個用於創建圖書借閱記錄的郵件別名。

准備

本節我們將繼續使用my_library模塊。我們將創建郵件地址為rent@yourdomain.com的郵件別名。如果你發郵件給這個地址,郵件主題為圖書的名字,那么odoo將會自動創建一個library.book.rent的記錄。

步驟

  1. 在my_library/data/mail_template.xml文件中創建郵件別名:
<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>
  1. 在my_library/models/library_book_rent.py文件中添加引用:
import re
from odoo.tools import email_split, email_escape_char
  1. 在library.book.rent模型中重寫message_new()方法:
@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查看郵件別名列表。

  • alias_name: 代表郵件地址的別名。
  • alias_model_id: 代表將根據接收到的郵件后所創建記錄的模型。
  • alias_user_id: 代表當郵件過來的時候,用哪個賬戶進行創建新紀錄。
  • alias_contact: 代表表名的權限配置。可選項為everyone, partners, followers, employees.
  • alias_defaults: 當接收到郵件后,odoo將會自動創建一條新的記錄。該字段可用於設置默認值。

步驟2,添加必要的引用。
步驟3,重寫message_new()方法。該方法將在接收到新郵件的時候自動觸發。該方法有兩個參數:

  • msg_dict: 包含到接收到的郵件的相關內容,比發件人地址、接收人地址、主題及郵件正文。
  • custom_values: 代表創建記錄時的自定義值。與alias_defaults的作用類似。

更多

一些業務模型有時需要針對每一條記錄進行區分別名。比如,在銷售團隊模型中,針對不同的團隊創建不同的別名。比如,為印度的團隊創建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的相關內容。本節,我們將給管理員發送已借閱的圖書。

准備

步驟

  1. 繼承digest.digest模型並添加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)
			])
  1. 繼承digest.digest模型的form視圖並添加KPI字段:
<?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視圖添加了用於啟停摘要郵件的字段。如果啟用了該功能,則可以收到摘要郵件了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM