210213e5f5593492084bdbcde1ff5e576172467c
[odoo/odoo.git] / doc / reference / workflows.rst
1 .. _reference/workflows:
2
3 Workflows
4 =========
5
6 In Odoo, a workflow is a technical artefact to manage a set of "things to
7 do" associated to the records of a model. The workflow provides a higher-level
8 way to organize tasks to perform with or on a record.
9
10 More specifically, a workflow is a directed graph where the nodes are called
11 "activities" and the arcs are called "transitions".
12
13 - Activities define work that should be done within the Odoo server, such
14   as changing the state of some records, or sending emails.
15 - Transitions control how the workflow progresses from activity to activity.
16
17 In the definition of a workflow, one can attach conditions, signals, and
18 triggers to transitions, so that the behavior of the workflow depends on user
19 actions (such as clicking on a button), changes to records, or arbitrary
20 Python code.
21
22 All in all, Odoo's workflow system provides:
23
24 * a description of the evolution of a record (document) over time
25 * automatic actions based on various and flexible conditions
26 * management of company roles and validation steps
27 * management of interactions between objects
28 * a visual representation of document flows through their lifecycle
29
30 For instance, a basic order could have the following flow:
31
32 .. sphinx.ext.graphviz would be nice, but it requires ``dot`` on any machine
33 .. where the doc is compiled... otoh this is a pain in the ass because you
34 .. need 2 compilation steps (dot -> image and rst -> html) every time
35
36 .. image:: workflow/order_0.*
37     :align: center
38
39 Orders start in the *Draft* state, can be *Confirmed* by a user, and then
40 either shipped (*Closed*) or *Canceled*.
41
42 A company using Odoo may want to add discount support to orders, where sales
43 staff has discretionary discounting powers up to 15%, but manager validation
44 is required for discounts beyond 15%. The workflow can be altered online to
45 add the relevant steps without editing Python or XML files:
46
47 .. image:: workflow/order_1.*
48     :align: center
49
50 Because Activities can perform arbitrary actions, the *Validation* can
51 automatically send a validation request to the relevant employee.
52
53 .. note:: the order view needs to be modified to add an *Accept Discount*
54           button for managers
55
56 Basics
57 ------
58
59 Defining a workflow with data files is straightforward: a record "workflow" is
60 given together with records for the activities and the transitions. For
61 instance, here is a simple sequence of two activities defined in XML
62
63 .. code-block:: xml
64
65     <record id="test_workflow" model="workflow">
66         <field name="name">test.workflow</field>
67         <field name="osv">test.workflow.model</field>
68         <field name="on_create">True</field>
69     </record>
70
71     <record id="activity_a" model="workflow.activity">
72         <field name="wkf_id" ref="test_workflow"/>
73         <field name="flow_start">True</field>
74         <field name="name">a</field>
75         <field name="kind">function</field>
76         <field name="action">print_a()</field>
77     </record>
78     <record id="activity_b" model="workflow.activity">
79         <field name="wkf_id" ref="test_workflow"/>
80         <field name="flow_stop">True</field>
81         <field name="name">b</field>
82         <field name="kind">function</field>
83         <field name="action">print_b()</field>
84     </record>
85
86     <record id="trans_a_b" model="workflow.transition">
87         <field name="act_from" ref="activity_a"/>
88         <field name="act_to" ref="activity_b"/>
89     </record>
90
91 A worfklow is always defined with respect to a particular model (the model is
92 given by the attribute ``osv`` on the model ``workflow``). Methods specified
93 in the activities or transitions will be called on that model.
94
95 In the example code above, a workflow called "test_workflow" is created. It is
96 made up of two activies, named "a" and "b", and one transition, going from "a"
97 to "b".
98
99 The first activity has its attribute ``flow_start`` set to ``True`` so that
100 Odoo knows where to start the workflow traversal after it is instanciated.
101 Because ``on_create`` is set to True on the workflow record, the workflow is
102 instanciated for each newly created record. (Otherwise, the workflow should be
103 instanciated by other means, such as from some module Python code.)
104
105 When the workflow is instanciated, it begins with activity "a". That activity
106 is of kind ``function``, which means that the action ``print_a()`` is a method
107 call on the model ``test.workflow`` (the usual ``cr, uid, ids, context``
108 arguments are passed for you).
109
110 The transition between "a" and "b" does not specify any condition. This means
111 that the workflow instance immediately goes from "a" to "b" after "a" has been
112 processed, and thus also processes activity "b".
113
114 Activities
115 ----------
116
117 While the transitions can be seen as the control structures of the workflows,
118 activities are the places where everything happens, from changing record
119 states to sending email.
120
121 Different kinds of activities exist: ``Dummy``, ``Function``, ``Subflow``, and
122 ``Stop all``, each doing different things when the activity is processed. In
123 addition to their kind, activies have other properties, detailed in the next
124 sections.
125
126 Flow start and flow stop
127 ''''''''''''''''''''''''
128
129 The attribute ``flow_start`` is a boolean value specifying whether the activity
130 is processed when the workflow is instanciated. Multiple activities can have
131 their attribute ``flow_start`` set to ``True``. When instanciating a workflow
132 for a record, Odoo simply processes all of them, and evaluate all their
133 outgoing transitions afterwards.
134
135 The attribute ``flow_stop`` is a boolean value specifying whether the activity
136 stops the workflow instance. A workflow instance is considered completed when
137 all its activities with the attribute ``flow_stop`` set to ``True`` are
138 completed.
139
140 It is important for Odoo to know when a workflow instance is completed. A
141 workflow can have an activity that is actually another workflow (called a
142 subflow); that activity is completed when the subflow is completed.
143
144 Subflow
145 '''''''
146
147 An activity can embed a complete workflow, called a subflow (the embedding
148 workflow is called the parent workflow). The workflow to instanciate is
149 specified by attribute ``subflow_id``.
150
151 .. note:: In the GUI, that attribute can not be set unless the kind of the
152           activity is ``Subflow``.
153
154 The activity is considered completed (and its outgoing transitions ready to be
155 evaluated) when the subflow is completed (see attribute ``flow_stop`` above).
156
157 Sending a signal from a subflow
158 '''''''''''''''''''''''''''''''
159
160 When a workflow is embedded in an activity (as a subflow) of a workflow, the
161 sublow can send a signal from its own activities to the parent workflow by
162 giving a signal name in the attribute ``signal_send``. Odoo processes those
163 activities by sending the value of ``signal_send`` prefixed by "subflow."  to
164 the parent workflow instance.
165
166 In other words, it is possible to react and get transitions in the parent
167 workflow as activities are executed in the sublow.
168
169 Server actions
170 ''''''''''''''
171
172 An activity can run a "Server Action" by specifying its ID in the attribute
173 ``action_id``.
174
175 Python action
176 '''''''''''''
177
178 An activity can execute some Python code, given by the attribute ``action``.
179 The evaluation environment is the same as the one explained in the section
180 `Conditions`_.
181
182 Split mode
183 ''''''''''
184
185 After an activity has been processed, Odoo evaluates its transition to reach
186 the next activity in the flow.
187
188 However if an activity has more than one transition, Odoo must decide which
189 activity or activities to follow.
190
191 .. image:: workflow/split.*
192     :align: center
193
194 This choice is controlled by the ``split_mode`` attribute:
195
196 ``XOR`` (default)
197     By default, Odoo will use the first transition (in ``sequence`` order)
198     whose condition is satisfied. All other transitions are ignored.
199 ``OR``
200     In ``OR`` mode, all transitions with a satisfied condition are traversed
201     simultanously. Transitions not yet valid will be ignored, even if they
202     become valid later.
203 ``AND``
204     In ``AND`` mode, Odoo will wait until *all* transitions are satisfied, and
205     will traverse all of them (much like the ``OR`` mode).
206
207 Both ``OR`` and ``AND`` mode will lead to activities being active in the same
208 workflow.
209
210 Join mode
211 '''''''''
212
213 Just like outgoing transition conditions can be combined together to decide
214 whether they can be traversed or not, incoming transitions can be combined
215 together to decide if and when an activity may be processed.
216
217 .. image:: workflow/join.*
218     :align: center
219
220 The ``join_mode`` attribute controls that behavior:
221
222 ``XOR`` (default)
223     Any incoming transition enables the activity and starts its processing.
224 ``AND``
225     The activity is enabled and processed only once *all* incoming transitions
226     have been traversed.
227
228 Kinds
229 '''''
230
231 An activity's kind defines the type of work an activity can perform.
232
233 Dummy (``dummy``, default)
234     Do nothing at all, or call a server action. Often used as dispatch or
235     gather "hubs" for transitions.
236 Function (``function``)
237     Run some python code, execute a server action.
238 Stop all (``stopall``)
239     Completely stops the workflow instance and marks it as completed.
240 Subflow (``subflow``)
241     Starts executing an other workflow, once that workflow is completed the
242     activity is done processing.
243
244     By default, the subflow is instanciated for the same record as the parent
245     workflow. It is possible to change that behavior by providing Python code
246     that returns a record ID (of the same data model as the subflow). The
247     embedded subflow instance is then the one of the given record.
248
249
250 Transitions
251 -----------
252
253 Transitions provide the control structures to orchestrate a workflow. When an
254 activity is completed, the workflow engine tries to get across transitions
255 departing from the completed activity, towards the next activities. In their
256 simplest form (as in the example above), they link activities sequentially:
257 activities are processed as soon as the activities preceding them are
258 completed.
259
260 Instead of running all activities in one fell swoop, it is also possible to
261 wait on transitions, going through them only when some criteria are met. The
262 criteria are the conditions, the signals, and the triggers. They are detailed
263 in the following sections.
264
265 Conditions
266 ''''''''''
267
268 When an activity has been completed, its outgoing transitions are inspected to
269 determine whether it is possible for the workflow instance to proceed through
270 them and reach the next activities. When only a condition is defined (i.e., no
271 signal or trigger is defined), the condition is evaluated by Odoo, and if
272 it evaluates to ``True``, the worklfow instance progresses through the
273 transition.  If the condition is not met, it will be reevaluated every time
274 the associated record is modified, or by an explicit method call to do it.
275
276 By default, the attribute ``condition`` (i.e., the expression to be evaluated)
277 is just "True", which trivially evaluates to ``True``. Note that the condition
278 may be several lines long; in that case, the value of the last one determines
279 whether the transition can be taken.
280
281 In the condition evaluation environment, several symbols are conveniently
282 defined (in addition to the Odoo ``safe_eval`` environment):
283
284 - all the model column names, and
285 - all the browse record's attributes.
286
287 Signals
288 '''''''
289
290 In addition to a condition, a transition can specify a signal name. When such
291 a signal name is present, the transition is not taken directly, even if the
292 condition evaluates to ``True``. Instead the transition blocks, waiting to be
293 woken up.
294
295 In order to wake up a transition with a defined signal name, the signal must
296 be sent to the workflow instance. A common way to send a signal is to use a
297 button in the user interface, using the element ``<button/>`` with the signal
298 name as the attribute ``name`` of the button. Once the button is clicked, the
299 signal is sent to the workflow instance of the current record.
300
301 .. note:: The condition is still evaluated when the signal is sent to the
302           workflow instance.
303
304 Triggers
305 ''''''''
306
307 With conditions that evaluate to ``False``, transitions are not taken (and
308 thus the activity it leads to is not processed immediately). Still, the
309 workflow instance can get new chances to progress across that transition by
310 providing so-called triggers. The idea is that when the condition is not
311 satisfied, triggers are recorded in database. Later, it is possible to wake up
312 specifically the workflow instances that installed those triggers, offering
313 them to reevaluate their transition conditions. This mechanism makes it
314 cheaper to wake up workflow instances by targetting just a few of them (those
315 that have installed the triggers) instead of all of them.
316
317 Triggers are recorded in database as record IDs (together with the model name)
318 and refer to the workflow instance waiting for those records. The transition
319 definition provides a model name (attribute ``trigger_model``) and a Python
320 expression (attribute ``trigger_expression``) that evaluates to a list of
321 record IDs in the given model. Any of those records can wake up the workflow
322 instance they are associated with.
323
324 .. note:: triggers are not re-installed whenever the transition is re-tried.