Dealing with Approval Process Returns with Ease: A Detailed Operational Guide
1. Retrieve Current Node Information
When implementing the return functionality, the first step is to obtain the current node information of the process instance. You can get the current node using the process instance ID:
TaskService taskService = processEngine.getTaskService();
Task currentTask = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
String currentTaskId = currentTask.getId();
2.1. Return to the Previous Node
If you need to return the process to the previous node, you can follow these steps:
Find the Previous Node
Get the information of the previous node of the current node:
public String getPreviousActivityId(HistoricActivityInstance currentActivity) {
List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(currentActivity.getProcessInstanceId())
.orderByHistoricActivityInstanceStartTime().asc()
.list();
HistoricActivityInstance previousActivity = null;
for (int i = 0; i < activities.size(); i++) {
if (activities.get(i).getId().equals(currentActivity.getId()) && i > 0) {
previousActivity = activities.get(i - 1);
break;
}
}
return previousActivity != null ? previousActivity.getActivityId() : null;
}
Delete the Current Node and Roll Back
Delete the current task node to roll back the process to the previous node:
RuntimeService runtimeService = processEngine.getRuntimeService();
runtimeService.createProcessInstanceModification(processInstanceId)
.cancelActivityInstance(currentActivity.getActivityInstanceId())
.startBeforeActivity(previousActivityId)
.execute();
2.2. Return to the Start Node
If you need to return the process to the start node, you can follow these steps:
Get the Start Node
Identify the start node in the process definition:
RepositoryService repositoryService = processEngine.getRepositoryService();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(currentTask.getProcessDefinitionId())
.singleResult();
String startActivityId = getStartActivityId(processDefinition);
Reset the Process Instance
Reset the process instance to the start node:
runtimeService.createProcessInstanceModification(processInstanceId)
.cancelAllForActivity(startActivityId)
.startBeforeActivity(startActivityId)
.execute();
3. Update Database Tables
After completing the process return operation, you need to update the relevant records in the database to ensure data consistency. Assuming we have created the following database tables:
- Process_Instances: Stores information about process instances
- Approval_Tasks: Stores information about approval tasks
- Approval_Logs: Stores logs of approval actions
Update the status in the process instances table:
UPDATE Process_Instances
SET Status = 'RETURNED', Updated_At = NOW()
WHERE Process_Instance_ID = ?;
Update the status of the relevant tasks in the approval tasks table:
UPDATE Approval_Tasks
SET Status = 'RETURNED', Completed_At = NOW()
WHERE Process_Instance_ID = ? AND Task_ID = ?;
Log the return action:
INSERT INTO Approval_Logs (Task_ID, Approver_ID, Action, Timestamp, Comments)
VALUES (?, ?, 'RETURNED', NOW(), 'Task has been returned');