Why Workflows

Workflows are used in order to design human decisions. Another usage of workflows are interactions.

Howto create a Worflow for ERP5

All workflows and methods to deal with workflows programmatically are stored in the WorkflowTool : portal_workflow.

ERP5 Workflows are based on DCWorkflow, so you may want to read DCWorkflow documentation first, or plone how-to on creating workflow.

Inside the portal_workflow of your ERP5 Site, you have to select the "content" tab, then add an ERP5-style workflow.

Transitions

Transitions defines how users can change the state of documents associated to this workflow.

The guard section defines what are the requirements to be able to pass this transition. If any all those 3 guards; Permission, Role and Expression, are evaluated as True (or are empty), then the transition will be available.

The Display in actions box section defines how the action is named and which screen we will display. This is only useful for Initiated by User Action transitions. It can be for example :

  name : Confirm Order
  url : %(content_url)s/Base_viewWorkflowActionDialog?workflow_action=confirm_action
  category : workflow

It's important that the action in this URL matches the id of the transition.

User Action vs Workflow Method

Usually, when defining a workflow, you create the logic of the workflow using transitions triggered by Workflow Methods and you add some transitions triggered by user actions to define which transitions can be controlled by the user. ERP5 patches the DCWorkflow engine to allow to call a workflow method as an after script. When creating an user action transition (eg. confirm_action), you should set the corresponding workflow method as an after script (eg. confirm).

States

Once you created all transitions, you can create all the states. For each state, we should select which transitions are possible. Don't forget to set the initial state.

Permissions

We can associate different permissions with each state. First, in the "permission" tab of your Workflow, you can add which permissions you want to manage with your workflow. For example, we can manage the "View" permission. After, you can select one of your state, then select the permission tab, and you will see that you can set who have the right to view the object in this current state. This documentation from plone.org also contains information on this topic.

Script (before) and Script (after)

You can define some scripts that will be before and after a transition takes place. These scripts must be defined in in the scripts folder of the given workflow.

There is one addition to the DCWorkflow here. If the before script from the user action transition (ie confirm_action) throws a Products.DCWorkflow.DCWorkflow.ValidationFailed Exception, the exception will be catched, and the error message passed to the Exception will be shown as a status message. The best solution here is probably to use Constraints by calling checkConsistency on the object.

Important: Because ValidationFailed are catched by the UI system, the ZODB Transaction is not aborted, so if your script makes changes before raising the ValidationFailed, changes will be made persistent. (We have this behaviour because we want the error message to be recorded in the workflow history).

After scripts should be used to do any actions that are required by the workflow logic (like creating a new document, or sending an email). Those logic scripts should be used as after scripts of logic transitions (ie confirm).

How to execute a transition within a script

Let's say you have an object "my_object", and you want to execute the transition "confirm_action" for the workflow "packing_list_workflow" (note that wf_id parameter is optionnal), you can do like this :

  context.portal_workflow.doActionFor(my_object,
                                    'confirm_action',
                                     wf_id='packing_list_workflow',
                                     comment=comment or '')

This way, permission check and validation will occur (if you created a validation script). Assuming you make the validation yourself, or do not want the validation to occur, you can call directly the workflow method like this :

  my_object.confirm()

Note that if you use ERP5Type based document, if a method confirm does not exist on the class, an empty method will be generated for documents of this portal type.

Variables

A workflow can define variables, that can be retrieved using portal_workflow.getInfoFor(document, variable_name). Those variables can be modified by TALES expressions on transitions or states.

State variable

A workflow have a state variable that can be queried like other variables using getInfoFor, but again if you use ERP5Type based document, some accessors are generated for documents using this portal type. For instance, if you use validation_state as state variable, methods like getValidationState and getTranslatedValidationStateTitle will be generated.

Worklists - to tell you how much work you have

It is often useful to be able to see how many given tasks are awaiting your action, and to be able to access them directly. Worklists are made just for that.

A worklist is a list of objects that fulfils certain criteria, most important of them being a given workflow state. If you have something on your worklist, it shows up in you Favourites menu saying something like "Things to do (24)." Click on it, and you see a listbox with your 24 things.

Worklist is created for a given workflow. In the worklist configuration screen you basically configure three things: job counter parameters, a way to display information about pending items, and a way to list the pending items.

Counter

Jobs are counted using portal_catalog, so you have to specify variables which are cataloged. Most important is workflow state - usually it is simulation_state, which is cataloged by default. If you want to specify more variables (portal_type is often useful here), you have to add them to the workflow variables and make sure it is cataloged (portal_type is). You can give more then one value by separating them with semicolons.

For counting jobs, you can also use "Guard" parameters - for example, if you type "Assignor" in the "Role(s)" box, ERP5 will count only these objects for which you have Assignor role. This is very useful if the action you are supposed to perform is a workflow action, and requires a certain role - you don't want to list actions which you are not allowed to perform!

Display in favourites

The system counts pending items and gives you a "count" variable which you can use; the most common way to configure the "Name" attribute is:

Things you should attend to (%(count)s)

List your pending jobs

When you select the worklist from Favourites, you should get a list of items, and these should be the same items that the system counted. This is configured in the URL field. You can create your own form or script and put it here; however, in most cases it is enough to use in-built search feature of every ERP5 module. A module is able to search its contents by portal_type, simulation state and local roles, so if your worklists counts Foo documents in submitted state for which you are Assignor, you can do just:

foo_module/list?simulation_state=submitted&portal_type=Foo&local_roles=%(local_roles)s

This way of using local roles will only display documents that you have to take care of, where the search does gives all documents regardless of who those documents are assigned to.

Local roles will be drawn from your Guard settings; and if you want to specify more than one portal_type, you can go like:

foo_module/list?simulation_state=submitted&portal_type:list=Foo&portal_type:list=Bar

Beware of cache

Changes in the contents of modules are not immediately reflected in your worklist, because worklists are cached with a 300 seconds cache, which is not flushable in any other way. So be patient. If you are in development rush, you can comment it out in DCWorkflow patch, but this would seriously impair your system's performance. You have been warned.

HowToUseAndDefineWorkflows (last edited 2010-09-14 20:14:30 by KurtMiebach)