diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskTransferrer.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskTransferrer.java index 7d84254a2..8249518e1 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskTransferrer.java +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskTransferrer.java @@ -1,5 +1,7 @@ package pro.taskana.task.internal; +import static java.util.Map.entry; + import java.time.Instant; import java.util.ArrayList; import java.util.Collections; @@ -244,26 +246,35 @@ final class TaskTransferrer { List taskSummaries, WorkbasketSummary destinationWorkbasket, boolean setTransferFlag) { - if (!taskSummaries.isEmpty()) { - TaskImpl updateObject = new TaskImpl(); - applyTransferValuesForTask(updateObject, destinationWorkbasket, setTransferFlag); - taskMapper.updateTransfered( - taskSummaries.stream().map(TaskSummary::getId).collect(Collectors.toSet()), updateObject); + Map> summariesByState = groupTasksByState(taskSummaries); + for (Map.Entry> entry : summariesByState.entrySet()) { + TaskState goalState = entry.getKey(); + List taskSummariesWithSameGoalState = entry.getValue(); + if (!taskSummariesWithSameGoalState.isEmpty()) { + TaskImpl updateObject = new TaskImpl(); + updateObject.setState(goalState); + applyTransferValuesForTask(updateObject, destinationWorkbasket, setTransferFlag); + taskMapper.updateTransfered( + taskSummariesWithSameGoalState.stream() + .map(TaskSummary::getId) + .collect(Collectors.toSet()), + updateObject); - if (historyEventManager.isEnabled()) { - taskSummaries.forEach( - oldSummary -> { - TaskSummaryImpl newSummary = (TaskSummaryImpl) oldSummary.copy(); - newSummary.setId(oldSummary.getId()); - newSummary.setExternalId(oldSummary.getExternalId()); - applyTransferValuesForTask(newSummary, destinationWorkbasket, setTransferFlag); + if (historyEventManager.isEnabled()) { + taskSummaries.forEach( + oldSummary -> { + TaskSummaryImpl newSummary = (TaskSummaryImpl) oldSummary.copy(); + newSummary.setId(oldSummary.getId()); + newSummary.setExternalId(oldSummary.getExternalId()); + applyTransferValuesForTask(newSummary, destinationWorkbasket, setTransferFlag); - createTransferredEvent( - oldSummary, - newSummary, - oldSummary.getWorkbasketSummary().getId(), - newSummary.getWorkbasketSummary().getId()); - }); + createTransferredEvent( + oldSummary, + newSummary, + oldSummary.getWorkbasketSummary().getId(), + newSummary.getWorkbasketSummary().getId()); + }); + } } } } @@ -272,7 +283,7 @@ final class TaskTransferrer { TaskSummaryImpl task, WorkbasketSummary workbasket, boolean setTransferFlag) { task.setRead(false); task.setTransferred(setTransferFlag); - task.setState(TaskState.READY); + task.setState(getStateAfterTransfer(task)); task.setOwner(null); task.setWorkbasketSummary(workbasket); task.setDomain(workbasket.getDomain()); @@ -294,4 +305,28 @@ final class TaskTransferrer { taskanaEngine.getEngine().getCurrentUserContext().getUserid(), details)); } + + private TaskState getStateAfterTransfer(TaskSummary taskSummary) { + TaskState stateBeforeTransfer = taskSummary.getState(); + if (stateBeforeTransfer.equals(TaskState.CLAIMED)) { + return TaskState.READY; + } + if (stateBeforeTransfer.equals(TaskState.IN_REVIEW)) { + return TaskState.READY_FOR_REVIEW; + } else { + return stateBeforeTransfer; + } + } + + private Map> groupTasksByState(List taskSummaries) { + Map> result = + Map.ofEntries( + entry((TaskState.READY), new ArrayList<>()), + entry((TaskState.READY_FOR_REVIEW), new ArrayList<>())); + for (TaskSummary taskSummary : taskSummaries) { + List relevantSummaries = result.get(getStateAfterTransfer(taskSummary)); + relevantSummaries.add(taskSummary); + } + return result; + } } diff --git a/lib/taskana-core/src/test/java/acceptance/task/transfer/TransferTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/transfer/TransferTaskAccTest.java index e50d53bcf..559b28ee5 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/transfer/TransferTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/transfer/TransferTaskAccTest.java @@ -10,15 +10,20 @@ import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.stream.Stream; import org.assertj.core.api.ThrowableAssert.ThrowingCallable; +import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.function.ThrowingConsumer; import pro.taskana.common.api.BulkOperationResults; import pro.taskana.common.api.exceptions.InvalidArgumentException; import pro.taskana.common.api.exceptions.NotAuthorizedException; import pro.taskana.common.api.exceptions.TaskanaException; +import pro.taskana.common.internal.util.Pair; import pro.taskana.common.test.security.JaasExtension; import pro.taskana.common.test.security.WithAccessId; import pro.taskana.task.api.TaskState; @@ -51,6 +56,51 @@ class TransferTaskAccTest extends AbstractAccTest { assertThat(transferredTask.getState()).isEqualTo(TaskState.READY); } + @WithAccessId(user = "admin") + @TestFactory + Stream should_SetStateCorrectly_When_TransferringSingleTask() { + List> testCases = + List.of( + Pair.of("TKI:100000000000000000000000000000000025", TaskState.READY_FOR_REVIEW), + Pair.of("TKI:000000000000000000000000000000000025", TaskState.READY), + Pair.of("TKI:200000000000000000000000000000000025", TaskState.READY_FOR_REVIEW), + Pair.of("TKI:000000000000000000000000000000000026", TaskState.READY)); + + ThrowingConsumer> test = + p -> { + String taskId = p.getLeft(); + TaskState expectedState = p.getRight(); + taskService.transfer(taskId, "WBI:100000000000000000000000000000000006"); + Task result = taskService.getTask(taskId); + assertThat(result.getState()).isEqualTo(expectedState); + taskService.transfer(taskId, "WBI:100000000000000000000000000000000007"); + }; + + return DynamicTest.stream( + testCases.iterator(), p -> "Expected state: " + p.getRight().name(), test); + } + + @WithAccessId(user = "admin") + @Test + void should_SetStateCorrectly_When_BulkTranferringTasks() throws Exception { + String readyForReview = "TKI:100000000000000000000000000000000025"; + String ready = "TKI:000000000000000000000000000000000025"; + String inReview = "TKI:200000000000000000000000000000000025"; + String claimed = "TKI:000000000000000000000000000000000026"; + List taskIds = List.of(readyForReview, ready, inReview, claimed); + + BulkOperationResults results = + taskService.transferTasks("WBI:100000000000000000000000000000000006", taskIds); + + assertThat(results.containsErrors()).isFalse(); + assertThat(taskService.getTask(readyForReview).getState()) + .isEqualTo(taskService.getTask(inReview).getState()) + .isEqualTo(TaskState.READY_FOR_REVIEW); + assertThat(taskService.getTask(ready).getState()) + .isEqualTo(taskService.getTask(claimed).getState()) + .isEqualTo(TaskState.READY); + } + @WithAccessId(user = "admin") @WithAccessId(user = "taskadmin") @TestTemplate