Skip to content

Commit

Permalink
Closes Taskana#2490: Set Owner of Task when Transferring
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesrdi committed Feb 13, 2024
1 parent 6ddb86f commit 02f64be
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 20 deletions.
117 changes: 117 additions & 0 deletions lib/taskana-core/src/main/java/pro/taskana/task/api/TaskService.java
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,11 @@ Task terminateTask(String taskId)
* Transfers a {@linkplain Task} to another {@linkplain Workbasket} while always setting
* {@linkplain Task#isTransferred() isTransferred} to true.
*
* @param taskId the {@linkplain Task#getId() id} of the {@linkplain Task} which should be
* transferred
* @param destinationWorkbasketId the {@linkplain Workbasket#getId() id} of the target {@linkplain
* Workbasket}
* @return the transferred {@linkplain Task}
* @see #transfer(String, String, boolean)
*/
@SuppressWarnings("checkstyle:JavadocMethod")
Expand Down Expand Up @@ -513,6 +518,13 @@ Task transfer(String taskId, String destinationWorkbasketId, boolean setTransfer
* Transfers a {@linkplain Task} to another {@linkplain Workbasket} while always setting
* {@linkplain Task#isTransferred isTransferred} .
*
* @param taskId the {@linkplain Task#getId() id} of the {@linkplain Task} which should be
* transferred
* @param workbasketKey the {@linkplain Workbasket#getKey() key} of the target {@linkplain
* Workbasket}
* @param domain the {@linkplain Workbasket#getDomain() domain} of the target {@linkplain
* Workbasket}
* @return the transferred {@linkplain Task}
* @see #transfer(String, String, String, boolean)
*/
@SuppressWarnings("checkstyle:JavadocMethod")
Expand Down Expand Up @@ -553,6 +565,111 @@ Task transfer(String taskId, String workbasketKey, String domain, boolean setTra
NotAuthorizedOnWorkbasketException,
InvalidTaskStateException;

/**
* Transfers a {@linkplain Task} to another {@linkplain Workbasket} and set owner of task in the
* new workbasket to {@param owner} while always setting {@linkplain Task#isTransferred()
* isTransferred} to true.
*
* @param taskId the {@linkplain Task#getId() id} of the {@linkplain Task} which should be
* transferred
* @param destinationWorkbasketId the {@linkplain Workbasket#getId() id} of the target {@linkplain
* Workbasket}
* @param owner the owner of the transferred {@linkplain Task} in the new workbasket
* @return the transferred {@linkplain Task}
* @see #transferWithOwner(String, String, String, boolean)
*/
@SuppressWarnings("checkstyle:JavadocMethod")
default Task transferWithOwner(String taskId, String destinationWorkbasketId, String owner)
throws TaskNotFoundException,
WorkbasketNotFoundException,
NotAuthorizedOnWorkbasketException,
InvalidTaskStateException {
return transferWithOwner(taskId, destinationWorkbasketId, owner, true);
}

/**
* Transfers a {@linkplain Task} to another {@linkplain Workbasket} and set owner.
*
* <p>The transfer resets {@linkplain Task#isRead() isRead} and sets {@linkplain
* Task#isTransferred() isTransferred} if setTransferFlag is true.
*
* @param taskId the {@linkplain Task#getId() id} of the {@linkplain Task} which should be
* transferred
* @param destinationWorkbasketId the {@linkplain Workbasket#getId() id} of the target {@linkplain
* Workbasket}
* @param owner the owner of the transferred {@linkplain Task} in the new workbasket
* @param setTransferFlag controls whether to set {@linkplain Task#isTransferred() isTransferred}
* to true or not
* @return the transferred {@linkplain Task}
* @throws TaskNotFoundException if the {@linkplain Task} with taskId wasn't found
* @throws WorkbasketNotFoundException if the target {@linkplain Workbasket} was not found
* @throws NotAuthorizedOnWorkbasketException if the current user has no {@linkplain
* WorkbasketPermission#READ} for the source {@linkplain Workbasket} or no {@linkplain
* WorkbasketPermission#TRANSFER} for the target {@linkplain Workbasket}
* @throws InvalidTaskStateException if the {@linkplain Task} is in one of the {@linkplain
* TaskState#END_STATES}
*/
Task transferWithOwner(
String taskId, String destinationWorkbasketId, String owner, boolean setTransferFlag)
throws TaskNotFoundException,
WorkbasketNotFoundException,
NotAuthorizedOnWorkbasketException,
InvalidTaskStateException;

/**
* Transfers a {@linkplain Task} to another {@linkplain Workbasket} and set owner of task in new
* workbasket to {@param owner} while always setting {@linkplain Task#isTransferred isTransferred}
* .
*
* @param taskId the {@linkplain Task#getId() id} of the {@linkplain Task} which should be
* transferred
* @param workbasketKey the {@linkplain Workbasket#getKey() key} of the target {@linkplain
* Workbasket}
* @param domain the {@linkplain Workbasket#getDomain() domain} of the target {@linkplain
* Workbasket}
* @param owner the owner of the transferred {@linkplain Task} in the new workbasket
* @see #transferWithOwner(String, String, String, String, boolean)
*/
@SuppressWarnings("checkstyle:JavadocMethod")
default Task transferWithOwner(String taskId, String workbasketKey, String domain, String owner)
throws TaskNotFoundException,
WorkbasketNotFoundException,
NotAuthorizedOnWorkbasketException,
InvalidTaskStateException {
return transferWithOwner(taskId, workbasketKey, domain, owner, true);
}

/**
* Transfers a {@linkplain Task} to another {@linkplain Workbasket} and set owner.
*
* <p>The transfer resets {@linkplain Task#isRead() isRead} and sets {@linkplain
* Task#isTransferred() isTransferred} if setTransferFlag is true.
*
* @param taskId the {@linkplain Task#getId() id} of the {@linkplain Task} which should be
* transferred
* @param workbasketKey the {@linkplain Workbasket#getKey() key} of the target {@linkplain
* Workbasket}
* @param domain the {@linkplain Workbasket#getDomain() domain} of the target {@linkplain
* Workbasket}
* @param owner the owner of the transferred {@linkplain Task} in the new workbasket
* @param setTransferFlag controls whether to set {@linkplain Task#isTransferred() isTransferred}
* or not
* @return the transferred {@linkplain Task}
* @throws TaskNotFoundException if the {@linkplain Task} with taskId was not found
* @throws WorkbasketNotFoundException if the target {@linkplain Workbasket} was not found
* @throws NotAuthorizedOnWorkbasketException if the current user has no {@linkplain
* WorkbasketPermission#READ} for the source {@linkplain Workbasket} or no {@linkplain
* WorkbasketPermission#TRANSFER} for the target {@linkplain Workbasket}
* @throws InvalidTaskStateException if the {@linkplain Task} is in one of the {@linkplain
* TaskState#END_STATES}
*/
Task transferWithOwner(
String taskId, String workbasketKey, String domain, String owner, boolean setTransferFlag)
throws TaskNotFoundException,
WorkbasketNotFoundException,
NotAuthorizedOnWorkbasketException,
InvalidTaskStateException;

/**
* Transfers a List of {@linkplain Task Tasks} to another {@linkplain Workbasket} while always
* setting {@linkplain Task#isTransferred isTransferred} to true.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,27 @@ public Task transfer(String taskId, String workbasketKey, String domain, boolean
return taskTransferrer.transfer(taskId, workbasketKey, domain, setTransferFlag);
}

@Override
public Task transferWithOwner(
String taskId, String destinationWorkbasketId, String owner, boolean setTransferFlag)
throws TaskNotFoundException,
WorkbasketNotFoundException,
NotAuthorizedOnWorkbasketException,
InvalidTaskStateException {
return taskTransferrer.transferWithOwner(
taskId, destinationWorkbasketId, owner, setTransferFlag);
}

@Override
public Task transferWithOwner(
String taskId, String workbasketKey, String domain, String owner, boolean setTransferFlag)
throws TaskNotFoundException,
WorkbasketNotFoundException,
NotAuthorizedOnWorkbasketException,
InvalidTaskStateException {
return taskTransferrer.transferWithOwner(taskId, workbasketKey, domain, owner, setTransferFlag);
}

@Override
public Task setTaskRead(String taskId, boolean isRead)
throws TaskNotFoundException, NotAuthorizedOnWorkbasketException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Task transfer(String taskId, String destinationWorkbasketId, boolean setTransfer
InvalidTaskStateException {
WorkbasketSummary destinationWorkbasket =
workbasketService.getWorkbasket(destinationWorkbasketId).asSummary();
return transferSingleTask(taskId, destinationWorkbasket, setTransferFlag);
return transferSingleTask(taskId, destinationWorkbasket, null, setTransferFlag);
}

Task transfer(
Expand All @@ -74,7 +74,7 @@ Task transfer(
InvalidTaskStateException {
WorkbasketSummary destinationWorkbasket =
workbasketService.getWorkbasket(destinationWorkbasketKey, destinationDomain).asSummary();
return transferSingleTask(taskId, destinationWorkbasket, setTransferFlag);
return transferSingleTask(taskId, destinationWorkbasket, null, setTransferFlag);
}

BulkOperationResults<String, TaskanaException> transfer(
Expand Down Expand Up @@ -104,8 +104,34 @@ BulkOperationResults<String, TaskanaException> transfer(
return transferMultipleTasks(taskIds, destinationWorkbasket, setTransferFlag);
}

Task transferWithOwner(
String taskId, String destinationWorkbasketId, String owner, boolean setTransferFlag)
throws TaskNotFoundException,
WorkbasketNotFoundException,
NotAuthorizedOnWorkbasketException,
InvalidTaskStateException {
WorkbasketSummary destinationWorkbasket =
workbasketService.getWorkbasket(destinationWorkbasketId).asSummary();
return transferSingleTask(taskId, destinationWorkbasket, owner, setTransferFlag);
}

Task transferWithOwner(
String taskId,
String destinationWorkbasketKey,
String destinationDomain,
String owner,
boolean setTransferFlag)
throws TaskNotFoundException,
WorkbasketNotFoundException,
NotAuthorizedOnWorkbasketException,
InvalidTaskStateException {
WorkbasketSummary destinationWorkbasket =
workbasketService.getWorkbasket(destinationWorkbasketKey, destinationDomain).asSummary();
return transferSingleTask(taskId, destinationWorkbasket, owner, setTransferFlag);
}

private Task transferSingleTask(
String taskId, WorkbasketSummary destinationWorkbasket, boolean setTransferFlag)
String taskId, WorkbasketSummary destinationWorkbasket, String owner, boolean setTransferFlag)
throws TaskNotFoundException,
WorkbasketNotFoundException,
NotAuthorizedOnWorkbasketException,
Expand All @@ -120,7 +146,7 @@ private Task transferSingleTask(
WorkbasketSummary originWorkbasket = task.getWorkbasketSummary();
checkPreconditionsForTransferTask(task, destinationWorkbasket, originWorkbasket);

applyTransferValuesForTask(task, destinationWorkbasket, setTransferFlag);
applyTransferValuesForTask(task, destinationWorkbasket, owner, setTransferFlag);
taskMapper.update(task);
if (historyEventManager.isEnabled()) {
createTransferredEvent(
Expand Down Expand Up @@ -262,7 +288,7 @@ private void updateTransferableTasks(
if (!taskSummariesWithSameGoalState.isEmpty()) {
TaskImpl updateObject = new TaskImpl();
updateObject.setState(goalState);
applyTransferValuesForTask(updateObject, destinationWorkbasket, setTransferFlag);
applyTransferValuesForTask(updateObject, destinationWorkbasket, null, setTransferFlag);
taskMapper.updateTransfered(
taskSummariesWithSameGoalState.stream()
.map(TaskSummary::getId)
Expand All @@ -275,7 +301,8 @@ private void updateTransferableTasks(
TaskSummaryImpl newSummary = (TaskSummaryImpl) oldSummary.copy();
newSummary.setId(oldSummary.getId());
newSummary.setExternalId(oldSummary.getExternalId());
applyTransferValuesForTask(newSummary, destinationWorkbasket, setTransferFlag);
applyTransferValuesForTask(
newSummary, destinationWorkbasket, null, setTransferFlag);

createTransferredEvent(
oldSummary,
Expand All @@ -289,11 +316,11 @@ private void updateTransferableTasks(
}

private void applyTransferValuesForTask(
TaskSummaryImpl task, WorkbasketSummary workbasket, boolean setTransferFlag) {
TaskSummaryImpl task, WorkbasketSummary workbasket, String owner, boolean setTransferFlag) {
task.setRead(false);
task.setTransferred(setTransferFlag);
task.setState(getStateAfterTransfer(task));
task.setOwner(null);
task.setOwner(owner);
task.setWorkbasketSummary(workbasket);
task.setDomain(workbasket.getDomain());
task.setModified(Instant.now());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.catchThrowableOfType;

import acceptance.AbstractAccTest;
import java.time.Instant;
Expand All @@ -29,6 +30,7 @@
import pro.taskana.task.api.exceptions.TaskNotFoundException;
import pro.taskana.task.api.models.Task;
import pro.taskana.task.api.models.TaskSummary;
import pro.taskana.workbasket.api.WorkbasketPermission;
import pro.taskana.workbasket.api.exceptions.NotAuthorizedOnWorkbasketException;
import pro.taskana.workbasket.api.exceptions.WorkbasketNotFoundException;
import pro.taskana.workbasket.api.models.Workbasket;
Expand Down Expand Up @@ -435,4 +437,40 @@ void should_NotSetTheTransferFlagWithinBulkTransfer_When_SetTransferFlagNotReque

assertThat(transferredTasks).extracting(TaskSummary::isTransferred).containsOnly(false);
}

@WithAccessId(user = "teamlead-1")
@Test
void should_SetOwnerAndNotBeAuthorized_When_TransferringTask() throws Exception {
taskService.transferWithOwner(
"TKI:000000000000000000000000000000000021",
"WBI:100000000000000000000000000000000005",
"teamlead-1");

Task transferredTask = taskService.getTask("TKI:000000000000000000000000000000000021");
assertThat(transferredTask.getOwner()).isEqualTo("teamlead-1");
ThrowingCallable call =
() ->
taskService.transfer(
"TKI:000000000000000000000000000000000021",
"WBI:100000000000000000000000000000000005");
NotAuthorizedOnWorkbasketException e =
catchThrowableOfType(call, NotAuthorizedOnWorkbasketException.class);
assertThat(e.getWorkbasketId()).isEqualTo("WBI:100000000000000000000000000000000005");
assertThat(e.getCurrentUserId()).isEqualTo("teamlead-1");
assertThat(e.getRequiredPermissions()).containsExactly(WorkbasketPermission.TRANSFER);
}

@WithAccessId(user = "teamlead-1", groups = GROUP_1_DN)
@Test
void should_TransferTaskAndSetOwner_When_WorkbasketKeyAndDomainIsProvided() throws Exception {
Task task = taskService.getTask("TKI:200000000000000000000000000000000066");

taskService.transferWithOwner(task.getId(), "USER-1-2", "DOMAIN_A", "teamlead-1");

Task transferredTask = taskService.getTask("TKI:200000000000000000000000000000000066");
assertThat(transferredTask).isNotNull();
assertThat(transferredTask.isTransferred()).isTrue();
assertThat(transferredTask.isRead()).isFalse();
assertThat(transferredTask.getState()).isEqualTo(TaskState.READY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import pro.taskana.task.rest.models.TaskRepresentationModel;
import pro.taskana.task.rest.models.TaskSummaryCollectionRepresentationModel;
import pro.taskana.task.rest.models.TaskSummaryPagedRepresentationModel;
import pro.taskana.task.rest.models.TransferTaskRepresentationModel;
import pro.taskana.workbasket.api.exceptions.NotAuthorizedOnWorkbasketException;
import pro.taskana.workbasket.api.exceptions.WorkbasketNotFoundException;

Expand Down Expand Up @@ -531,7 +532,8 @@ public ResponseEntity<TaskRepresentationModel> terminateTask(@PathVariable Strin
* @title Transfer a Task to another Workbasket
* @param taskId the Id of the Task which should be transferred
* @param workbasketId the Id of the destination Workbasket
* @param setTransferFlag sets the tansfer flag of the task (default: true)
* @param transferTaskRepresentationModel sets the transfer flag of the task (default: true) and
* owner of task
* @return the successfully transferred Task.
* @throws TaskNotFoundException if the requested Task does not exist
* @throws WorkbasketNotFoundException if the requested Workbasket does not exist
Expand All @@ -544,13 +546,27 @@ public ResponseEntity<TaskRepresentationModel> terminateTask(@PathVariable Strin
public ResponseEntity<TaskRepresentationModel> transferTask(
@PathVariable String taskId,
@PathVariable String workbasketId,
@RequestBody(required = false) Boolean setTransferFlag)
@RequestBody(required = false)
TransferTaskRepresentationModel transferTaskRepresentationModel)
throws TaskNotFoundException,
WorkbasketNotFoundException,
NotAuthorizedOnWorkbasketException,
InvalidTaskStateException {
Task updatedTask =
taskService.transfer(taskId, workbasketId, setTransferFlag == null || setTransferFlag);
Task updatedTask;
if (transferTaskRepresentationModel == null) {
updatedTask = taskService.transfer(taskId, workbasketId);
} else if (transferTaskRepresentationModel.getOwner() == null) {
updatedTask =
taskService.transfer(
taskId, workbasketId, transferTaskRepresentationModel.getSetTransferFlag());
} else {
updatedTask =
taskService.transferWithOwner(
taskId,
workbasketId,
transferTaskRepresentationModel.getOwner(),
transferTaskRepresentationModel.getSetTransferFlag());
}

return ResponseEntity.ok(taskRepresentationModelAssembler.toModel(updatedTask));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package pro.taskana.task.rest.models;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.beans.ConstructorProperties;

public class TransferTaskRepresentationModel {

@JsonProperty("owner")
private final String owner;

@JsonProperty("setTransferFlag")
private final Boolean setTransferFlag;

@ConstructorProperties({"setTransferFlag", "owner"})
public TransferTaskRepresentationModel(Boolean setTransferFlag, String owner) {
this.setTransferFlag = setTransferFlag == null || setTransferFlag;
this.owner = owner;
}

public Boolean getSetTransferFlag() {
return setTransferFlag;
}

public String getOwner() {
return owner;
}
}
Loading

0 comments on commit 02f64be

Please sign in to comment.