2
.. i18n: =========================
3
.. i18n: Workflow-Business Process
4
.. i18n: =========================
7
=========================
8
Workflow-Business Process
9
=========================
18
.. i18n: The workflow system in OpenERP is a very powerful mechanism that can describe the evolution of documents (model) in time.
21
The workflow system in OpenERP is a very powerful mechanism that can describe the evolution of documents (model) in time.
23
.. i18n: Workflows are entirely customizable, they can be adapted to the flows and trade logic of almost any company. The workflow system makes OpenERP very flexible and allows it to easily support changing needs without having to program new functionalities.
26
Workflows are entirely customizable, they can be adapted to the flows and trade logic of almost any company. The workflow system makes OpenERP very flexible and allows it to easily support changing needs without having to program new functionalities.
33
.. i18n: * description of document evolution in time
34
.. i18n: * automatic trigger of actions if some conditions are met
35
.. i18n: * management of company roles and validation steps
36
.. i18n: * management of interactions between the different objects/modules
37
.. i18n: * graphical tool for visualization of document flows
40
* description of document evolution in time
41
* automatic trigger of actions if some conditions are met
42
* management of company roles and validation steps
43
* management of interactions between the different objects/modules
44
* graphical tool for visualization of document flows
46
.. i18n: **To understand its utility, see these three examples:**
49
**To understand its utility, see these three examples:**
51
.. i18n: WkfExample1: Discount On Orders
52
.. i18n: -------------------------------
55
WkfExample1: Discount On Orders
56
-------------------------------
58
.. i18n: The first diagram represent a very basic workflow of an order:
61
The first diagram represent a very basic workflow of an order:
63
.. i18n: .. image:: images/Workflow_bc1.png
66
.. image:: images/Workflow_bc1.png
68
.. i18n: The order starts in the 'draft' state, when it is in redaction and not approved. When the user press on the 'Confirm' button, the invoice is created and the order comes into the 'CONFIRMED' state.
71
The order starts in the 'draft' state, when it is in redaction and not approved. When the user press on the 'Confirm' button, the invoice is created and the order comes into the 'CONFIRMED' state.
73
.. i18n: Then, two operations are possible:
76
Then, two operations are possible:
78
.. i18n: #. the order is done (shipped)
80
.. i18n: #. the order is canceled
83
#. the order is done (shipped)
85
#. the order is canceled
87
.. i18n: Let's suppose a company has a need not implemented in OpenERP. For example, suppose their sales staff can only offer discounts of 15% or less. Every order having a discount above 15% must be approved by the sales manager.
90
Let's suppose a company has a need not implemented in OpenERP. For example, suppose their sales staff can only offer discounts of 15% or less. Every order having a discount above 15% must be approved by the sales manager.
92
.. i18n: This modification in the sale logic doesn't need any line of python code! A simple modification of the workflow allows us to take this new need into account and add the extra validation step.
95
This modification in the sale logic doesn't need any line of python code! A simple modification of the workflow allows us to take this new need into account and add the extra validation step.
97
.. i18n: .. image:: images/Workflow_bc2.png
100
.. image:: images/Workflow_bc2.png
102
.. i18n: The workflow is thus modified as above and the orders will react as we want to. We then only need to modify the order form view and add a validation button at the desired location.
105
The workflow is thus modified as above and the orders will react as we want to. We then only need to modify the order form view and add a validation button at the desired location.
107
.. i18n: We could then further improve this workflow by sending a request to the sales manager when an order enters the 'Validation' state. Workflow nodes can execute object methods; only two lines of Python are needed to send a request asking the sales manager to validate or not the order.
110
We could then further improve this workflow by sending a request to the sales manager when an order enters the 'Validation' state. Workflow nodes can execute object methods; only two lines of Python are needed to send a request asking the sales manager to validate or not the order.
112
.. i18n: WkfExample2: A sale order that generates an invoice and a shipping order.
113
.. i18n: -------------------------------------------------------------------------
116
WkfExample2: A sale order that generates an invoice and a shipping order.
117
-------------------------------------------------------------------------
119
.. i18n: .. image:: images/Workflow_sale.png
122
.. image:: images/Workflow_sale.png
124
.. i18n: WkfExample3: Acount invoice basic workflow
127
WkfExample3: Acount invoice basic workflow
129
.. i18n: .. image:: images/Acount_inv_wkf.jpg
132
.. image:: images/Acount_inv_wkf.jpg
134
.. i18n: Defining Workflow
135
.. i18n: =================
136
.. i18n: Workflows are defined in the file server/bin/addons/base/ir/workflow/workflow.py. The first three classes defined in this file are workflow, wkf_activity and wkf_transition. They correspond to the three types of resources that are necessary to describe a workflow :
141
Workflows are defined in the file server/bin/addons/base/ir/workflow/workflow.py. The first three classes defined in this file are workflow, wkf_activity and wkf_transition. They correspond to the three types of resources that are necessary to describe a workflow :
143
.. i18n: * `workflow <http://openobject.com/wiki/index.php/WkfDefXML>`_ : the workflow,
144
.. i18n: * `wkf_activity <http://openobject.com/wiki/index.php/WorkflowActivity>`_ : the activities (nodes),
145
.. i18n: * `wkf_transition <http://openobject.com/wiki/index.php/WorkflowTransition>`_ : the transitions between the activities.
148
* `workflow <http://openobject.com/wiki/index.php/WkfDefXML>`_ : the workflow,
149
* `wkf_activity <http://openobject.com/wiki/index.php/WorkflowActivity>`_ : the activities (nodes),
150
* `wkf_transition <http://openobject.com/wiki/index.php/WorkflowTransition>`_ : the transitions between the activities.
152
.. i18n: General structure of a workflow XML file
153
.. i18n: ========================================
156
General structure of a workflow XML file
157
========================================
159
.. i18n: The general structure of a workflow XML file is as follows :
162
The general structure of a workflow XML file is as follows :
164
.. i18n: .. code-block:: xml
166
.. i18n: <?xml version="1.0"?>
169
.. i18n: <record model="workflow" id=workflow_id>
171
.. i18n: <field name="name">workflow.name</field>
172
.. i18n: <field name="osv">resource.model</field>
173
.. i18n: <field name="on_create">True | False</field>
183
<?xml version="1.0"?>
186
<record model="workflow" id=workflow_id>
188
<field name="name">workflow.name</field>
189
<field name="osv">resource.model</field>
190
<field name="on_create">True | False</field>
202
.. i18n: * **id** (here "workflow_id") is a workflow identifier. Each workflow must have an unique identifier.
203
.. i18n: * **name** (here "workflow.name") is the name of the workflow. The name of the workflow must respect the OpenERP syntax of "dotted names".
204
.. i18n: * **osv** (here "resource.model") is the name of the object we use as a model [-(Remember an OpenERP object inherits from osv.osv, hence the '<field name="osv">')-].
205
.. i18n: * **on_create** is True if workflow.name must be instantiated automatically when resource.model is created, and False otherwise.
208
* **id** (here "workflow_id") is a workflow identifier. Each workflow must have an unique identifier.
209
* **name** (here "workflow.name") is the name of the workflow. The name of the workflow must respect the OpenERP syntax of "dotted names".
210
* **osv** (here "resource.model") is the name of the object we use as a model [-(Remember an OpenERP object inherits from osv.osv, hence the '<field name="osv">')-].
211
* **on_create** is True if workflow.name must be instantiated automatically when resource.model is created, and False otherwise.
218
.. i18n: The workflow **"sale.order.basic"** defined in addons/sale/sale_workflow.xml follows exactly this model, the code of its workflow tag is :
221
The workflow **"sale.order.basic"** defined in addons/sale/sale_workflow.xml follows exactly this model, the code of its workflow tag is :
223
.. i18n: .. code-block:: xml
225
.. i18n: <record model="workflow" id="wkf_sale">
227
.. i18n: <field name="name">sale.order.basic</field>
228
.. i18n: <field name="osv">sale.order</field>
229
.. i18n: <field name="on_create">True</field>
236
<record model="workflow" id="wkf_sale">
238
<field name="name">sale.order.basic</field>
239
<field name="osv">sale.order</field>
240
<field name="on_create">True</field>
251
.. i18n: Introduction
252
.. i18n: ------------
258
.. i18n: The wkf_activity class represents the nodes of workflows. These nodes are the actions to be executed.
261
The wkf_activity class represents the nodes of workflows. These nodes are the actions to be executed.
277
.. i18n: .. image:: images/Wkf_split.png
280
.. image:: images/Wkf_split.png
282
.. i18n: * XOR: One necessary transition, takes the first one found (default).
283
.. i18n: * OR : Take only valid transitions (0 or more) in sequential order.
284
.. i18n: * AND: All valid transitions are launched at the same time (fork).
287
* XOR: One necessary transition, takes the first one found (default).
288
* OR : Take only valid transitions (0 or more) in sequential order.
289
* AND: All valid transitions are launched at the same time (fork).
291
.. i18n: In the OR and AND separation mode, certain workitems can be generated.
294
In the OR and AND separation mode, certain workitems can be generated.
296
.. i18n: In the AND mode, the activity waits for all transitions to be valid, even if some of them are already valid. They are all triggered at the same time.
299
In the AND mode, the activity waits for all transitions to be valid, even if some of them are already valid. They are all triggered at the same time.
308
.. i18n: .. image:: images/Wkf_join.png
311
.. image:: images/Wkf_join.png
313
.. i18n: * **XOR**: One transition necessary to continue to the destination activity (default).
314
.. i18n: * **AND**: Waits for all transition conditions to be valid to execute the destination activity.
317
* **XOR**: One transition necessary to continue to the destination activity (default).
318
* **AND**: Waits for all transition conditions to be valid to execute the destination activity.
327
.. i18n: :The type of the activity can take several values:
330
:The type of the activity can take several values:
332
.. i18n: * **DUMMY**: Do nothing (default).
333
.. i18n: * **FUNCTION**: Execute the function selected by an action.
334
.. i18n: * **SUBFLOW**: Execute a sub-workflow SUBFLOW_ID. The action method must return the ID of the concerned resource by the subflow ! If the action returns False, the workitem disappears !
335
.. i18n: * **STOPALL**:
338
* **DUMMY**: Do nothing (default).
339
* **FUNCTION**: Execute the function selected by an action.
340
* **SUBFLOW**: Execute a sub-workflow SUBFLOW_ID. The action method must return the ID of the concerned resource by the subflow ! If the action returns False, the workitem disappears !
343
.. i18n: A sub-workflow is executed when an activity is of the type SUBFLOW. This activity ends when the sub-workflow has finished. While the sub-workflow is active, the workitem of this activity is frozen.
346
A sub-workflow is executed when an activity is of the type SUBFLOW. This activity ends when the sub-workflow has finished. While the sub-workflow is active, the workitem of this activity is frozen.
355
.. i18n: The action indicates the method to execute when a workitem comes into this activity. The method must be defined in an object which belongs to this workflow and have the following signature:
358
The action indicates the method to execute when a workitem comes into this activity. The method must be defined in an object which belongs to this workflow and have the following signature:
360
.. i18n: def object_method(self, cr, uid, ids):
363
def object_method(self, cr, uid, ids):
365
.. i18n: In the action though, they will be called by a statement like:
368
In the action though, they will be called by a statement like:
370
.. i18n: object_method()
389
.. i18n: Indicates if the node is a start node. When a new instance of a workflow is created, a workitem is activated for each activity marked as a flow_start.
392
Indicates if the node is a start node. When a new instance of a workflow is created, a workitem is activated for each activity marked as a flow_start.
394
.. i18n: .. warning::
396
.. i18n: Be warned to not use this flag unless your activity really is a "flow
397
.. i18n: start". There are tiny versions that do not care about the tags contents
398
.. i18n: like "true" or "false". Using such tag and tiny version, you will always
399
.. i18n: end up with an activity which is tagged as "flow start = true", leaving u
400
.. i18n: with a nasty hunt to find out where your workflow design could be wrong.
402
.. i18n: This is because tags content are always evaluated as string. Read the
403
.. i18n: section about the :ref:`eval attribute <eval-attribute-link>` for an
404
.. i18n: explanation.
409
Be warned to not use this flag unless your activity really is a "flow
410
start". There are tiny versions that do not care about the tags contents
411
like "true" or "false". Using such tag and tiny version, you will always
412
end up with an activity which is tagged as "flow start = true", leaving u
413
with a nasty hunt to find out where your workflow design could be wrong.
415
This is because tags content are always evaluated as string. Read the
416
section about the :ref:`eval attribute <eval-attribute-link>` for an
426
.. i18n: Indicates if the node is an ending node. When all the active workitems for a given instance come in the node marked by flow_stop, the workflow is finished.
429
Indicates if the node is an ending node. When all the active workitems for a given instance come in the node marked by flow_stop, the workflow is finished.
431
.. i18n: .. warning::
433
.. i18n: Be warned to not use this flag unless your activity really is a "flow
434
.. i18n: stop". There are tiny versions that do not care about the tags contents
435
.. i18n: like "true" or "false". Using such tag and tiny version, you will always
436
.. i18n: end up with an activity which is tagged as "flow stop = true", leaving u
437
.. i18n: with a nasty hunt to find out where your workflow design could be wrong.
439
.. i18n: This is because tags content are always evaluated as string. Read the
440
.. i18n: section about the :ref:`eval attribute <eval-attribute-link>` for an
441
.. i18n: explanation.
446
Be warned to not use this flag unless your activity really is a "flow
447
stop". There are tiny versions that do not care about the tags contents
448
like "true" or "false". Using such tag and tiny version, you will always
449
end up with an activity which is tagged as "flow stop = true", leaving u
450
with a nasty hunt to find out where your workflow design could be wrong.
452
This is because tags content are always evaluated as string. Read the
453
section about the :ref:`eval attribute <eval-attribute-link>` for an
463
.. i18n: The workflow which this activity belongs to.
466
The workflow which this activity belongs to.
468
.. i18n: Defining activities using XML files
469
.. i18n: -----------------------------------
472
Defining activities using XML files
473
-----------------------------------
475
.. i18n: The general structure of an activity record is as follows
478
The general structure of an activity record is as follows
480
.. i18n: .. code-block:: xml
482
.. i18n: <record model="workflow.activity" id="''activity_id''">
483
.. i18n: <field name="wkf_id" ref="''workflow_id''"/>
484
.. i18n: <field name="name">''activity.name''</field>::
486
.. i18n: <field name="split_mode">XOR | OR | AND</field>
487
.. i18n: <field name="join_mode">XOR | AND</field>
488
.. i18n: <field name="kind">dummy | function | subflow | stopall</field>
490
.. i18n: <field name="action">''(...)''</field>
491
.. i18n: <field name="signal_send">''(...)''</field>
492
.. i18n: <field name="flow_start">True | False</field>
493
.. i18n: <field name="flow_stop">True | False</field>
499
<record model="workflow.activity" id="''activity_id''">
500
<field name="wkf_id" ref="''workflow_id''"/>
501
<field name="name">''activity.name''</field>::
503
<field name="split_mode">XOR | OR | AND</field>
504
<field name="join_mode">XOR | AND</field>
505
<field name="kind">dummy | function | subflow | stopall</field>
507
<field name="action">''(...)''</field>
508
<field name="signal_send">''(...)''</field>
509
<field name="flow_start">True | False</field>
510
<field name="flow_stop">True | False</field>
513
.. i18n: The first two arguments **wkf_id** and name are mandatory.
516
The first two arguments **wkf_id** and name are mandatory.
518
.. i18n: .. warning::
520
.. i18n: Be warned to not use **flow_start** and **flow_stop** unless your activity
521
.. i18n: really is a **flow start** or **flow_stop**. There are tiny versions that
522
.. i18n: do not care about the tags contents like "True" or "False".
524
.. i18n: This is because tags content are always evaluated as string. Read the
525
.. i18n: section about the :ref:`eval attribute <eval-attribute-link>` for an
526
.. i18n: explanation.
531
Be warned to not use **flow_start** and **flow_stop** unless your activity
532
really is a **flow start** or **flow_stop**. There are tiny versions that
533
do not care about the tags contents like "True" or "False".
535
This is because tags content are always evaluated as string. Read the
536
section about the :ref:`eval attribute <eval-attribute-link>` for an
546
.. i18n: There are too many possibilities of activity definition to choose from using this definition. We recommend you to have a look at the file **server/bin/addons/sale/sale_workflow.xml** for several examples of activity definitions.
549
There are too many possibilities of activity definition to choose from using this definition. We recommend you to have a look at the file **server/bin/addons/sale/sale_workflow.xml** for several examples of activity definitions.
558
.. i18n: Introduction
559
.. i18n: ------------
565
.. i18n: Workflow transitions are the conditions to be satisfied to go from one activity to the next one. They are represented by one-way arrows joining two activities.
568
Workflow transitions are the conditions to be satisfied to go from one activity to the next one. They are represented by one-way arrows joining two activities.
570
.. i18n: The conditions are of different types:
573
The conditions are of different types:
575
.. i18n: * role to satisfy by the user
576
.. i18n: * button pressed in the interface
577
.. i18n: * end of a subflow through a selected activity of subflow
580
* role to satisfy by the user
581
* button pressed in the interface
582
* end of a subflow through a selected activity of subflow
584
.. i18n: The roles and signals are evaluated before the expression. If a role or a signal is false, the expression will not be evaluated.
587
The roles and signals are evaluated before the expression. If a role or a signal is false, the expression will not be evaluated.
589
.. i18n: Transition tests may not write values in objects.
592
Transition tests may not write values in objects.
610
.. i18n: Source activity. When this activity is over, the condition is tested to determine if we can start the ACT_TO activity.
613
Source activity. When this activity is over, the condition is tested to determine if we can start the ACT_TO activity.
624
.. i18n: The destination activity.
627
The destination activity.
638
.. i18n: **Expression** to be satisfied if we want the transition done.
641
**Expression** to be satisfied if we want the transition done.
652
.. i18n: When the operation of transition comes from a button pressed in the client form, signal tests the name of the pressed button.
655
When the operation of transition comes from a button pressed in the client form, signal tests the name of the pressed button.
657
.. i18n: If signal is NULL, no button is necessary to validate this transition.
660
If signal is NULL, no button is necessary to validate this transition.
671
.. i18n: The **role** that a user must have to validate this transition.
674
The **role** that a user must have to validate this transition.
676
.. i18n: Defining Transitions Using XML Files
677
.. i18n: ------------------------------------
680
Defining Transitions Using XML Files
681
------------------------------------
683
.. i18n: The general structure of a transition record is as follows
686
The general structure of a transition record is as follows
688
.. i18n: .. code-block:: xml
690
.. i18n: <record model="workflow.transition" id="transition_id">
692
.. i18n: <field name="act_from" ref="activity_id'_1_'"/>
693
.. i18n: <field name="act_to" ref="activity_id'_2_'"/>
695
.. i18n: <field name="signal">(...)</field>
696
.. i18n: <field name="role_id" ref="role_id'_1_'"/>
697
.. i18n: <field name="condition">(...)</field>
699
.. i18n: <field name="trigger_model">(...)</field>
700
.. i18n: <field name="trigger_expr_id">(...)</field>
707
<record model="workflow.transition" id="transition_id">
709
<field name="act_from" ref="activity_id'_1_'"/>
710
<field name="act_to" ref="activity_id'_2_'"/>
712
<field name="signal">(...)</field>
713
<field name="role_id" ref="role_id'_1_'"/>
714
<field name="condition">(...)</field>
716
<field name="trigger_model">(...)</field>
717
<field name="trigger_expr_id">(...)</field>
721
.. i18n: Only the fields **act_from** and **act_to** are mandatory.
724
Only the fields **act_from** and **act_to** are mandatory.
733
.. i18n: Expressions are written as in python:
736
Expressions are written as in python:
740
.. i18n: * 'hello' in ['hello','bye']
745
* 'hello' in ['hello','bye']
747
.. i18n: Any field from the resource the workflow refers to can be used in these expressions. For example, if you were creating a workflow for partner addresses, you could use expressions like:
750
Any field from the resource the workflow refers to can be used in these expressions. For example, if you were creating a workflow for partner addresses, you could use expressions like:
753
.. i18n: * phone==mobile
761
.. i18n: Roles can be attached to transitions. If a role is given for a transition, that transition can only be executed if the user who triggered it possess the necessary role.
766
Roles can be attached to transitions. If a role is given for a transition, that transition can only be executed if the user who triggered it possess the necessary role.
768
.. i18n: Each user can have one or several roles. Roles are defined in a tree of roles, parent roles having the rights of all their children.
771
Each user can have one or several roles. Roles are defined in a tree of roles, parent roles having the rights of all their children.
783
.. i18n: * Technical manager
785
.. i18n: - Lead developer
792
.. i18n: + Developers
799
.. i18n: * Sales manager
801
.. i18n: - Commercials
810
.. i18n: Let's suppose we handle our own bug database and that the action of marking a bug as valid needs the Testers role. In the example tree above, marking a bug as valid could be done by all the users having the following roles: Testers, Lead developer, Technical manager, CEO.
813
Let's suppose we handle our own bug database and that the action of marking a bug as valid needs the Testers role. In the example tree above, marking a bug as valid could be done by all the users having the following roles: Testers, Lead developer, Technical manager, CEO.
815
.. i18n: Error handling
816
.. i18n: ==============
822
.. i18n: As of this writing, there is no exception handling in workflows.
825
As of this writing, there is no exception handling in workflows.
827
.. i18n: Workflows being made of several actions executed in batch, they can't trigger exceptions. In order to improve the execution efficiency and to release a maximum of locks, workflows commit at the end of each activity. This approach is reasonable because an activity is only started if the conditions of the transactions are satisfied.
830
Workflows being made of several actions executed in batch, they can't trigger exceptions. In order to improve the execution efficiency and to release a maximum of locks, workflows commit at the end of each activity. This approach is reasonable because an activity is only started if the conditions of the transactions are satisfied.
832
.. i18n: The only problem comes from exceptions due to programming errors; in that case, only transactions belonging to the entirely completed activities are executed. Other transactions are "rolled back".
835
The only problem comes from exceptions due to programming errors; in that case, only transactions belonging to the entirely completed activities are executed. Other transactions are "rolled back".
837
.. i18n: Creating a Workflow
838
.. i18n: ===================
844
.. i18n: Steps for creating a simple state-changing workflow for a custom module called **mymod**
847
Steps for creating a simple state-changing workflow for a custom module called **mymod**
849
.. i18n: Define the States of your object
850
.. i18n: --------------------------------
853
Define the States of your object
854
--------------------------------
856
.. i18n: The first step is to define the States your object can be in. We do this by adding a 'state' field to our object, in the _columns collection
859
The first step is to define the States your object can be in. We do this by adding a 'state' field to our object, in the _columns collection
861
.. i18n: .. code-block:: python
863
.. i18n: _columns = {
865
.. i18n: 'state': fields.selection([
866
.. i18n: ('new','New'),
867
.. i18n: ('assigned','Assigned'),
868
.. i18n: ('negotiation','Negotiation'),
869
.. i18n: ('won','Won'),
870
.. i18n: ('lost','Lost')], 'Stage', readonly=True),
874
.. code-block:: python
878
'state': fields.selection([
880
('assigned','Assigned'),
881
('negotiation','Negotiation'),
883
('lost','Lost')], 'Stage', readonly=True),
886
.. i18n: Define the State-change Handling Methods
887
.. i18n: ----------------------------------------
890
Define the State-change Handling Methods
891
----------------------------------------
893
.. i18n: Add the following additional methods to your object. These will be called by our workflow buttons
896
Add the following additional methods to your object. These will be called by our workflow buttons
898
.. i18n: .. code-block:: python
900
.. i18n: def mymod_new(self, cr, uid, ids):
901
.. i18n: self.write(cr, uid, ids, { 'state' : 'new' })
904
.. i18n: def mymod_assigned(self, cr, uid, ids):
905
.. i18n: self.write(cr, uid, ids, { 'state' : 'assigned' })
908
.. i18n: def mymod_negotiation(self, cr, uid, ids):
909
.. i18n: self.write(cr, uid, ids, { 'state' : 'negotiation' })
912
.. i18n: def mymod_won(self, cr, uid, ids):
913
.. i18n: self.write(cr, uid, ids, { 'state' : 'won' })
916
.. i18n: def mymod_lost(self, cr, uid, ids):
917
.. i18n: self.write(cr, uid, ids, { 'state' : 'lost' })
921
.. code-block:: python
923
def mymod_new(self, cr, uid, ids):
924
self.write(cr, uid, ids, { 'state' : 'new' })
927
def mymod_assigned(self, cr, uid, ids):
928
self.write(cr, uid, ids, { 'state' : 'assigned' })
931
def mymod_negotiation(self, cr, uid, ids):
932
self.write(cr, uid, ids, { 'state' : 'negotiation' })
935
def mymod_won(self, cr, uid, ids):
936
self.write(cr, uid, ids, { 'state' : 'won' })
939
def mymod_lost(self, cr, uid, ids):
940
self.write(cr, uid, ids, { 'state' : 'lost' })
943
.. i18n: Obviously you would extend these methods in the future to do something more useful!
946
Obviously you would extend these methods in the future to do something more useful!
948
.. i18n: Create your Workflow XML file
949
.. i18n: -----------------------------
952
Create your Workflow XML file
953
-----------------------------
955
.. i18n: There are three types of records we need to define in a file called mymod_workflow.xml
958
There are three types of records we need to define in a file called mymod_workflow.xml
960
.. i18n: #. Workflow header record (only one of these)
963
#. Workflow header record (only one of these)
965
.. i18n: .. code-block:: xml
967
.. i18n: <record model="workflow" id="wkf_mymod">
968
.. i18n: <field name="name">mymod.wkf</field>
969
.. i18n: <field name="osv">mymod.mymod</field>
970
.. i18n: <field name="on_create">True</field>
976
<record model="workflow" id="wkf_mymod">
977
<field name="name">mymod.wkf</field>
978
<field name="osv">mymod.mymod</field>
979
<field name="on_create">True</field>
982
.. i18n: #. Workflow Activity records
985
#. Workflow Activity records
987
.. i18n: These define the actions that should be executed when the workflow reaches a particular state
990
These define the actions that should be executed when the workflow reaches a particular state
992
.. i18n: .. code-block:: xml
994
.. i18n: <record model="workflow.activity" id="act_new">
995
.. i18n: <field name="wkf_id" ref="wkf_mymod" />
996
.. i18n: <field name="flow_start">True</field>
997
.. i18n: <field name="name">new</field>
998
.. i18n: <field name="kind">function</field>
999
.. i18n: <field name="action">mymod_new()</field>
1002
.. i18n: <record model="workflow.activity" id="act_assigned">
1003
.. i18n: <field name="wkf_id" ref="wkf_mymod" />
1004
.. i18n: <field name="name">assigned</field>
1005
.. i18n: <field name="kind">function</field>
1006
.. i18n: <field name="action">mymod_assigned()</field>
1009
.. i18n: <record model="workflow.activity" id="act_negotiation">
1010
.. i18n: <field name="wkf_id" ref="wkf_mymod" />
1011
.. i18n: <field name="name">negotiation</field>
1012
.. i18n: <field name="kind">function</field>
1013
.. i18n: <field name="action">mymod_negotiation()</field>
1016
.. i18n: <record model="workflow.activity" id="act_won">
1017
.. i18n: <field name="wkf_id" ref="wkf_mymod" />
1018
.. i18n: <field name="name">won</field>
1019
.. i18n: <field name="kind">function</field>
1020
.. i18n: <field name="action">mymod_won()</field>
1021
.. i18n: <field name="flow_stop">True</field>
1024
.. i18n: <record model="workflow.activity" id="act_lost">
1025
.. i18n: <field name="wkf_id" ref="wkf_mymod" />
1026
.. i18n: <field name="name">lost</field>
1027
.. i18n: <field name="kind">function</field>
1028
.. i18n: <field name="action">mymod_lost()</field>
1029
.. i18n: <field name="flow_stop">True</field>
1035
<record model="workflow.activity" id="act_new">
1036
<field name="wkf_id" ref="wkf_mymod" />
1037
<field name="flow_start">True</field>
1038
<field name="name">new</field>
1039
<field name="kind">function</field>
1040
<field name="action">mymod_new()</field>
1043
<record model="workflow.activity" id="act_assigned">
1044
<field name="wkf_id" ref="wkf_mymod" />
1045
<field name="name">assigned</field>
1046
<field name="kind">function</field>
1047
<field name="action">mymod_assigned()</field>
1050
<record model="workflow.activity" id="act_negotiation">
1051
<field name="wkf_id" ref="wkf_mymod" />
1052
<field name="name">negotiation</field>
1053
<field name="kind">function</field>
1054
<field name="action">mymod_negotiation()</field>
1057
<record model="workflow.activity" id="act_won">
1058
<field name="wkf_id" ref="wkf_mymod" />
1059
<field name="name">won</field>
1060
<field name="kind">function</field>
1061
<field name="action">mymod_won()</field>
1062
<field name="flow_stop">True</field>
1065
<record model="workflow.activity" id="act_lost">
1066
<field name="wkf_id" ref="wkf_mymod" />
1067
<field name="name">lost</field>
1068
<field name="kind">function</field>
1069
<field name="action">mymod_lost()</field>
1070
<field name="flow_stop">True</field>
1073
.. i18n: #. Workflow Transition records
1076
#. Workflow Transition records
1078
.. i18n: These define the possible transitions between workflow states
1081
These define the possible transitions between workflow states
1083
.. i18n: .. code-block:: xml
1085
.. i18n: <record model="workflow.transition" id="t1">
1086
.. i18n: <field name="act_from" ref="act_new" />
1087
.. i18n: <field name="act_to" ref="act_assigned" />
1088
.. i18n: <field name="signal">mymod_assigned</field>
1091
.. i18n: <record model="workflow.transition" id="t2">
1092
.. i18n: <field name="act_from" ref="act_assigned" />
1093
.. i18n: <field name="act_to" ref="act_negotiation" />
1094
.. i18n: <field name="signal">mymod_negotiation</field>
1097
.. i18n: <record model="workflow.transition" id="t3">
1098
.. i18n: <field name="act_from" ref="act_negotiation" />
1099
.. i18n: <field name="act_to" ref="act_won" />
1100
.. i18n: <field name="signal">mymod_won</field>
1103
.. i18n: <record model="workflow.transition" id="t4">
1104
.. i18n: <field name="act_from" ref="act_negotiation" />
1105
.. i18n: <field name="act_to" ref="act_lost" />
1106
.. i18n: <field name="signal">mymod_lost</field>
1112
<record model="workflow.transition" id="t1">
1113
<field name="act_from" ref="act_new" />
1114
<field name="act_to" ref="act_assigned" />
1115
<field name="signal">mymod_assigned</field>
1118
<record model="workflow.transition" id="t2">
1119
<field name="act_from" ref="act_assigned" />
1120
<field name="act_to" ref="act_negotiation" />
1121
<field name="signal">mymod_negotiation</field>
1124
<record model="workflow.transition" id="t3">
1125
<field name="act_from" ref="act_negotiation" />
1126
<field name="act_to" ref="act_won" />
1127
<field name="signal">mymod_won</field>
1130
<record model="workflow.transition" id="t4">
1131
<field name="act_from" ref="act_negotiation" />
1132
<field name="act_to" ref="act_lost" />
1133
<field name="signal">mymod_lost</field>
1136
.. i18n: Add mymod_workflow.xml to __terp__.py
1137
.. i18n: -------------------------------------
1140
Add mymod_workflow.xml to __terp__.py
1141
-------------------------------------
1143
.. i18n: Edit your module's __terp__.py and add mymod_workflow.xml to the "update_xml" array, so that OpenERP picks it up next time your module is loaded.
1146
Edit your module's __terp__.py and add mymod_workflow.xml to the "update_xml" array, so that OpenERP picks it up next time your module is loaded.
1148
.. i18n: Add Workflow Buttons to your View
1149
.. i18n: ---------------------------------
1152
Add Workflow Buttons to your View
1153
---------------------------------
1155
.. i18n: The final step is to add the required buttons to mymod_views.xml file.
1158
The final step is to add the required buttons to mymod_views.xml file.
1160
.. i18n: Add the following at the end of the <form> section of your object's view definition:
1163
Add the following at the end of the <form> section of your object's view definition:
1165
.. i18n: .. code-block:: xml
1167
.. i18n: <separator string="Workflow Actions" colspan="4"/>
1168
.. i18n: <group colspan="4" col="3">
1169
.. i18n: <button name="mymod_assigned" string="Assigned" states="new" />
1170
.. i18n: <button name="mymod_negotiation" string="In Negotiation" states="assigned" />
1171
.. i18n: <button name="mymod_won" string="Won" states="negotiating" />
1172
.. i18n: <button name="mymod_lost" string="Lost" states="negotiating" />
1178
<separator string="Workflow Actions" colspan="4"/>
1179
<group colspan="4" col="3">
1180
<button name="mymod_assigned" string="Assigned" states="new" />
1181
<button name="mymod_negotiation" string="In Negotiation" states="assigned" />
1182
<button name="mymod_won" string="Won" states="negotiating" />
1183
<button name="mymod_lost" string="Lost" states="negotiating" />
1188
.. i18n: Now use the Module Manager to install or update your module. If you have done everything correctly you shouldn't get any errors. You can check if your workflow is installed in the menu :menuselection:`Administration --> Customization --> Workflow Definitions`.
1193
Now use the Module Manager to install or update your module. If you have done everything correctly you shouldn't get any errors. You can check if your workflow is installed in the menu :menuselection:`Administration --> Customization --> Workflow Definitions`.
1195
.. i18n: When you are testing, remember that the workflow will only apply to NEW records that you create.
1198
When you are testing, remember that the workflow will only apply to NEW records that you create.
1200
.. i18n: Troubleshooting
1201
.. i18n: ---------------
1202
.. i18n: If your buttons do not seem to be doing anything, one of the following two things are likely:
1207
If your buttons do not seem to be doing anything, one of the following two things are likely:
1209
.. i18n: 1. The record you are working on does not have a Workflow Instance record associated with it (it was probably created before you defined your workflow)
1210
.. i18n: 2. You have not set the "osv" field correctly in your workflow XML file
1213
1. The record you are working on does not have a Workflow Instance record associated with it (it was probably created before you defined your workflow)
1214
2. You have not set the "osv" field correctly in your workflow XML file