Sandip Nirmal
Sandip Nirmal

Reputation: 435

Activiti: Restart a process from particular step

I am using activiti 6 for designing business process for one of our project. The process is pretty straight forward, it consists of number of "User Taks" or "Service Task" with role based assignments. However our Client wants that an admin user should be able to rerun any of the previous "User Task" or "Service Task" at any point of time.

For example, following is my process :

Start –> Service-Task1 –>User-Task2 –>Service-Task3 –>User-Task4 –>Service-Task5 -> User-Task6 -> Service-Task7 -> User-Task8 ->End

Client want that at any point of time during a process execution, an admin user should be able to change workflow execution from : for example state "User-Task8" to any of Service-Task1 or User-Task2 or Service-Task3 or User-Task4 or Service-Task5 or User-Task6 or Service-Task7.

As per Alfresco Community thread : User Task Rollback

I have created a custom command as

public class RestartInstanceActivitiCommand implements Command<Void> { 
   private final String executionId;
   private final FlowElement flowElement;

   public RestartInstanceActivitiCommand(String executionId, FlowElement flowElement) {
      this.executionId = executionId;
      this.flowElement = flowElement;
   }

   public Void execute(CommandContext commandContext) {
      ExecutionEntity execution = commandContext.getExecutionEntityManager().findById(this.executionId); 
      execution.setCurrentFlowElement(flowElement); 
      return null;
   }
}

And executed it with :

BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
FlowElement flowElement = bpmnModel.getFlowElement("Service-Task1");
commandExecutor.execute(new RestartInstanceActivitiCommand(processInstanceId, flowElement));
runtimeService.trigger(processInstanceId);

With this the current task is set Service-Task1, but it is not getting executed automatically as a normal flow would do usually. Also I can see User-Task8 is also active and assigned to the user which I don't want becasue I want to cancel the current task and rerun it from the desired step.

Appreciate your help with a code sample.

Regards, Sandip

Upvotes: 1

Views: 2200

Answers (2)

Greg Harley
Greg Harley

Reputation: 3240

I wrote a simple command method that should achieve what you want to do. You can find the answer int eh following thread on the Alfresco forum:

https://community.alfresco.com/thread/224300-user-task-rollback

Upvotes: 2

J-Alex
J-Alex

Reputation: 7127

If the Return to Step A is a part of the workflow process, maybe it's better to include it in your workflow tree.

So the Review Filter is your validation step, after which you'll implement Exclusive Gateway.

Exclusive gateway will allow you to construct if-else like conditions in your workflow.

An exclusive gateway (also called the XOR gateway or more technical the exclusive data-based gateway), is used to model a decision in the process. When the execution arrives at this gateway, all outgoing sequence flow are evaluated in the order in which they are defined. The sequence flow which condition evaluates to true (or which doesn’t have a condition set, conceptually having a 'true' defined on the sequence flow) is selected for continuing the process.

enter image description here

And corresponding XML representation:

<exclusiveGateway id="exclusiveGw" name="Exclusive Gateway" />

<sequenceFlow id="flow2" sourceRef="exclusiveGw" targetRef="theTask1">
  <conditionExpression xsi:type="tFormalExpression">${input == 1}</conditionExpression>
</sequenceFlow>

<sequenceFlow id="flow3" sourceRef="exclusiveGw" targetRef="theTask2">
  <conditionExpression xsi:type="tFormalExpression">${input == 2}</conditionExpression>
</sequenceFlow>

<sequenceFlow id="flow4" sourceRef="exclusiveGw" targetRef="theTask3">
  <conditionExpression xsi:type="tFormalExpression">${input == 3}</conditionExpression>
</sequenceFlow>

In your case:

Start -> Service Task (Calls some python script for filtering) -> Review Filter -> Exclusive Gateway:

if approved -> Review Categories -> end

else GOTO: -> Service Task (Calls some python script for filtering)

You can pass conditional variable to Activiti process when completing a task as a key-value pairs (Map):

boolean approved = true;
variableMap.put("input", approved);
taskService.complete(task.getId(), variableMap);

Question about exclusive gateway that may be useful.

Upvotes: 1

Related Questions