Note: This how-to is work in progress, written mostly by inexperienced developer, needs review
Normal workflows are used to implement effects of user interaction - validating
of objects, ordering, planning and confirming of orders, etc.
Table of Contents
Interaction Workflows¶
By interaction workflows it is possible to define interactions on objects -
in other words catching some methods invocations and defining actions, which
shall happen on object. You can think of it as something similar to a "trigger"
in relation database, a "hook", or a "side effect" of other actions. In other
words, you can add some behaviour to an object without altering the object (class) itself.
For example, you may want to set a generated Title on new created objects like
T0001, T0002, ... To gain such possibility, it's possible to use interaction workflow.
Examples of interaction workflow are in business templates - very interesting
usage is in trade_model_line_interaction_workflow.
Example¶
We want to set titles on Purchase Order and Sale Order objects.
Go to Contents tab of workflow tool, create custom_title_setter_sale_order_interaction_workflow,
choose interaction workflow.
Now go to Workflows tab of workflow tool and associate custom_title_seter_sale_order_interaction_workflow
with Purchase Order Module and Sale Order Module portal types, then return to
defining of interaction workflow.
Create scripts: PurchaseOrder_titleSetter and SaleOrder_titleSetter.
## Script (Python) "PurchaseOrder_titleSetter"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=state_change
##title=
##
module = state_change['object']
# get the new created object
new_created_object = state_change['kwargs']['workflow_method_result']
# id group si used to define what will define your counter
id_group = ('title', new_created_object.getPortalType())
default = 1
title = module.portal_ids.generateNewLengthId(id_group=id_group, default=default)
new_created_object.setTitle('T%04d' % title)
So now we have to define interaction for our portal types. Go to Interactions
tab, and create PurchaseOrder_titleSetInteraction. Edit it, and for set fields to:
- Filter : Purchase Order Module
- Trigger Method Id(s) : newContent
- Script (after) : PurchaseOrder_titleSetter
Create interaction SaleOrder_titleSetInteraction and set fields properly.
As exercise base definitions of above values.
Now create Purchase or Sale order and watch what happens. Titles looking like
T0001, T0002, ... should be used
Most important part in interaction definition is Trigger Method Id(s). To catch
all typical invocations. You can use method like newContent, but also edit and _edit
you can also catch workflow transition like cancel, validate. And last, but not
least, you can catch relating order with source/destination section we have to
add _setDestinationValue, _setDestinationSectionValue, _setSourceValue, _setSourceSectionValue.
Reference documentation¶
Creating interaction workflows¶
To create interaction workflow navigate to workflow tool Contents tab add new
workflow, type its Id and choose Type interaction_workflow.
Proposed Id grammar is someprefix[_portal_or_meta_type][_description_]interaction_workflow, eg:
- custom_packing_list_interaction_workflow
- custom_order_line_title_setter_interaction_workflow
Interaction workflows can be organised in various ways - per portal type (one
interaction workflow for each portal type which needs it), or per function
(aspect), or something else. For example, some developers find it convenient
to create one security_update_interaction_workflow which is then used for every
portal type which requires a security update upon certain actions.
Properties¶
Same as in normal workflows.
Interactions¶
List of possible interactions, which every can have additional constraints:
- Filter: interaction will be invoked only on chosen portal types ((!) this list will be filled after association interaction workflows with portal types)
- Trigger type:
- Automatic - TODO
- Initiated by WorkflowMethod - TODO
- Trigger Method Id(s): list of methods, which will trigger workflows. You can catch many things
- edit and _edit (though think twice, this would be triggered very often)
- normal workflow actions (like stop, cancel, confirm)
- low level methods (manage_afterClone)
- category setters (_setResourceValue,_setDestinationValue)
- property setters (use _set[PropertyName].* to catch all invocations of the setter)
-
Script (before), Script (after) and Activities (later) - list of script which
will be invoked before action happens, after action happens and which will be
invoked in activities. /!\ Experiment with other scripts which are invoked
by those actions.
- Guard - which guards applies to this interaction, same as in normal workflows
Note: It is quite good idea to define methods (scripts) before defining interactions.
Variables¶
Todo
Scripts¶
Every script in you interaction workflows definition shall have argument called
(by convention) state_change. To access changed object use:
changed_object = state_change['object']
Don't do state_change.object - it usually works but sometimes causes security problems.
Scripts can be invoked:
- before - ran immediately; if triggered by a setter uses the old value of a property
- after - ran immediately; if triggered by a setter uses the new value of a property
- later - executed a bit later, usually a few seconds but can be much longer
QUESTION: what to do if an interaction has to compare the old value to the new
one? Is there a way to access them both at the same time (other then request lookup)?
List of usable Trigger methods¶
When editing using the standard ERP5 interface, edit method will be called. Then
for each modified property, when you have for example a field "my_foo", the
corresponding accessor _setFoo will be called. If _setFoo does not exists,
setFoo will be called instead. If setFoo does not exist either, setProperty('foo', value)
will be called.
There is an exception for RelationFields.
When a RelationField is modified,
either the field defines a "Relation Update Method" that will be called, either
the default _set${base_category}Value (or _set${base_category}ValueList when
setting a multiple relation) accessor will be called, where ${base_category}
is the capitalized name of the base category used for this accessor.
Here is a summary of methods that can be used:
- edit: this method shall trigger on when object is edited, but see below
- _setResourceValue: this method will be triggered on when relation defined on resource category will be changed. /!\ Such change will NOT be triggered by edit method
- _set.*: you may use regular expressions to trigger on more then one method - it is quite usefull in case of relation setting methods
- manage_afterAdd: trigger on while adding object
- manage_afterClone: trigger on while pasting copied or cut object. Also note that you can use _afterClone TypeBasedMethod.
- manager_beforeDelete: trigger on before deleting object
Questions and Answers¶
How can I redirect from an interaction workflow script?
You can't.
Related Articles¶