45.2 Workflow configuration

LedgerSMB uses the concept of workflows to manage object life cycle. An invoice, for example, may be saved, posted or reversed. These are states in the life cycle of the invoice. Each state may have associated actions. E.g. in case of the invoice there may be a Post action when it’s saved or to E-mail it when it’s posted. Actions may cause the document to change state: if the Post action is executed on a saved invoice, its new state will be posted. E-mailing an invoice does not change its state: it remains posted. Instead, a new workflow is created which manages state of the e-mail.

\digraph

[scale=0.4]wf1 rankdir=LR; subgraph invoice graph [label=”Invoice”]; cluster = true; saved -¿ posted [label=”post”]; posted -¿ reversed [label=”reverse”]; ;

subgraph email graph [label=”email”]; cluster = true; created -¿ sent [label=”send”]; ;

posted -¿ created [label=”e-mail”]; posted -¿ posted [label=”e-mail”];

Figure 45.1: Workflow triggered from another workflow

Actions belonging to a state may (or may not) be available. This is determined by one or more conditions. Examples are “is the posting date of the transaction in a closed period” and “is the current user allowed to post transactions”. When the condition evaluates to false, the action is not available.

Workflows are configurable. Configurations list the following aspects:

  1. 1.

    A list of states

  2. 2.

    A list of allowable actions per state

  3. 3.

    A list of conditions per action

  4. 4.

    A mapping of actions to Perl code

  5. 5.

    A mapping of conditions to Perl code

With these ingredients, the software’s behavior can be changed. E.g. by adding a new state and action in the invoice, an extra reviewing pairs of eyes can be added to the posting process. By adding a condition on this action, it can be made required for invoices over 100.000 USD (but not for other invoices).

\digraph

[scale=0.4]wf2 rankdir=LR; subgraph invoice graph [label=”Invoice”]; cluster=true; saved -¿ posted [label=”post (¡100.000)”]; saved -¿ submitted [label=”submit (¿100.000)”]; submitted -¿ posted [label=”post”]; posted -¿ reversed [label=”reverse”]

Figure 45.2: Conditional workflow actions

By changing association of the save action with its code, the application will act differently when saving the invoice. Customizations may associate new behaviors with existing actions or create new ones entirely. The behavior does not need to be known by the application developers, as the association may point to code added to the local installation. This way, a remind action can be added to posted invoices, triggering a text (SMS) message to the customer.

Workflows are stored in the ./workflows/ directory. Each workflow consists of several files, prefixed with the name of the workflow (e.g. ar-ap. for ’AR/AP’ workflows):

ar-ap.actions.xml

(optional) names the list of available transitions in the workflow naming Perl code to be executed

ar-ap.conditions.xml

(optional) names the list of conditions to be used in the workflow naming Perl code to evaluate

ar-ap.persisters.xml

(optional) defines the Perl mechanism to load and store workflow instances

ar-ap.workflow.xml

(required) defines the life cycle by combining states with the actions and conditions listed in the respective configuration files. Each state lists the allowable actions with the conditions to enable the action and a resulting state.

Customized versions of workflow definition files must be stored in ./customized_workflows/11 1 See Section 17.4.1 on page 17.4.1 on how to configure these paths. Files stored in this directory will be used to override those in the standard location: the file./custom_workflows/ar-ap.workflow.xml will replace the built-in workflow from ./workflows/ar-ap.workflow.xml used for invoices and AR/AP transactions. No changes should be made directly to the standard files because of the risk that those files will be overwritten on upgrade – loosing the changes.

Next to the per-workflow files, there is a generic definition file for actions, conditions and persisters. Elements defined in these files can be used in all workflows; those elements defined in the per-workflow files can only be used in the specific workflow.

The engine driving workflow state management is the Workflow22 2 https://metacpan.org/pod/Workflow library. See its documentation on MetaCPAN as well as the built-in workflows as examples of how to define one’s own.

45.2.1 Workflow observers

Particularly interesting is the concept of observers: this functionality allows the application to be extended based a specific action occurring without changing the life cycle. An example could be to create a PayPal payment request when an invoice is posted: an observer could be “listening” to “AR/AP” workflow events which at some point will flag the state of the invoice becoming posted.

Notes on Quote, Order, AR, AP and GL workflow customization

The actions in the workflows order-quote, ar-ap and gl are hard coded33 3 This is not a permanent situation, but rather a consequence of these workflows being used in old code . This means that the list of actions is restricted to those defined in the files order-quote.actions.xml, ar-ap.actions.xml and gl.actions.xml. It’s not necessary to use all actions in the workflow, but additional ones cannot be created – contrary to what is in the Workflow documentation.

The class attribute for most actions in these workflows is set to the value LedgerSMB::Workflow::Action::Null. This means it does nothing. Rather, it doesn’t do anything in addition to what the action already does in its hard coded implementation. Setting the action’s class attribute to some other value allows the developer to add behavior on top of what’s hard coded.