id: 6feecd0808a4435f82e0bfbce0e23c90
parent_id: 
item_type: 1
item_id: 5f84e52aadc74519bc94fb029de2c096
item_updated_time: 1764365026875
title_diff: "[{\"diffs\":[[1,\"深入理解OpenERP的工作流(Workflow)\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":25}]"
body_diff: "[{\"diffs\":[[1,\"<html>\\\r\\\n<head>\\\r\\\n  <title>深入理解OpenERP的工作流(Workflow)</title>\\\r\\\n  <basefont face=\\\"微软雅黑\\\" size=\\\"2\\\" />\\\r\\\n  <meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html;charset=utf-8\\\" />\\\r\\\n  <meta name=\\\"exporter-version\\\" content=\\\"YXBJ Windows/608924 (zh-CN, DDL); Windows/10.0.0 (Win64); EDAMVersion=V2;\\\"/>\\\r\\\n  <meta name=\\\"application-data:2525275\\\" content=\\\"6692893/s30/1d546a11-a1ae-4998-b1d9-9feb0cc66788/app.yinxiang.com\\\"/>\\\r\\\n  <style>\\\r\\\n\\tbody, td {\\\r\\\n\\t  font-family: 微软雅黑;\\\r\\\n\\t  font-size: 12pt;\\\r\\\n\\t}\\\r\\\n  </style>\\\r\\\n</head>\\\r\\\n<body>\\\r\\\n<a name=\\\"16756\\\"></a>\\\r\\\n<h1>深入理解OpenERP的工作流(Workflow)</h1>\\\r\\\n\\\r\\\n<div><span><br/><div style=\\\"position: relative;\\\"><div style=\\\"font-size: 16px\\\"><div><div style=\\\"font-style:normal;font-variant:normal;font-weight:normal;font-size:83%;line-height:130%;font-family:Verdana, Arial, Helvetica, sans-serif;background:url(http://shine-it.net/Themes/default/images/theme/backdrop.png) repeat-x rgb(233, 238, 242);color:rgb(68, 68, 68);\\\"><div style=\\\"background:url(http://shine-it.net/Themes/default/images/theme/frame_repeat.png) 0% 0% repeat-y rgb(255, 255, 255);\\\"><div style=\\\"background:url(http://shine-it.net/Themes/default/images/theme/frame_repeat.png) 100% 0% repeat-y;\\\"><div><div><div style=\\\"margin:0;\\\"><div style=\\\"color:rgb(0, 0, 0);background-color:rgb(231, 234, 239);\\\"><div><div><div style=\\\"overflow:hidden;width:100%;\\\"><div style=\\\"float:left;width:50%;\\\"><div style=\\\"float:left;margin:0px 0.5em 0px 0px;\\\">\\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t<div style=\\\"padding:6px 3px;display:inline-block;\\\"><img src=\\\"深入理解OpenERP的工作流(Workflow)_files/resource.png\\\" type=\\\"image/png\\\" data-filename=\\\"resource.png\\\" height=\\\"20\\\" width=\\\"20\\\"/></div>\\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t</div>\\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t<h5 style=\\\"color:rgb(0, 0, 0);font-size:1em;margin:0px;padding:0px;\\\">\\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t<a href=\\\"http://shine-it.net/index.php/topic,2494.msg8251.html#msg8251\\\" rel=\\\"nofollow\\\" style=\\\"color:rgb(51, 68, 102);text-decoration:none;\\\">深入理解OpenERP的工作流(Workflow)</a>\\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t</h5>\\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t<div style=\\\"font-size:0.85em;font-family:verdana, sans-serif;\\\">« <strong style=\\\"font-weight:bold;\\\"> 于:</strong> 六月 27, 2011, 01:29:39 下午 »</div>\\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t<div></div>\\\n\\t\\t\\t\\t\\t\\t\\t\\t</div>\\\n\\t\\t\\t\\t\\t\\t\\t\\t<ul style=\\\"font-size:0.85em;font-family:arial, sans-serif;padding:0px;margin:0.9em 11px 0px 0px;list-style:none;clear:right;float:right;text-align:right;font-weight:bold;font-style:normal;font-variant:normal;line-height:normal;\\\">\\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t<li style=\\\"padding:0px;margin:0px 0px 0px 11px;list-style:none;float:left;display:inline;background:url(http://shine-it.net/Themes/default/images/theme/quickbuttons.png) 0px 0px no-repeat;\\\"><a href=\\\"http://shine-it.net/index.php?action=post;quote=8251;topic=2494.0;last_msg=25744\\\" style=\\\"color:rgb(51, 68, 102);text-decoration:none;padding:0px 0px 0px 20px;display:block;height:20px;line-height:18px;float:left;\\\">引用</a></li>\\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t<li style=\\\"padding:0px;margin:0px 0px 0px 11px;list-style:none;float:left;display:inline;\\\"><a href=\\\"#\\\" style=\\\"color:rgb(51, 68, 102);text-decoration:none;padding:0px 0px 0px 20px;display:block;height:20px;line-height:18px;float:left;\\\">Add Multi Quote</a></li>\\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t<li style=\\\"padding:0px;margin:0px 0px 0px 11px;list-style:none;float:left;display:inline;\\\"><a href=\\\"#\\\" style=\\\"color:rgb(51, 68, 102);text-decoration:none;padding:0px 0px 0px 20px;display:block;height:20px;line-height:18px;float:left;\\\">Remove Multi Quote</a></li>\\\n\\t\\t\\t\\t\\t\\t\\t\\t</ul>\\\n\\t\\t\\t\\t\\t\\t\\t</div>\\\n\\t\\t\\t\\t\\t\\t\\t<div style=\\\"overflow:auto;line-height:1.4em;padding:0.1em 0px;margin-top:0.5em;clear:right;\\\">\\\n\\t\\t\\t\\t\\t\\t\\t\\t<div style=\\\"padding:1em 1em 2px 0px;margin:0px 1em 0px 0px;border-top-width:1px;border-top-style:solid;border-top-color:rgb(153, 153, 170);\\\">一、工作流定义：<br/>&lt;?xml version=&quot;1.0&quot;?&gt;<br/>  &lt;terp&gt;&lt;data&gt;<br/>    &lt;record model=&quot;workflow&quot; id=workflow_id&gt;<br/>    &lt;field name=&quot;name&quot;&gt;workflow.name&lt;/field&gt;<br/>    &lt;field name=&quot;osv&quot;&gt;resource.model&lt;/field&gt;<br/>    &lt;field name=&quot;on_create&quot;&gt;True | False&lt;/field&gt;<br/>  &lt;/record&gt;<br/>&lt;/data&gt;&lt;/terp&gt;<br/><br/>model：固定取值&quot;workflow&quot;<br/>id：任意值，唯一标识本工作流<br/>name: 工作流的名称，任意定义<br/>osv： 本工作流关联的对象类型，是OpenERP模块中定义的某对象名，如采购单对象（purchase.order）。是本工作流处理的数据对象。<br/>on_create：每当系统新产生一个osv 中定义的对象的实例时候，是否对应的产生一个和该对象实例关联的工作流实例。默认是True.<br/><br/>工作流和工作流实例：工作流定义了对某一类型的对象，如采购订单（PO）的处理流程。例如，PO单的一般处理流程也许是：1）新建PO，State = draft；2）审批PO，审批的同时，a)系统自动产生收货单，工仓库收货；b)系统自动产生凭据（Invoice），供财务确认付款；c)系统自动产生PDF的采购订单，并自动EMail给该PO单对应的供应商。但对于特定的某个PO对象，需要一个工作流实例，以记录本PO对象处在流程的哪个阶段，如PO1尚在draft状态，PO2已经审批通过。<br/>PO单的审批，以及对应的a)、b)、c)的动作，都可以在OE的工作流中定义解决，而不需要全编码在PO对象上。即工作流实现了流程处理相关的代码和被处理对象的代码相分离，降低了不同处理代码的耦合性，增加了系统功能的柔软性。<br/><br/>二、活动（Activity）定义<br/>&lt;record model=&quot;workflow.activity&quot; id=&quot;activity_id&quot;&gt;<br/>  &lt;field name=&quot;wkf_id&quot; ref=&quot;workflow_id&quot;/&gt;<br/>  &lt;field name=&quot;name&quot;&gt;activity.name&lt;/field&gt;<br/>  &lt;field name=&quot;kind&quot;&gt;dummy | function | subflow | stopall&lt;/field&gt;<br/>  &lt;field name=&quot;subflow_id&quot;&gt;subflow_id&lt;/field&gt;<br/>  &lt;field name=&quot;action&quot;&gt;(...)&lt;/field&gt;<br/>  &lt;field name=&quot;action_id&quot;&gt;(...)&lt;/field&gt;<br/>  &lt;field name=&quot;split_mode&quot;&gt;XOR | OR | AND&lt;/field&gt;<br/>  &lt;field name=&quot;join_mode&quot;&gt;XOR | AND&lt;/field&gt;<br/>  &lt;field name=&quot;signal_send&quot;&gt;(...)&lt;/field&gt;<br/>  &lt;field name=&quot;flow_start&quot;&gt;True | False&lt;/field&gt;<br/>  &lt;field name=&quot;flow_stop&quot;&gt;True | False&lt;/field&gt;<br/>&lt;/record&gt;<br/><br/>model：固定取值workflow.activity<br/>wkf_id：本Activity所属的工作流id<br/>name: 本Activity名称，任意值<br/>kind：本Activity类型，有Dummy, Function, Subflow, Stop All 四种。kind说明，如果流程到达本节点，系统应执行的动作类别。<br/>  Dummy 表示不执行任何动作，即action中定义的代码不会被执行。<br/>  Function 表示执行action中定义的python代码，且，执行action_id中定义的server action。常见情况是，action中定义一个write方法，修改流程关联的对象的状态。对于Function类型的节点，action中定义的代码或者返回False，或者返回一个客户端动作id（A client action should be returned）。<br/>  Subflow类型表示触发“subflow_id”中指定的工作流。仔细的读者或许要问，工作流的执行总是和某个被处理的对象关联，是的，如果定义了action，subflow 关联的对象id 由action中定义的代码返回。如果没有定义action，系统默认subflow关联的对象和本节点所属的工作流处理的对象id一致。stopall类型表示，流程到此节点则结束，但结束前，系统仍会执行action中的代码。<br/><br/>signal_send：执行完本节点的动作（action及action_id定义的动作）后，应向别的工作流发往的signal，格式是：subflow.signal。subflow_id和signal_send必须配合使用，subflow_id表示，触发子工作流subflow_id，在该子工作流中，通常必须定义signal_send，signal_send定义父流程中的某个signal，表示，子流程处理结束后触发父流程中的信号subflow.signal。注意，用于父子流程通信的工作流signal必须是形如subflow.* 。例如，在HR模块的workflow &quot;wkf_expenses&quot;中，需要开发票时候，它触发流程account模块中的工作流“account.wkf”（&lt;field name=&quot;subflow_id&quot; ref=&quot;account.wkf&quot;/&gt;）。account.wkf处理完成后，发出信号subflow.paid 通知wkf_expenses流程（&lt;field name=&quot;signal_send&quot;&gt;subflow.paid&lt;/field&gt;）。wkf_expenses中定义了信号subflow.paid（&lt;field name=&quot;signal&quot;&gt;subflow.paid&lt;/field&gt;）。<br/><br/>split_mode：有三个选项，XOR，OR，AND，默认是XOR。XOR 表示，由本节点始发的出迁移中，沿着第一个满足迁移条件的迁移跳转。OR 表示由本节点始发的出迁移中，只要满足迁移条件即沿该迁移跳转。AND 表示由本节点始发的出迁移中，只有所有迁移皆满足迁移条件才跳转，而且是同时沿所有迁移跳转。XOR 只有一个跳转，OR 有零或多个跳转，AND 有零或全部跳转。<br/>join_mode：有两个选项，XOR，AND，默认是XOR。XOR 表示，以本节点为终点的入迁移中，只要有一个跳至本节点，即执行本节点的action。AND 表示，以本节点为终点的入迁移中，只有所有迁移都已经跳至本节点，才执行本节点的action。<br/>flow_start：表示流程的开始节点。<br/>flow_stop：表示流程的结束节点。<br/><br/>三、迁移（Transition）的定义<br/>迁移的完整 XML 定义格式如下。<br/>&lt;record model=&quot;workflow.transition&quot; id=&quot;transition_id&quot;&gt;<br/>  &lt;field name=&quot;act_from&quot; ref=&quot;activity_id_1&quot;/&gt;<br/>  &lt;field name=&quot;act_to&quot; ref=&quot;activity_id_2&quot;/&gt;<br/>  &lt;field name=&quot;signal&quot;&gt;(...)&lt;/field&gt;<br/>  &lt;field name=&quot;condition&quot;&gt;(...)&lt;/field&gt;<br/>  &lt;field name=&quot;trigger_model&quot;&gt;(...)&lt;/field&gt;<br/>  &lt;field name=&quot;trigger_expr_id&quot;&gt;(...)&lt;/field&gt;<br/>&lt;/record&gt;<br/><br/>act_from：本迁移的起始节点，引用之前定义的Activity。<br/>act_to：本迁移的结束节点，引用之前定义的Activity。<br/>signal：触发本迁移的信号，表示，如果系统收到signal定义的信号，则触发本迁移。触发信号有三种方式，1）最常见的是用户点击视图中的“name = 本处定义的signal”的button，此时相当于向系统发送迁移信号量。系统会根据视图中的对象id，找到对象关联的workflow，再找到与button name相同的signal，触发之。2）调用workflow_service的方法：trg_validate(self, uid, res_type, res_id, signal, cr)，此方法表示，触发对象类型res_type关联的workflow的signal信号，工作流实例关联的对象实例是 res_id。3）子流程的signal_send 发出的信号，此种情况前文已说过。<br/><br/>condition：迁移的条件，是一段Python代码，通常是一个函数调用。当系统收到signal中定义的信号时候，检查此处的条件，条件为真则实际触发迁移。<br/>trigger_model和trigger_expr_id：此二字段表示启动一个新工作流实例。trigger_model定义对象类型，trigger_expr_id 定义一段Python代码，返回trigger_model类型的对象id。此二字段表示，如果act_from 中的action 执行完毕，且condition 条件OK，则系统中插入一个trigger_model类型，trigger_expr_id返回的对象id关联的工作流实例。然后，可以调用workflow_service的方法trg_trigger(self, uid, res_type, res_id, cr)实际执行该工作流。实际使用例子请参考Sale模块的工作流定义 wkf_sale：<br/>            &lt;field name=&quot;trigger_model&quot;&gt;procurement.order&lt;/field&gt;<br/>            &lt;field name=&quot;trigger_expr_id&quot;&gt;procurement_lines_get()&lt;/field&gt;</div></div></div></div></div></div></div></div></div></div></div></div></div></div><br/></span>\\\n</div></body></html>\\u0000\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":8912}]"
metadata_diff: {"new":{"id":"5f84e52aadc74519bc94fb029de2c096","parent_id":"f67288c3a0be4374b5d532b5dcc3aabc","latitude":"0.00000000","longitude":"0.00000000","altitude":"0.0000","author":"","source_url":"","is_todo":0,"todo_due":0,"todo_completed":0,"source":"joplin-desktop","source_application":"net.cozic.joplin-desktop","application_data":"","order":1764348868305,"user_updated_time":1764345582860,"markup_language":2,"is_shared":0,"share_id":"","conflict_original_id":"","master_key_id":"","user_data":"","deleted_time":1764365026875},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2025-11-28T21:24:55.620Z
created_time: 2025-11-28T21:24:55.620Z
type_: 13