2.6.1. Creating the Process model

The final version of process model will look like this:

ProcessFull

Let’s look at the sequence of steps to create the model.

Open the screen BPM → Process models in the running application web interface and press Create. Enter the model name Contract approval and press OK. A new browser tab Model editor will be opened.

Select the Process roles property in the model properties panel. The process roles edit window will be opened.

ProcessRolesProperty

There are 2 types of actors participate in the process: a manager and a controller. Create 2 roles: Controller and Manager.

ProcessRolesEditor

Drag and drop the Start event node from the Start Events group to the workspace. We need to display a form to select the process actors when the process starts. Select the start event node. Select the Start form in its properties panel - a form selection window will be opened. Select Standard form in the Form name field. Then add 2 form parameters:

  • procActorsVisible with true value indicates that a table for process actors selection will be displayed on the form
  • attachmentsVisible with true value indicates that a table for attachments upload will be displayed on the form
StartForm

Add the User task node from an Activities group to the model. Name it Validation.

ModelValidationNode

Select this node and assign the controller value to the Process role property at the properties panel. This is how we defined that the task will be assigned to a process actor with controller role.

SelectProcRoleForValidation

Next select the Task outcomes property. The window for task outcomes edit will be opened. Outcomes define possible users actions when users receive tasks. Create 2 outcomes: Valid and Not valid. Define the Standard form for both outcomes. Add form parameter commentRequired=true for the Not valid outcome, because we want to make a user add a comment in case of invalid contract.

OutcomesForValidation

Depending on the controller’s decision we have to send the contract to managers approval or to finish the process with the Not valid state. The Exclusive gateway node from the Gateways group is used to control the process flow. Add it to the workspace and then add 2 more elements: Script task with Set 'Not valid' state name and User task with Approval name. Name the flow to the Script task as Not valid and the flow to the User task should be named Valid.

ModelValidationExclGateway

Select the Not valid flow. Expand the dropdown list Flow outcome from the properties panel. It shows outcomes from the tasks before the gateway. Select the Not valid value.

NotValidFlowOutcome

Now, if the Not valid outcome is selected, a transition to this flow will be performed.

The Valid flow should be marked as the default flow (if no other flows condition are true). Select the Valid flow and tick the Default flow property.

Next select the Exclusive gateway and open its Flow order property editor. Make sure that the Not valid flow goes on the first place in a list. If it is not true then change the flows sequence.

ValidationFlowOrder

Let’s move to the Set 'Not valid' state node. We need to set the state property of the Contract entity to the Not valid value. Select the node. Set the Script format property value to groovy. Click on the Script property field - the script editor will be opened. Copy and paste the following code there:

import com.company.demo.entity.Contract

def em = persistence.getEntityManager()
def contract = em.find(Contract.class, entityId)
contract.setState('Not valid')

You are allowed to use the process variables and platform objects persistence and metadata (see CUBA Platform. Developer’s Manual) in scripts. An entityId variable is created on process start and stores an identifier of the linked entity.

After the contract state is changed, the process should be finished. Let’s add an End event node from the End events group to the workspace and link the node with the Set 'Not valid' state.

Let’s go back to the Approval task. Define the manager process role for it like we did for the first task. In order the task to be assigned to many managers simultaneously set its Multi-instance type property to Parallel.

ApprovalMutlInstanceType

Create 2 task outcomes: Approve and Reject (Task outcomes property). For both outcomes set the Standard form form and set commentRequired parameter to true for the Reject outcome.

After the approval is completed, or Approved either Not approved status should be assigned to the contract depending on the approval result. Add an Exclusive gateway node after the Approval task. Add 2 Service task after the exclusive gateway: Set 'Approved' state and Set 'Not approved' state. They will do the same thing as the Script task we added earlier, but in another way. They will invoke a Spring bean method. Name the flow to the Set 'Approved' state as Approved, and name the flow to the Set 'Not approved' state as Not approved.

ModelWithApproval

Select the Not approved flow node and select the Reject value in the Flow outcome list. Now if at least one of the managers performs the Reject action then this outcome will be initiated. Select the Approved flow node and check the Default flow checkbox. This means that if no other flow is initiated then this flow will be used.

Set the flow order for the Exclusive gateway like we did for the previous one. Select the Exclusive gateway and open the Flow order property editor. Not approved should be processed first.

ApprovalFlowOrder

Let’s go back to the Service task. Select the Set 'Approved' state node and set its Expression property to the following value:

${demo_ApprovalHelper.updateState(entityId, 'Approved')}

Apply the following script for the Set 'Not approved' state:

${demo_ApprovalHelper.updateState(entityId, 'Not approved')}

Activiti engine is integrated with the String framework, so we can access Spring managed beans by their names. entityId is a process variable that stores an identifier of the contract which is linked to the process. Its value is set on a process start.

Link both Service tasks with the End event and press the save model button. The model is ready and we can move to the model deployment.

ProcessFull