Hello everyone,
I’ve created a workflow based on our business requirements. In this workflow, we have different scenarios for the approval process. Let’s consider two examples:
Example 1:
- Reviewer 1 (approved)
- Reviewer 2 (approved)
- Reviewer 3 (approved)
- Reviewer 4 (rejected)
In this case, if Reviewer 4 rejects the request, I can retrieve the 2nd latest user task (HistoricActivityInstance) from the historyService and update the process variable to “false,” which will cause the workflow to revert to the previous user task (i.e., Reviewer 3).
When sorting the HistoricActivityInstances based on their start time (orderByHistoricActivityInstanceStartTime), the list looks like this:
- HistoricActivityInstance of Reviewer 4
- HistoricActivityInstance of Reviewer 3
- HistoricActivityInstance of Reviewer 2
- HistoricActivityInstance of Reviewer 1
However, I’m facing a challenge in the following scenario:
Example 2:
- Reviewer 1 (approved)
- Reviewer 2 (approved)
- Reviewer 3 (approved)
- Reviewer 4 (rejected) (So workflow goes to Reviewer 3)
- Reviewer 3 (rejected) (Reviewer 3 also rejected so workflow should go to Reviewer 2)
In this case, the previous user task should be Reviewer 2. But the HistoricActivityInstances are ordered differently when I sort using orderByHistoricActivityInstanceStartTime(). Below is the list I received from historyService
- HistoricActivityInstance of Reviewer 3
- HistoricActivityInstance of Reviewer 4
- HistoricActivityInstance of Reviewer 3
- HistoricActivityInstance of Reviewer 2
- HistoricActivityInstance of Reviewer 1
My question is, how can I reliably retrieve the parent or previous user task (in this case, always Reviewer 2 for Reviewer 3 and Reviewer 3 for Reviewer 4) without depending on the order of activities in HistoricActivityInstance, as the history order can be dynamic based on user actions? It’s also important to consider that the configuration of reviewers can be customized in a DMN file, and if a reviewer is not required (set to “false” in the DMN file), the flow should skip that reviewer. If Reviewer 3 is not required then then flow will be Reviewer 1 → Reviewer 2 → Reviewer 4
My Java code:
```
List<HistoricActivityInstance> userTasks = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.activityType("userTask")
.orderByHistoricActivityInstanceStartTime()
.desc()
.list();
// Update the variable to false
userTasks.stream()
.skip(1)
.findFirst()
.ifPresent(secondLatestUserTask -> {
String activityId = secondLatestUserTask.getActivityId();
String variableName = getVariableNameFromActivityId(activityId);
runtimeService.setVariable(processInstanceId, variableName, false);
});

Thank you in advance