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