Merge 421a607ead
into e1a273a236
This commit is contained in:
commit
8b69d8076f
|
@ -37,6 +37,12 @@
|
|||
</dependency>
|
||||
|
||||
<!-- test dependencies -->
|
||||
<dependency>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-test-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-common-data</artifactId>
|
||||
|
|
|
@ -0,0 +1,244 @@
|
|||
package acceptance.events.task;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import acceptance.events.task.CreateHistoryEventOnTaskRerouteAccTest.TaskRoutingProviderForDomainA;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.session.SqlSessionManager;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import pro.taskana.classification.api.ClassificationService;
|
||||
import pro.taskana.classification.api.models.ClassificationSummary;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.test.security.JaasExtension;
|
||||
import pro.taskana.common.test.security.WithAccessId;
|
||||
import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
|
||||
import pro.taskana.simplehistory.impl.TaskHistoryQueryImpl;
|
||||
import pro.taskana.simplehistory.impl.TaskanaHistoryEngineImpl;
|
||||
import pro.taskana.simplehistory.impl.task.TaskHistoryQueryMapper;
|
||||
import pro.taskana.spi.history.api.TaskanaHistory;
|
||||
import pro.taskana.spi.history.api.events.task.TaskHistoryEvent;
|
||||
import pro.taskana.spi.history.api.events.task.TaskHistoryEventType;
|
||||
import pro.taskana.spi.routing.api.TaskRoutingProvider;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.task.api.models.Task;
|
||||
import pro.taskana.testapi.DefaultTestEntities;
|
||||
import pro.taskana.testapi.TaskanaInject;
|
||||
import pro.taskana.testapi.TaskanaIntegrationTest;
|
||||
import pro.taskana.testapi.WithServiceProvider;
|
||||
import pro.taskana.testapi.builder.TaskBuilder;
|
||||
import pro.taskana.testapi.builder.WorkbasketAccessItemBuilder;
|
||||
import pro.taskana.workbasket.api.WorkbasketPermission;
|
||||
import pro.taskana.workbasket.api.WorkbasketService;
|
||||
import pro.taskana.workbasket.api.models.Workbasket;
|
||||
import pro.taskana.workbasket.api.models.WorkbasketSummary;
|
||||
|
||||
@WithServiceProvider(
|
||||
serviceProviderInterface = TaskRoutingProvider.class,
|
||||
serviceProviders = TaskRoutingProviderForDomainA.class)
|
||||
@WithServiceProvider(
|
||||
serviceProviderInterface = TaskanaHistory.class,
|
||||
serviceProviders = SimpleHistoryServiceImpl.class)
|
||||
@TaskanaIntegrationTest
|
||||
@ExtendWith(JaasExtension.class)
|
||||
class CreateHistoryEventOnTaskRerouteAccTest {
|
||||
@TaskanaInject TaskanaEngine taskanaEngine;
|
||||
@TaskanaInject TaskService taskService;
|
||||
@TaskanaInject WorkbasketService workbasketService;
|
||||
@TaskanaInject ClassificationService classificationService;
|
||||
|
||||
ClassificationSummary classificationSummary;
|
||||
WorkbasketSummary domainAWorkbasketSummary;
|
||||
WorkbasketSummary domainBWorkbasketSummary;
|
||||
Task task1;
|
||||
Task task2;
|
||||
Task task3;
|
||||
Task task4;
|
||||
SimpleHistoryServiceImpl historyService;
|
||||
TaskanaHistoryEngineImpl taskanaHistoryEngine;
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@BeforeAll
|
||||
void setup() throws Exception {
|
||||
historyService = new SimpleHistoryServiceImpl();
|
||||
taskanaHistoryEngine = TaskanaHistoryEngineImpl.createTaskanaEngine(taskanaEngine);
|
||||
historyService.initialize(taskanaEngine);
|
||||
classificationSummary =
|
||||
DefaultTestEntities.defaultTestClassification()
|
||||
.buildAndStoreAsSummary(classificationService);
|
||||
domainAWorkbasketSummary =
|
||||
DefaultTestEntities.defaultTestWorkbasket()
|
||||
.domain("DOMAIN_A")
|
||||
.buildAndStoreAsSummary(workbasketService);
|
||||
domainBWorkbasketSummary =
|
||||
DefaultTestEntities.defaultTestWorkbasket()
|
||||
.domain("DOMAIN_B")
|
||||
.buildAndStoreAsSummary(workbasketService);
|
||||
|
||||
task1 =
|
||||
TaskBuilder.newTask()
|
||||
.classificationSummary(classificationSummary)
|
||||
.workbasketSummary(domainAWorkbasketSummary)
|
||||
.primaryObjRef(DefaultTestEntities.defaultTestObjectReference().build())
|
||||
.buildAndStore(taskService);
|
||||
task2 =
|
||||
TaskBuilder.newTask()
|
||||
.classificationSummary(classificationSummary)
|
||||
.workbasketSummary(domainAWorkbasketSummary)
|
||||
.primaryObjRef(DefaultTestEntities.defaultTestObjectReference().build())
|
||||
.buildAndStore(taskService);
|
||||
task3 =
|
||||
TaskBuilder.newTask()
|
||||
.classificationSummary(classificationSummary)
|
||||
.workbasketSummary(domainBWorkbasketSummary)
|
||||
.primaryObjRef(DefaultTestEntities.defaultTestObjectReference().build())
|
||||
.buildAndStore(taskService);
|
||||
|
||||
task4 =
|
||||
TaskBuilder.newTask()
|
||||
.classificationSummary(classificationSummary)
|
||||
.workbasketSummary(domainAWorkbasketSummary)
|
||||
.primaryObjRef(DefaultTestEntities.defaultTestObjectReference().build())
|
||||
.buildAndStore(taskService);
|
||||
|
||||
WorkbasketAccessItemBuilder.newWorkbasketAccessItem()
|
||||
.workbasketId(domainAWorkbasketSummary.getId())
|
||||
.accessId("user-1-1")
|
||||
.permission(WorkbasketPermission.OPEN)
|
||||
.permission(WorkbasketPermission.READ)
|
||||
.permission(WorkbasketPermission.APPEND)
|
||||
.buildAndStore(workbasketService);
|
||||
|
||||
WorkbasketAccessItemBuilder.newWorkbasketAccessItem()
|
||||
.workbasketId(domainBWorkbasketSummary.getId())
|
||||
.accessId("user-1-1")
|
||||
.permission(WorkbasketPermission.OPEN)
|
||||
.permission(WorkbasketPermission.READ)
|
||||
.permission(WorkbasketPermission.APPEND)
|
||||
.buildAndStore(workbasketService);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@Test
|
||||
void should_CreateRerouteHistoryEvent_When_TaskIsRerouted() throws Exception {
|
||||
historyService.deleteHistoryEventsByTaskIds(List.of(task4.getId()));
|
||||
TaskHistoryQueryMapper taskHistoryQueryMapper = getHistoryQueryMapper();
|
||||
taskService.rerouteTask(task4.getId());
|
||||
|
||||
List<TaskHistoryEvent> events =
|
||||
taskHistoryQueryMapper.queryHistoryEvents(
|
||||
(TaskHistoryQueryImpl) historyService.createTaskHistoryQuery().taskIdIn(task4.getId()));
|
||||
|
||||
assertThat(events).hasSize(1);
|
||||
String eventType = events.get(0).getEventType();
|
||||
assertThat(eventType).isEqualTo(TaskHistoryEventType.REROUTED.getName());
|
||||
assertRerouteHistoryEvent(
|
||||
events.get(0).getId(),
|
||||
domainAWorkbasketSummary.getId(),
|
||||
domainBWorkbasketSummary.getId(),
|
||||
"admin");
|
||||
|
||||
historyService.deleteHistoryEventsByTaskIds(List.of(task4.getId()));
|
||||
}
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@Test
|
||||
void should_CreateRerouteHistoryEvent_When_MultipleTasksAreRerouted() throws Exception {
|
||||
List<String> taskIds = List.of(task1.getId(), task2.getId(), task3.getId());
|
||||
historyService.deleteHistoryEventsByTaskIds(taskIds);
|
||||
TaskHistoryQueryMapper taskHistoryQueryMapper = getHistoryQueryMapper();
|
||||
taskService.rerouteTasks(taskIds);
|
||||
|
||||
List<TaskHistoryEvent> events =
|
||||
taskHistoryQueryMapper.queryHistoryEvents(
|
||||
(TaskHistoryQueryImpl)
|
||||
historyService.createTaskHistoryQuery().taskIdIn(taskIds.toArray(new String[0])));
|
||||
|
||||
assertThat(events)
|
||||
.extracting(TaskHistoryEvent::getTaskId)
|
||||
.containsExactlyInAnyOrderElementsOf(taskIds);
|
||||
|
||||
for (TaskHistoryEvent event : events) {
|
||||
if (event.getTaskId().equals(task1.getId())) {
|
||||
assertRerouteHistoryEvent(
|
||||
event.getId(),
|
||||
domainAWorkbasketSummary.getId(),
|
||||
domainBWorkbasketSummary.getId(),
|
||||
"admin");
|
||||
} else if (event.getTaskId().equals(task2.getId())) {
|
||||
assertRerouteHistoryEvent(
|
||||
event.getId(),
|
||||
domainAWorkbasketSummary.getId(),
|
||||
domainBWorkbasketSummary.getId(),
|
||||
"admin");
|
||||
} else {
|
||||
assertRerouteHistoryEvent(
|
||||
event.getId(),
|
||||
domainBWorkbasketSummary.getId(),
|
||||
domainAWorkbasketSummary.getId(),
|
||||
"admin");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TaskHistoryQueryMapper getHistoryQueryMapper()
|
||||
throws NoSuchFieldException, IllegalAccessException {
|
||||
Field sessionManagerField = TaskanaHistoryEngineImpl.class.getDeclaredField("sessionManager");
|
||||
sessionManagerField.setAccessible(true);
|
||||
SqlSessionManager sqlSessionManager =
|
||||
(SqlSessionManager) sessionManagerField.get(taskanaHistoryEngine);
|
||||
|
||||
return sqlSessionManager.getMapper(TaskHistoryQueryMapper.class);
|
||||
}
|
||||
|
||||
private void assertRerouteHistoryEvent(
|
||||
String eventId, String expectedOldValue, String expectedNewValue, String expectedUser)
|
||||
throws Exception {
|
||||
TaskHistoryEvent event = historyService.getTaskHistoryEvent(eventId);
|
||||
assertThat(event.getDetails()).isNotNull();
|
||||
JSONArray changes = new JSONObject(event.getDetails()).getJSONArray("changes");
|
||||
assertThat(changes.length()).isPositive();
|
||||
boolean foundField = false;
|
||||
for (int i = 0; i < changes.length() && !foundField; i++) {
|
||||
JSONObject change = changes.getJSONObject(i);
|
||||
if (change.get("fieldName").equals("workbasketSummary")) {
|
||||
foundField = true;
|
||||
String oldWorkbasketStr = change.get("oldValue").toString();
|
||||
String newWorkbasketStr = change.get("newValue").toString();
|
||||
Workbasket oldWorkbasket = workbasketService.getWorkbasket(expectedOldValue);
|
||||
assertThat(oldWorkbasketStr)
|
||||
.isEqualTo(JSONObject.wrap(oldWorkbasket.asSummary()).toString());
|
||||
Workbasket newWorkbasket = workbasketService.getWorkbasket(expectedNewValue);
|
||||
assertThat(newWorkbasketStr)
|
||||
.isEqualTo(JSONObject.wrap(newWorkbasket.asSummary()).toString());
|
||||
}
|
||||
}
|
||||
assertThat(foundField).describedAs("changes do not contain field 'workbasketSummary'").isTrue();
|
||||
|
||||
assertThat(event.getId()).startsWith("THI:");
|
||||
assertThat(event.getOldValue()).isEqualTo(expectedOldValue);
|
||||
assertThat(event.getNewValue()).isEqualTo(expectedNewValue);
|
||||
assertThat(event.getUserId()).isEqualTo(expectedUser);
|
||||
assertThat(event.getEventType()).isEqualTo(TaskHistoryEventType.REROUTED.getName());
|
||||
}
|
||||
|
||||
class TaskRoutingProviderForDomainA implements TaskRoutingProvider {
|
||||
|
||||
@Override
|
||||
public void initialize(TaskanaEngine taskanaEngine) {}
|
||||
|
||||
@Override
|
||||
public String determineWorkbasketId(Task task) {
|
||||
if ("DOMAIN_A".equals(task.getDomain())) {
|
||||
return domainBWorkbasketSummary.getId();
|
||||
} else if ("DOMAIN_B".equals(task.getDomain())) {
|
||||
return domainAWorkbasketSummary.getId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,368 @@
|
|||
package acceptance.taskrouting;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowableOfType;
|
||||
import static pro.taskana.testapi.DefaultTestEntities.defaultTestClassification;
|
||||
import static pro.taskana.testapi.DefaultTestEntities.defaultTestObjectReference;
|
||||
import static pro.taskana.testapi.DefaultTestEntities.defaultTestWorkbasket;
|
||||
|
||||
import acceptance.taskrouting.TaskReroutingAccTest.CustomTaskRoutingProvider;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import pro.taskana.classification.api.ClassificationService;
|
||||
import pro.taskana.classification.api.models.ClassificationSummary;
|
||||
import pro.taskana.common.api.BulkOperationResults;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.api.exceptions.TaskanaException;
|
||||
import pro.taskana.spi.routing.api.TaskRoutingProvider;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.task.api.TaskState;
|
||||
import pro.taskana.task.api.exceptions.InvalidTaskStateException;
|
||||
import pro.taskana.task.api.exceptions.TaskNotFoundException;
|
||||
import pro.taskana.task.api.models.ObjectReference;
|
||||
import pro.taskana.task.api.models.Task;
|
||||
import pro.taskana.task.api.models.TaskSummary;
|
||||
import pro.taskana.testapi.TaskanaInject;
|
||||
import pro.taskana.testapi.TaskanaIntegrationTest;
|
||||
import pro.taskana.testapi.WithServiceProvider;
|
||||
import pro.taskana.testapi.builder.ObjectReferenceBuilder;
|
||||
import pro.taskana.testapi.builder.TaskBuilder;
|
||||
import pro.taskana.testapi.builder.WorkbasketAccessItemBuilder;
|
||||
import pro.taskana.testapi.security.WithAccessId;
|
||||
import pro.taskana.workbasket.api.WorkbasketPermission;
|
||||
import pro.taskana.workbasket.api.WorkbasketService;
|
||||
import pro.taskana.workbasket.api.exceptions.NotAuthorizedOnWorkbasketException;
|
||||
import pro.taskana.workbasket.api.models.WorkbasketSummary;
|
||||
|
||||
@WithServiceProvider(
|
||||
serviceProviderInterface = TaskRoutingProvider.class,
|
||||
serviceProviders = CustomTaskRoutingProvider.class)
|
||||
@TaskanaIntegrationTest
|
||||
class TaskReroutingAccTest {
|
||||
|
||||
@TaskanaInject TaskService taskService;
|
||||
@TaskanaInject ClassificationService classificationService;
|
||||
@TaskanaInject WorkbasketService workbasketService;
|
||||
|
||||
ClassificationSummary defaultClassificationSummary;
|
||||
WorkbasketSummary defaultWorkbasketSummary;
|
||||
WorkbasketSummary workbasketSummary1;
|
||||
WorkbasketSummary workbasketSummary2;
|
||||
WorkbasketSummary workbasketSummary3;
|
||||
ObjectReference defaultObjectReference;
|
||||
|
||||
@WithAccessId(user = "businessadmin")
|
||||
@BeforeAll
|
||||
void setup() throws Exception {
|
||||
defaultClassificationSummary =
|
||||
defaultTestClassification().buildAndStoreAsSummary(classificationService);
|
||||
defaultWorkbasketSummary = defaultTestWorkbasket().buildAndStoreAsSummary(workbasketService);
|
||||
workbasketSummary1 =
|
||||
defaultTestWorkbasket().key("key_1").buildAndStoreAsSummary(workbasketService);
|
||||
workbasketSummary2 =
|
||||
defaultTestWorkbasket().key("key_2").buildAndStoreAsSummary(workbasketService);
|
||||
workbasketSummary3 =
|
||||
defaultTestWorkbasket().key("key_3").buildAndStoreAsSummary(workbasketService);
|
||||
defaultObjectReference = defaultTestObjectReference().build();
|
||||
|
||||
WorkbasketAccessItemBuilder.newWorkbasketAccessItem()
|
||||
.workbasketId(defaultWorkbasketSummary.getId())
|
||||
.accessId("user-1-2")
|
||||
.permission(WorkbasketPermission.OPEN)
|
||||
.permission(WorkbasketPermission.READ)
|
||||
.permission(WorkbasketPermission.READTASKS)
|
||||
.permission(WorkbasketPermission.EDITTASKS)
|
||||
.permission(WorkbasketPermission.APPEND)
|
||||
.permission(WorkbasketPermission.TRANSFER)
|
||||
.buildAndStore(workbasketService);
|
||||
|
||||
WorkbasketAccessItemBuilder.newWorkbasketAccessItem()
|
||||
.workbasketId(workbasketSummary1.getId())
|
||||
.accessId("user-1-2")
|
||||
.permission(WorkbasketPermission.OPEN)
|
||||
.permission(WorkbasketPermission.READ)
|
||||
.permission(WorkbasketPermission.READTASKS)
|
||||
.permission(WorkbasketPermission.EDITTASKS)
|
||||
.permission(WorkbasketPermission.APPEND)
|
||||
.buildAndStore(workbasketService);
|
||||
|
||||
WorkbasketAccessItemBuilder.newWorkbasketAccessItem()
|
||||
.workbasketId(workbasketSummary2.getId())
|
||||
.accessId("user-1-2")
|
||||
.permission(WorkbasketPermission.OPEN)
|
||||
.permission(WorkbasketPermission.READ)
|
||||
.permission(WorkbasketPermission.READTASKS)
|
||||
.permission(WorkbasketPermission.EDITTASKS)
|
||||
.buildAndStore(workbasketService);
|
||||
|
||||
WorkbasketAccessItemBuilder.newWorkbasketAccessItem()
|
||||
.workbasketId(workbasketSummary3.getId())
|
||||
.accessId("user-1-2")
|
||||
.permission(WorkbasketPermission.OPEN)
|
||||
.permission(WorkbasketPermission.READ)
|
||||
.permission(WorkbasketPermission.READTASKS)
|
||||
.permission(WorkbasketPermission.EDITTASKS)
|
||||
.permission(WorkbasketPermission.APPEND)
|
||||
.buildAndStore(workbasketService);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "taskadmin")
|
||||
@Test
|
||||
void should_RerouteTask_When_PorValueIsChanged() throws Exception {
|
||||
Task task = createDefaultTask().buildAndStore(taskService, "admin");
|
||||
Instant before = Instant.now().truncatedTo(ChronoUnit.MILLIS);
|
||||
|
||||
task.setPrimaryObjRef(createObjectReference("company", null, null, "MyType1", "Value1"));
|
||||
taskService.updateTask(task);
|
||||
Task reroutedTask = taskService.rerouteTask(task.getId());
|
||||
|
||||
assertTaskIsRerouted(before, reroutedTask.asSummary(), task.getState(), workbasketSummary1);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-2")
|
||||
@Test
|
||||
void should_NotRerouteTask_When_UserHasNoAppendPermissionToDestinationWb() throws Exception {
|
||||
Task task = createDefaultTask().buildAndStore(taskService, "admin");
|
||||
|
||||
task.setPrimaryObjRef(createObjectReference("company", null, null, "MyType1", "Value2"));
|
||||
taskService.updateTask(task);
|
||||
|
||||
ThrowingCallable call = () -> taskService.rerouteTask(task.getId());
|
||||
NotAuthorizedOnWorkbasketException e =
|
||||
catchThrowableOfType(call, NotAuthorizedOnWorkbasketException.class);
|
||||
|
||||
assertThat(e.getWorkbasketId()).isEqualTo(workbasketSummary2.getId());
|
||||
assertThat(e.getCurrentUserId()).isEqualTo("user-1-2");
|
||||
assertThat(e.getRequiredPermissions()).containsExactlyInAnyOrder(WorkbasketPermission.APPEND);
|
||||
|
||||
Task readTask = taskService.getTask(task.getId());
|
||||
assertThat(readTask.getWorkbasketSummary().getId())
|
||||
.isEqualTo(task.getWorkbasketSummary().getId());
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-2")
|
||||
@Test
|
||||
void should_NotRerouteTask_When_UserHasNoTransferPermissionToOriginWb() throws Exception {
|
||||
Task task =
|
||||
createDefaultTask()
|
||||
.workbasketSummary(workbasketSummary1)
|
||||
.buildAndStore(taskService, "admin");
|
||||
|
||||
task.setPrimaryObjRef(createObjectReference("company", null, null, "MyType1", "Value2"));
|
||||
taskService.updateTask(task);
|
||||
|
||||
ThrowingCallable call = () -> taskService.rerouteTask(task.getId());
|
||||
NotAuthorizedOnWorkbasketException e =
|
||||
catchThrowableOfType(call, NotAuthorizedOnWorkbasketException.class);
|
||||
|
||||
assertThat(e.getWorkbasketId()).isEqualTo(workbasketSummary1.getId());
|
||||
assertThat(e.getCurrentUserId()).isEqualTo("user-1-2");
|
||||
assertThat(e.getRequiredPermissions()).containsExactlyInAnyOrder(WorkbasketPermission.TRANSFER);
|
||||
|
||||
Task readTask = taskService.getTask(task.getId());
|
||||
assertThat(readTask.getWorkbasketSummary().getId())
|
||||
.isEqualTo(task.getWorkbasketSummary().getId());
|
||||
}
|
||||
|
||||
@WithAccessId(user = "taskadmin")
|
||||
@Test
|
||||
void should_RerouteTasksToSameWb_When_PorValueIsChanged() throws Exception {
|
||||
Task task1 = createDefaultTask().buildAndStore(taskService, "admin");
|
||||
Task task2 = createDefaultTask().buildAndStore(taskService, "admin");
|
||||
Task task3 = createDefaultTask().buildAndStore(taskService, "admin");
|
||||
List<Task> tasks = Arrays.asList(task1, task2, task3);
|
||||
Instant before = Instant.now().truncatedTo(ChronoUnit.MILLIS);
|
||||
|
||||
for (Task task : tasks) {
|
||||
task.setPrimaryObjRef(createObjectReference("company", null, null, "MyType1", "Value1"));
|
||||
taskService.updateTask(task);
|
||||
}
|
||||
List<String> taskIds = tasks.stream().map(Task::getId).collect(Collectors.toList());
|
||||
|
||||
BulkOperationResults<String, TaskanaException> results = taskService.rerouteTasks(taskIds);
|
||||
assertThat(results.containsErrors()).isFalse();
|
||||
List<TaskSummary> reroutedTasks =
|
||||
taskService.createTaskQuery().idIn(taskIds.toArray(new String[0])).list();
|
||||
assertThat(reroutedTasks).isNotEmpty();
|
||||
for (int i = 0; i < reroutedTasks.size(); i++) {
|
||||
assertTaskIsRerouted(
|
||||
before, reroutedTasks.get(i), tasks.get(i).getState(), workbasketSummary1);
|
||||
}
|
||||
}
|
||||
|
||||
@WithAccessId(user = "taskadmin")
|
||||
@Test
|
||||
void should_RerouteTasksToMultipleWorkbaskets_When_PorValueIsChanged() throws Exception {
|
||||
final Task task1 = createDefaultTask().buildAndStore(taskService, "admin");
|
||||
final Task task2 = createDefaultTask().buildAndStore(taskService, "admin");
|
||||
final Task task3 = createDefaultTask().buildAndStore(taskService, "admin");
|
||||
Instant before = Instant.now().truncatedTo(ChronoUnit.MILLIS);
|
||||
|
||||
task1.setPrimaryObjRef(createObjectReference("company", null, null, "MyType1", "Value1"));
|
||||
taskService.updateTask(task1);
|
||||
task2.setPrimaryObjRef(createObjectReference("company", null, null, "MyType1", "Value2"));
|
||||
taskService.updateTask(task2);
|
||||
task3.setPrimaryObjRef(createObjectReference("company", null, null, "MyType1", "Value3"));
|
||||
taskService.updateTask(task3);
|
||||
List<Task> tasks = Arrays.asList(task1, task2, task3);
|
||||
List<String> taskIds = tasks.stream().map(Task::getId).collect(Collectors.toList());
|
||||
|
||||
BulkOperationResults<String, TaskanaException> results = taskService.rerouteTasks(taskIds);
|
||||
assertThat(results.containsErrors()).isFalse();
|
||||
List<TaskSummary> reroutedTasks =
|
||||
taskService.createTaskQuery().idIn(taskIds.toArray(new String[0])).list();
|
||||
assertThat(reroutedTasks).isNotEmpty();
|
||||
for (TaskSummary reroutedTask : reroutedTasks) {
|
||||
if (reroutedTask.getId().equals(task1.getId())) {
|
||||
assertTaskIsRerouted(before, reroutedTask, task1.getState(), workbasketSummary1);
|
||||
} else if (reroutedTask.getId().equals(task2.getId())) {
|
||||
assertTaskIsRerouted(before, reroutedTask, task2.getState(), workbasketSummary2);
|
||||
} else {
|
||||
assertTaskIsRerouted(before, reroutedTask, task3.getState(), workbasketSummary3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-2")
|
||||
@Test
|
||||
void should_RerouteValidTasksEvenIfErrorsExist_When_PorValueIsChanged() throws Exception {
|
||||
final Task taskToBeRerouted1 = createDefaultTask().buildAndStore(taskService, "admin");
|
||||
final Task taskToBeRerouted3 = createDefaultTask().buildAndStore(taskService, "admin");
|
||||
final Task taskNotNeededToReroute =
|
||||
createDefaultTask()
|
||||
.workbasketSummary(workbasketSummary1)
|
||||
.buildAndStore(taskService, "admin");
|
||||
final Task taskWithFinalState =
|
||||
createDefaultTask().state(TaskState.COMPLETED).buildAndStore(taskService, "admin");
|
||||
final Task taskWithNoTransferPerm =
|
||||
createDefaultTask()
|
||||
.workbasketSummary(workbasketSummary1)
|
||||
.buildAndStore(taskService, "admin");
|
||||
final Task taskWithNoAppendDestPerm = createDefaultTask().buildAndStore(taskService, "admin");
|
||||
Instant before = Instant.now().truncatedTo(ChronoUnit.MILLIS);
|
||||
|
||||
taskToBeRerouted1.setPrimaryObjRef(
|
||||
createObjectReference("company", null, null, "MyType1", "Value1"));
|
||||
taskService.updateTask(taskToBeRerouted1);
|
||||
taskToBeRerouted3.setPrimaryObjRef(
|
||||
createObjectReference("company", null, null, "MyType1", "Value3"));
|
||||
taskService.updateTask(taskToBeRerouted3);
|
||||
taskNotNeededToReroute.setPrimaryObjRef("company", null, null, "MyType1", "Value1");
|
||||
taskService.updateTask(taskNotNeededToReroute);
|
||||
taskWithFinalState.setPrimaryObjRef("company", null, null, "MyType1", "Value1");
|
||||
taskService.updateTask(taskWithFinalState);
|
||||
taskWithNoTransferPerm.setPrimaryObjRef("company", null, null, "MyType1", "Value3");
|
||||
taskService.updateTask(taskWithNoTransferPerm);
|
||||
taskWithNoAppendDestPerm.setPrimaryObjRef("company", null, null, "MyType1", "Value2");
|
||||
taskService.updateTask(taskWithNoAppendDestPerm);
|
||||
List<Task> tasks =
|
||||
Arrays.asList(
|
||||
taskToBeRerouted1,
|
||||
taskToBeRerouted3,
|
||||
taskNotNeededToReroute,
|
||||
taskWithFinalState,
|
||||
taskWithNoTransferPerm,
|
||||
taskWithNoAppendDestPerm);
|
||||
List<String> taskIds = tasks.stream().map(Task::getId).collect(Collectors.toList());
|
||||
taskIds.add("invalid-id");
|
||||
|
||||
BulkOperationResults<String, TaskanaException> results = taskService.rerouteTasks(taskIds);
|
||||
final List<TaskSummary> reroutedTasks =
|
||||
taskService.createTaskQuery().idIn(taskIds.toArray(new String[0])).list();
|
||||
assertThat(results.containsErrors()).isTrue();
|
||||
assertThat(results.getErrorMap()).hasSize(4);
|
||||
assertThat(results.getErrorForId("invalid-id")).isOfAnyClassIn(TaskNotFoundException.class);
|
||||
assertThat(results.getErrorForId(taskWithFinalState.getId()))
|
||||
.isOfAnyClassIn(InvalidTaskStateException.class);
|
||||
assertThat(results.getErrorForId(taskWithNoTransferPerm.getId()))
|
||||
.isOfAnyClassIn(NotAuthorizedOnWorkbasketException.class);
|
||||
assertThat(results.getErrorForId(taskWithNoAppendDestPerm.getId()))
|
||||
.isOfAnyClassIn(NotAuthorizedOnWorkbasketException.class);
|
||||
|
||||
for (TaskSummary reroutedTask : reroutedTasks) {
|
||||
if (reroutedTask.getId().equals(taskToBeRerouted1.getId())) {
|
||||
assertTaskIsRerouted(
|
||||
before, reroutedTask, taskToBeRerouted1.getState(), workbasketSummary1);
|
||||
} else if (reroutedTask.getId().equals(taskToBeRerouted3.getId())) {
|
||||
assertTaskIsRerouted(
|
||||
before, reroutedTask, taskToBeRerouted3.getState(), workbasketSummary3);
|
||||
} else if (reroutedTask.getId().equals(taskNotNeededToReroute.getId())) {
|
||||
assertThat(reroutedTask).isEqualTo(taskNotNeededToReroute.asSummary());
|
||||
} else if (reroutedTask.getId().equals(taskWithFinalState.getId())) {
|
||||
assertThat(reroutedTask).isEqualTo(taskWithFinalState.asSummary());
|
||||
} else if (reroutedTask.getId().equals(taskWithNoTransferPerm.getId())) {
|
||||
assertThat(reroutedTask).isEqualTo(taskWithNoTransferPerm.asSummary());
|
||||
} else if (reroutedTask.getId().equals(taskWithNoAppendDestPerm.getId())) {
|
||||
assertThat(reroutedTask).isEqualTo(taskWithNoAppendDestPerm.asSummary());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ObjectReference createObjectReference(
|
||||
String company, String system, String systemInstance, String type, String value) {
|
||||
return ObjectReferenceBuilder.newObjectReference()
|
||||
.company(company)
|
||||
.system(system)
|
||||
.systemInstance(systemInstance)
|
||||
.type(type)
|
||||
.value(value)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void assertTaskIsRerouted(
|
||||
Instant before,
|
||||
TaskSummary reroutedTask,
|
||||
TaskState stateBeforeTransfer,
|
||||
WorkbasketSummary wbAfterReroute) {
|
||||
assertThat(reroutedTask).isNotNull();
|
||||
assertThat(reroutedTask.isRead()).isFalse();
|
||||
assertThat(reroutedTask.isTransferred()).isTrue();
|
||||
assertThat(reroutedTask.getState()).isEqualTo(getStateAfterTransfer(stateBeforeTransfer));
|
||||
assertThat(reroutedTask.getOwner()).isNull();
|
||||
assertThat(reroutedTask.getWorkbasketSummary().getId()).isEqualTo(wbAfterReroute.getId());
|
||||
assertThat(reroutedTask.getDomain()).isEqualTo(wbAfterReroute.getDomain());
|
||||
assertThat(reroutedTask.getModified()).isAfterOrEqualTo(before);
|
||||
}
|
||||
|
||||
private TaskBuilder createDefaultTask() {
|
||||
return (TaskBuilder.newTask()
|
||||
.workbasketSummary(defaultWorkbasketSummary)
|
||||
.primaryObjRef(defaultObjectReference))
|
||||
.classificationSummary(defaultClassificationSummary);
|
||||
}
|
||||
|
||||
private TaskState getStateAfterTransfer(TaskState stateBeforeTransfer) {
|
||||
if (stateBeforeTransfer.equals(TaskState.CLAIMED)) {
|
||||
return TaskState.READY;
|
||||
}
|
||||
if (stateBeforeTransfer.equals(TaskState.IN_REVIEW)) {
|
||||
return TaskState.READY_FOR_REVIEW;
|
||||
} else {
|
||||
return stateBeforeTransfer;
|
||||
}
|
||||
}
|
||||
|
||||
class CustomTaskRoutingProvider implements TaskRoutingProvider {
|
||||
|
||||
@Override
|
||||
public void initialize(TaskanaEngine taskanaEngine) {}
|
||||
|
||||
@Override
|
||||
public String determineWorkbasketId(Task task) {
|
||||
if (task.getPrimaryObjRef().getValue().equals("Value1")) {
|
||||
return workbasketSummary1.getId();
|
||||
} else if (task.getPrimaryObjRef().getValue().equals("Value2")) {
|
||||
return workbasketSummary2.getId();
|
||||
} else if (task.getPrimaryObjRef().getValue().equals("Value3")) {
|
||||
return workbasketSummary3.getId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,8 @@ public enum TaskHistoryEventType {
|
|||
CANCELLED("CANCELLED"),
|
||||
TERMINATED("TERMINATED"),
|
||||
TRANSFERRED("TRANSFERRED"),
|
||||
DELETED("DELETED");
|
||||
DELETED("DELETED"),
|
||||
REROUTED("REROUTED");
|
||||
|
||||
private String name;
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package pro.taskana.spi.history.api.events.task;
|
||||
|
||||
import pro.taskana.task.api.models.TaskSummary;
|
||||
|
||||
public class TaskReroutedEvent extends TaskHistoryEvent {
|
||||
|
||||
public TaskReroutedEvent(
|
||||
String id,
|
||||
TaskSummary task,
|
||||
String oldWorkbasketId,
|
||||
String newWorkbasketId,
|
||||
String userId,
|
||||
String details) {
|
||||
super(id, task, userId, details);
|
||||
eventType = TaskHistoryEventType.REROUTED.getName();
|
||||
this.oldValue = oldWorkbasketId;
|
||||
this.newValue = newWorkbasketId;
|
||||
}
|
||||
}
|
|
@ -1255,4 +1255,12 @@ public interface TaskService {
|
|||
* @return a {@linkplain TaskCommentQuery}
|
||||
*/
|
||||
TaskCommentQuery createTaskCommentQuery();
|
||||
|
||||
Task rerouteTask(String taskId)
|
||||
throws NotAuthorizedOnWorkbasketException,
|
||||
TaskNotFoundException,
|
||||
WorkbasketNotFoundException,
|
||||
InvalidTaskStateException;
|
||||
|
||||
BulkOperationResults<String, TaskanaException> rerouteTasks(List<String> taskIds);
|
||||
}
|
||||
|
|
|
@ -315,4 +315,6 @@ public interface TaskSummary {
|
|||
* @return a copy of this TaskSummary
|
||||
*/
|
||||
TaskSummary copy();
|
||||
|
||||
Task asTask();
|
||||
}
|
||||
|
|
|
@ -168,6 +168,47 @@ public interface TaskMapper {
|
|||
void updateTransfered(
|
||||
@Param("taskIds") Set<String> taskIds, @Param("referencetask") TaskImpl referencetask);
|
||||
|
||||
@Update(
|
||||
"<script>"
|
||||
+ " UPDATE TASK SET MODIFIED = CASE ID"
|
||||
+ "<foreach item='task' index='index' separator='' collection='referenceTasks'>WHEN #{task.id, jdbcType=VARCHAR} THEN CAST(#{task.modified, jdbcType=TIMESTAMP} AS TIMESTAMP)"
|
||||
+ "</foreach> END, "
|
||||
+ " STATE = CASE ID "
|
||||
+ "<foreach item='task' collection='referenceTasks' separator=' '>WHEN #{task.id, jdbcType=VARCHAR} THEN CAST(#{task.state} AS VARCHAR(20))"
|
||||
+ "</foreach> END, "
|
||||
+ " WORKBASKET_KEY = CASE ID "
|
||||
+ "<foreach item='task' collection='referenceTasks' separator=' '>WHEN #{task.id, jdbcType=VARCHAR} THEN CAST(#{task.workbasketSummary.key, jdbcType=VARCHAR} AS VARCHAR(64))"
|
||||
+ "</foreach> END, "
|
||||
+ " WORKBASKET_ID = CASE ID "
|
||||
+ "<foreach item='task' collection='referenceTasks' separator=' '>WHEN #{task.id, jdbcType=VARCHAR} THEN CAST(#{task.workbasketSummary.id, jdbcType=VARCHAR} AS VARCHAR(40))"
|
||||
+ "</foreach> END, "
|
||||
+ " DOMAIN = CASE ID "
|
||||
+ "<foreach item='task' collection='referenceTasks' separator=' '>WHEN #{task.id, jdbcType=VARCHAR} THEN CAST(#{task.workbasketSummary.domain, jdbcType=VARCHAR} AS VARCHAR(32))"
|
||||
+ "</foreach> END, "
|
||||
+ " OWNER = NULL,"
|
||||
+ " IS_READ = "
|
||||
+ "<choose>"
|
||||
+ "<when test =\"_databaseId == 'postgres'\">FALSE, </when><otherwise>0, </otherwise>"
|
||||
+ "</choose>"
|
||||
+ "IS_TRANSFERRED = CASE ID "
|
||||
+ "<foreach item='task' collection='referenceTasks' separator=' '>WHEN #{task.id, jdbcType=VARCHAR} THEN "
|
||||
+ "<choose>"
|
||||
+ "<when test =\"_databaseId == 'postgres'\">#{task.isTransferred}</when>"
|
||||
+ "<otherwise>"
|
||||
+ "<choose>"
|
||||
+ "<when test='task.isTransferred'>1</when>"
|
||||
+ "<otherwise>0</otherwise>"
|
||||
+ "</choose>"
|
||||
+ "</otherwise>"
|
||||
+ "</choose>"
|
||||
+ "</foreach> END"
|
||||
+ " WHERE ID IN "
|
||||
+ "<foreach item='taskId' index='index' separator=',' open='(' close=')' collection='taskIds'> #{taskId, jdbcType=VARCHAR} </foreach>"
|
||||
+ "</script>")
|
||||
void updateTransferMultipleWorkbaskets(
|
||||
@Param("taskIds") Set<String> taskIds,
|
||||
@Param("referenceTasks") List<TaskSummary> referenceTasks);
|
||||
|
||||
@Update(
|
||||
"<script>"
|
||||
+ " UPDATE TASK SET COMPLETED = #{referenceTask.completed}, MODIFIED = #{referenceTask.modified}, STATE = #{referenceTask.state}, OWNER = #{referenceTask.owner}"
|
||||
|
|
|
@ -1088,6 +1088,19 @@ public class TaskServiceImpl implements TaskService {
|
|||
return terminatedTask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task rerouteTask(String taskId) throws NotAuthorizedOnWorkbasketException,
|
||||
TaskNotFoundException,
|
||||
WorkbasketNotFoundException,
|
||||
InvalidTaskStateException {
|
||||
return taskTransferrer.rerouteTask(taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BulkOperationResults<String, TaskanaException> rerouteTasks(List<String> taskIds) {
|
||||
return taskTransferrer.rerouteTasks(taskIds);
|
||||
}
|
||||
|
||||
public List<String> findTasksIdsAffectedByClassificationChange(String classificationId) {
|
||||
// tasks directly affected
|
||||
List<TaskSummary> tasksAffectedDirectly =
|
||||
|
|
|
@ -16,9 +16,12 @@ import pro.taskana.common.api.BulkOperationResults;
|
|||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.TaskanaException;
|
||||
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||
import pro.taskana.common.internal.configuration.DB;
|
||||
import pro.taskana.common.internal.util.EnumUtil;
|
||||
import pro.taskana.common.internal.util.IdGenerator;
|
||||
import pro.taskana.common.internal.util.ObjectAttributeChangeDetector;
|
||||
import pro.taskana.common.internal.util.Pair;
|
||||
import pro.taskana.spi.history.api.events.task.TaskReroutedEvent;
|
||||
import pro.taskana.spi.history.api.events.task.TaskTransferredEvent;
|
||||
import pro.taskana.spi.history.internal.HistoryEventManager;
|
||||
import pro.taskana.task.api.TaskState;
|
||||
|
@ -158,6 +161,69 @@ final class TaskTransferrer {
|
|||
return transferSingleTask(taskId, destinationWorkbasket, owner, setTransferFlag);
|
||||
}
|
||||
|
||||
Task rerouteTask(String taskId)
|
||||
throws NotAuthorizedOnWorkbasketException,
|
||||
TaskNotFoundException,
|
||||
WorkbasketNotFoundException,
|
||||
InvalidTaskStateException {
|
||||
TaskImpl task = (TaskImpl) taskService.getTask(taskId);
|
||||
WorkbasketSummary originWorkbasket = task.getWorkbasketSummary();
|
||||
String newWorkbasketId = taskanaEngine.getTaskRoutingManager().determineWorkbasketId(task);
|
||||
|
||||
if (!originWorkbasket.getId().equals(newWorkbasketId)) {
|
||||
try {
|
||||
taskanaEngine.openConnection();
|
||||
TaskImpl oldTask = task.copy();
|
||||
oldTask.setId(task.getId());
|
||||
oldTask.setExternalId(task.getExternalId());
|
||||
WorkbasketSummary destinationWorkbasket =
|
||||
workbasketService.getWorkbasket(newWorkbasketId).asSummary();
|
||||
|
||||
checkPreconditionsForTransferTask(task, destinationWorkbasket, originWorkbasket);
|
||||
applyTransferValuesForTask(task, destinationWorkbasket, true);
|
||||
taskMapper.update(task);
|
||||
if (historyEventManager.isEnabled()) {
|
||||
createReroutedEvent(
|
||||
oldTask, task, originWorkbasket.getId(), destinationWorkbasket.getId());
|
||||
}
|
||||
return task;
|
||||
} finally {
|
||||
taskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
BulkOperationResults<String, TaskanaException> rerouteTasks(List<String> taskIds) {
|
||||
|
||||
BulkOperationResults<String, TaskanaException> bulkLog = new BulkOperationResults<>();
|
||||
List<TaskSummary> taskSummaries = filterNotExistingTaskIds(taskIds, bulkLog);
|
||||
|
||||
List<String> workbasketIds =
|
||||
taskSummaries.stream()
|
||||
.map(TaskSummary::asTask)
|
||||
.map(task -> taskanaEngine.getTaskRoutingManager().determineWorkbasketId(task))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
filterOutTasksWhichNotNeededToBeTransferred(taskSummaries, workbasketIds);
|
||||
|
||||
List<String> taskIdsToBeTransferred =
|
||||
taskSummaries.stream().map(TaskSummary::getId).collect(Collectors.toList());
|
||||
filterOutTasksWhichDoNotMatchRerouteCriteria(
|
||||
taskIdsToBeTransferred, taskSummaries, workbasketIds, bulkLog);
|
||||
List<WorkbasketSummary> destinationWorkbaskets =
|
||||
filterOutDestinationWbsWhichDoNotMatchTransferCriteria(
|
||||
taskSummaries, workbasketIds, bulkLog);
|
||||
try {
|
||||
taskanaEngine.openConnection();
|
||||
updateReroutableTasksWithDifferentWorkbaskets(taskSummaries, destinationWorkbaskets, true);
|
||||
|
||||
return bulkLog;
|
||||
} finally {
|
||||
taskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
private Task transferSingleTask(
|
||||
String taskId, WorkbasketSummary destinationWorkbasket, String owner, boolean setTransferFlag)
|
||||
throws TaskNotFoundException,
|
||||
|
@ -265,6 +331,33 @@ final class TaskTransferrer {
|
|||
return filteredOutTasks;
|
||||
}
|
||||
|
||||
private void filterOutTasksWhichDoNotMatchRerouteCriteria(
|
||||
List<String> taskIds,
|
||||
List<TaskSummary> taskSummaries,
|
||||
List<String> workbasketIds,
|
||||
BulkOperationResults<String, TaskanaException> bulkLog) {
|
||||
Map<String, TaskSummary> taskIdToTaskSummary =
|
||||
taskSummaries.stream().collect(Collectors.toMap(TaskSummary::getId, Function.identity()));
|
||||
|
||||
Set<String> sourceWorkbasketIds = getSourceWorkbasketIdsWithTransferPermission(taskSummaries);
|
||||
|
||||
for (String taskId : new HashSet<>(taskIds)) {
|
||||
TaskSummary taskSummary = taskIdToTaskSummary.get(taskId);
|
||||
Optional<TaskanaException> error =
|
||||
checkTaskForTransferCriteria(sourceWorkbasketIds, taskId, taskSummary);
|
||||
if (error.isPresent()) {
|
||||
bulkLog.addError(taskId, error.get());
|
||||
for (int i = 0; i < taskSummaries.size(); i++) {
|
||||
if (taskSummaries.get(i).getId().equals(taskId)) {
|
||||
taskSummaries.remove(i);
|
||||
workbasketIds.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<TaskanaException> checkTaskForTransferCriteria(
|
||||
Set<String> sourceWorkbasketIds, String taskId, TaskSummary taskSummary) {
|
||||
TaskanaException error = null;
|
||||
|
@ -372,6 +465,22 @@ final class TaskTransferrer {
|
|||
details));
|
||||
}
|
||||
|
||||
private void createReroutedEvent(
|
||||
TaskSummary oldTask,
|
||||
TaskSummary newTask,
|
||||
String originWorkbasketId,
|
||||
String destinationWorkbasketId) {
|
||||
String details = ObjectAttributeChangeDetector.determineChangesInAttributes(oldTask, newTask);
|
||||
historyEventManager.createEvent(
|
||||
new TaskReroutedEvent(
|
||||
IdGenerator.generateWithPrefix(IdGenerator.ID_PREFIX_TASK_HISTORY_EVENT),
|
||||
newTask,
|
||||
originWorkbasketId,
|
||||
destinationWorkbasketId,
|
||||
taskanaEngine.getEngine().getCurrentUserContext().getUserid(),
|
||||
details));
|
||||
}
|
||||
|
||||
private TaskState getStateAfterTransfer(TaskSummary taskSummary) {
|
||||
TaskState stateBeforeTransfer = taskSummary.getState();
|
||||
if (stateBeforeTransfer.equals(TaskState.CLAIMED)) {
|
||||
|
@ -395,4 +504,127 @@ final class TaskTransferrer {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void filterOutTasksWhichNotNeededToBeTransferred(
|
||||
List<TaskSummary> taskSummaries, List<String> workbasketIds) {
|
||||
for (int i = taskSummaries.size() - 1; i >= 0; i--) {
|
||||
TaskSummary taskSummary = taskSummaries.get(i);
|
||||
String workbasketId = workbasketIds.get(i);
|
||||
if (taskSummary.getWorkbasketSummary().getId().equals(workbasketId)) {
|
||||
taskSummaries.remove(i);
|
||||
workbasketIds.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<WorkbasketSummary> filterOutDestinationWbsWhichDoNotMatchTransferCriteria(
|
||||
List<TaskSummary> taskSummaries,
|
||||
List<String> workbasketIds,
|
||||
BulkOperationResults<String, TaskanaException> bulkLog) {
|
||||
List<WorkbasketSummary> wbsWithAppendPerm =
|
||||
workbasketService
|
||||
.createWorkbasketQuery()
|
||||
.callerHasPermissions(WorkbasketPermission.APPEND)
|
||||
.idIn(workbasketIds.toArray(new String[0]))
|
||||
.list();
|
||||
List<WorkbasketSummary> destinationWbSummaries = new ArrayList<>();
|
||||
for (int i = taskSummaries.size() - 1; i >= 0; i--) {
|
||||
String workbasketId = workbasketIds.get(i);
|
||||
WorkbasketSummary matchingSummary =
|
||||
wbsWithAppendPerm.stream()
|
||||
.filter(summary -> workbasketId.equals(summary.getId()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (matchingSummary == null) {
|
||||
bulkLog.addError(
|
||||
taskSummaries.get(i).getId(),
|
||||
new NotAuthorizedOnWorkbasketException(
|
||||
taskanaEngine.getEngine().getCurrentUserContext().getUserid(),
|
||||
workbasketId,
|
||||
WorkbasketPermission.APPEND));
|
||||
workbasketIds.remove(i);
|
||||
taskSummaries.remove(i);
|
||||
} else if (matchingSummary.isMarkedForDeletion()) {
|
||||
bulkLog.addError(
|
||||
taskSummaries.get(i).getId(), new WorkbasketNotFoundException(matchingSummary.getId()));
|
||||
workbasketIds.remove(i);
|
||||
taskSummaries.remove(i);
|
||||
} else {
|
||||
destinationWbSummaries.add(matchingSummary);
|
||||
}
|
||||
}
|
||||
Collections.reverse(destinationWbSummaries);
|
||||
return destinationWbSummaries;
|
||||
}
|
||||
|
||||
private void updateReroutableTasksWithDifferentWorkbaskets(
|
||||
List<TaskSummary> taskSummaries,
|
||||
List<WorkbasketSummary> workbasketSummaries,
|
||||
boolean setTransferFlag) {
|
||||
List<TaskSummary> oldTaskSummaries = new ArrayList<>();
|
||||
for (TaskSummary taskSummary : taskSummaries) {
|
||||
TaskSummaryImpl copy = new TaskSummaryImpl();
|
||||
copy.setRead(taskSummary.isRead());
|
||||
copy.setTransferred(taskSummary.isTransferred());
|
||||
copy.setState(taskSummary.getState());
|
||||
copy.setOwner(taskSummary.getOwner());
|
||||
copy.setWorkbasketSummary(taskSummary.getWorkbasketSummary());
|
||||
copy.setDomain(taskSummary.getDomain());
|
||||
copy.setModified(taskSummary.getModified());
|
||||
copy.setId(taskSummary.getId());
|
||||
oldTaskSummaries.add(copy);
|
||||
}
|
||||
for (int i = 0; i < taskSummaries.size(); i++) {
|
||||
applyTransferValuesForTask(
|
||||
(TaskSummaryImpl) taskSummaries.get(i), workbasketSummaries.get(i), setTransferFlag);
|
||||
}
|
||||
Set<String> taskIds =
|
||||
taskSummaries.stream().map(TaskSummary::getId).collect(Collectors.toSet());
|
||||
taskMapper.updateTransferMultipleWorkbaskets(taskIds, taskSummaries);
|
||||
|
||||
if (historyEventManager.isEnabled()) {
|
||||
for (int i = 0; i < taskSummaries.size(); i++) {
|
||||
TaskSummary oldSummary = oldTaskSummaries.get(i);
|
||||
TaskSummary newSummary = taskSummaries.get(i);
|
||||
|
||||
createReroutedEvent(
|
||||
oldSummary,
|
||||
newSummary,
|
||||
oldSummary.getWorkbasketSummary().getId(),
|
||||
newSummary.getWorkbasketSummary().getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DB getDB() {
|
||||
return DB.getDB(this.taskanaEngine.getSqlSession().getConfiguration().getDatabaseId());
|
||||
}
|
||||
|
||||
private List<TaskSummary> filterNotExistingTaskIds(
|
||||
List<String> taskIds, BulkOperationResults<String, TaskanaException> bulkLog) {
|
||||
|
||||
Map<String, TaskSummaryImpl> taskSummaryMap =
|
||||
getTasksToChange(taskIds).stream()
|
||||
.collect(Collectors.toMap(TaskSummary::getId, TaskSummaryImpl.class::cast));
|
||||
return taskIds.stream()
|
||||
.map(id -> Pair.of(id, taskSummaryMap.get(id)))
|
||||
.filter(
|
||||
pair -> {
|
||||
if (pair.getRight() != null) {
|
||||
return true;
|
||||
}
|
||||
String taskId = pair.getLeft();
|
||||
bulkLog.addError(taskId, new TaskNotFoundException(taskId));
|
||||
return false;
|
||||
})
|
||||
.map(Pair::getRight)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<TaskSummary> getTasksToChange(List<String> taskIds) {
|
||||
return taskanaEngine
|
||||
.getEngine()
|
||||
.runAsAdmin(
|
||||
() -> taskService.createTaskQuery().idIn(taskIds.toArray(new String[0])).list());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,10 @@ import pro.taskana.common.api.exceptions.SystemException;
|
|||
import pro.taskana.task.api.TaskCustomField;
|
||||
import pro.taskana.task.api.TaskCustomIntField;
|
||||
import pro.taskana.task.api.TaskState;
|
||||
import pro.taskana.task.api.models.Attachment;
|
||||
import pro.taskana.task.api.models.AttachmentSummary;
|
||||
import pro.taskana.task.api.models.ObjectReference;
|
||||
import pro.taskana.task.api.models.Task;
|
||||
import pro.taskana.task.api.models.TaskSummary;
|
||||
import pro.taskana.workbasket.api.models.WorkbasketSummary;
|
||||
import pro.taskana.workbasket.internal.models.WorkbasketSummaryImpl;
|
||||
|
@ -787,6 +789,78 @@ public class TaskSummaryImpl implements TaskSummary {
|
|||
this.customInt8 = customInt8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task asTask() {
|
||||
TaskImpl task = new TaskImpl();
|
||||
List<Attachment> attachments = new ArrayList<>();
|
||||
for (AttachmentSummary attachmentSummary : attachmentSummaries) {
|
||||
AttachmentImpl attachment = new AttachmentImpl();
|
||||
attachment.setId(attachmentSummary.getId());
|
||||
attachment.setTaskId(attachmentSummary.getTaskId());
|
||||
attachment.setCreated(attachmentSummary.getCreated());
|
||||
attachment.setModified(attachmentSummary.getModified());
|
||||
attachment.setClassificationSummary(attachmentSummary.getClassificationSummary());
|
||||
attachment.setObjectReference(attachmentSummary.getObjectReference());
|
||||
attachment.setChannel(attachmentSummary.getChannel());
|
||||
attachment.setReceived(attachmentSummary.getReceived());
|
||||
attachments.add(attachment);
|
||||
}
|
||||
task.setAttachments(attachments);
|
||||
task.setSecondaryObjectReferences(secondaryObjectReferences);
|
||||
task.setBusinessProcessId(this.businessProcessId);
|
||||
task.setClaimed(claimed);
|
||||
if (classificationSummary != null) {
|
||||
task.setClassificationSummary(classificationSummary);
|
||||
}
|
||||
task.setExternalId(externalId);
|
||||
task.setCompleted(completed);
|
||||
task.setCreated(created);
|
||||
task.setCustom1(custom1);
|
||||
task.setCustom2(custom2);
|
||||
task.setCustom3(custom3);
|
||||
task.setCustom4(custom4);
|
||||
task.setCustom5(custom5);
|
||||
task.setCustom6(custom6);
|
||||
task.setCustom7(custom7);
|
||||
task.setCustom8(custom8);
|
||||
task.setCustom9(custom9);
|
||||
task.setCustom10(custom10);
|
||||
task.setCustom11(custom11);
|
||||
task.setCustom12(custom12);
|
||||
task.setCustom13(custom13);
|
||||
task.setCustom14(custom14);
|
||||
task.setCustom15(custom15);
|
||||
task.setCustom16(custom16);
|
||||
task.setCustomInt1(customInt1);
|
||||
task.setCustomInt2(customInt2);
|
||||
task.setCustomInt3(customInt3);
|
||||
task.setCustomInt4(customInt4);
|
||||
task.setCustomInt5(customInt5);
|
||||
task.setCustomInt6(customInt6);
|
||||
task.setCustomInt7(customInt7);
|
||||
task.setCustomInt8(customInt8);
|
||||
task.setDue(due);
|
||||
task.setId(id);
|
||||
task.setModified(modified);
|
||||
task.setName(name);
|
||||
task.setCreator(creator);
|
||||
task.setNote(note);
|
||||
task.setDescription(description);
|
||||
task.setOwner(owner);
|
||||
task.setOwnerLongName(ownerLongName);
|
||||
task.setParentBusinessProcessId(parentBusinessProcessId);
|
||||
task.setPlanned(planned);
|
||||
task.setReceived(received);
|
||||
task.setPrimaryObjRef(primaryObjRef);
|
||||
task.setPriority(priority);
|
||||
task.setManualPriority(manualPriority);
|
||||
task.setRead(isRead);
|
||||
task.setState(state);
|
||||
task.setTransferred(isTransferred);
|
||||
task.setWorkbasketSummary(workbasketSummary);
|
||||
return task;
|
||||
}
|
||||
|
||||
protected boolean canEqual(Object other) {
|
||||
return (other instanceof TaskSummaryImpl);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue