odoo开发笔记:Server+Action服务器动作自动触发执行
Odoo的市场定位是SME(中小型企业),这个市场的ERP产品,多如牛毛,产品各具特色。不过,Odoo的自动化处理机制,可以睥睨天下,无人能及。包括一些大型国产软件,如用友、金蝶也不具备如此强大的自动化业务处理功能。Odoo的业务自动化机制,可以非常容易地扩充ERP系统功能,非常容易地让业务工作自动化。
Odoo自动化动作
如下图,增加一个自动化动作,“自动删除过期的SaaS DB”。系统会按定义好的条件筛选出符合条件的数据记录(业务对象),自动执行定义好的Server Action(服务器端动作)。
- 相关的文档模型:本自动化处理适用于哪个业务对象
- 何时运行:什么时候触发本自动化动作,选项有“业务对象创建时候”,“业务对象更新时候”,“业务对象创建或更新时候”,“基于时间条件触发”
- 筛选:定义一个过滤条件,仅对符合该过滤条件的业务对象执行本自动化动作
- 触发日期:业务对象上的一个日期型字段
- 使用日期:触发日期的前/后多少天(或小时、分钟)触发本动作。如果是触发日期前则填写负数。
- 使用日历:如果是希望定义触发日期前/后多少个工作天,则需要使用该字段。该字段定义工作日历。
- 最后运行:本动作最近一次运行的时间。
- 动作:定义要自动执行的Server Action,可以有多个。
需要注意的是,系统的时间条件是,假设 触发日期 + 使用日期 后得到的时间 为DT,本动作最后运行时间 LT,当前时间CT。当满足条件 LT < DT <= CT时候,系统才会促发本动作。如果某次执行失败,下次再执行时候,失败的那条记录,由于不满足条件 LT < DT,系统不会再次执行该对象。
Odoo服务端动作Server Action
如下图,增加一个Server Action,“删除过期的SaaS Client DB”。Server Action有多种类型,本例是Python代码。Python代码最为灵活,你可以自己写Python代码,完成任意你希望的业务处理。本例是调用业务对象的删除数据库的方法"delete_database_server()"。
非常有用的是,你可以将定义好的Server Action添加到对象视图的“更多”按钮下面,从而点击按钮自动执行
Odoo筛选条件
如下图,自动化动作中,可以定义需要执行自动化动作的对象过滤条件。过滤条件可以在对象的列表视图中自定义,然后“保存当前过滤器”。需要注意的是,保存时候,一定要勾选“与所有用户共享”。
Odoo计划任务
如下图,Odoo有一个计划任务机制,类似于Linux的 crontab,或者Windows的计划任务。计划任务机制中,你可以指定系统每隔多少时间执行指定的对象方法。
Odoo的自动动作,是通过“Check Action Rules”的计划任务,默认情况是每隔4小时检查一遍“自动动作”,如果你希望更频繁地执行“自动动作”,你可以在此修改。
OODO设计模式一消息通知
问题
Odoo系统根据单据更新发送消息通知相关人员。
举例:
生产订单下发,库管人员就会得到需要发货的消息。
相关的设计模式有:
- 重写动作函数.
- 自动化动作
- 定制开发,根据单据状态,发送消息
下面就,讨论不同模式的实现方法,和利弊。
重写动作函数
odoo v8 中 确认生产订单 通过workflow完成,
workflow 调用的确认函数是:
def action_confirm(self, cr, uid, ids, context=None):
""" Confirms production order.
@return: Newly generated Shipment Id.
"""
user_lang = self.pool.get('res.users').browse(cr, uid, [uid]).partner_id.lang
context = dict(context, lang=user_lang)
uncompute_ids = filter(lambda x: x, [not x.product_lines and x.id or False for x in self.browse(cr, uid, ids, context=context)])
self.action_compute(cr, uid, uncompute_ids, context=context)
for production in self.browse(cr, uid, ids, context=context):
self._make_production_produce_line(cr, uid, production, context=context)
stock_moves = []
for line in production.product_lines:
if line.product_id.type != 'service':
stock_move_id = self._make_production_consume_line(cr, uid, line, context=context)
stock_moves.append(stock_move_id)
else:
self._make_service_procurement(cr, uid, line, context=context)
if stock_moves:
self.pool.get('stock.move').action_confirm(cr, uid, stock_moves, context=context)
production.write({'state': 'confirmed'})
return 0
重写函数, 增加以下代码实现。
SUPER(mrp_prodduction, self).action_confirm(cr, uid, ids, context=None)
self.message_post(cr, uid, ids, body=_("Order %s confirmed. Please Send Material") % self._description, context=context)
修改结果
优点: 简单直接
缺点: 需要找到代码函数,重写函数。
定制,根据状态变化
此方法需要修改代码,在单据状态变化的时候,自动推送消息。
依赖代码部分
模块集成
_inherit = ['mail.thread', 'ir.needaction_mixin']
定义状态, 增加track_visibility属性
'state': fields.selection(
[('draft', 'New'), ('cancel', 'Cancelled'), ('confirmed', 'Awaiting Raw Materials'),
('ready', 'Ready to Produce'), ('in_production', 'Production Started'), ('done', 'Done')],
string='Status', readonly=True,
track_visibility='onchange', copy=False,
定义_trace 字段以及参数
ps. mrp.production 中未定义_track, 故状态更新 不会推送消息通知。
# Automatic logging system if mail installed
# _track = {
# 'field': {
# 'module.subtype_xml': lambda self, cr, uid, obj, context=None: obj[state] == done,
# 'module.subtype_xml2': lambda self, cr, uid, obj, context=None: obj[state] != done,
# },
# 'field2': {
# ...
# },
# }
# where
# :param string field: field name
# :param module.subtype_xml: xml_id of a mail.message.subtype (i.e. mail.mt_comment)
# :param obj: is a browse_record
# :param function lambda: returns whether the tracking should record using this subtype
其中 module.subtype_xml 需要在xml中定义消息类型。 例如 account_voucher 的跟踪消息类型
1
2
3
4
5
6
7
|
<! - - Voucher - related subtypes for messaging / Chatter - - > <record id = "mt_voucher_state_change" model = "mail.message.subtype" > <field name = "name" >Status Change< / field> <field name = "res_model" >account.voucher< / field> <field name = "default" eval = "False" / > <field name = "description" >Status changed< / field> < / record> |
优点:根据状态或其他字段自动推送消息。
缺点:定义复杂。
自动化动作
创建自动话动作,定义对象和条件
定义动作: 更改负责人 或增加关注者(本例中可以增加仓库人员)
或 更复杂动作,用服务器动作定义
优点 : 用户可配置
缺点: server action 需要写python代码
总结
以上三种方法,都是使用message_post方法发送消息给关注者,如需使用其他发送消息方法,需要在mail thread寻找新的方法。
方法三,可以自定义配置条件,也可以增加关注者,也可以增加复杂动作,灵活。
方法一,对开发者来说更直接。
参考:https://www.zhiyunerp.com/blog/2/post/15