在Odoo中,工作流是一种技术手段,用于管理与模型记录相关联的一组“要做的事情”。 工作流程提供了一种更高级别的方法来组织要在记录上执行或在记录上执行的任务。
更具体地,工作流是有向图,其中节点被称为“活动”并且弧被称为“转变”。
- 活动定义应在Odoo服务器中完成的工作,例如更改某些记录的状态或发送电子邮件。
- 转换控制工作流如何从活动进展到活动。
在工作流的定义中,可以将条件,信号和触发器附加到转换,以便工作流的行为取决于用户操作(例如单击按钮),更改记录或任意Python代码。
总而言之,Odoo的工作流程系统提供:
- 随着时间的推移描述记录(文档)的演变
- 基于各种灵活条件的自动动作
- 管理公司角色和验证步骤
- 管理对象之间的交互
- 文档在其生命周期中流动的直观表示
例如,基本订单可以具有以下流程:
订单从Draft状态开始,可由用户确认,然后发货(已关闭)或已取消。
使用Odoo的公司可能希望为订单增加折扣支持,其中销售人员的可自由支配折扣率高达15%,但超过15%的折扣需要经理验证。 可以在线更改工作流程以添加相关步骤,而无需编辑Python或XML文件:
由于活动可以执行任意操作,因此验证可以自动向相关员工发送验证请求。
Note
需要修改订单视图以为经理添加接受折扣按钮
基本
使用数据文件定义工作流很简单:记录“工作流”与活动和转换的记录一起提供。 例如,这是XML中定义的两个活动的简单序列
<record id="test_workflow" model="workflow">
<field name="name">test.workflow</field>
<field name="osv">test.workflow.model</field>
<field name="on_create">True</field>
</record>
<record id="activity_a" model="workflow.activity">
<field name="wkf_id" ref="test_workflow"/>
<field name="flow_start">True</field>
<field name="name">a</field>
<field name="kind">function</field>
<field name="action">print_a()</field>
</record>
<record id="activity_b" model="workflow.activity">
<field name="wkf_id" ref="test_workflow"/>
<field name="flow_stop">True</field>
<field name="name">b</field>
<field name="kind">function</field>
<field name="action">print_b()</field>
</record>
<record id="trans_a_b" model="workflow.transition">
<field name="act_from" ref="activity_a"/>
<field name="act_to" ref="activity_b"/>
<field name="signal">signal_goto_b</signal>
</record>
总是根据特定模型定义worfklow(模型由模型工作流
上的属性osv
给出)。 将在该模型上调用活动或转换中指定的方法。
在上面的示例代码中,创建了一个名为“test_workflow”的工作流。 它由两个名为“a”和“b”的活动组成,以及一个从“a”到“b”的转换。
第一个活动将其属性flow_start
设置为True
,以便Odoo知道在实例化之后从哪里开始工作流遍历。
由于on_create
在工作流记录中设置为True,因此将为每个新创建的记录实例化工作流。 (否则,工作流应该通过其他方式实现,例如来自某些模块的Python代码。)
当工作流程实例化时,它以活动“a”开头。 该活动属于函数
,这意味着操作print_a()
是对模型test.workflow
的方法调用(通常的 cr,uid,ids,context
参数为你传递)。
“a”和“b”之间的过渡指定信号但不指定任何条件。 这意味着当收到信号signal_goto_b
时,工作流实例将立即从“a”转换为“b”,从而处理活动“b”的动作print_b()
。
活动
虽然转换可以被视为工作流的控制结构,但活动是所有事情发生的地方,从更改记录状态到发送电子邮件。
存在不同类型的活动: Dummy
, Function
, Subflow
, 和Stop all
,每个活动都做不同的事情活动已处理完毕。 除了他们的类型,活动还有其他属性,详见下一节。
流量启动和流量停止
属性flow_start
是一个布尔值,指定在实例化工作流时是否处理活动。 多个活动可以将其属性flow_start
设置为True
。 在为记录实例化工作流时,Odoo只需处理所有这些记录,然后评估所有传出的转换。
属性flow_stop
是一个布尔值,指定活动是否停止工作流实例。 当工作流实例的所有活动(属性flow_stop
设置为True
)完成时,它被视为已完成。
对于Odoo来说,了解工作流实例何时完成非常重要。 工作流可以具有实际上是另一个工作流的活动(称为子流);子流程完成后,该活动已完成。
子流
活动可以嵌入称为子流的完整工作流(嵌入工作流称为父工作流)。 实例化的工作流程由属性subflow_id
指定。
Note
在GUI中,除非活动类型为Subflow
,否则无法设置该属性。
当子流程完成时,活动被视为已完成(并且其传出转换已准备好进行评估)(请参阅上面的属性flow_stop
)。
从子流发送信号
当工作流嵌入到工作流的活动(作为子流)时,子流可以通过在属性signal_send
中给出信号名称,将信号从其自己的活动发送到父工作流。 Odoo通过发送前缀为“subflow”的signal_send
的值来处理这些活动。到父工作流实例。
换句话说,当在子流中执行活动时,可以在父工作流中做出反应并获得转换。
服务器动作
活动可以通过在属性action_id
中指定其ID来运行“服务器操作”。
Python动作
活动可以执行一些Python代码,由属性action
给出。
评估环境与条件部分中说明的评估环境相同。
分割模式
处理完活动后,Odoo会评估其转换以达到流程中的下一个活动。
但是,如果活动有多个转换,Odoo必须决定要遵循哪些活动。
此选项由split_mode
属性控制:
XOR
(default)- 默认情况下,Odoo将使用满足条件的第一个转换(以
sequence
顺序)。 忽略所有其他转换。 OR
- 在
OR
模式中,同时遍历具有满足条件的所有转换。 即使转换有效,也会忽略尚未生效的转换。 AND
- 在
AND
模式下,Odoo将等待满足所有转换,并将遍历所有这些(非常类似于OR
模式)。
OR
和AND
模式都将导致活动在同一工作流程中处于活动状态。
加入模式
就像传出的转换条件可以组合在一起来决定它们是否可以被遍历一样,可以将传入的转换组合在一起以决定是否以及何时可以处理活动。
join_mode
属性控制该行为:
XOR
(default)- 任何传入转换都会启用活动并开始处理。
AND
- 仅在遍历所有传入转换时启用并处理活动。
Kinds
活动的种类定义了活动可以执行的工作类型。
- Dummy (
dummy
, default) - 什么都不做,或者调用服务器动作。 通常用作调度或收集转换的“集线器”。
- Function (
function
) - 运行一些python代码,执行服务器操作。
- Stop all (
stopall
) - 完全停止工作流实例并将其标记为已完成。
- Subflow (
subflow
) 开始执行其他工作流程,一旦完成该工作流程,活动就完成了处理。
默认情况下,子流将与父工作流相同的记录进行实例化。 可以通过提供返回记录ID(与子流相同的数据模型)的Python代码来更改该行为。 然后嵌入的子流实例是给定记录之一。
转变
过渡提供了控制结构来协调工作流程。 活动完成后,工作流引擎会尝试跨越从已完成活动转移到下一个活动的转换。 它们以最简单的形式(如上例所示),按顺序链接活动:一旦活动完成,活动就会被处理。
除了一举运行所有活动之外,还可以等待转换,仅在满足某些条件时才通过转换。 标准是条件,信号和触发器。 它们在以下部分中详述。
条件
活动完成后,将检查其传出转换,以确定工作流实例是否可以继续执行它们并到达下一个活动。 当仅定义条件时(即,没有定义信号或触发器),条件由Odoo评估,如果评估为True
,则工作站实例通过转换进行。 如果不满足条件,则每次修改关联记录时都会重新评估,或者通过显式方法调用来重新评估。
默认情况下,属性condition
(即要评估的表达式)只是“True”,这通常评估为True
。 注意,条件可能是几行长;在这种情况下,最后一个的值确定是否可以进行转换。
在条件评估环境中,方便地定义了几个符号(除了Odoo safe_eval
环境):
- 所有模型列名称,以及
- 所有浏览记录的属性。
信号
除条件外,转换还可以指定信号名称。 当存在这样的信号名称时,即使条件评估为True
,也不直接进行转换。 相反,转换阻止,等待被唤醒。
为了唤醒具有已定义信号名称的转换,必须将信号发送到工作流实例。 发送信号的常用方法是使用用户界面中的按钮,使用元素<button />
,信号名称作为按键的属性name
。 单击按钮后,信号将发送到当前记录的工作流实例。
Note
当信号发送到工作流实例时,仍会评估条件。
触发器
如果条件评估为False
,则不会进行转换(因此不会立即处理它导致的活动)。 尽管如此,工作流实例仍然可以通过提供所谓的触发器来获得跨越该转换的新机会。 这个想法是当条件不满足时,触发器被记录在数据库中。 稍后,可以专门唤醒安装这些触发器的工作流实例,让他们重新评估其转换条件。 这种机制使得通过仅针对其中的一些(已安装触发器的那些)而不是所有这些实例来唤醒工作流实例更便宜。
触发器作为记录ID(与模型名称一起)记录在数据库中,并引用等待这些记录的工作流实例。 转换定义提供模型名称(属性trigger_model
)和Python表达式(属性trigger_expression
),其计算结果为给定模型中的记录ID列表。 任何这些记录都可以唤醒与之关联的工作流实例。
Note
无论何时重新尝试转换,都不会重新安装触发器。