[IMP] doc: improve workflow documentation

bzr revid: rco@openerp.com-20130731135814-386v5w6rkc40kwwv
This commit is contained in:
Raphael Collet 2013-07-31 15:58:14 +02:00
parent fc435af428
commit 3c0d11271e
1 changed files with 144 additions and 140 deletions

View File

@ -3,24 +3,29 @@
Workflows Workflows
========= =========
A workflow is a directed graph where the nodes are called "activities" and the In OpenERP, a workflow is a technical artefact to manage a set of "things to do"
arcs are called "transitions". associated to the records of some data model. The workflow provides a higher-
level way to organize the things to do on a record.
More specifically, a workflow is a directed graph where the nodes are called
"activities" and the arcs are called "transitions".
- Activities define work that should be done within the OpenERP server, such as - Activities define work that should be done within the OpenERP server, such as
changing the state of some records, or sending mails. changing the state of some records, or sending emails.
- Transitions control how the workflow will go from activities to activities. - Transitions control how the workflow progresses from activity to activity.
When defining a workflow, one can attach conditions, signals, and triggers to In the definition of a workflow, one can attach conditions, signals, and
transitions, so that the behavior of the workflow can depend on user actions triggers to transitions, so that the behavior of the workflow depends on user
(such as clicking on a button), changes to records, or arbitrary Python code. actions (such as clicking on a button), changes to records, or arbitrary Python
code.
Basics Basics
------ ------
Defining a workflow with data files is straightforward: a record "workflow" is Defining a workflow with data files is straightforward: a record "workflow" is
needed together with records for the activities and the transitions. For given together with records for the activities and the transitions. For
instance here is a simple sequence of two activities defined in XML:: instance, here is a simple sequence of two activities defined in XML::
<record id="test_workflow" model="workflow"> <record id="test_workflow" model="workflow">
<field name="name">test.workflow</field> <field name="name">test.workflow</field>
@ -49,81 +54,82 @@ instance here is a simple sequence of two activities defined in XML::
</record> </record>
A worfklow is always defined with respect to a particular model (the model is A worfklow is always defined with respect to a particular model (the model is
given through the ``osv`` attribute on the ``workflow`` model). Methods given by attribute ``osv`` on the model ``workflow``). Methods specified in the
specified in the activities or transitions will be called on that model. activities or transitions will be called on that model.
In the example code above, a workflow called "test_workflow" is created. It is In the example code above, a workflow called "test_workflow" is created. It is
made up of two activies, named "a" and "b", and one transition, going from "a" made up of two activies, named "a" and "b", and one transition, going from "a"
to "b". to "b".
The first activity has its ``flow_start`` attribute set to True so that OpenERP The first activity has its attribute ``flow_start`` set to ``True`` so that
knows where to start the workflow when it is instanciated. Because OpenERP knows where to start the workflow traversal after it is instanciated.
``on_create`` is set to True on the workflow record, the workflow is Because ``on_create`` is set to True on the workflow record, the workflow is
instanciated for each newly created record. (Otherwise, the workflow should be instanciated for each newly created record. (Otherwise, the workflow should be
created by other means, such as from some module Python code.) instanciated by other means, such as from some module Python code.)
When the workflow is instanciated, it will start by the "a" activity. That When the workflow is instanciated, it begins with activity "a". That activity is
activity is of kind ``function`` which means the action ``print_a()`` is a of kind ``function``, which means that the action ``print_a()`` is method call
method to be called on the ``test.workflow`` model (the usual ``cr, uid, ids, on the model ``test.workflow`` (the usual ``cr, uid, ids, context`` arguments
context`` arguments are passed for you). are passed for you).
The transition between "a" and "b" does not specify any conditions. This means The transition between "a" and "b" does not specify any condition. This means
the workflow instance will immediately progress from "a" to "b" (after "a" has that the workflow instance immediately goes from "a" to "b" after "a" has been
been processed), and thus also process the "b" activity. processed, and thus also processes activity "b".
Transitions Transitions
----------- -----------
Transitions provide the control structures to orchestrate a workflow. When an Transitions provide the control structures to orchestrate a workflow. When an
activity is completed, the workflow engine will try to get across transitions activity is completed, the workflow engine tries to get across transitions
departing from the completed activity, towards the next activities. In their departing from the completed activity, towards the next activities. In their
simplest form they just link activities from one to the others (as in the simplest form (as in the example above), they link activities sequentially:
example above), and activities are processed as soon as the activities activities are processed as soon as the activities preceding them are completed.
preceding them are completed.
But instead of running all activities in one fell swoop, it is also possible to Instead of running all activities in one fell swoop, it is also possible to wait
block on transitions, going through them only when some criteria are met. Such on transitions, going through them only when some criteria are met. The criteria
criteria are the conditions, the signals, and the triggers. They are detailed are the conditions, the signals, and the triggers. They are detailed in the
in the next sections. following sections.
Conditions Conditions
'''''''''' ''''''''''
When an activity has been completed, its outgoing transitions will be inspected When an activity has been completed, its outgoing transitions are inspected to
to see if it is possible for the workflow instance to proceed through them and determine whether it is possible for the workflow instance to proceed through
reach the next activities. When only a condition is defined (i.e. no signal or them and reach the next activities. When only a condition is defined (i.e., no
trigger is defined), the condition is evaluated by OpenERP, and if it evaluates signal or trigger is defined), the condition is evaluated by OpenERP, and if it
to ``True``, the worklfow instance will go through. evaluates to ``True``, the worklfow instance progresses through the transition.
If the condition is not met, it will be reevaluated every time the associated
record is modified, or by an explicit method call to do it.
By default, the ``condition`` attribute (i.e. the expression to be evaluated) By default, the attribute ``condition`` (i.e., the expression to be evaluated)
is just "True", which will trivially evaluate to ``True``. is just "True", which trivially evaluates to ``True``. Note that the condition
may be several lines long; in that case, the value of the last one determines
Actually, the condition can be several lines long, and the value of the last whether the transition can be taken.
one will be used to test if the transition can be taken.
In the condition evaluation environment, several symbols are conveniently In the condition evaluation environment, several symbols are conveniently
defined: defined:
- The database cursor (``cr``), - the database cursor (``cr``),
- the user ID (``uid``), the record ID tied to the workflow instance (``id``), - the user ID (``uid``),
- the user ID wrapped in a list (``ids``), - the record ID tied to the workflow instance (``id``),
- the record ID wrapped in a list (``ids``),
- the model name (``model``), - the model name (``model``),
- the model instance (``obj``), - the model instance (``obj``),
- all the model column names, - all the model column names, and
- and all the record (the one obtained by browsing the provided ID) attributes. - all the browse record's attributes.
Signals Signals
''''''' '''''''
In addition of a condition, a transition can specify a signal name. When such In addition to a condition, a transition can specify a signal name. When such
signal name is present, the transition will not be taken directly (even if the signal name is present, the transition is not taken directly, even if the
condition evaluates to true). Instead the transition will block, waiting to be condition evaluates to ``True``. Instead the transition blocks, waiting to be
woken up. woken up.
To wake up a transition with a defined signal name, the signal must be sent to In order to wake up a transition with a defined signal name, the signal must be
the workflow. A common way to send a signal is to use a button in the web sent to the workflow instance. A common way to send a signal is to use a button
interface, using the ``<button/>`` element with the signal name as the ``name`` in the user interface, using the element ``<button/>`` with the signal name as
attribute of the button. the ``name`` attribute of the button. Once the button is clicked,
.. note:: The condition is still evaluated when the signal is sent to the .. note:: The condition is still evaluated when the signal is sent to the
workflow instance. workflow instance.
@ -131,22 +137,22 @@ attribute of the button.
Triggers Triggers
'''''''' ''''''''
With conditions that evaluate to false, transitions are not taken (and thus the With conditions that evaluate to ``False``, transitions are not taken (and thus
activity it leads to will not be processed). Still, the workflow instance can the activity it leads to is not processed immediately). Still, the workflow
get new chances to progress across that transition by providing so-called instance can get new chances to progress across that transition by providing so-
triggers. The idea is that when the condition fails, triggers are recorded in called triggers. The idea is that when the condition is not satisfied, triggers
database. Later, it is possible to wake-up specifically the workflow instances are recorded in database. Later, it is possible to wake up specifically the
that installed those triggers, offering them a new chance to evaluation their workflow instances that installed those triggers, offering them to reevaluate
transition conditions. This mechnism makes it cheaper to wake-up workflow their transition conditions. This mechanism makes it cheaper to wake up workflow
instances by targetting just a few of them (those that have installed the instances by targetting just a few of them (those that have installed the
triggers) instead of all of them. triggers) instead of all of them.
Triggers are recorded in database as record IDs (together with the model name) Triggers are recorded in database as record IDs (together with the model name)
and refer to the workflow instance waiting for them. The transition definition and refer to the workflow instance waiting for those records. The transition
can thus provide a Python expression (using the ``trigger_model`` attribute) definition provides a model name (attribute ``trigger_model``) and a Python
that when evaluated will return the record IDs. Unlike the other expressions expression (attribute ``trigger_expression``) that evaluates to a list of record
defined on the workflow, this one is evaluated with respect to a model that can IDs in the given model. Any of those records can wake up the workflow instance
be chosen on a per-transition basis with the ``trigger_expression`` attribute. they are associated to.
.. note:: Note that triggers are not re-installed whenever the transition is .. note:: Note that triggers are not re-installed whenever the transition is
re-tried. re-tried.
@ -154,128 +160,125 @@ be chosen on a per-transition basis with the ``trigger_expression`` attribute.
Splitting and joining transitions Splitting and joining transitions
''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''
When multiple transitions leave the same activity, or lead to the same When multiple transitions leave the same activity, or lead to the same activity,
activity, OpenERP provides some control about which transitions will be OpenERP provides some control over which transitions are actually taken, or how
crossed, or how the reached activity will be processed. The ``split_mode`` and the reached activity will be processed. The attributes ``split_mode`` and
``join_mode`` attributes on the activity are used for such control. ``join_mode`` on the activity are used for such control. The possible values of
those attributes are explained below.
Activities Activities
---------- ----------
While the transitions can be seen as the control structure of the workflows, While the transitions can be seen as the control structures of the workflows,
activities are the place where everything happen, from changing record states activities are the places where everything happens, from changing record states
to sending email. to sending email.
Different kind of activities exist: ``Dummy``, ``Function``, ``Subflow``, and Different kinds of activities exist: ``Dummy``, ``Function``, ``Subflow``, and
``Stop all``; different kind of activities can do different and they are ``Stop all``, each doing different things when the activity is processed. In
detailed below. addition to their kind, activies have other properties, detailed in the next
sections.
In addition to the activity kind, activies have some properties, detailed in
the next sections.
Flow start and flow stop Flow start and flow stop
'''''''''''''''''''''''' ''''''''''''''''''''''''
The ``flow_start`` attribute is a boolean value specifying if the activity The attribute ``flow_start`` is a boolean value specifying whether the activity
starts the workflow. Multiple activities can have the ``flow_start`` attribute is processed when the workflow is instanciated. Multiple activities can have
set to ``True`` and when instanciating a workflow for a record, OpenERP will their attribute ``flow_start`` set to ``True``. When instanciating a workflow
simply process all of them, and try all their outgoing transitions afterwards. for a record, OpenERP simply processes all of them, and evaluate all their
outgoing transitions afterwards.
The ``flow_stop`` attribute is also a boolean value, specifying if the activity The attribute ``flow_stop`` is a boolean value specifying whether the activity
ends the workflow. A workflow is considered to be completed when all its stops the workflow instance. A workflow instance is considered completed when
activities with the ``flow_stop`` attribute set to ``True`` are completed. all its activities with the ``flow_stop`` attribute set to ``True`` are
It is important for OpenERP to know when a workflow instance is completed: a
workflow can have an activity that is actually another workflow (called a
subflow) and that activity will be completed only when the subflow is
completed. completed.
It is important for OpenERP to know when a workflow instance is completed. A
workflow can have an activity that is actually another workflow (called a
subflow); that activity is completed when the subflow is completed.
Subflow Subflow
''''''' '''''''
An activity can embed a complete workflow, called a subflow (the embedding An activity can embed a complete workflow, called a subflow (the embedding
workflow is called the parent workflow). The workflow to instanciate is workflow is called the parent workflow). The workflow to instanciate is
specified by the ``subflow_id`` attribute. specified by attribute ``subflow_id``.
.. note:: In the GUI, that attribute can not be set unless the kind of the .. note:: In the GUI, that attribute can not be set unless the kind of the
activity is ``Subflow``. activity is ``Subflow``.
The activity will be completed (and its outgoing transitions will be tried) The activity is considered completed (and its outgoing transitions ready to be
when the subflow is completed (see the ``flow_stop`` attribute above to read evaluated) when the subflow is completed (see attribute ``flow_stop`` above).
about when a workflow is considered completed by OpenERP).
Sending a signal from a subflow Sending a signal from a subflow
''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''
When a workflow is used (as a sublfow) in the activity of a (parent) workflow, When a workflow is embedded in an activity (as a subflow) of a workflow, the
the sublow can send a signal from its own activities to the parent by specifying a sublow can send a signal from its own activities to the parent workflow by
signal name in the ``signal_send`` attribute. OpenERP will process those giving a signal name in attribute ``signal_send``. OpenERP processes those
activities normally and send to the parent workflow instance a signal with activities by sending the value of ``signal_send`` prefixed by "subflow" to the
``signal_send`` value prefixed with ``subflow.``. parent workflow instance.
In other words, it is possible to react and take transitions in the parent In other words, it is possible to react and get transitions in the parent
workflow as activities are executed in the sublow. workflow as activities are executed in the sublow.
Server actions Server actions
'''''''''''''' ''''''''''''''
An activity can run a "Server Action" by specifying its ID in the ``action_id`` An activity can run a "Server Action" by specifying its ID in the attribute
attribute. ``action_id``.
Python action Python action
''''''''''''' '''''''''''''
An activity can run some Python code, provided through the ``action`` An activity can execute some Python code, given by attribute ``action``. The
attribute. See the section about transition conditions to read about the evaluation environment is the same as the one explained in the section
evaluation environment. `Conditions`_.
Split mode Split mode
'''''''''' ''''''''''
After an activity has been processed, its outgoing transitions will be tried. After an activity has been processed, its outgoing transitions are evaluated.
Normally, if a transition can be taken, OpenERP will do it and proceed to the Normally, if a transition can be taken, OpenERP traverses it and proceed to the
activity the transition leads to. activity the transition leads to.
Actually, when more than a single transition is leaving an activity, OpenERP Actually, when more than a single transition is leaving an activity, OpenERP may
can proceed, or not, depending on the other transitions. That is, the condition proceed or not, depending on the other transitions. That is, the condition on
on the transitions can be combined together, and the combined result will the transitions can be combined together, and the combined result instructs
instruct OpenERP to cross zero, one, or all the transitions. The way they are OpenERP to traverse zero, one, or all the transitions. The way they are combined
combined is controlled by the ``split_mode`` attribute. is controlled by the attribute ``split_mode``.
There are indeed three modes to decide how to combine the transition There are three possible split modes: ``XOR``, ``OR`` and ``AND``.
conditions, ``XOR``, ``OR``, and ``AND``.
``XOR`` ``XOR``
When the transitions are combined with a ``XOR`` split mode, as soon as a When the transitions are combined with a ``XOR`` split mode, as soon as a
transition with a condition that evaluates to true is found, the transition has a satisfied condition, the transition is traversed and the
transition is taken and the other will not be tried. others are skipped.
``OR`` ``OR``
With an ``OR`` mode, all the transitions with a condition that evaluates to With the ``OR`` mode, all the transitions with a satisfied condition are
true are taken. The remaining transitions will not be tried later. traversed. The remaining transitions will not be evaluated later.
``AND`` ``AND``
With an ``AND`` mode, OpenERP will wait for all transition conditions to With the ``AND`` mode, OpenERP will wait for all outgoing transition
evaluate to true, then cross all the transitions at the same time. conditions to be satisfied, then traverse all of them at once.
Join mode Join mode
''''''''' '''''''''
Just as departing transition conditions can be combined together to decide Just like outgoing transition conditions can be combined together to decide
whether they can be taken or not, arriving transitions can be combined together whether they can be traversed or not, incoming transitions can be combined
to decide if an activity must be run. The attribute to control that behavior is together to decide if and when an activity may be processed. The attribute
called ``join_mode``. ``join_mode`` controls that behavior.
The join mode is a bit simpler than the split mode: only two modes are There are two possible join modes: ``XOR`` and ``AND``.
provided, ``XOR`` and ``AND``.
``XOR`` ``XOR``
An activity with a ``XOR`` join mode will be run as soon as a transition is With the ``XOR`` mode, an incoming transition with a satisfied condition is
crossed to arrive at the activity. traversed immediately, and enables the processing of the activity.
``AND`` ``AND``
With an ``AND`` mode, the activity will wait for all its incoming With the ``AND`` mode, OpenERP will wait until all incoming transitions have
transitions to be crossed before being run. been traversed before enabling the processing of the activity.
Kinds Kinds
''''' '''''
@ -284,24 +287,25 @@ Activities can be of different kinds: ``dummy``, ``function``, ``subflow``, or
``stopall``. The kind defines what type of work an activity can do. ``stopall``. The kind defines what type of work an activity can do.
Dummy Dummy
The ``dummy`` kind is for activities that do nothing (i.e. they act as hubs The ``dummy`` kind is for activities that do nothing, or for activities that
to gather/dispatch transitions), or for activities that only call a Server only call a server action. Activities that do nothing can be used as hubs to
Action. gather/dispatch transitions.
Function Function
The ``function`` kind is for activities that only need to run some Python The ``function`` kind is for activities that only need to run some Python
code, and possibly a Server Action. code, and possibly a server action.
Stop all Stop all
The ``stopall`` kind is for activities that will completely halt the The ``stopall`` kind is for activities that will completely stop the
workflow instance. In addition they can also run some Python code. workflow instance and mark it as completed. In addition they can also run
some Python code.
Subflow Subflow
When the kind of the activity is ``subflow``, the activity will run When the kind of the activity is ``subflow``, the activity embeds another
another workflow. When the sub-workflow is completed, the activity will also be workflow instance. When the subflow is completed, the activity is also
considered completed. considered completed.
Normally the sub-workflow is instanciated for the same record as the parent By default, the subflow is instanciated for the same record as the parent
workflow. It is possible to change that default behavior by providing workflow. It is possible to change that behavior by providing Python code
Python code that has to return a record ID for which a workflow has been that returns a record ID (of the same data model as the subflow). The
instanciated. embedded subflow instance is then the one of the given record.