TSK-1160 TaskStates CANCELLED and TERMINATED

This commit is contained in:
BerndBreier 2020-03-13 14:52:23 +01:00
parent 4fe3c96a87
commit 2ce7f86456
31 changed files with 608 additions and 167 deletions

View File

@ -19,17 +19,17 @@ import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.SystemException;
/**
* The DaysToWorkingDaysConverter provides a method to convert an age in days into an age in working
* The WorkingDaysToDaysConverter provides a method to convert an age in working days into an age in
* days.
*/
public final class DaysToWorkingDaysConverter {
public final class WorkingDaysToDaysConverter {
private static boolean germanHolidaysEnabled;
private static Set<LocalDate> customHolidays = new HashSet<>();
private Instant referenceDate;
private LocalDate easterSunday;
private DaysToWorkingDaysConverter(Instant referenceDate) {
private WorkingDaysToDaysConverter(Instant referenceDate) {
easterSunday =
getEasterSunday(LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).getYear());
this.referenceDate = referenceDate;
@ -40,30 +40,37 @@ public final class DaysToWorkingDaysConverter {
}
/**
* Initializes the DaysToWorkingDaysConverter for the current day.
* Initializes the WorkingDaysToDaysConverter for the current day.
*
* @return an instance of the DaysToWorkingDaysConverter
* @throws InvalidArgumentException thrown if columnHeaders is null
* @return an instance of the WorkingDaysToDaysConverter
* @throws SystemException is thrown when the {@link WorkingDaysToDaysConverter} cannot be
* initialized with the current Instant. Should never occur.
*/
public static DaysToWorkingDaysConverter initialize() throws InvalidArgumentException {
return initialize(Instant.now());
public static WorkingDaysToDaysConverter initialize() {
try {
return initialize(Instant.now());
} catch (InvalidArgumentException ex) {
throw new SystemException(
"Internal error. Cannot initialize WorkingDaysToDaysConverter. This should not happen",
ex);
}
}
/**
* Initializes the DaysToWorkingDaysConverter for a referenceDate.
* Initializes the WorkingDaysToDaysConverter for a referenceDate.
*
* @param referenceDate a {@link Instant} that represents the current day of the table
* @return an instance of the DaysToWorkingDaysConverter
* @return an instance of the WorkingDaysToDaysConverter
* @throws InvalidArgumentException thrown if columnHeaders or referenceDate is null
*/
public static DaysToWorkingDaysConverter initialize(Instant referenceDate)
public static WorkingDaysToDaysConverter initialize(Instant referenceDate)
throws InvalidArgumentException {
if (referenceDate == null) {
throw new InvalidArgumentException("ReferenceDate cannot be used as NULL-Parameter");
}
return new DaysToWorkingDaysConverter(referenceDate);
return new WorkingDaysToDaysConverter(referenceDate);
}
public static void setGermanPublicHolidaysEnabled(boolean germanPublicHolidaysEnabled) {
@ -161,12 +168,12 @@ public final class DaysToWorkingDaysConverter {
int e = (2 * b + 4 * c + 6 * d + n) % 7;
if (d == 29 && e == 6) {
return LocalDate.of(year, 3, 15).plusDays(d + e);
return LocalDate.of(year, 3, 15).plusDays((long) d + e);
}
if (d == 28 && e == 6 && (11 * m + 11) % 30 < 19) {
return LocalDate.of(year, 3, 15).plusDays(d + e);
return LocalDate.of(year, 3, 15).plusDays((long) d + e);
}
return LocalDate.of(year, 3, 22).plusDays(d + e);
return LocalDate.of(year, 3, 22).plusDays((long) d + e);
}
private void refreshReferenceDate(Instant newReferenceDate) {
@ -182,7 +189,7 @@ public final class DaysToWorkingDaysConverter {
@Override
public String toString() {
return "DaysToWorkingDaysConverter{"
return "WorkingDaysToDaysConverter{"
+ "dateCreated="
+ referenceDate
+ ", easterSunday="

View File

@ -8,13 +8,13 @@ import org.slf4j.LoggerFactory;
import pro.taskana.common.api.LoggerUtils;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.internal.util.DaysToWorkingDaysConverter;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.monitor.api.reports.header.TimeIntervalColumnHeader;
/**
* The DaysToWorkingDaysReportConverter provides a method to convert an age in days into an age in
* working days. Before the method convertDaysToWorkingDays() can be used, the
* DaysToWorkingDaysConverter has to be initialized. For a list of {@link TimeIntervalColumnHeader}s
* WorkingDaysToDaysConverter has to be initialized. For a list of {@link TimeIntervalColumnHeader}s
* the converter creates a "table" with integer that represents the age in days from the largest
* lower limit until the smallest upper limit of the timeIntervalColumnHeaders. This table is valid
* for a whole day until the converter is initialized with bigger limits.
@ -25,19 +25,19 @@ public class DaysToWorkingDaysReportConverter {
LoggerFactory.getLogger(DaysToWorkingDaysReportConverter.class);
private List<Integer> positiveDaysToWorkingDays;
private List<Integer> negativeDaysToWorkingDays;
private DaysToWorkingDaysConverter daysToWorkingDaysConverter;
private WorkingDaysToDaysConverter workingDaysToDaysConverter;
DaysToWorkingDaysReportConverter(
List<? extends TimeIntervalColumnHeader> columnHeaders,
DaysToWorkingDaysConverter daysToWorkingDaysConverter) {
WorkingDaysToDaysConverter workingDaysToDaysConverter) {
this.daysToWorkingDaysConverter = daysToWorkingDaysConverter;
this.workingDaysToDaysConverter = workingDaysToDaysConverter;
positiveDaysToWorkingDays =
generatePositiveDaysToWorkingDays(
columnHeaders, daysToWorkingDaysConverter.getReferenceDate());
columnHeaders, workingDaysToDaysConverter.getReferenceDate());
negativeDaysToWorkingDays =
generateNegativeDaysToWorkingDays(
columnHeaders, daysToWorkingDaysConverter.getReferenceDate());
columnHeaders, workingDaysToDaysConverter.getReferenceDate());
}
public static DaysToWorkingDaysReportConverter initialize(
@ -46,14 +46,14 @@ public class DaysToWorkingDaysReportConverter {
}
/**
* Initializes the DaysToWorkingDaysConverter for a list of {@link TimeIntervalColumnHeader}s and
* Initializes the WorkingDaysToDaysConverter for a list of {@link TimeIntervalColumnHeader}s and
* a referenceDate. A new table is only created if there are bigger limits or the date has
* changed.
*
* @param columnHeaders a list of {@link TimeIntervalColumnHeader}s that determines the size of
* the table
* @param referenceDate a {@link Instant} that represents the current day of the table
* @return an instance of the DaysToWorkingDaysConverter
* @return an instance of the WorkingDaysToDaysConverter
* @throws InvalidArgumentException thrown if columnHeaders or referenceDate is null
*/
public static DaysToWorkingDaysReportConverter initialize(
@ -61,7 +61,7 @@ public class DaysToWorkingDaysReportConverter {
throws InvalidArgumentException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"Initialize DaysToWorkingDaysConverter with columnHeaders: {}",
"Initialize WorkingDaysToDaysConverter with columnHeaders: {}",
LoggerUtils.listToString(columnHeaders));
}
if (columnHeaders == null) {
@ -71,10 +71,10 @@ public class DaysToWorkingDaysReportConverter {
if (referenceDate == null) {
throw new InvalidArgumentException("ReferenceDate can´t be used as NULL-Parameter");
}
DaysToWorkingDaysConverter daysToWorkingDaysConverter =
DaysToWorkingDaysConverter.initialize(referenceDate);
WorkingDaysToDaysConverter workingDaysToDaysConverter =
WorkingDaysToDaysConverter.initialize(referenceDate);
return new DaysToWorkingDaysReportConverter(columnHeaders, daysToWorkingDaysConverter);
return new DaysToWorkingDaysReportConverter(columnHeaders, workingDaysToDaysConverter);
}
/**
@ -163,7 +163,7 @@ public class DaysToWorkingDaysReportConverter {
int day = -1;
int workingDay = 0;
while (workingDay > minUpperLimit) {
workingDay -= (daysToWorkingDaysConverter.isWorkingDay(day--, referenceDate)) ? 1 : 0;
workingDay -= (workingDaysToDaysConverter.isWorkingDay(day--, referenceDate)) ? 1 : 0;
daysToWorkingDays.add(workingDay);
}
return daysToWorkingDays;
@ -178,7 +178,7 @@ public class DaysToWorkingDaysReportConverter {
int day = 1;
int workingDay = 0;
while (workingDay < maxLowerLimit) {
workingDay += (daysToWorkingDaysConverter.isWorkingDay(day++, referenceDate)) ? 1 : 0;
workingDay += (workingDaysToDaysConverter.isWorkingDay(day++, referenceDate)) ? 1 : 0;
daysToWorkingDays.add(workingDay);
}
return daysToWorkingDays;
@ -190,8 +190,8 @@ public class DaysToWorkingDaysReportConverter {
+ positiveDaysToWorkingDays
+ ", negativeDaysToWorkingDays="
+ negativeDaysToWorkingDays
+ ", daysToWorkingDaysConverter="
+ daysToWorkingDaysConverter
+ ", workingDaysToDaysConverter="
+ workingDaysToDaysConverter
+ "]";
}
}

View File

@ -3,13 +3,13 @@ package pro.taskana.monitor.internal.preprocessor;
import java.util.List;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.internal.util.DaysToWorkingDaysConverter;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.monitor.api.reports.header.TimeIntervalColumnHeader;
import pro.taskana.monitor.api.reports.item.AgeQueryItem;
import pro.taskana.monitor.api.reports.item.QueryItemPreprocessor;
/**
* Uses {@link DaysToWorkingDaysConverter} to convert an &lt;I&gt;s age to working days.
* Uses {@link WorkingDaysToDaysConverter} to convert an &lt;I&gt;s age to working days.
*
* @param <I> QueryItem which is being processed
*/

View File

@ -13,7 +13,7 @@ import pro.taskana.common.api.TaskanaRole;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.internal.InternalTaskanaEngine;
import pro.taskana.common.internal.util.DaysToWorkingDaysConverter;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.monitor.api.SelectedItem;
import pro.taskana.monitor.api.reports.ClassificationReport;
import pro.taskana.monitor.api.reports.TimeIntervalReportBuilder;
@ -55,7 +55,7 @@ abstract class TimeIntervalReportBuilderImpl<
this.taskanaEngine = taskanaEngine;
this.monitorMapper = monitorMapper;
this.columnHeaders = Collections.emptyList();
configureDaysToWorkingDaysConverter();
configureWorkingDaysToDaysConverter();
}
@Override
@ -185,10 +185,10 @@ abstract class TimeIntervalReportBuilderImpl<
protected abstract String determineGroupedBy();
private void configureDaysToWorkingDaysConverter() {
DaysToWorkingDaysConverter.setCustomHolidays(
private void configureWorkingDaysToDaysConverter() {
WorkingDaysToDaysConverter.setCustomHolidays(
this.taskanaEngine.getEngine().getConfiguration().getCustomHolidays());
DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled(
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(
this.taskanaEngine.getEngine().getConfiguration().isGermanPublicHolidaysEnabled());
}

View File

@ -490,4 +490,28 @@ public interface TaskService {
*/
BulkOperationResults<String, TaskanaException> setPlannedPropertyOfTasks(
Instant planned, List<String> taskIds);
/**
* Cancels a task.
*
* @param taskId the id of the task to cancel.
* @return the updated task.
* @throws TaskNotFoundException if the Task with Id TaskId is not found
* @throws InvalidStateException if the task is not in state READY or CLAIMED
* @throws NotAuthorizedException if the current user is not authorized to see the task
*/
Task cancelTask(String taskId)
throws TaskNotFoundException, InvalidStateException, NotAuthorizedException;
/**
* Terminates a task.
*
* @param taskId the id of the task to cancel.
* @return the updated task.
* @throws TaskNotFoundException if the Task with Id TaskId is not found
* @throws InvalidStateException if the task is not in state READY or CLAIMED
* @throws NotAuthorizedException if the current user is not authorized to see the task
*/
Task terminateTask(String taskId)
throws TaskNotFoundException, InvalidStateException, NotAuthorizedException;
}

View File

@ -4,5 +4,20 @@ package pro.taskana.task.api;
public enum TaskState {
READY,
CLAIMED,
COMPLETED
COMPLETED,
CANCELLED,
TERMINATED;
public boolean isInStates(TaskState... states) {
for (TaskState currState : states) {
if (this.equals(currState)) {
return true;
}
}
return false;
}
public boolean isEndState() {
return this.equals(COMPLETED) || this.equals(CANCELLED) || this.equals(TERMINATED);
}
}

View File

@ -17,11 +17,11 @@ import org.slf4j.LoggerFactory;
import pro.taskana.classification.api.models.ClassificationSummary;
import pro.taskana.common.api.BulkOperationResults;
import pro.taskana.common.api.LoggerUtils;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.SystemException;
import pro.taskana.common.api.exceptions.TaskanaException;
import pro.taskana.common.internal.InternalTaskanaEngine;
import pro.taskana.common.internal.util.DaysToWorkingDaysConverter;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.task.api.exceptions.UpdateFailedException;
import pro.taskana.task.api.models.Attachment;
import pro.taskana.task.api.models.AttachmentSummary;
@ -33,13 +33,11 @@ import pro.taskana.task.internal.models.TaskImpl;
class ServiceLevelHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(ServiceLevelHandler.class);
private static final String ERROR_CANNOT_INITIALIZE_DAYS_TO_WORKING_DAYS_CONVERTER =
"Internal error. Cannot initialize DaysToWorkingDaysConverter";
private static final Duration MAX_DURATION = Duration.ofSeconds(Long.MAX_VALUE, 999_999_999);
private final InternalTaskanaEngine taskanaEngine;
private final TaskMapper taskMapper;
private final AttachmentMapper attachmentMapper;
private DaysToWorkingDaysConverter converter;
private WorkingDaysToDaysConverter converter;
ServiceLevelHandler(
InternalTaskanaEngine taskanaEngine,
@ -48,14 +46,9 @@ class ServiceLevelHandler {
this.taskanaEngine = taskanaEngine;
this.taskMapper = taskMapper;
this.attachmentMapper = attachmentMapper;
DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled(
taskanaEngine.getEngine().getConfiguration().isGermanPublicHolidaysEnabled());
try {
converter = DaysToWorkingDaysConverter.initialize();
} catch (InvalidArgumentException e) {
LOGGER.error(ERROR_CANNOT_INITIALIZE_DAYS_TO_WORKING_DAYS_CONVERTER);
throw new SystemException(
ERROR_CANNOT_INITIALIZE_DAYS_TO_WORKING_DAYS_CONVERTER, e.getCause());
this.converter = WorkingDaysToDaysConverter.initialize();
if (taskanaEngine.getEngine().getConfiguration().isGermanPublicHolidaysEnabled()) {
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);
}
}
@ -91,8 +84,16 @@ class ServiceLevelHandler {
BulkLog setPlannedPropertyOfTasksImpl(Instant planned, List<MinimalTaskSummary> tasks) {
BulkLog bulkLog = new BulkLog();
List<AttachmentSummaryImpl> attachments = getAttachmentSummaries(tasks);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("found attachments {}.", LoggerUtils.listToString(attachments));
}
List<ClassificationSummary> allInvolvedClassifications =
findAllClassificationsReferencedByTasksAndAttachments(tasks, attachments);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"found involved classifications {}.",
LoggerUtils.listToString(allInvolvedClassifications));
}
List<ClassificationWithServiceLevelResolved> allInvolvedClassificationsWithDuration =
resolveDurationsInClassifications(allInvolvedClassifications);
Map<Duration, List<String>> durationToTaskIdsMap =

View File

@ -72,16 +72,17 @@ import pro.taskana.workbasket.internal.models.WorkbasketSummaryImpl;
@SuppressWarnings("checkstyle:OverloadMethodsDeclarationOrder")
public class TaskServiceImpl implements TaskService {
private static final String IS_ALREADY_CLAIMED_BY = " is already claimed by ";
private static final String IS_ALREADY_COMPLETED = " is already completed.";
public static final String IDS_WITH_EMPTY_OR_NULL_VALUE_ARE_NOT_ALLOWED =
"IDs with EMPTY or NULL value are not allowed.";
private static final String TASK_WITH_ID_IS_NOT_READY =
"Task with id %s is in state %s and not in state ready.";
private static final String TASK_WITH_ID_WAS_NOT_FOUND = "Task with id %s was not found.";
private static final String TASK_WITH_ID_HAS_TO_BE_CLAIMED_BEFORE =
"Task with Id %s has to be claimed before.";
private static final String TASK_WITH_ID_CALLBACK_NOT_PROCESSED =
"Task wit Id %s cannot be deleted because its callback is not yet processed";
private static final String WAS_NOT_FOUND2 = " was not found.";
private static final String WAS_NOT_FOUND = " was not found";
private static final String TASK_WITH_ID = "Task with id ";
private static final String TASK_WITH_ID_IS_ALREADY_CLAIMED_BY =
"Task with id %s is already claimed by %s.";
private static final String WAS_MARKED_FOR_DELETION = " was marked for deletion";
private static final String THE_WORKBASKET = "The workbasket ";
private static final String TASK = "Task";
@ -89,9 +90,10 @@ public class TaskServiceImpl implements TaskService {
private static final String ID_PREFIX_TASK = "TKI";
private static final String ID_PREFIX_EXT_TASK_ID = "ETI";
private static final String ID_PREFIX_BUSINESS_PROCESS = "BPI";
private static final Set<String> ALLOWED_KEYS =
IntStream.rangeClosed(1, 16).mapToObj(String::valueOf).collect(Collectors.toSet());
private static final String TASK_WITH_ID_IS_ALREADY_IN_END_STATE =
"Task with Id %s is already in an end state.";
private InternalTaskanaEngine taskanaEngine;
private WorkbasketService workbasketService;
private ClassificationService classificationService;
@ -314,7 +316,7 @@ public class TaskServiceImpl implements TaskService {
resultTask.setClassificationSummary(classification);
return resultTask;
} else {
throw new TaskNotFoundException(id, TASK_WITH_ID + id + WAS_NOT_FOUND);
throw new TaskNotFoundException(id, String.format(TASK_WITH_ID_WAS_NOT_FOUND, id));
}
} finally {
taskanaEngine.returnConnection();
@ -749,6 +751,32 @@ public class TaskServiceImpl implements TaskService {
}
}
@Override
public Task cancelTask(String taskId)
throws TaskNotFoundException, InvalidStateException, NotAuthorizedException {
LOGGER.debug("entry to cancelTask(task = {})", taskId);
try {
taskanaEngine.openConnection();
return terminateCancelCommonActions(taskId, TaskState.CANCELLED);
} finally {
taskanaEngine.returnConnection();
LOGGER.debug("exit from cancelTask()");
}
}
@Override
public Task terminateTask(String taskId)
throws TaskNotFoundException, InvalidStateException, NotAuthorizedException {
LOGGER.debug("entry to terminateTask(task = {})", taskId);
try {
taskanaEngine.openConnection();
return terminateCancelCommonActions(taskId, TaskState.TERMINATED);
} finally {
taskanaEngine.returnConnection();
LOGGER.debug("exit from terminateTask()");
}
}
public List<String> findTasksIdsAffectedByClassificationChange(String classificationId) {
LOGGER.debug(
"entry to findTasksIdsAffectedByClassificationChange(classificationId = {})",
@ -894,7 +922,7 @@ public class TaskServiceImpl implements TaskService {
String currentTaskId = taskIdIterator.next();
if (currentTaskId == null || currentTaskId.equals("")) {
bulkLog.addError(
"", new InvalidArgumentException("IDs with EMPTY or NULL value are not allowed."));
"", new InvalidArgumentException(IDS_WITH_EMPTY_OR_NULL_VALUE_ARE_NOT_ALLOWED));
taskIdIterator.remove();
}
}
@ -951,6 +979,29 @@ public class TaskServiceImpl implements TaskService {
return newTaskImpl;
}
private TaskImpl terminateCancelCommonActions(String taskId, TaskState targetState)
throws NotAuthorizedException, TaskNotFoundException, InvalidStateException {
if (taskId == null || taskId.isEmpty()) {
throw new TaskNotFoundException(taskId, String.format(TASK_WITH_ID_WAS_NOT_FOUND, taskId));
}
TaskImpl task = (TaskImpl) getTask(taskId);
TaskState state = task.getState();
if (state.isEndState()) {
throw new InvalidStateException(String.format(TASK_WITH_ID_IS_ALREADY_IN_END_STATE, taskId));
}
Instant now = Instant.now();
task.setOwner(null);
task.setModified(now);
task.setCompleted(now);
task.setClaimed(null);
task.setRead(true);
task.setState(targetState);
taskMapper.update(task);
LOGGER.debug("Task '{}' cancelled by user '{}'.", taskId, CurrentUserContext.getUserid());
return task;
}
private BulkOperationResults<String, TaskanaException> addExceptionsForTasksWhoseOwnerWasNotSet(
String owner, List<MinimalTaskSummary> existingMinimalTaskSummaries) {
BulkOperationResults<String, TaskanaException> bulkLog = new BulkOperationResults<>();
@ -987,12 +1038,13 @@ public class TaskServiceImpl implements TaskService {
taskanaEngine.openConnection();
task = (TaskImpl) getTask(taskId);
TaskState state = task.getState();
if (state == TaskState.COMPLETED) {
throw new InvalidStateException(TASK_WITH_ID + taskId + IS_ALREADY_COMPLETED);
if (!state.isInStates(TaskState.READY, TaskState.CLAIMED)) {
throw new InvalidStateException(
String.format(TASK_WITH_ID_IS_ALREADY_IN_END_STATE, taskId));
}
if (state == TaskState.CLAIMED && !forceClaim && !task.getOwner().equals(userId)) {
throw new InvalidOwnerException(
TASK_WITH_ID + taskId + IS_ALREADY_CLAIMED_BY + task.getOwner() + ".");
String.format(TASK_WITH_ID_IS_ALREADY_CLAIMED_BY, taskId, task.getOwner()));
}
Instant now = Instant.now();
task.setOwner(userId);
@ -1026,12 +1078,13 @@ public class TaskServiceImpl implements TaskService {
taskanaEngine.openConnection();
task = (TaskImpl) getTask(taskId);
TaskState state = task.getState();
if (state == TaskState.COMPLETED) {
throw new InvalidStateException(TASK_WITH_ID + taskId + IS_ALREADY_COMPLETED);
if (state.isEndState()) {
throw new InvalidStateException(
String.format(TASK_WITH_ID_IS_ALREADY_IN_END_STATE, taskId));
}
if (state == TaskState.CLAIMED && !forceUnclaim && !userId.equals(task.getOwner())) {
throw new InvalidOwnerException(
TASK_WITH_ID + taskId + IS_ALREADY_CLAIMED_BY + task.getOwner() + ".");
String.format(TASK_WITH_ID_IS_ALREADY_CLAIMED_BY, taskId, task.getOwner()));
}
Instant now = Instant.now();
task.setOwner(null);
@ -1067,10 +1120,17 @@ public class TaskServiceImpl implements TaskService {
return task;
}
if (task.getState().isInStates(TaskState.CANCELLED, TaskState.TERMINATED)) {
throw new InvalidStateException(
String.format(
"Cannot complete task %s because it is in state %s.", taskId, task.getState()));
}
// check pre-conditions for non-forced invocation
if (!isForced) {
if (task.getClaimed() == null || task.getState() != TaskState.CLAIMED) {
throw new InvalidStateException(TASK_WITH_ID + taskId + " has to be claimed before.");
throw new InvalidStateException(
String.format(TASK_WITH_ID_HAS_TO_BE_CLAIMED_BEFORE, taskId));
} else if (!CurrentUserContext.getAccessIds().contains(task.getOwner())) {
throw new InvalidOwnerException(
String.format(
@ -1109,11 +1169,12 @@ public class TaskServiceImpl implements TaskService {
taskanaEngine.openConnection();
task = (TaskImpl) getTask(taskId);
if (!TaskState.COMPLETED.equals(task.getState()) && !forceDelete) {
if (!(task.getState().isEndState()) && !forceDelete) {
throw new InvalidStateException(
"Cannot delete Task " + taskId + " because it is not completed.");
"Cannot delete Task " + taskId + " because it is not in an end state.");
}
if (CallbackState.CALLBACK_PROCESSING_REQUIRED.equals(task.getCallbackState())) {
if ((!task.getState().isInStates(TaskState.TERMINATED, TaskState.CANCELLED))
&& CallbackState.CALLBACK_PROCESSING_REQUIRED.equals(task.getCallbackState())) {
throw new InvalidStateException(String.format(TASK_WITH_ID_CALLBACK_NOT_PROCESSED, taskId));
}
@ -1133,7 +1194,7 @@ public class TaskServiceImpl implements TaskService {
String currentTaskId = taskIdIterator.next();
if (currentTaskId == null || currentTaskId.equals("")) {
bulkLog.addError(
"", new InvalidArgumentException("IDs with EMPTY or NULL value are not allowed."));
"", new InvalidArgumentException(IDS_WITH_EMPTY_OR_NULL_VALUE_ARE_NOT_ALLOWED));
taskIdIterator.remove();
} else {
MinimalTaskSummary foundSummary =
@ -1145,13 +1206,14 @@ public class TaskServiceImpl implements TaskService {
bulkLog.addError(
currentTaskId,
new TaskNotFoundException(
currentTaskId, TASK_WITH_ID + currentTaskId + WAS_NOT_FOUND2));
currentTaskId, String.format(TASK_WITH_ID_WAS_NOT_FOUND, currentTaskId)));
taskIdIterator.remove();
} else if (!TaskState.COMPLETED.equals(foundSummary.getTaskState())) {
} else if (!(foundSummary.getTaskState().isEndState())) {
bulkLog.addError(currentTaskId, new InvalidStateException(currentTaskId));
taskIdIterator.remove();
} else {
if (CallbackState.CALLBACK_PROCESSING_REQUIRED.equals(foundSummary.getCallbackState())) {
if ((!foundSummary.getTaskState().isInStates(TaskState.CANCELLED, TaskState.TERMINATED))
&& CallbackState.CALLBACK_PROCESSING_REQUIRED.equals(foundSummary.getCallbackState())) {
bulkLog.addError(
currentTaskId,
new InvalidStateException(
@ -1172,7 +1234,7 @@ public class TaskServiceImpl implements TaskService {
String currentExternalId = externalIdIterator.next();
if (currentExternalId == null || currentExternalId.equals("")) {
bulkLog.addError(
"", new InvalidArgumentException("IDs with EMPTY or NULL value are not allowed."));
"", new InvalidArgumentException(IDS_WITH_EMPTY_OR_NULL_VALUE_ARE_NOT_ALLOWED));
externalIdIterator.remove();
} else {
MinimalTaskSummary foundSummary =
@ -1184,7 +1246,7 @@ public class TaskServiceImpl implements TaskService {
bulkLog.addError(
currentExternalId,
new TaskNotFoundException(
currentExternalId, TASK_WITH_ID + currentExternalId + WAS_NOT_FOUND2));
currentExternalId, String.format(TASK_WITH_ID_WAS_NOT_FOUND, currentExternalId)));
externalIdIterator.remove();
} else if (!desiredCallbackStateCanBeSetForFoundSummary(foundSummary, desiredCallbackState)) {
bulkLog.addError(currentExternalId, new InvalidStateException(currentExternalId));
@ -1202,7 +1264,7 @@ public class TaskServiceImpl implements TaskService {
switch (desiredCallbackState) {
case CALLBACK_PROCESSING_COMPLETED:
return currentTaskState.equals(TaskState.COMPLETED);
return currentTaskState.isEndState();
case CLAIMED:
if (!currentTaskState.equals(TaskState.CLAIMED)) {

View File

@ -37,8 +37,8 @@ import pro.taskana.workbasket.internal.WorkbasketQueryImpl;
public class TaskTransferrer {
private static final String WAS_NOT_FOUND2 = " was not found.";
private static final String CANNOT_BE_TRANSFERRED = " cannot be transferred.";
private static final String COMPLETED_TASK_WITH_ID = "Completed task with id ";
private static final String TASK_IN_END_STATE_WITH_ID_CANNOT_BE_TRANSFERRED
= "Task in end state with id %s cannot be transferred.";
private static final String TASK_WITH_ID = "Task with id ";
private static final String WAS_MARKED_FOR_DELETION = " was marked for deletion";
private static final String THE_WORKBASKET = "The workbasket ";
@ -73,9 +73,9 @@ public class TaskTransferrer {
taskanaEngine.openConnection();
task = (TaskImpl) taskService.getTask(taskId);
if (task.getState() == TaskState.COMPLETED) {
if (task.getState().isEndState()) {
throw new InvalidStateException(
COMPLETED_TASK_WITH_ID + task.getId() + CANNOT_BE_TRANSFERRED);
String.format(TASK_IN_END_STATE_WITH_ID_CANNOT_BE_TRANSFERRED, task.getId()));
}
// Save previous workbasket id before transfer it.
@ -134,9 +134,9 @@ public class TaskTransferrer {
taskanaEngine.openConnection();
task = (TaskImpl) taskService.getTask(taskId);
if (task.getState() == TaskState.COMPLETED) {
if (task.getState().isEndState()) {
throw new InvalidStateException(
COMPLETED_TASK_WITH_ID + task.getId() + CANNOT_BE_TRANSFERRED);
String.format(TASK_IN_END_STATE_WITH_ID_CANNOT_BE_TRANSFERRED, task.getId()));
}
oldWorkbasketSummary = task.getWorkbasketSummary();
@ -344,11 +344,11 @@ public class TaskTransferrer {
new TaskNotFoundException(
currentTaskId, TASK_WITH_ID + currentTaskId + WAS_NOT_FOUND2));
taskIdIterator.remove();
} else if (taskSummary.getTaskState() == TaskState.COMPLETED) {
} else if (taskSummary.getTaskState().isEndState()) {
bulkLog.addError(
currentTaskId,
new InvalidStateException(
COMPLETED_TASK_WITH_ID + currentTaskId + CANNOT_BE_TRANSFERRED));
String.format(TASK_IN_END_STATE_WITH_ID_CANNOT_BE_TRANSFERRED, currentTaskId)));
taskIdIterator.remove();
} else if (sourceWorkbaskets.stream()
.noneMatch(wb -> taskSummary.getWorkbasketId().equals(wb.getId()))) {

View File

@ -900,7 +900,7 @@ public class WorkbasketServiceImpl implements WorkbasketService {
.getTaskService()
.createTaskQuery()
.workbasketIdIn(workbasketId)
.stateNotIn(TaskState.COMPLETED)
.stateNotIn(TaskState.COMPLETED, TaskState.TERMINATED, TaskState.CANCELLED)
.count();
}

View File

@ -27,7 +27,7 @@ import pro.taskana.common.api.exceptions.DomainNotFoundException;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.internal.jobs.JobRunner;
import pro.taskana.common.internal.util.DaysToWorkingDaysConverter;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.security.JaasExtension;
import pro.taskana.security.WithAccessId;
import pro.taskana.task.api.TaskService;
@ -234,8 +234,8 @@ public class UpdateClassificationAccTest extends AbstractAccTest {
assertFalse(modifiedBefore.isAfter(updatedClassification.getModified()));
// TODO - resume old behaviour after attachment query is possible.
TaskService taskService = taskanaEngine.getTaskService();
DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled(true);
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(Instant.now());
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
List<String> tasksWithP1D =
new ArrayList<>(
@ -353,8 +353,8 @@ public class UpdateClassificationAccTest extends AbstractAccTest {
assertFalse(modifiedBefore.isAfter(updatedClassification.getModified()));
// TODO - resume old behaviour after attachment query is possible.
TaskService taskService = taskanaEngine.getTaskService();
DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled(true);
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(Instant.now());
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
List<String> tasksWithPrio99 =
new ArrayList<>(
@ -493,8 +493,8 @@ public class UpdateClassificationAccTest extends AbstractAccTest {
assertFalse(modifiedBefore.isAfter(updatedClassification.getModified()));
// TODO - resume old behaviour after attachment query is possible.
TaskService taskService = taskanaEngine.getTaskService();
DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled(true);
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(Instant.now());
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
List<String> tasksWithPD12 =
new ArrayList<>(
Arrays.asList(
@ -573,12 +573,13 @@ public class UpdateClassificationAccTest extends AbstractAccTest {
Instant before,
List<String> tasksUpdated,
TaskService taskService,
DaysToWorkingDaysConverter converter,
WorkingDaysToDaysConverter converter,
int serviceLevel,
int priority)
throws TaskNotFoundException, NotAuthorizedException, InvalidArgumentException {
for (String taskId : tasksUpdated) {
Task task = taskService.getTask(taskId);
assertTrue(
task.getModified().isAfter(before), "Task " + task.getId() + " has not been refreshed.");
long calendarDays = converter.convertWorkingDaysToDays(task.getPlanned(), serviceLevel);

View File

@ -46,7 +46,7 @@ class TaskCleanupJobAccTest extends AbstractAccTest {
createAndCompleteTask();
long totalTasksCount = taskService.createTaskQuery().count();
assertEquals(74, totalTasksCount);
assertEquals(84, totalTasksCount);
taskanaEngine.getConfiguration().setTaskCleanupJobAllCompletedSameParentBusiness(false);
@ -61,7 +61,7 @@ class TaskCleanupJobAccTest extends AbstractAccTest {
@Test
void shouldCleanCompletedTasksUntilDateWithSameParentBussiness() throws Exception {
long totalTasksCount = taskService.createTaskQuery().count();
assertEquals(73, totalTasksCount);
assertEquals(83, totalTasksCount);
taskanaEngine.getConfiguration().setTaskCleanupJobAllCompletedSameParentBusiness(true);

View File

@ -59,6 +59,7 @@ public class UpdateObjectsUseUtcTimeStampsAccTest extends AbstractAccTest {
TaskService taskService = taskanaEngine.getTaskService();
Task task = taskService.getTask("TKI:000000000000000000000000000000000000");
Instant now = Instant.now();
task.setPlanned(now.plus(Duration.ofHours(17)));
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);

View File

@ -23,7 +23,7 @@ public class AbstractReportAccTest {
resetDb();
}
private static void resetDb() throws SQLException {
protected static void resetDb() throws SQLException {
DataSource dataSource = TaskanaEngineTestConfiguration.getDataSource();
String schemaName = TaskanaEngineTestConfiguration.getSchemaName();
taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false, schemaName);

View File

@ -5,9 +5,11 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
@ -22,7 +24,10 @@ import pro.taskana.monitor.api.reports.item.TaskQueryItem;
import pro.taskana.monitor.api.reports.row.Row;
import pro.taskana.security.JaasExtension;
import pro.taskana.security.WithAccessId;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.TaskState;
import pro.taskana.task.api.exceptions.InvalidStateException;
import pro.taskana.task.api.exceptions.TaskNotFoundException;
/** Acceptance test for all "task status report" scenarios. */
@ExtendWith(JaasExtension.class)
@ -31,6 +36,11 @@ class ProvideTaskStatusReportAccTest extends AbstractReportAccTest {
private static final Logger LOGGER =
LoggerFactory.getLogger(ProvideWorkbasketReportAccTest.class);
@BeforeEach
public void reset() throws Exception {
resetDb();
}
@Test
void testRoleCheck() {
MonitorService monitorService = taskanaEngine.getMonitorService();
@ -54,19 +64,19 @@ class ProvideTaskStatusReportAccTest extends AbstractReportAccTest {
assertEquals(3, report.rowSize());
Row<TaskQueryItem> row1 = report.getRow("DOMAIN_A");
assertArrayEquals(new int[] {22, 4, 0}, row1.getCells());
assertArrayEquals(new int[] {22, 4, 0, 0, 0}, row1.getCells());
assertEquals(26, row1.getTotalValue());
Row<TaskQueryItem> row2 = report.getRow("DOMAIN_B");
assertArrayEquals(new int[] {9, 3, 0}, row2.getCells());
assertArrayEquals(new int[] {9, 3, 0, 0, 0}, row2.getCells());
assertEquals(12, row2.getTotalValue());
Row<TaskQueryItem> row3 = report.getRow("DOMAIN_C");
assertArrayEquals(new int[] {10, 2, 0}, row3.getCells());
assertArrayEquals(new int[] {10, 2, 0, 0, 0}, row3.getCells());
assertEquals(12, row3.getTotalValue());
Row<TaskQueryItem> sumRow = report.getSumRow();
assertArrayEquals(new int[] {41, 9, 0}, sumRow.getCells());
assertArrayEquals(new int[] {41, 9, 0, 0, 0}, sumRow.getCells());
assertEquals(50, sumRow.getTotalValue());
}
@ -98,15 +108,15 @@ class ProvideTaskStatusReportAccTest extends AbstractReportAccTest {
assertEquals(2, report.rowSize());
Row<TaskQueryItem> row1 = report.getRow("DOMAIN_A");
assertArrayEquals(new int[] {22, 4, 0}, row1.getCells());
assertArrayEquals(new int[] {22, 4, 0, 0, 0}, row1.getCells());
assertEquals(26, row1.getTotalValue());
Row<TaskQueryItem> row2 = report.getRow("DOMAIN_C");
assertArrayEquals(new int[] {10, 2, 0}, row2.getCells());
assertArrayEquals(new int[] {10, 2, 0, 0, 0}, row2.getCells());
assertEquals(12, row2.getTotalValue());
Row<TaskQueryItem> sumRow = report.getSumRow();
assertArrayEquals(new int[] {32, 6, 0}, sumRow.getCells());
assertArrayEquals(new int[] {32, 6, 0, 0, 0}, sumRow.getCells());
assertEquals(38, sumRow.getTotalValue());
}
@ -146,6 +156,40 @@ class ProvideTaskStatusReportAccTest extends AbstractReportAccTest {
assertEquals(41, sumRow.getTotalValue());
}
@WithAccessId(
userName = "monitor",
groupNames = {"admin"})
@Test
void testCompleteTaskStatusReportWithStates()
throws NotAuthorizedException, InvalidArgumentException, InvalidStateException,
TaskNotFoundException {
TaskService taskService = taskanaEngine.getTaskService();
taskService.terminateTask("TKI:000000000000000000000000000000000010");
taskService.terminateTask("TKI:000000000000000000000000000000000011");
taskService.terminateTask("TKI:000000000000000000000000000000000012");
taskService.cancelTask("TKI:000000000000000000000000000000000013");
taskService.cancelTask("TKI:000000000000000000000000000000000014");
MonitorService monitorService = taskanaEngine.getMonitorService();
TaskStatusReport report =
monitorService
.createTaskStatusReportBuilder()
.stateIn(
Arrays.asList(
TaskState.READY,
TaskState.CLAIMED,
TaskState.COMPLETED,
TaskState.CANCELLED,
TaskState.TERMINATED))
.buildReport();
// String rep = reportToString(report);
// System.out.println(rep);
int[] summaryNumbers = report.getSumRow().getCells();
assertEquals(5, summaryNumbers.length);
assertEquals(2, summaryNumbers[3]); // number of cancelled tasks
assertEquals(3, summaryNumbers[4]); // number of terminated tasks
}
private String reportToString(TaskStatusReport report) {
List<TaskStatusColumnHeader> columnHeaders = report.getColumnHeaders();
String formatColumnWidth = "| %-7s ";

View File

@ -61,6 +61,6 @@ class TaskQueryAccTest extends AbstractAccTest {
List<TaskSummary> results = taskService.createTaskQuery().ownerLike("%a%", "%u%").list();
assertThat(results.size(), equalTo(25));
assertThat(results.size(), equalTo(35));
}
}

View File

@ -0,0 +1,128 @@
package acceptance.task;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import acceptance.AbstractAccTest;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.security.JaasExtension;
import pro.taskana.security.WithAccessId;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.TaskState;
import pro.taskana.task.api.exceptions.InvalidStateException;
import pro.taskana.task.api.exceptions.TaskNotFoundException;
import pro.taskana.task.api.models.Task;
import pro.taskana.task.api.models.TaskSummary;
/** Acceptance tests for all claim and complete scenarios. */
@ExtendWith(JaasExtension.class)
class CancelTaskAccTest extends AbstractAccTest {
private TaskService taskService;
CancelTaskAccTest() {
super();
taskService = taskanaEngine.getTaskService();
}
@BeforeEach
public static void setupTest() throws Exception {
resetDb(false);
}
@WithAccessId(
userName = "user_1_1",
groupNames = {"group_1"})
@Test
void testQeryCancelledTasks() {
List<TaskSummary> taskSummaries =
taskService.createTaskQuery().stateIn(TaskState.CANCELLED).list();
assertThat(taskSummaries.size()).isEqualTo(5);
}
@WithAccessId(
userName = "admin",
groupNames = {"group_1"})
@Test
void testCancelReadyTask()
throws NotAuthorizedException, TaskNotFoundException, InvalidStateException {
List<TaskSummary> taskSummaries = taskService.createTaskQuery().stateIn(TaskState.READY).list();
assertThat(taskSummaries.size()).isEqualTo(47);
Task task = taskService.getTask(taskSummaries.get(0).getId());
taskService.cancelTask(taskSummaries.get(0).getId());
long numTasks = taskService.createTaskQuery().stateIn(TaskState.READY).count();
assertThat(numTasks).isEqualTo(46);
numTasks = taskService.createTaskQuery().stateIn(TaskState.CANCELLED).count();
assertThat(numTasks).isEqualTo(6);
}
@WithAccessId(
userName = "admin",
groupNames = {"group_1"})
@Test
void testCancelClaimedTask()
throws NotAuthorizedException, TaskNotFoundException, InvalidStateException {
List<TaskSummary> taskSummaries =
taskService.createTaskQuery().stateIn(TaskState.CLAIMED).list();
assertThat(taskSummaries.size()).isEqualTo(19);
Task task = taskService.getTask(taskSummaries.get(0).getId());
taskService.cancelTask(taskSummaries.get(0).getId());
long numTasks = taskService.createTaskQuery().stateIn(TaskState.CLAIMED).count();
assertThat(numTasks).isEqualTo(18);
numTasks = taskService.createTaskQuery().stateIn(TaskState.CANCELLED).count();
assertThat(numTasks).isEqualTo(6);
}
@WithAccessId(
userName = "admin",
groupNames = {"group_1"})
@Test
void testCancelCompletedTask()
throws NotAuthorizedException, TaskNotFoundException, InvalidStateException {
List<TaskSummary> taskSummaries =
taskService.createTaskQuery().stateIn(TaskState.COMPLETED).list();
assertThat(taskSummaries.size()).isEqualTo(7);
Task task = taskService.getTask(taskSummaries.get(0).getId());
assertThatThrownBy(
() -> {
taskService.cancelTask(taskSummaries.get(0).getId());
}).isInstanceOf(InvalidStateException.class);
}
@WithAccessId(
userName = "admin",
groupNames = {"group_1"})
@Test
void testCancelTerminatedTask()
throws NotAuthorizedException, TaskNotFoundException, InvalidStateException {
List<TaskSummary> taskSummaries =
taskService.createTaskQuery().stateIn(TaskState.TERMINATED).list();
assertThat(taskSummaries.size()).isEqualTo(5);
Task task = taskService.getTask(taskSummaries.get(0).getId());
assertThatThrownBy(
() -> {
taskService.cancelTask(taskSummaries.get(0).getId());
}).isInstanceOf(InvalidStateException.class);
}
@WithAccessId(
userName = "admin",
groupNames = {"group_1"})
@Test
void testCancelCancelledTask()
throws NotAuthorizedException, TaskNotFoundException, InvalidStateException {
List<TaskSummary> taskSummaries =
taskService.createTaskQuery().stateIn(TaskState.CANCELLED).list();
assertThat(taskSummaries.size()).isEqualTo(6);
Task task = taskService.getTask(taskSummaries.get(0).getId());
assertThatThrownBy(
() -> {
taskService.cancelTask(taskSummaries.get(0).getId());
}).isInstanceOf(InvalidStateException.class);
}
}

View File

@ -1,5 +1,6 @@
package acceptance.task;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -29,11 +30,12 @@ import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.internal.TaskanaEngineProxyForTest;
import pro.taskana.common.internal.security.CurrentUserContext;
import pro.taskana.common.internal.util.DaysToWorkingDaysConverter;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.security.JaasExtension;
import pro.taskana.security.WithAccessId;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.TaskState;
import pro.taskana.task.api.exceptions.InvalidStateException;
import pro.taskana.task.api.exceptions.TaskAlreadyExistException;
import pro.taskana.task.api.exceptions.TaskNotFoundException;
import pro.taskana.task.api.models.Attachment;
@ -42,6 +44,7 @@ import pro.taskana.task.api.models.Task;
import pro.taskana.task.internal.AttachmentMapper;
import pro.taskana.task.internal.TaskTestMapper;
import pro.taskana.workbasket.api.WorkbasketService;
import pro.taskana.workbasket.api.exceptions.WorkbasketInUseException;
import pro.taskana.workbasket.api.exceptions.WorkbasketNotFoundException;
import pro.taskana.workbasket.api.models.Workbasket;
@ -161,7 +164,7 @@ class CreateTaskAccTest extends AbstractAccTest {
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
newTask.setOwner("user_1_1");
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize();
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize();
// TODO: this is a temporal bug fix because we did not define what happens when a task is
// planned on the weekend.
long i = converter.convertWorkingDaysToDays(instantPlanned, 0);
@ -445,7 +448,7 @@ class CreateTaskAccTest extends AbstractAccTest {
assertEquals(planned, readTask.getPlanned());
long calendarDays =
DaysToWorkingDaysConverter.initialize()
WorkingDaysToDaysConverter.initialize()
.convertWorkingDaysToDays(readTask.getPlanned(), serviceLevelDays);
Instant shouldBeDueDate = readTask.getPlanned().plus(Duration.ofDays(calendarDays));
@ -480,7 +483,7 @@ class CreateTaskAccTest extends AbstractAccTest {
assertEquals(due, readTask.getDue());
long calendarDaysToSubstract =
DaysToWorkingDaysConverter.initialize().convertWorkingDaysToDays(due, -serviceLevelDays);
WorkingDaysToDaysConverter.initialize().convertWorkingDaysToDays(due, -serviceLevelDays);
assertTrue(calendarDaysToSubstract < 0);
assertTrue(calendarDaysToSubstract <= -serviceLevelDays);
@ -546,7 +549,7 @@ class CreateTaskAccTest extends AbstractAccTest {
assertEquals(99, readTask.getPriority());
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(Instant.now());
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
long calendarDays = converter.convertWorkingDaysToDays(readTask.getPlanned(), 1);
assertEquals(readTask.getDue(), readTask.getPlanned().plus(Duration.ofDays(calendarDays)));
@ -865,6 +868,35 @@ class CreateTaskAccTest extends AbstractAccTest {
Assertions.assertThrows(NotAuthorizedException.class, () -> taskService.createTask(task));
}
@WithAccessId(
userName = "admin",
groupNames = {"group_1"})
@Test
void testCreateTaskWithWorkbasketMarkedForDeletion()
throws NotAuthorizedException, InvalidStateException, TaskNotFoundException,
TaskAlreadyExistException, InvalidArgumentException, WorkbasketNotFoundException,
ClassificationNotFoundException, WorkbasketInUseException {
String wbId = "WBI:100000000000000000000000000000000008";
Task taskToPreventWorkbasketDeletion = taskService.newTask(wbId);
taskToPreventWorkbasketDeletion = setTaskProperties(taskToPreventWorkbasketDeletion);
taskService.createTask(taskToPreventWorkbasketDeletion);
taskService.cancelTask(taskToPreventWorkbasketDeletion.getId());
WorkbasketService workbasketService = taskanaEngine.getWorkbasketService();
workbasketService.deleteWorkbasket(wbId);
Task task = taskService.newTask(wbId);
final Task testTask = setTaskProperties(task);
assertThatThrownBy(() -> taskService.createTask(testTask))
.isInstanceOf(WorkbasketNotFoundException.class);
}
private Task setTaskProperties(Task task) {
task.setClassificationKey("L12010");
task.setPrimaryObjRef(
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
return task;
}
private Task makeNewTask(TaskService taskService) {
Task newTask = taskService.newTask("USER_1_1", "DOMAIN_A");
newTask.setClassificationKey("L12010");

View File

@ -98,11 +98,11 @@ class QueryTaskByClassificationNameAccTest extends AbstractAccTest {
.classificationNameLike("Dynamik%", "Widerruf")
.orderByClassificationName(SortDirection.ASCENDING)
.list();
assertEquals(22, tasks.size());
assertEquals(32, tasks.size());
// without sort, the same number of tasks should be returned
tasks = taskService.createTaskQuery().classificationNameLike("Dynamik%", "Widerruf").list();
assertEquals(22, tasks.size());
assertEquals(32, tasks.size());
}
@WithAccessId(

View File

@ -93,7 +93,7 @@ class QueryTasksAccTest extends AbstractAccTest {
columnValueList = taskService.createTaskQuery().listValues(STATE, null);
assertNotNull(columnValueList);
assertEquals(3, columnValueList.size());
assertEquals(5, columnValueList.size());
}
@WithAccessId(
@ -145,7 +145,7 @@ class QueryTasksAccTest extends AbstractAccTest {
List<TaskSummary> results =
taskService.createTaskQuery().ownerLike("%a%", "%u%").orderByCreated(ASCENDING).list();
assertThat(results.size(), equalTo(25));
assertThat(results.size(), equalTo(35));
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
if (previousSummary != null) {
@ -164,7 +164,7 @@ class QueryTasksAccTest extends AbstractAccTest {
List<TaskSummary> results =
taskService.createTaskQuery().parentBusinessProcessIdLike("%PBPI%", "doc%3%").list();
assertThat(results.size(), equalTo(24));
assertThat(results.size(), equalTo(32));
for (TaskSummary taskSummary : results) {
assertNotNull(taskSummary.getExternalId());
}
@ -174,7 +174,7 @@ class QueryTasksAccTest extends AbstractAccTest {
List<TaskSummary> result2 =
taskService.createTaskQuery().parentBusinessProcessIdIn(parentIds).list();
assertThat(result2.size(), equalTo(24));
assertThat(result2.size(), equalTo(32));
}
@WithAccessId(
@ -201,17 +201,17 @@ class QueryTasksAccTest extends AbstractAccTest {
TaskService taskService = taskanaEngine.getTaskService();
List<TaskSummary> results = taskService.createTaskQuery().classificationKeyLike("L10%").list();
assertThat(results.size(), equalTo(67));
assertThat(results.size(), equalTo(77));
String[] ids =
results.stream().map(t -> t.getClassificationSummary().getKey()).toArray(String[]::new);
List<TaskSummary> result2 = taskService.createTaskQuery().classificationKeyIn(ids).list();
assertThat(result2.size(), equalTo(67));
assertThat(result2.size(), equalTo(77));
List<TaskSummary> result3 =
taskService.createTaskQuery().classificationKeyNotIn("T2100", "T2000").list();
assertThat(result3.size(), equalTo(71));
assertThat(result3.size(), equalTo(81));
List<TaskSummary> result4 =
taskService.createTaskQuery().classificationKeyNotIn("L1050", "L1060", "T2100").list();
@ -404,7 +404,7 @@ class QueryTasksAccTest extends AbstractAccTest {
List<TaskSummary> results =
taskService.createTaskQuery().customAttributeLike("5", "ew", "al").list();
assertThat(results.size(), equalTo(2));
assertThat(results.size(), equalTo(6));
String[] ids =
results.stream()
@ -420,7 +420,7 @@ class QueryTasksAccTest extends AbstractAccTest {
.toArray(String[]::new);
List<TaskSummary> result2 = taskService.createTaskQuery().customAttributeIn("5", ids).list();
assertThat(result2.size(), equalTo(2));
assertThat(result2.size(), equalTo(6));
}
@WithAccessId(
@ -432,7 +432,7 @@ class QueryTasksAccTest extends AbstractAccTest {
List<TaskSummary> results =
taskService.createTaskQuery().customAttributeLike("6", "%custom6%", "%vvg%", "11%").list();
assertThat(results.size(), equalTo(3));
assertThat(results.size(), equalTo(5));
String[] ids =
results.stream()
@ -448,7 +448,7 @@ class QueryTasksAccTest extends AbstractAccTest {
.toArray(String[]::new);
List<TaskSummary> result2 = taskService.createTaskQuery().customAttributeIn("6", ids).list();
assertThat(result2.size(), equalTo(3));
assertThat(result2.size(), equalTo(5));
}
@WithAccessId(
@ -693,7 +693,7 @@ class QueryTasksAccTest extends AbstractAccTest {
TaskService taskService = taskanaEngine.getTaskService();
List<TaskSummary> results = taskService.createTaskQuery().customAttributeLike("14", "%").list();
assertThat(results.size(), equalTo(48));
assertThat(results.size(), equalTo(58));
String[] ids =
results.stream()
@ -708,7 +708,7 @@ class QueryTasksAccTest extends AbstractAccTest {
})
.toArray(String[]::new);
List<TaskSummary> results2 = taskService.createTaskQuery().customAttributeIn("14", ids).list();
assertThat(results2.size(), equalTo(48));
assertThat(results2.size(), equalTo(58));
}
@WithAccessId(
@ -925,7 +925,7 @@ class QueryTasksAccTest extends AbstractAccTest {
void testQueryForReadEquals() {
TaskService taskService = taskanaEngine.getTaskService();
List<TaskSummary> results = taskService.createTaskQuery().readEquals(true).list();
assertEquals(25, results.size());
assertEquals(35, results.size());
}
@WithAccessId(userName = "admin")
@ -950,7 +950,7 @@ class QueryTasksAccTest extends AbstractAccTest {
void testQueryForBusinessProcessIdLike() {
TaskService taskService = taskanaEngine.getTaskService();
List<TaskSummary> results = taskService.createTaskQuery().businessProcessIdLike("pI_%").list();
assertEquals(67, results.size());
assertEquals(77, results.size());
}
@WithAccessId(userName = "admin")

View File

@ -47,7 +47,7 @@ class QueryTasksByTimeIntervalsAccTest extends AbstractAccTest {
.orderByCreated(asc)
.list();
assertThat(results.size(), equalTo(40));
assertThat(results.size(), equalTo(50));
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
Instant cr = taskSummary.getCreated();
@ -97,7 +97,7 @@ class QueryTasksByTimeIntervalsAccTest extends AbstractAccTest {
List<TaskSummary> results =
taskService.createTaskQuery().createdWithin(interval1).orderByCreated(asc).list();
assertThat(results.size(), equalTo(38));
assertThat(results.size(), equalTo(48));
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
Instant cr = taskSummary.getCreated();
@ -129,7 +129,7 @@ class QueryTasksByTimeIntervalsAccTest extends AbstractAccTest {
.orderByCreated(asc)
.list();
assertThat(results.size(), equalTo(25));
assertThat(results.size(), equalTo(35));
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
Instant cr = taskSummary.getClaimed();
@ -154,7 +154,7 @@ class QueryTasksByTimeIntervalsAccTest extends AbstractAccTest {
List<TaskSummary> results =
taskService.createTaskQuery().completedWithin(interval).orderByCompleted(asc).list();
assertThat(results.size(), equalTo(5));
assertThat(results.size(), equalTo(15));
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
Instant cr = taskSummary.getCompleted();
@ -204,7 +204,7 @@ class QueryTasksByTimeIntervalsAccTest extends AbstractAccTest {
List<TaskSummary> results =
taskService.createTaskQuery().plannedWithin(interval).orderByPlanned(asc).list();
assertThat(results.size(), equalTo(71));
assertThat(results.size(), equalTo(81));
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
Instant cr = taskSummary.getPlanned();
@ -229,7 +229,7 @@ class QueryTasksByTimeIntervalsAccTest extends AbstractAccTest {
List<TaskSummary> results =
taskService.createTaskQuery().dueWithin(interval).orderByPlanned(asc).list();
assertThat(results.size(), equalTo(71));
assertThat(results.size(), equalTo(81));
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
Instant cr = taskSummary.getDue();

View File

@ -40,7 +40,7 @@ class QueryTasksByWorkbasketAccTest extends AbstractAccTest {
.createTaskQuery()
.workbasketKeyDomainIn(workbasketIdentifiers.toArray(new KeyDomain[0]))
.list();
assertThat(results.size(), equalTo(42));
assertThat(results.size(), equalTo(52));
String[] ids =
results.stream()
@ -49,7 +49,7 @@ class QueryTasksByWorkbasketAccTest extends AbstractAccTest {
.toArray(new String[0]);
List<TaskSummary> result2 = taskService.createTaskQuery().workbasketIdIn(ids).list();
assertThat(result2.size(), equalTo(42));
assertThat(result2.size(), equalTo(52));
}
@WithAccessId(

View File

@ -20,7 +20,7 @@ import pro.taskana.common.api.exceptions.ConcurrencyException;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.api.exceptions.TaskanaException;
import pro.taskana.common.internal.util.DaysToWorkingDaysConverter;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.security.JaasExtension;
import pro.taskana.security.WithAccessId;
import pro.taskana.task.api.TaskService;
@ -37,7 +37,7 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
ServiceLevelPriorityAccTest() {
super();
DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled(true);
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);
taskService = taskanaEngine.getTaskService();
}
@ -270,7 +270,7 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
taskService.setPlannedPropertyOfTasks(planned, Arrays.asList(taskId));
Task task = taskService.getTask(taskId);
assertThat(results.containsErrors()).isFalse();
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize();
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize();
long days = converter.convertWorkingDaysToDays(task.getPlanned(), 1);
assertThat(task.getDue()).isEqualTo(planned.plus(Duration.ofDays(days)));
}
@ -284,7 +284,7 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
ConcurrencyException, InvalidStateException, ClassificationNotFoundException,
AttachmentPersistenceException {
String taskId = "TKI:000000000000000000000000000000000002";
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize();
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize();
Task task = taskService.getTask(taskId);
// test update of planned date via updateTask()
task.setPlanned(task.getPlanned().plus(Duration.ofDays(3)));
@ -317,7 +317,7 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
// update due and planned as expected.
task = taskService.getTask(taskId);
task.setDue(planned.plus(Duration.ofDays(3)));
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize();
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize();
long days = converter.convertWorkingDaysToDays(task.getDue(), -1);
task.setPlanned(task.getDue().plus(Duration.ofDays(-1)));
task = taskService.updateTask(task);
@ -347,7 +347,7 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
task.setPlanned(null);
task = taskService.updateTask(task);
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize();
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize();
long days = converter.convertWorkingDaysToDays(task.getPlanned(), 1);
assertThat(task.getDue()).isEqualTo(task.getPlanned().plus(Duration.ofDays(days)));

View File

@ -198,9 +198,9 @@ public class SetOwnerAccTest extends AbstractAccTest {
allTaskSummaries.stream().map(TaskSummary::getId).collect(Collectors.toList());
BulkOperationResults<String, TaskanaException> results =
taskanaEngine.getTaskService().setOwnerOfTasks("theWorkaholic", allTaskIds);
assertThat(allTaskSummaries.size()).isEqualTo(73);
assertThat(allTaskSummaries.size()).isEqualTo(83);
assertThat(results.containsErrors()).isTrue();
assertThat(results.getErrorMap().size()).isEqualTo(48);
assertThat(results.getErrorMap().size()).isEqualTo(58);
long numberOfInvalidStateExceptions =
results.getErrorMap().entrySet().stream()
.filter(
@ -210,7 +210,7 @@ public class SetOwnerAccTest extends AbstractAccTest {
.getName()
.equals(InvalidStateException.class.getCanonicalName()))
.count();
assertThat(numberOfInvalidStateExceptions).isEqualTo(25);
assertThat(numberOfInvalidStateExceptions).isEqualTo(35);
long numberOfNotAuthorizedExceptions =
results.getErrorMap().entrySet().stream()
@ -236,9 +236,9 @@ public class SetOwnerAccTest extends AbstractAccTest {
allTaskSummaries.stream().map(TaskSummary::getId).collect(Collectors.toList());
BulkOperationResults<String, TaskanaException> results =
taskanaEngine.getTaskService().setOwnerOfTasks("theWorkaholic", allTaskIds);
assertThat(allTaskSummaries.size()).isEqualTo(73);
assertThat(allTaskSummaries.size()).isEqualTo(83);
assertThat(results.containsErrors()).isTrue();
assertThat(results.getErrorMap().size()).isEqualTo(26);
assertThat(results.getErrorMap().size()).isEqualTo(36);
long numberOfInvalidStateExceptions =
results.getErrorMap().entrySet().stream()
.filter(
@ -248,7 +248,7 @@ public class SetOwnerAccTest extends AbstractAccTest {
.getName()
.equals(InvalidStateException.class.getCanonicalName()))
.count();
assertThat(numberOfInvalidStateExceptions).isEqualTo(26);
assertThat(numberOfInvalidStateExceptions).isEqualTo(36);
}

View File

@ -0,0 +1,111 @@
package acceptance.task;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import acceptance.AbstractAccTest;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.security.JaasExtension;
import pro.taskana.security.WithAccessId;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.TaskState;
import pro.taskana.task.api.exceptions.InvalidStateException;
import pro.taskana.task.api.exceptions.TaskNotFoundException;
import pro.taskana.task.api.models.Task;
import pro.taskana.task.api.models.TaskSummary;
/** Acceptance tests for all claim and complete scenarios. */
@ExtendWith(JaasExtension.class)
class TerminateTaskAccTest extends AbstractAccTest {
private TaskService taskService;
TerminateTaskAccTest() {
super();
taskService = taskanaEngine.getTaskService();
}
@BeforeEach
public static void setupTest() throws Exception {
resetDb(false);
}
@WithAccessId(
userName = "user_1_1",
groupNames = {"group_1"})
@Test
void testQueryTerminatedTasks() {
List<TaskSummary> taskSummaries =
taskService.createTaskQuery().stateIn(TaskState.TERMINATED).list();
assertThat(taskSummaries.size()).isEqualTo(5);
}
@WithAccessId(
userName = "admin",
groupNames = {"group_1"})
@Test
void testTerminateReadyTask()
throws NotAuthorizedException, TaskNotFoundException, InvalidStateException {
List<TaskSummary> taskSummaries = taskService.createTaskQuery().stateIn(TaskState.READY).list();
assertThat(taskSummaries.size()).isEqualTo(47);
Task task = taskService.getTask(taskSummaries.get(0).getId());
taskService.terminateTask(taskSummaries.get(0).getId());
long numTasks = taskService.createTaskQuery().stateIn(TaskState.READY).count();
assertThat(numTasks).isEqualTo(46);
numTasks = taskService.createTaskQuery().stateIn(TaskState.TERMINATED).count();
assertThat(numTasks).isEqualTo(6);
}
@WithAccessId(
userName = "admin",
groupNames = {"group_1"})
@Test
void testTerminateClaimedTask()
throws NotAuthorizedException, TaskNotFoundException, InvalidStateException {
List<TaskSummary> taskSummaries =
taskService.createTaskQuery().stateIn(TaskState.CLAIMED).list();
assertThat(taskSummaries.size()).isEqualTo(19);
Task task = taskService.getTask(taskSummaries.get(0).getId());
taskService.terminateTask(taskSummaries.get(0).getId());
long numTasks = taskService.createTaskQuery().stateIn(TaskState.CLAIMED).count();
assertThat(numTasks).isEqualTo(18);
numTasks = taskService.createTaskQuery().stateIn(TaskState.TERMINATED).count();
assertThat(numTasks).isEqualTo(7);
}
@WithAccessId(
userName = "admin",
groupNames = {"group_1"})
@Test
void testTerminateCompletedTask()
throws NotAuthorizedException, TaskNotFoundException, InvalidStateException {
List<TaskSummary> taskSummaries =
taskService.createTaskQuery().stateIn(TaskState.COMPLETED).list();
assertThat(taskSummaries.size()).isEqualTo(7);
Task task = taskService.getTask(taskSummaries.get(0).getId());
assertThatThrownBy(
() -> {
taskService.terminateTask(taskSummaries.get(0).getId());
}).isInstanceOf(InvalidStateException.class);
}
@WithAccessId(
userName = "admin",
groupNames = {"group_1"})
@Test
void testTerminateTerminatedTask()
throws NotAuthorizedException, TaskNotFoundException, InvalidStateException {
List<TaskSummary> taskSummaries =
taskService.createTaskQuery().stateIn(TaskState.TERMINATED).list();
assertThat(taskSummaries.size()).isEqualTo(5);
Task task = taskService.getTask(taskSummaries.get(0).getId());
assertThatThrownBy(
() -> {
taskService.terminateTask(taskSummaries.get(0).getId());
}).isInstanceOf(InvalidStateException.class);
}
}

View File

@ -24,7 +24,7 @@ import pro.taskana.common.api.exceptions.ConcurrencyException;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.internal.security.CurrentUserContext;
import pro.taskana.common.internal.util.DaysToWorkingDaysConverter;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.security.JaasExtension;
import pro.taskana.security.WithAccessId;
import pro.taskana.task.api.TaskService;
@ -172,7 +172,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
assertThat(task.getAttachments().get(0).getChannel(), equalTo(newChannel));
assertEquals(999, task.getPriority());
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(Instant.now());
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
long calendarDays = converter.convertWorkingDaysToDays(task.getDue(), 1);
assertEquals(task.getDue(), task.getPlanned().plus(Duration.ofDays(calendarDays)));
}
@ -330,7 +330,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
assertThat(task.getAttachments().size(), equalTo(attachmentCount));
assertThat(task.getAttachments().get(0).getChannel(), equalTo(newChannel));
assertEquals(999, task.getPriority());
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(Instant.now());
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
long calendarDays = converter.convertWorkingDaysToDays(task.getDue(), 1);
assertEquals(task.getDue(), task.getPlanned().plus(Duration.ofDays(calendarDays)));
@ -365,7 +365,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
task = taskService.updateTask(task);
task = taskService.getTask(task.getId());
assertEquals(101, task.getPriority());
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(Instant.now());
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
long calendarDays = converter.convertWorkingDaysToDays(task.getDue(), 1);
assertEquals(task.getDue(), task.getPlanned().plus(Duration.ofDays(calendarDays)));
@ -561,7 +561,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
assertEquals(99, readTask.getPriority());
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(Instant.now());
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
long calendarDays = converter.convertWorkingDaysToDays(readTask.getPlanned(), 1);
assertEquals(readTask.getDue(), readTask.getPlanned().plus(Duration.ofDays(calendarDays)));

View File

@ -3,7 +3,7 @@ package pro.taskana.common.internal.util;
import static java.util.Collections.singletonList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static pro.taskana.common.internal.util.DaysToWorkingDaysConverter.getEasterSunday;
import static pro.taskana.common.internal.util.WorkingDaysToDaysConverter.getEasterSunday;
import java.time.Instant;
import java.time.LocalDate;
@ -17,21 +17,21 @@ import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.monitor.api.reports.header.TimeIntervalColumnHeader;
import pro.taskana.monitor.internal.preprocessor.DaysToWorkingDaysReportConverter;
/** Test for the DaysToWorkingDaysConverter. */
class DaysToWorkingDaysConverterTest {
/** Test for the WorkingDaysToDaysConverter. */
class WorkingDaysToDaysConverterTest {
@BeforeAll
static void setup() {
DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled(true);
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);
LocalDate dayOfReformation = LocalDate.of(2018, 10, 31);
LocalDate allSaintsDays = LocalDate.of(2018, 11, 1);
DaysToWorkingDaysConverter.setCustomHolidays(Arrays.asList(dayOfReformation, allSaintsDays));
WorkingDaysToDaysConverter.setCustomHolidays(Arrays.asList(dayOfReformation, allSaintsDays));
}
@Test
void testConvertWorkingDaysToDaysForTasks() throws InvalidArgumentException {
Instant thursday0201 = Instant.parse("2018-02-01T07:00:00.000Z");
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(thursday0201);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(thursday0201);
long days = converter.convertWorkingDaysToDays(thursday0201, -7); // = tuesday (sat + sun)
assertEquals(-9, days);
@ -76,7 +76,7 @@ class DaysToWorkingDaysConverterTest {
@Test
void testConvertWorkingDaysToDaysForKarFreitag() throws InvalidArgumentException {
Instant thursday0201 = Instant.parse("2018-02-01T07:00:00.000Z");
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(thursday0201);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(thursday0201);
Instant gruenDonnerstag2018 = Instant.parse("2018-03-29T01:00:00.000Z");
long days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 0);
assertEquals(0, days);
@ -90,7 +90,7 @@ class DaysToWorkingDaysConverterTest {
void testConvertWorkingDaysToDaysForHolidays() throws InvalidArgumentException {
List<TimeIntervalColumnHeader> reportItems = singletonList(new TimeIntervalColumnHeader(0));
Instant thursday0201 = Instant.parse("2018-02-01T07:00:00.000Z");
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(thursday0201);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(thursday0201);
Instant freitag0427 = Instant.parse("2018-04-27T19:00:00.000Z");
long days = converter.convertWorkingDaysToDays(freitag0427, 0);

View File

@ -13,7 +13,7 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.internal.util.DaysToWorkingDaysConverter;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.monitor.api.reports.header.TimeIntervalColumnHeader;
import pro.taskana.monitor.internal.preprocessor.DaysToWorkingDaysReportConverter;
@ -22,10 +22,10 @@ class DaysToWorkingDaysReportConverterTest {
@BeforeAll
static void setup() {
DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled(true);
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);
LocalDate dayOfReformation = LocalDate.of(2018, 10, 31);
LocalDate allSaintsDays = LocalDate.of(2018, 11, 1);
DaysToWorkingDaysConverter.setCustomHolidays(Arrays.asList(dayOfReformation, allSaintsDays));
WorkingDaysToDaysConverter.setCustomHolidays(Arrays.asList(dayOfReformation, allSaintsDays));
}
@Test

View File

@ -11,6 +11,7 @@ import org.junit.jupiter.api.Test;
import pro.taskana.classification.api.models.Classification;
import pro.taskana.classification.internal.models.ClassificationImpl;
import pro.taskana.common.internal.JunitHelper;
import pro.taskana.task.api.TaskState;
import pro.taskana.task.api.models.ObjectReference;
import pro.taskana.task.api.models.TaskSummary;
import pro.taskana.task.internal.models.TaskImpl;
@ -69,6 +70,7 @@ class TaskServiceImplTest {
Instant now = Instant.now().minus(Duration.ofMinutes(1L));
task.setCreated(now);
task.setModified(now);
task.setState(TaskState.READY);
if (classification == null) {
classification = createDummyClassification();
}

View File

@ -77,8 +77,8 @@ class TaskStatusReportBuilderImplTest {
assertNotNull(report);
assertEquals(1, report.rowSize());
assertArrayEquals(new int[] {50, 0, 30}, report.getRow("DOMAIN_X").getCells());
assertArrayEquals(new int[] {50, 0, 30}, report.getSumRow().getCells());
assertArrayEquals(new int[] {50, 0, 30, 0, 0}, report.getRow("DOMAIN_X").getCells());
assertArrayEquals(new int[] {50, 0, 30, 0, 0}, report.getSumRow().getCells());
assertEquals(80, report.getRow("DOMAIN_X").getTotalValue());
assertEquals(80, report.getSumRow().getTotalValue());
}

View File

@ -76,3 +76,16 @@ INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000065', 'ETI:0000000
INSERT INTO TASK VALUES('TKI:100000000000000000000000000000000006', 'ETI:100000000000000000000000000000000006', '2018-01-29 15:55:06', '2018-01-30 15:55:06', '2018-01-30 16:55:06', '2018-01-30 16:55:06', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'COMPLETED' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000004' , 'TEAMLEAD_1' , 'DOMAIN_A', 'PI_0000000000041' , 'DOC_0000000000000000041' , null , '00' , 'PASystem' , '00' , 'VNR' , '11223344' , false , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:200000000000000000000000000000000006', 'ETI:200000000000000000000000000000000006', '2018-03-29 15:55:06', '2018-03-30 15:55:06', null , '2018-03-30 15:55:06', '2018-03-29 15:55:00', '2018-03-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'COMPLETED' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000005' , 'TEAMLEAD_2' , 'DOMAIN_A', 'PI_0000000000006' , 'DOC_0000000000000000006' , null , '00' , 'PASystem' , '00' , 'SDNR' , '98765432' , false , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:200000000000000000000000000000000007', 'ETI:200000000000000000000000000000000007', '2018-03-29 15:55:06', '2018-03-30 15:55:06', null , '2018-03-30 15:55:06', '2018-03-29 15:55:00', '2018-03-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000005' , 'TEAMLEAD_2' , 'DOMAIN_A', 'PI_0000000000006' , 'DOC_0000000000000000006' , null , '00' , 'PASystem' , '00' , 'SDNR' , '98765432' , false , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
-- Tasks for state cancelled
INSERT INTO TASK VALUES('TKI:300000000000000000000000000000000000', 'ETI:300000000000000000000000000000000000', '2018-01-29 15:55:24', '2018-01-30 15:55:24', '2018-01-30 16:55:24', '2018-01-30 16:55:24', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'CANCELLED' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000007' , 'USER_1_2' , 'DOMAIN_A', 'PI_0000000000036' , 'DOC_0000000000000000036' , 'user_1_2' , '00' , 'PASystem' , '00' , 'SDNR' , '00011122' , true , false , null , 'NONE' , null , null , null , null , null , 'ew' , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:300000000000000000000000000000000001', 'ETI:300000000000000000000000000000000001', '2018-01-29 15:55:24', '2018-01-30 15:55:24', '2018-01-30 16:55:24', '2018-01-30 16:55:24', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'CANCELLED' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000007' , 'USER_1_2' , 'DOMAIN_A', 'PI_0000000000037' , 'DOC_0000000000000000037' , 'user_1_2' , '00' , 'PASystem' , '00' , 'SDNR' , '00011122' , true , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:300000000000000000000000000000000002', 'ETI:300000000000000000000000000000000002', '2018-01-29 15:55:24', '2018-01-30 15:55:24', '2018-01-30 16:55:24', '2018-01-30 16:55:24', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'CANCELLED' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000007' , 'USER_1_2' , 'DOMAIN_A', 'PI_0000000000038' , 'DOC_0000000000000000038' , 'user_1_2' , '00' , 'PASystem' , '00' , 'SDNR' , '00011122' , true , false , null , 'NONE' , null , null , null , null , null , 'al' , '11' , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:300000000000000000000000000000000003', 'ETI:300000000000000000000000000000000003', '2018-01-29 15:55:24', '2018-01-30 15:55:24', '2018-01-30 16:55:24', '2018-01-30 16:55:24', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'CANCELLED' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000007' , 'USER_1_2' , 'DOMAIN_A', 'PI_0000000000039' , 'DOC_0000000000000000039' , 'user_1_2' , '00' , 'PASystem' , '00' , 'SDNR' , '00011122' , true , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:300000000000000000000000000000000004', 'ETI:300000000000000000000000000000000004', '2018-01-29 15:55:24', '2018-01-30 15:55:24', '2018-01-30 16:55:24', '2018-01-30 16:55:24', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'CANCELLED' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000007' , 'USER_1_2' , 'DOMAIN_A', 'PI_0000000000040' , 'DOC_0000000000000000040' , 'user_1_2' , '00' , 'PASystem' , '00' , 'SDNR' , '00011122' , true , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
-- Tasks for state terminated
INSERT INTO TASK VALUES('TKI:300000000000000000000000000000000010', 'ETI:300000000000000000000000000000000010', '2018-01-29 15:55:24', '2018-01-30 15:55:24', '2018-01-30 16:55:24', '2018-01-30 16:55:24', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'TERMINATED' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000007' , 'USER_1_2' , 'DOMAIN_A', 'PI_0000000000036' , 'DOC_0000000000000000036' , 'user_1_2' , '00' , 'PASystem' , '00' , 'SDNR' , '00011122' , true , false , null , 'NONE' , null , null , null , null , null , 'ew' , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:300000000000000000000000000000000011', 'ETI:300000000000000000000000000000000011', '2018-01-29 15:55:24', '2018-01-30 15:55:24', '2018-01-30 16:55:24', '2018-01-30 16:55:24', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'TERMINATED' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000007' , 'USER_1_2' , 'DOMAIN_A', 'PI_0000000000037' , 'DOC_0000000000000000037' , 'user_1_2' , '00' , 'PASystem' , '00' , 'SDNR' , '00011122' , true , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:300000000000000000000000000000000012', 'ETI:300000000000000000000000000000000012', '2018-01-29 15:55:24', '2018-01-30 15:55:24', '2018-01-30 16:55:24', '2018-01-30 16:55:24', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'TERMINATED' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000007' , 'USER_1_2' , 'DOMAIN_A', 'PI_0000000000038' , 'DOC_0000000000000000038' , 'user_1_2' , '00' , 'PASystem' , '00' , 'SDNR' , '00011122' , true , false , null , 'NONE' , null , null , null , null , null , 'al' , '11' , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:300000000000000000000000000000000013', 'ETI:300000000000000000000000000000000013', '2018-01-29 15:55:24', '2018-01-30 15:55:24', '2018-01-30 16:55:24', '2018-01-30 16:55:24', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'TERMINATED' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000007' , 'USER_1_2' , 'DOMAIN_A', 'PI_0000000000039' , 'DOC_0000000000000000039' , 'user_1_2' , '00' , 'PASystem' , '00' , 'SDNR' , '00011122' , true , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:300000000000000000000000000000000014', 'ETI:300000000000000000000000000000000014', '2018-01-29 15:55:24', '2018-01-30 15:55:24', '2018-01-30 16:55:24', '2018-01-30 16:55:24', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'TERMINATED' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000007' , 'USER_1_2' , 'DOMAIN_A', 'PI_0000000000040' , 'DOC_0000000000000000040' , 'user_1_2' , '00' , 'PASystem' , '00' , 'SDNR' , '00011122' , true , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );