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)

修改结果

rewrite_function.png

优点: 简单直接
缺点: 需要找到代码函数,重写函数。

定制,根据状态变化

此方法需要修改代码,在单据状态变化的时候,自动推送消息。

依赖代码部分
模块集成

    _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>

  

优点:根据状态或其他字段自动推送消息。
缺点:定义复杂。

自动化动作

创建自动话动作,定义对象和条件

Automatci_action.png

定义动作: 更改负责人 或增加关注者(本例中可以增加仓库人员)

set_action1.png

或 更复杂动作,用服务器动作定义

create_server_action.png

优点 : 用户可配置
缺点: server action 需要写python代码

总结

以上三种方法,都是使用message_post方法发送消息给关注者,如需使用其他发送消息方法,需要在mail thread寻找新的方法。
方法三,可以自定义配置条件,也可以增加关注者,也可以增加复杂动作,灵活。
方法一,对开发者来说更直接。

参考:https://www.zhiyunerp.com/blog/2/post/15

odoo开发笔记:Server+Action服务器动作自动触发执行的更多相关文章

  1. odoo开发笔记 -- 应用服务器&数据库服务器分开部署

    app+db在一台服务器: odoo.conf配置文件: db_host = False db_maxconn = 64 db_name = False db_password = 123456db_ ...

  2. odoo开发笔记 -- div标签代替odoo button写法

    odoo开发笔记 -- div标签代替odoo button写法 并调用自定义js <footer> <div id="confirm_request_cloud_repo ...

  3. odoo开发笔记 -- 搜索视图继承扩展

    odoo开发笔记 -- 搜索视图继承扩展

  4. odoo开发笔记 -- 后台日志输出及分析

    odoo开发笔记 -- 后台日志输出及分析 附:日志分析软件

  5. odoo开发笔记--自定义server action页面跳转注意

    场景描述: 在添加自定义服务器动作 “复制全部”后发现直接创建了新的记录,并且直接进入到form保存完的状态. 如何解决: if yourself_obj_copy: return { 'type': ...

  6. odoo开发笔记--from视图隐藏顶部&tree视图保留

    场景描述: 开发过程中,有时候我们需要去除odoo自带的一些样式, 比如,form视图,要集成自定义的界面时,就希望把顶部的服务动作 和 分页按钮 隐藏掉. 处理方式: 分两种情况: 1. 保留顶部区 ...

  7. odoo开发笔记 -- 触发机制/埋点设置

    场景描述: 项目需求中,经常会需要,当某个字段处某个特定状态时候,触发执行特定的方法:或者创建某条记录的时候,同时做另一个操作:如何实现类似的需求? 实现方式: odoo中提供了几种触发方式: 1. ...

  8. Jenkins 自动触发执行的配置

    1. 两种触发方式 2. jenkins 和 github 同步配置 ngrok 安装 webhook 配置 1. 两种触发条件 Jenkins 中建立的任务是可以设置自动触发,更进一步的实现自动化. ...

  9. odoo开发笔记 -- docker容器打包到另一台服务器部署异常

    场景描述: odoo.conf文件指定了数据库配置,如果docker打包的时候,没注意,新环境启动该镜像,会导致并没有连接本地的数据库,如果你配置文件中的数据库地址,当前这台服务器也可以访问到,那么问 ...

随机推荐

  1. 走进JDK(一)------Object

    阅读JDK源码也是一件非常重要的事情,尤其是使用频率最高的一些类,通过源码可以清晰的清楚其内部机制. 如何阅读jdk源码(基于java8)? 首先找到本地电脑中的jdk安装路径,例如我的就是E:\jd ...

  2. Latex表格插入

    \begin{table}[h] \centering \caption{Traffic flows description} \begin{tabular}{|c||c|c|c|c|} \hline ...

  3. bootstrap 后台模板

    http://wangye0119-html1.demo.smallseashell.com/index.html

  4. s5-12 RIP

    什么是RIP? RIP:Routing information protocol,路由选择信息协议 1988年,RFC1058 RIPv1:有类的路由选择协议 RIPv2:无类的路由选择协议,支持CI ...

  5. INtellJ IDEA 2017 创建Annotation注解类

    1.建立一个文件夹 java ------->new ---->Package--->输入名字 2.New ---->java class --->如图修改红圈位置的下拉 ...

  6. Kafka常用命令收录

    目录 目录 1 1. 前言 2 2. Broker默认端口号 2 3. 安装Kafka 2 4. 启动Kafka 2 5. 创建Topic 2 6. 列出所有Topic 3 7. 删除Topic 3 ...

  7. android的消息处理机制(图文+源码分析)—Looper/Handler/Message[转]

    from:http://www.jb51.net/article/33514.htm 作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习google大牛们的设计思想.andro ...

  8. mysql_结构

    代码执行结构:顺序结构.分支机构.循环结构 分支结构:实现准备多个代码块,按照条件选择执行某段代码 在mysql中只有if分支 基本语法 if 条件判断 then -- 满足条件要执行的代码; els ...

  9. Codeforces822 C. Hacker, pack your bags!

    C. Hacker, pack your bags! time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  10. user_agent

    public function getipinfo($ip) { $res = '其他'; $url = "http://int.dpool.sina.com.cn/iplookup/ipl ...