Closes #2389 Possibility to keep the Owner and OwnerLongName of a task when cancelClaiming
This commit is contained in:
parent
67502025a5
commit
422fd4aa19
|
@ -43,7 +43,7 @@ import pro.taskana.workbasket.api.exceptions.NotAuthorizedOnWorkbasketException;
|
||||||
import pro.taskana.workbasket.api.models.WorkbasketSummary;
|
import pro.taskana.workbasket.api.models.WorkbasketSummary;
|
||||||
|
|
||||||
@TaskanaIntegrationTest
|
@TaskanaIntegrationTest
|
||||||
class ClaimTaskAccTest {
|
class ClaimTaskAccTest implements TaskanaConfigurationModifier {
|
||||||
@TaskanaInject TaskService taskService;
|
@TaskanaInject TaskService taskService;
|
||||||
@TaskanaInject ClassificationService classificationService;
|
@TaskanaInject ClassificationService classificationService;
|
||||||
@TaskanaInject WorkbasketService workbasketService;
|
@TaskanaInject WorkbasketService workbasketService;
|
||||||
|
@ -56,6 +56,11 @@ class ClaimTaskAccTest {
|
||||||
WorkbasketSummary wbWithoutReadTasks;
|
WorkbasketSummary wbWithoutReadTasks;
|
||||||
WorkbasketSummary wbWithoutRead;
|
WorkbasketSummary wbWithoutRead;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TaskanaConfiguration.Builder modify(TaskanaConfiguration.Builder builder) {
|
||||||
|
return builder.addAdditionalUserInfo(true);
|
||||||
|
}
|
||||||
|
|
||||||
@WithAccessId(user = "businessadmin")
|
@WithAccessId(user = "businessadmin")
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
void setup() throws Exception {
|
void setup() throws Exception {
|
||||||
|
@ -371,6 +376,52 @@ class ClaimTaskAccTest {
|
||||||
assertThat(unclaimedTask.getOwnerLongName()).isNull();
|
assertThat(unclaimedTask.getOwnerLongName()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WithAccessId(user = "user-1-2")
|
||||||
|
@Test
|
||||||
|
void should_KeepOwnerAndOwnerLongName_When_CancelClaimWithKeepOwner() throws Exception {
|
||||||
|
Task claimedTask =
|
||||||
|
TaskBuilder.newTask()
|
||||||
|
.state(TaskState.CLAIMED)
|
||||||
|
.claimed(Instant.now())
|
||||||
|
.owner("user-1-2")
|
||||||
|
.classificationSummary(defaultClassificationSummary)
|
||||||
|
.workbasketSummary(defaultWorkbasketSummary)
|
||||||
|
.primaryObjRef(defaultObjectReference)
|
||||||
|
.buildAndStore(taskService);
|
||||||
|
|
||||||
|
Task unclaimedTask = taskService.cancelClaim(claimedTask.getId(), true);
|
||||||
|
|
||||||
|
assertThat(unclaimedTask).isNotNull();
|
||||||
|
assertThat(unclaimedTask.getState()).isEqualTo(TaskState.READY);
|
||||||
|
assertThat(unclaimedTask.getClaimed()).isNull();
|
||||||
|
assertThat(unclaimedTask.isRead()).isTrue();
|
||||||
|
assertThat(unclaimedTask.getOwner()).isEqualTo("user-1-2");
|
||||||
|
assertThat(unclaimedTask.getOwnerLongName()).isEqualTo("Long name of user-1-2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@WithAccessId(user = "user-1-2")
|
||||||
|
@Test
|
||||||
|
void should_KeepOwnerAndOwnerLongName_When_ForceCancelClaimWithKeepOwner() throws Exception {
|
||||||
|
Task claimedTask =
|
||||||
|
TaskBuilder.newTask()
|
||||||
|
.state(TaskState.CLAIMED)
|
||||||
|
.claimed(Instant.now())
|
||||||
|
.owner("user-1-2")
|
||||||
|
.classificationSummary(defaultClassificationSummary)
|
||||||
|
.workbasketSummary(defaultWorkbasketSummary)
|
||||||
|
.primaryObjRef(defaultObjectReference)
|
||||||
|
.buildAndStore(taskService);
|
||||||
|
|
||||||
|
Task unclaimedTask = taskService.forceCancelClaim(claimedTask.getId(), true);
|
||||||
|
|
||||||
|
assertThat(unclaimedTask).isNotNull();
|
||||||
|
assertThat(unclaimedTask.getState()).isEqualTo(TaskState.READY);
|
||||||
|
assertThat(unclaimedTask.getClaimed()).isNull();
|
||||||
|
assertThat(unclaimedTask.isRead()).isTrue();
|
||||||
|
assertThat(unclaimedTask.getOwner()).isEqualTo("user-1-2");
|
||||||
|
assertThat(unclaimedTask.getOwnerLongName()).isEqualTo("Long name of user-1-2");
|
||||||
|
}
|
||||||
|
|
||||||
@WithAccessId(user = "user-1-2")
|
@WithAccessId(user = "user-1-2")
|
||||||
@Test
|
@Test
|
||||||
void should_CancelClaimTask_When_TaskIsInReview() throws Exception {
|
void should_CancelClaimTask_When_TaskIsInReview() throws Exception {
|
||||||
|
|
|
@ -220,6 +220,44 @@ public interface TaskService {
|
||||||
NotAuthorizedOnWorkbasketException,
|
NotAuthorizedOnWorkbasketException,
|
||||||
InvalidTaskStateException;
|
InvalidTaskStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel the claim of an existing {@linkplain Task} if it was claimed by the current user before.
|
||||||
|
*
|
||||||
|
* @param taskId the {@linkplain Task#getId() id} of the {@linkplain Task} which should be
|
||||||
|
* unclaimed
|
||||||
|
* @param keepOwner If set to true, will keep the {@linkplain Task#getOwner()} and {@linkplain
|
||||||
|
* Task#getOwnerLongName()}
|
||||||
|
* @return the unclaimed {@linkplain Task}
|
||||||
|
* @throws TaskNotFoundException if the {@linkplain Task} with taskId was not found
|
||||||
|
* @throws InvalidTaskStateException if the {@linkplain Task} is already in one of the {@linkplain
|
||||||
|
* TaskState#END_STATES}
|
||||||
|
* @throws InvalidOwnerException if the {@linkplain Task} is claimed by another user
|
||||||
|
* @throws NotAuthorizedOnWorkbasketException if the current user has no {@linkplain
|
||||||
|
* WorkbasketPermission#READ} for the {@linkplain Workbasket} the {@linkplain Task} is in
|
||||||
|
*/
|
||||||
|
Task cancelClaim(String taskId, boolean keepOwner)
|
||||||
|
throws TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
|
InvalidTaskStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel the claim of an existing {@linkplain Task} even if it was claimed by another user.
|
||||||
|
*
|
||||||
|
* @param taskId the {@linkplain Task#getId() id} of the {@linkplain Task} which should be
|
||||||
|
* unclaimed
|
||||||
|
* @param keepOwner If set to true, will keep the {@linkplain Task#getOwner()} and {@linkplain
|
||||||
|
* Task#getOwnerLongName()}
|
||||||
|
* @return the unclaimed {@linkplain Task}
|
||||||
|
* @throws TaskNotFoundException if the {@linkplain Task} with taskId was not found
|
||||||
|
* @throws InvalidTaskStateException if the {@linkplain Task} is already in one of the {@linkplain
|
||||||
|
* TaskState#END_STATES}
|
||||||
|
* @throws NotAuthorizedOnWorkbasketException if the current user has no {@linkplain
|
||||||
|
* WorkbasketPermission#READ} for the {@linkplain Workbasket} the {@linkplain Task} is in
|
||||||
|
*/
|
||||||
|
Task forceCancelClaim(String taskId, boolean keepOwner)
|
||||||
|
throws TaskNotFoundException, NotAuthorizedOnWorkbasketException, InvalidTaskStateException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel the claim of an existing {@linkplain Task} even if it was claimed by another user.
|
* Cancel the claim of an existing {@linkplain Task} even if it was claimed by another user.
|
||||||
*
|
*
|
||||||
|
|
|
@ -160,30 +160,55 @@ public class TaskServiceImpl implements TaskService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task claim(String taskId)
|
public Task claim(String taskId)
|
||||||
throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
InvalidTaskStateException {
|
InvalidTaskStateException {
|
||||||
return claim(taskId, false);
|
return claim(taskId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task forceClaim(String taskId)
|
public Task forceClaim(String taskId)
|
||||||
throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
InvalidTaskStateException {
|
InvalidTaskStateException {
|
||||||
return claim(taskId, true);
|
return claim(taskId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task cancelClaim(String taskId)
|
public Task cancelClaim(String taskId)
|
||||||
throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
InvalidTaskStateException {
|
InvalidTaskStateException {
|
||||||
return this.cancelClaim(taskId, false);
|
return this.cancelClaim(taskId, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task forceCancelClaim(String taskId)
|
public Task forceCancelClaim(String taskId)
|
||||||
throws TaskNotFoundException, InvalidTaskStateException, NotAuthorizedOnWorkbasketException {
|
throws TaskNotFoundException, InvalidTaskStateException, NotAuthorizedOnWorkbasketException {
|
||||||
try {
|
try {
|
||||||
return this.cancelClaim(taskId, true);
|
return this.cancelClaim(taskId, true, false);
|
||||||
|
} catch (InvalidOwnerException e) {
|
||||||
|
throw new SystemException("this should not have happened. You've discovered a new bug!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Task cancelClaim(String taskId, boolean keepOwner)
|
||||||
|
throws TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
|
InvalidTaskStateException {
|
||||||
|
return this.cancelClaim(taskId, false, keepOwner);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Task forceCancelClaim(String taskId, boolean keepOwner)
|
||||||
|
throws TaskNotFoundException, InvalidTaskStateException, NotAuthorizedOnWorkbasketException {
|
||||||
|
try {
|
||||||
|
return this.cancelClaim(taskId, true, keepOwner);
|
||||||
} catch (InvalidOwnerException e) {
|
} catch (InvalidOwnerException e) {
|
||||||
throw new SystemException("this should not have happened. You've discovered a new bug!", e);
|
throw new SystemException("this should not have happened. You've discovered a new bug!", e);
|
||||||
}
|
}
|
||||||
|
@ -191,51 +216,67 @@ public class TaskServiceImpl implements TaskService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task requestReview(String taskId)
|
public Task requestReview(String taskId)
|
||||||
throws InvalidTaskStateException, TaskNotFoundException, InvalidOwnerException,
|
throws InvalidTaskStateException,
|
||||||
|
TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
NotAuthorizedOnWorkbasketException {
|
NotAuthorizedOnWorkbasketException {
|
||||||
return requestReview(taskId, false);
|
return requestReview(taskId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task forceRequestReview(String taskId)
|
public Task forceRequestReview(String taskId)
|
||||||
throws InvalidTaskStateException, TaskNotFoundException, InvalidOwnerException,
|
throws InvalidTaskStateException,
|
||||||
|
TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
NotAuthorizedOnWorkbasketException {
|
NotAuthorizedOnWorkbasketException {
|
||||||
return requestReview(taskId, true);
|
return requestReview(taskId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task requestChanges(String taskId)
|
public Task requestChanges(String taskId)
|
||||||
throws InvalidTaskStateException, TaskNotFoundException, InvalidOwnerException,
|
throws InvalidTaskStateException,
|
||||||
|
TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
NotAuthorizedOnWorkbasketException {
|
NotAuthorizedOnWorkbasketException {
|
||||||
return requestChanges(taskId, false);
|
return requestChanges(taskId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task forceRequestChanges(String taskId)
|
public Task forceRequestChanges(String taskId)
|
||||||
throws InvalidTaskStateException, TaskNotFoundException, InvalidOwnerException,
|
throws InvalidTaskStateException,
|
||||||
|
TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
NotAuthorizedOnWorkbasketException {
|
NotAuthorizedOnWorkbasketException {
|
||||||
return requestChanges(taskId, true);
|
return requestChanges(taskId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task completeTask(String taskId)
|
public Task completeTask(String taskId)
|
||||||
throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
InvalidTaskStateException {
|
InvalidTaskStateException {
|
||||||
return completeTask(taskId, false);
|
return completeTask(taskId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task forceCompleteTask(String taskId)
|
public Task forceCompleteTask(String taskId)
|
||||||
throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
InvalidTaskStateException {
|
InvalidTaskStateException {
|
||||||
return completeTask(taskId, true);
|
return completeTask(taskId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task createTask(Task taskToCreate)
|
public Task createTask(Task taskToCreate)
|
||||||
throws WorkbasketNotFoundException, ClassificationNotFoundException,
|
throws WorkbasketNotFoundException,
|
||||||
TaskAlreadyExistException, InvalidArgumentException, AttachmentPersistenceException,
|
ClassificationNotFoundException,
|
||||||
ObjectReferencePersistenceException, NotAuthorizedOnWorkbasketException {
|
TaskAlreadyExistException,
|
||||||
|
InvalidArgumentException,
|
||||||
|
AttachmentPersistenceException,
|
||||||
|
ObjectReferencePersistenceException,
|
||||||
|
NotAuthorizedOnWorkbasketException {
|
||||||
|
|
||||||
if (createTaskPreprocessorManager.isEnabled()) {
|
if (createTaskPreprocessorManager.isEnabled()) {
|
||||||
taskToCreate = createTaskPreprocessorManager.processTaskBeforeCreation(taskToCreate);
|
taskToCreate = createTaskPreprocessorManager.processTaskBeforeCreation(taskToCreate);
|
||||||
|
@ -417,14 +458,18 @@ public class TaskServiceImpl implements TaskService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task transfer(String taskId, String destinationWorkbasketId, boolean setTransferFlag)
|
public Task transfer(String taskId, String destinationWorkbasketId, boolean setTransferFlag)
|
||||||
throws TaskNotFoundException, WorkbasketNotFoundException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
|
WorkbasketNotFoundException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
InvalidTaskStateException {
|
InvalidTaskStateException {
|
||||||
return taskTransferrer.transfer(taskId, destinationWorkbasketId, setTransferFlag);
|
return taskTransferrer.transfer(taskId, destinationWorkbasketId, setTransferFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task transfer(String taskId, String workbasketKey, String domain, boolean setTransferFlag)
|
public Task transfer(String taskId, String workbasketKey, String domain, boolean setTransferFlag)
|
||||||
throws TaskNotFoundException, WorkbasketNotFoundException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
|
WorkbasketNotFoundException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
InvalidTaskStateException {
|
InvalidTaskStateException {
|
||||||
return taskTransferrer.transfer(taskId, workbasketKey, domain, setTransferFlag);
|
return taskTransferrer.transfer(taskId, workbasketKey, domain, setTransferFlag);
|
||||||
}
|
}
|
||||||
|
@ -506,9 +551,13 @@ public class TaskServiceImpl implements TaskService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task updateTask(Task task)
|
public Task updateTask(Task task)
|
||||||
throws InvalidArgumentException, TaskNotFoundException, ConcurrencyException,
|
throws InvalidArgumentException,
|
||||||
AttachmentPersistenceException, ObjectReferencePersistenceException,
|
TaskNotFoundException,
|
||||||
ClassificationNotFoundException, NotAuthorizedOnWorkbasketException,
|
ConcurrencyException,
|
||||||
|
AttachmentPersistenceException,
|
||||||
|
ObjectReferencePersistenceException,
|
||||||
|
ClassificationNotFoundException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
InvalidTaskStateException {
|
InvalidTaskStateException {
|
||||||
String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid();
|
String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid();
|
||||||
TaskImpl newTaskImpl = (TaskImpl) task;
|
TaskImpl newTaskImpl = (TaskImpl) task;
|
||||||
|
@ -563,7 +612,8 @@ public class TaskServiceImpl implements TaskService {
|
||||||
@Override
|
@Override
|
||||||
public BulkOperationResults<String, TaskanaException> transferTasks(
|
public BulkOperationResults<String, TaskanaException> transferTasks(
|
||||||
String destinationWorkbasketId, List<String> taskIds, boolean setTransferFlag)
|
String destinationWorkbasketId, List<String> taskIds, boolean setTransferFlag)
|
||||||
throws InvalidArgumentException, WorkbasketNotFoundException,
|
throws InvalidArgumentException,
|
||||||
|
WorkbasketNotFoundException,
|
||||||
NotAuthorizedOnWorkbasketException {
|
NotAuthorizedOnWorkbasketException {
|
||||||
return taskTransferrer.transfer(taskIds, destinationWorkbasketId, setTransferFlag);
|
return taskTransferrer.transfer(taskIds, destinationWorkbasketId, setTransferFlag);
|
||||||
}
|
}
|
||||||
|
@ -574,7 +624,8 @@ public class TaskServiceImpl implements TaskService {
|
||||||
String destinationWorkbasketDomain,
|
String destinationWorkbasketDomain,
|
||||||
List<String> taskIds,
|
List<String> taskIds,
|
||||||
boolean setTransferFlag)
|
boolean setTransferFlag)
|
||||||
throws InvalidArgumentException, WorkbasketNotFoundException,
|
throws InvalidArgumentException,
|
||||||
|
WorkbasketNotFoundException,
|
||||||
NotAuthorizedOnWorkbasketException {
|
NotAuthorizedOnWorkbasketException {
|
||||||
return taskTransferrer.transfer(
|
return taskTransferrer.transfer(
|
||||||
taskIds, destinationWorkbasketKey, destinationWorkbasketDomain, setTransferFlag);
|
taskIds, destinationWorkbasketKey, destinationWorkbasketDomain, setTransferFlag);
|
||||||
|
@ -582,15 +633,21 @@ public class TaskServiceImpl implements TaskService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteTask(String taskId)
|
public void deleteTask(String taskId)
|
||||||
throws TaskNotFoundException, NotAuthorizedException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
InvalidTaskStateException, InvalidCallbackStateException {
|
NotAuthorizedException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
|
InvalidTaskStateException,
|
||||||
|
InvalidCallbackStateException {
|
||||||
deleteTask(taskId, false);
|
deleteTask(taskId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void forceDeleteTask(String taskId)
|
public void forceDeleteTask(String taskId)
|
||||||
throws TaskNotFoundException, NotAuthorizedException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
InvalidTaskStateException, InvalidCallbackStateException {
|
NotAuthorizedException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
|
InvalidTaskStateException,
|
||||||
|
InvalidCallbackStateException {
|
||||||
deleteTask(taskId, true);
|
deleteTask(taskId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,22 +816,30 @@ public class TaskServiceImpl implements TaskService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskComment updateTaskComment(TaskComment taskComment)
|
public TaskComment updateTaskComment(TaskComment taskComment)
|
||||||
throws ConcurrencyException, TaskCommentNotFoundException, TaskNotFoundException,
|
throws ConcurrencyException,
|
||||||
InvalidArgumentException, NotAuthorizedOnTaskCommentException,
|
TaskCommentNotFoundException,
|
||||||
|
TaskNotFoundException,
|
||||||
|
InvalidArgumentException,
|
||||||
|
NotAuthorizedOnTaskCommentException,
|
||||||
NotAuthorizedOnWorkbasketException {
|
NotAuthorizedOnWorkbasketException {
|
||||||
return taskCommentService.updateTaskComment(taskComment);
|
return taskCommentService.updateTaskComment(taskComment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteTaskComment(String taskCommentId)
|
public void deleteTaskComment(String taskCommentId)
|
||||||
throws TaskCommentNotFoundException, TaskNotFoundException, InvalidArgumentException,
|
throws TaskCommentNotFoundException,
|
||||||
NotAuthorizedOnTaskCommentException, NotAuthorizedOnWorkbasketException {
|
TaskNotFoundException,
|
||||||
|
InvalidArgumentException,
|
||||||
|
NotAuthorizedOnTaskCommentException,
|
||||||
|
NotAuthorizedOnWorkbasketException {
|
||||||
taskCommentService.deleteTaskComment(taskCommentId);
|
taskCommentService.deleteTaskComment(taskCommentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskComment getTaskComment(String taskCommentid)
|
public TaskComment getTaskComment(String taskCommentid)
|
||||||
throws TaskCommentNotFoundException, TaskNotFoundException, InvalidArgumentException,
|
throws TaskCommentNotFoundException,
|
||||||
|
TaskNotFoundException,
|
||||||
|
InvalidArgumentException,
|
||||||
NotAuthorizedOnWorkbasketException {
|
NotAuthorizedOnWorkbasketException {
|
||||||
return taskCommentService.getTaskComment(taskCommentid);
|
return taskCommentService.getTaskComment(taskCommentid);
|
||||||
}
|
}
|
||||||
|
@ -922,7 +987,9 @@ public class TaskServiceImpl implements TaskService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task terminateTask(String taskId)
|
public Task terminateTask(String taskId)
|
||||||
throws TaskNotFoundException, NotAuthorizedException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
|
NotAuthorizedException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
InvalidTaskStateException {
|
InvalidTaskStateException {
|
||||||
|
|
||||||
taskanaEngine.getEngine().checkRoleMembership(TaskanaRole.ADMIN, TaskanaRole.TASK_ADMIN);
|
taskanaEngine.getEngine().checkRoleMembership(TaskanaRole.ADMIN, TaskanaRole.TASK_ADMIN);
|
||||||
|
@ -1265,7 +1332,9 @@ public class TaskServiceImpl implements TaskService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task claim(String taskId, boolean forceClaim)
|
private Task claim(String taskId, boolean forceClaim)
|
||||||
throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
InvalidTaskStateException {
|
InvalidTaskStateException {
|
||||||
TaskImpl task;
|
TaskImpl task;
|
||||||
try {
|
try {
|
||||||
|
@ -1309,7 +1378,9 @@ public class TaskServiceImpl implements TaskService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task requestReview(String taskId, boolean force)
|
private Task requestReview(String taskId, boolean force)
|
||||||
throws TaskNotFoundException, InvalidTaskStateException, InvalidOwnerException,
|
throws TaskNotFoundException,
|
||||||
|
InvalidTaskStateException,
|
||||||
|
InvalidOwnerException,
|
||||||
NotAuthorizedOnWorkbasketException {
|
NotAuthorizedOnWorkbasketException {
|
||||||
String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid();
|
String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid();
|
||||||
TaskImpl task;
|
TaskImpl task;
|
||||||
|
@ -1360,7 +1431,9 @@ public class TaskServiceImpl implements TaskService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task requestChanges(String taskId, boolean force)
|
private Task requestChanges(String taskId, boolean force)
|
||||||
throws InvalidTaskStateException, TaskNotFoundException, InvalidOwnerException,
|
throws InvalidTaskStateException,
|
||||||
|
TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
NotAuthorizedOnWorkbasketException {
|
NotAuthorizedOnWorkbasketException {
|
||||||
String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid();
|
String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid();
|
||||||
TaskImpl task;
|
TaskImpl task;
|
||||||
|
@ -1422,9 +1495,12 @@ public class TaskServiceImpl implements TaskService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void cancelClaimActionsOnTask(TaskSummaryImpl task, Instant now) {
|
private static void cancelClaimActionsOnTask(
|
||||||
task.setOwner(null);
|
TaskSummaryImpl task, Instant now, boolean keepOwner) {
|
||||||
task.setOwnerLongName(null);
|
if (!keepOwner) {
|
||||||
|
task.setOwner(null);
|
||||||
|
task.setOwnerLongName(null);
|
||||||
|
}
|
||||||
task.setModified(now);
|
task.setModified(now);
|
||||||
task.setClaimed(null);
|
task.setClaimed(null);
|
||||||
task.setRead(true);
|
task.setRead(true);
|
||||||
|
@ -1501,15 +1577,16 @@ public class TaskServiceImpl implements TaskService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task cancelClaim(String taskId, boolean forceUnclaim)
|
private Task cancelClaim(String taskId, boolean forceUnclaim, boolean keepOwner)
|
||||||
throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
InvalidTaskStateException {
|
InvalidTaskStateException {
|
||||||
String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid();
|
String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid();
|
||||||
TaskImpl task;
|
TaskImpl task;
|
||||||
try {
|
try {
|
||||||
taskanaEngine.openConnection();
|
taskanaEngine.openConnection();
|
||||||
task = (TaskImpl) getTask(taskId);
|
task = (TaskImpl) getTask(taskId);
|
||||||
|
|
||||||
TaskImpl oldTask = duplicateTaskExactly(task);
|
TaskImpl oldTask = duplicateTaskExactly(task);
|
||||||
|
|
||||||
TaskState state = task.getState();
|
TaskState state = task.getState();
|
||||||
|
@ -1529,7 +1606,7 @@ public class TaskServiceImpl implements TaskService {
|
||||||
throw new InvalidOwnerException(userId, taskId);
|
throw new InvalidOwnerException(userId, taskId);
|
||||||
}
|
}
|
||||||
Instant now = Instant.now();
|
Instant now = Instant.now();
|
||||||
cancelClaimActionsOnTask(task, now);
|
cancelClaimActionsOnTask(task, now, keepOwner);
|
||||||
taskMapper.update(task);
|
taskMapper.update(task);
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
LOGGER.debug("Task '{}' unclaimed by user '{}'.", taskId, userId);
|
LOGGER.debug("Task '{}' unclaimed by user '{}'.", taskId, userId);
|
||||||
|
@ -1552,7 +1629,9 @@ public class TaskServiceImpl implements TaskService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task completeTask(String taskId, boolean isForced)
|
private Task completeTask(String taskId, boolean isForced)
|
||||||
throws TaskNotFoundException, InvalidOwnerException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
|
InvalidOwnerException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
InvalidTaskStateException {
|
InvalidTaskStateException {
|
||||||
String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid();
|
String userId = taskanaEngine.getEngine().getCurrentUserContext().getUserid();
|
||||||
TaskImpl task;
|
TaskImpl task;
|
||||||
|
@ -1596,8 +1675,11 @@ public class TaskServiceImpl implements TaskService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteTask(String taskId, boolean forceDelete)
|
private void deleteTask(String taskId, boolean forceDelete)
|
||||||
throws TaskNotFoundException, NotAuthorizedException, NotAuthorizedOnWorkbasketException,
|
throws TaskNotFoundException,
|
||||||
InvalidTaskStateException, InvalidCallbackStateException {
|
NotAuthorizedException,
|
||||||
|
NotAuthorizedOnWorkbasketException,
|
||||||
|
InvalidTaskStateException,
|
||||||
|
InvalidCallbackStateException {
|
||||||
taskanaEngine.getEngine().checkRoleMembership(TaskanaRole.ADMIN);
|
taskanaEngine.getEngine().checkRoleMembership(TaskanaRole.ADMIN);
|
||||||
TaskImpl task;
|
TaskImpl task;
|
||||||
try {
|
try {
|
||||||
|
@ -1751,8 +1833,10 @@ public class TaskServiceImpl implements TaskService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void standardSettingsOnTaskCreation(TaskImpl task, Classification classification)
|
private void standardSettingsOnTaskCreation(TaskImpl task, Classification classification)
|
||||||
throws InvalidArgumentException, ClassificationNotFoundException,
|
throws InvalidArgumentException,
|
||||||
AttachmentPersistenceException, ObjectReferencePersistenceException {
|
ClassificationNotFoundException,
|
||||||
|
AttachmentPersistenceException,
|
||||||
|
ObjectReferencePersistenceException {
|
||||||
final Instant now = Instant.now();
|
final Instant now = Instant.now();
|
||||||
task.setId(IdGenerator.generateWithPrefix(IdGenerator.ID_PREFIX_TASK));
|
task.setId(IdGenerator.generateWithPrefix(IdGenerator.ID_PREFIX_TASK));
|
||||||
if (task.getExternalId() == null) {
|
if (task.getExternalId() == null) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import pro.taskana.classification.api.exceptions.ClassificationNotFoundException;
|
import pro.taskana.classification.api.exceptions.ClassificationNotFoundException;
|
||||||
import pro.taskana.common.api.BaseQuery.SortDirection;
|
import pro.taskana.common.api.BaseQuery.SortDirection;
|
||||||
|
@ -288,6 +289,7 @@ public class TaskController {
|
||||||
* before.
|
* before.
|
||||||
*
|
*
|
||||||
* @param taskId the Id of the requested Task.
|
* @param taskId the Id of the requested Task.
|
||||||
|
* @param keepOwner flag whether or not to keep the owner despite the cancel claim
|
||||||
* @return the unclaimed Task.
|
* @return the unclaimed Task.
|
||||||
* @throws TaskNotFoundException if the requested Task does not exist.
|
* @throws TaskNotFoundException if the requested Task does not exist.
|
||||||
* @throws InvalidTaskStateException if the Task is already in an end state.
|
* @throws InvalidTaskStateException if the Task is already in an end state.
|
||||||
|
@ -298,12 +300,13 @@ public class TaskController {
|
||||||
*/
|
*/
|
||||||
@DeleteMapping(path = RestEndpoints.URL_TASKS_ID_CLAIM)
|
@DeleteMapping(path = RestEndpoints.URL_TASKS_ID_CLAIM)
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public ResponseEntity<TaskRepresentationModel> cancelClaimTask(@PathVariable String taskId)
|
public ResponseEntity<TaskRepresentationModel> cancelClaimTask(
|
||||||
|
@PathVariable String taskId, @RequestParam(defaultValue = "false") boolean keepOwner)
|
||||||
throws TaskNotFoundException,
|
throws TaskNotFoundException,
|
||||||
InvalidTaskStateException,
|
InvalidTaskStateException,
|
||||||
InvalidOwnerException,
|
InvalidOwnerException,
|
||||||
NotAuthorizedOnWorkbasketException {
|
NotAuthorizedOnWorkbasketException {
|
||||||
Task updatedTask = taskService.cancelClaim(taskId);
|
Task updatedTask = taskService.cancelClaim(taskId, keepOwner);
|
||||||
|
|
||||||
return ResponseEntity.ok(taskRepresentationModelAssembler.toModel(updatedTask));
|
return ResponseEntity.ok(taskRepresentationModelAssembler.toModel(updatedTask));
|
||||||
}
|
}
|
||||||
|
@ -312,6 +315,7 @@ public class TaskController {
|
||||||
* This endpoint force cancels the claim of an existing Task.
|
* This endpoint force cancels the claim of an existing Task.
|
||||||
*
|
*
|
||||||
* @param taskId the Id of the requested Task.
|
* @param taskId the Id of the requested Task.
|
||||||
|
* @param keepOwner flag whether or not to keep the owner despite the cancel claim
|
||||||
* @return the unclaimed Task.
|
* @return the unclaimed Task.
|
||||||
* @throws TaskNotFoundException if the requested Task does not exist.
|
* @throws TaskNotFoundException if the requested Task does not exist.
|
||||||
* @throws InvalidTaskStateException if the Task is already in an end state.
|
* @throws InvalidTaskStateException if the Task is already in an end state.
|
||||||
|
@ -322,12 +326,13 @@ public class TaskController {
|
||||||
*/
|
*/
|
||||||
@DeleteMapping(path = RestEndpoints.URL_TASKS_ID_CLAIM_FORCE)
|
@DeleteMapping(path = RestEndpoints.URL_TASKS_ID_CLAIM_FORCE)
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public ResponseEntity<TaskRepresentationModel> forceCancelClaimTask(@PathVariable String taskId)
|
public ResponseEntity<TaskRepresentationModel> forceCancelClaimTask(
|
||||||
|
@PathVariable String taskId, @RequestParam(defaultValue = "false") boolean keepOwner)
|
||||||
throws TaskNotFoundException,
|
throws TaskNotFoundException,
|
||||||
InvalidTaskStateException,
|
InvalidTaskStateException,
|
||||||
InvalidOwnerException,
|
InvalidOwnerException,
|
||||||
NotAuthorizedOnWorkbasketException {
|
NotAuthorizedOnWorkbasketException {
|
||||||
Task updatedTask = taskService.forceCancelClaim(taskId);
|
Task updatedTask = taskService.forceCancelClaim(taskId, keepOwner);
|
||||||
return ResponseEntity.ok(taskRepresentationModelAssembler.toModel(updatedTask));
|
return ResponseEntity.ok(taskRepresentationModelAssembler.toModel(updatedTask));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,16 +64,12 @@ class TaskControllerIntTest {
|
||||||
@Autowired TaskanaConfiguration taskanaConfiguration;
|
@Autowired TaskanaConfiguration taskanaConfiguration;
|
||||||
private static final ParameterizedTypeReference<TaskSummaryPagedRepresentationModel>
|
private static final ParameterizedTypeReference<TaskSummaryPagedRepresentationModel>
|
||||||
TASK_SUMMARY_PAGE_MODEL_TYPE = new ParameterizedTypeReference<>() {};
|
TASK_SUMMARY_PAGE_MODEL_TYPE = new ParameterizedTypeReference<>() {};
|
||||||
|
|
||||||
private static final ParameterizedTypeReference<TaskSummaryCollectionRepresentationModel>
|
private static final ParameterizedTypeReference<TaskSummaryCollectionRepresentationModel>
|
||||||
TASK_SUMMARY_COLLECTION_MODEL_TYPE = new ParameterizedTypeReference<>() {};
|
TASK_SUMMARY_COLLECTION_MODEL_TYPE = new ParameterizedTypeReference<>() {};
|
||||||
|
|
||||||
private static final ParameterizedTypeReference<TaskRepresentationModel> TASK_MODEL_TYPE =
|
private static final ParameterizedTypeReference<TaskRepresentationModel> TASK_MODEL_TYPE =
|
||||||
ParameterizedTypeReference.forType(TaskRepresentationModel.class);
|
ParameterizedTypeReference.forType(TaskRepresentationModel.class);
|
||||||
|
|
||||||
private final RestHelper restHelper;
|
private final RestHelper restHelper;
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
|
|
||||||
private final String schemaName;
|
private final String schemaName;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -2350,6 +2346,70 @@ class TaskControllerIntTest {
|
||||||
assertThat(cancelClaimedtaskRepresentationModel.getState()).isEqualTo(TaskState.READY);
|
assertThat(cancelClaimedtaskRepresentationModel.getState()).isEqualTo(TaskState.READY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_KeepOwnerAndOwnerLongName_When_CancelClaimWithKeepOwner() {
|
||||||
|
String url =
|
||||||
|
restHelper.toUrl(RestEndpoints.URL_TASKS_ID, "TKI:000000000000000000000000000000000000");
|
||||||
|
HttpEntity<Object> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("user-1-1"));
|
||||||
|
|
||||||
|
// retrieve task from Rest Api
|
||||||
|
ResponseEntity<TaskRepresentationModel> getTaskResponse =
|
||||||
|
TEMPLATE.exchange(url, HttpMethod.GET, auth, TASK_MODEL_TYPE);
|
||||||
|
assertThat(getTaskResponse.getBody()).isNotNull();
|
||||||
|
TaskRepresentationModel taskRepresentationModel = getTaskResponse.getBody();
|
||||||
|
assertThat(taskRepresentationModel.getState()).isEqualTo(TaskState.CLAIMED);
|
||||||
|
assertThat(taskRepresentationModel.getOwner()).isEqualTo("user-1-1");
|
||||||
|
|
||||||
|
// cancel claim
|
||||||
|
String url2 =
|
||||||
|
restHelper.toUrl(
|
||||||
|
RestEndpoints.URL_TASKS_ID_CLAIM + "?keepOwner=true",
|
||||||
|
"TKI:000000000000000000000000000000000000");
|
||||||
|
ResponseEntity<TaskRepresentationModel> cancelClaimResponse =
|
||||||
|
TEMPLATE.exchange(url2, HttpMethod.DELETE, auth, TASK_MODEL_TYPE);
|
||||||
|
|
||||||
|
assertThat(cancelClaimResponse.getBody()).isNotNull();
|
||||||
|
assertThat(cancelClaimResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
|
TaskRepresentationModel cancelClaimedtaskRepresentationModel = cancelClaimResponse.getBody();
|
||||||
|
assertThat(cancelClaimedtaskRepresentationModel.getClaimed()).isNull();
|
||||||
|
assertThat(cancelClaimedtaskRepresentationModel.getState()).isEqualTo(TaskState.READY);
|
||||||
|
assertThat(cancelClaimedtaskRepresentationModel.getOwner()).isEqualTo("user-1-1");
|
||||||
|
assertThat(cancelClaimedtaskRepresentationModel.getOwnerLongName())
|
||||||
|
.isEqualTo("Mustermann, Max - (user-1-1)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_KeepOwnerAndOwnerLongName_When_ForceCancelClaimWithKeepOwner() {
|
||||||
|
String url =
|
||||||
|
restHelper.toUrl(RestEndpoints.URL_TASKS_ID, "TKI:000000000000000000000000000000000001");
|
||||||
|
HttpEntity<Object> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("user-1-1"));
|
||||||
|
|
||||||
|
// retrieve task from Rest Api
|
||||||
|
ResponseEntity<TaskRepresentationModel> getTaskResponse =
|
||||||
|
TEMPLATE.exchange(url, HttpMethod.GET, auth, TASK_MODEL_TYPE);
|
||||||
|
assertThat(getTaskResponse.getBody()).isNotNull();
|
||||||
|
TaskRepresentationModel taskRepresentationModel = getTaskResponse.getBody();
|
||||||
|
assertThat(taskRepresentationModel.getState()).isEqualTo(TaskState.CLAIMED);
|
||||||
|
assertThat(taskRepresentationModel.getOwner()).isEqualTo("user-1-1");
|
||||||
|
|
||||||
|
// cancel claim
|
||||||
|
String url2 =
|
||||||
|
restHelper.toUrl(
|
||||||
|
RestEndpoints.URL_TASKS_ID_CLAIM_FORCE + "?keepOwner=true",
|
||||||
|
"TKI:000000000000000000000000000000000001");
|
||||||
|
ResponseEntity<TaskRepresentationModel> cancelClaimResponse =
|
||||||
|
TEMPLATE.exchange(url2, HttpMethod.DELETE, auth, TASK_MODEL_TYPE);
|
||||||
|
|
||||||
|
assertThat(cancelClaimResponse.getBody()).isNotNull();
|
||||||
|
assertThat(cancelClaimResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
|
TaskRepresentationModel cancelClaimedtaskRepresentationModel = cancelClaimResponse.getBody();
|
||||||
|
assertThat(cancelClaimedtaskRepresentationModel.getClaimed()).isNull();
|
||||||
|
assertThat(cancelClaimedtaskRepresentationModel.getState()).isEqualTo(TaskState.READY);
|
||||||
|
assertThat(cancelClaimedtaskRepresentationModel.getOwner()).isEqualTo("user-1-1");
|
||||||
|
assertThat(cancelClaimedtaskRepresentationModel.getOwnerLongName())
|
||||||
|
.isEqualTo("Mustermann, Max - (user-1-1)");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void should_ForceCancelClaim_When_TaskIsClaimedByDifferentOwner() {
|
void should_ForceCancelClaim_When_TaskIsClaimedByDifferentOwner() {
|
||||||
String url =
|
String url =
|
||||||
|
|
|
@ -30,4 +30,5 @@ taskana.jobs.priority.task.enable=true
|
||||||
taskana.jobs.cleanup.workbasket.enable=true
|
taskana.jobs.cleanup.workbasket.enable=true
|
||||||
taskana.jobs.refresh.user.enable=true
|
taskana.jobs.refresh.user.enable=true
|
||||||
taskana.jobs.cleanup.history.simple.enable=false
|
taskana.jobs.cleanup.history.simple.enable=false
|
||||||
|
taskana.user.addAdditionalUserInfo=true
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue