TSK-313 Calculate due and prio of task based on associated classification and attachment classifications

This commit is contained in:
BerndBreier 2018-03-01 15:32:35 +01:00 committed by Holger Hagen
parent dd241cc9a5
commit 066acd408e
12 changed files with 367 additions and 70 deletions

View File

@ -39,6 +39,9 @@ public interface BaseQuery<T> {
*
* @param dbColumnName
* column name of a existing DB Table.
* @param sortDirection
* Determines whether the result is sorted in ascending or descending order. If sortDirection is null,
* the result is sorted in ascending order
* @return a list of all existing values.
*/
List<String> listValues(String dbColumnName, SortDirection sortDirection);

View File

@ -54,4 +54,19 @@ public interface ClassificationSummary {
* @return parentId
*/
String getParentId();
/**
* Gets the service level of the parent classification. It is a String in ISO-8601 duration format. See the parse()
* method of {@code Duration} for details.
*
* @return the service level
*/
String getServiceLevel();
/**
* Gets the priority of the lassification.
*
* @return the priority
*/
int getPriority();
}

View File

@ -266,6 +266,8 @@ public class ClassificationImpl implements Classification {
summary.setName(this.name);
summary.setType(this.type);
summary.setParentId(this.parentId);
summary.setPriority(this.priority);
summary.setServiceLevel(this.serviceLevel);
return summary;
}

View File

@ -14,6 +14,26 @@ public class ClassificationSummaryImpl implements ClassificationSummary {
private String domain;
private String name;
private String parentId;
private int priority;
private String serviceLevel; // PddDThhHmmM
@Override
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
@Override
public String getServiceLevel() {
return serviceLevel;
}
public void setServiceLevel(String serviceLevel) {
this.serviceLevel = serviceLevel;
}
ClassificationSummaryImpl() {
}
@ -176,6 +196,10 @@ public class ClassificationSummaryImpl implements ClassificationSummary {
builder.append(name);
builder.append(", parentId=");
builder.append(parentId);
builder.append(", priority=");
builder.append(priority);
builder.append(", serviceLevel=");
builder.append(serviceLevel);
builder.append("]");
return builder.toString();
}

View File

@ -57,6 +57,7 @@ public class TaskServiceImpl implements TaskService {
private static final String ID_PREFIX_TASK = "TKI";
private static final String ID_PREFIX_BUSINESS_PROCESS = "BPI";
private static final String MUST_NOT_BE_EMPTY = " must not be empty";
private static final Duration MAX_DURATION = Duration.ofSeconds(Long.MAX_VALUE, 999_999_999);
private TaskanaEngineImpl taskanaEngine;
private WorkbasketService workbasketService;
private ClassificationServiceImpl classificationService;
@ -307,9 +308,9 @@ public class TaskServiceImpl implements TaskService {
workbasket.getDomain());
task.setClassificationSummary(classification.asSummary());
validateObjectReference(task.getPrimaryObjRef(), "primary ObjectReference", "Task");
validateAttachments(task);
PrioDurationHolder prioDurationFromAttachments = handleAttachments(task);
task.setDomain(workbasket.getDomain());
standardSettings(task, classification);
standardSettings(task, classification, prioDurationFromAttachments);
this.taskMapper.insert(task);
LOGGER.debug("Method createTask() created Task '{}'.", task.getId());
}
@ -577,8 +578,8 @@ public class TaskServiceImpl implements TaskService {
try {
taskanaEngine.openConnection();
oldTaskImpl = (TaskImpl) getTask(newTaskImpl.getId());
standardUpdateActions(oldTaskImpl, newTaskImpl);
handleAttachmentsOnTaskUpdate(oldTaskImpl, newTaskImpl);
PrioDurationHolder prioDurationFromAttachments = handleAttachmentsOnTaskUpdate(oldTaskImpl, newTaskImpl);
standardUpdateActions(oldTaskImpl, newTaskImpl, prioDurationFromAttachments);
newTaskImpl.setModified(Instant.now());
taskMapper.update(newTaskImpl);
@ -591,7 +592,8 @@ public class TaskServiceImpl implements TaskService {
return task;
}
private void standardSettings(TaskImpl task, Classification classification) {
private void standardSettings(TaskImpl task, Classification classification,
PrioDurationHolder prioDurationFromAttachments) {
Instant now = Instant.now();
task.setId(IdGenerator.generateWithPrefix(ID_PREFIX_TASK));
task.setState(TaskState.READY);
@ -621,23 +623,24 @@ public class TaskServiceImpl implements TaskService {
// insert Classification specifications if Classification is given.
if (classification != null) {
if (classification.getServiceLevel() != null) {
Duration serviceLevel = Duration.parse(classification.getServiceLevel());
Instant due = task.getPlanned().plus(serviceLevel);
PrioDurationHolder finalPrioDuration = getNewPrioDuration(prioDurationFromAttachments.getPrio(),
prioDurationFromAttachments.getDuration(),
classification.getPriority(), classification.getServiceLevel());
Duration finalDuration = finalPrioDuration.getDuration();
if (finalDuration != null && !MAX_DURATION.equals(finalDuration)) {
Instant due = task.getPlanned().plus(finalDuration);
task.setDue(due);
}
task.setPriority(finalPrioDuration.getPrio());
if (task.getName() == null) {
task.setName(classification.getName());
}
}
if (task.getDescription() == null) {
task.setDescription(classification.getDescription());
}
if (task.getName() == null) {
task.setName(classification.getName());
}
if (task.getPriority() == 0) {
task.setPriority(classification.getPriority());
}
if (task.getDescription() == null) {
task.setDescription(classification.getDescription());
}
// insert Attachments if needed
@ -1013,11 +1016,14 @@ public class TaskServiceImpl implements TaskService {
}
}
private void validateAttachments(TaskImpl task) throws InvalidArgumentException {
private PrioDurationHolder handleAttachments(TaskImpl task) throws InvalidArgumentException {
List<Attachment> attachments = task.getAttachments();
if (attachments == null || attachments.isEmpty()) {
return;
return new PrioDurationHolder(null, Integer.MIN_VALUE);
}
Duration minDuration = MAX_DURATION;
int maxPrio = Integer.MIN_VALUE;
Iterator<Attachment> i = attachments.iterator();
while (i.hasNext()) {
Attachment attachment = i.next();
@ -1029,12 +1035,26 @@ public class TaskServiceImpl implements TaskService {
if (attachment.getClassificationSummary() == null) {
throw new InvalidArgumentException(
"Classification of attachment " + attachment + " must not be null");
} else {
ClassificationSummary classificationSummary = attachment.getClassificationSummary();
if (classificationSummary != null) {
PrioDurationHolder newPrioDuraton = getNewPrioDuration(maxPrio, minDuration,
classificationSummary.getPriority(), classificationSummary.getServiceLevel());
maxPrio = newPrioDuraton.getPrio();
minDuration = newPrioDuraton.getDuration();
}
}
}
}
if (minDuration != null && MAX_DURATION.equals(minDuration)) {
minDuration = null;
}
return new PrioDurationHolder(minDuration, maxPrio);
}
private void standardUpdateActions(TaskImpl oldTaskImpl, TaskImpl newTaskImpl)
private void standardUpdateActions(TaskImpl oldTaskImpl, TaskImpl newTaskImpl,
PrioDurationHolder prioDurationFromAttachments)
throws InvalidArgumentException, ConcurrencyException, WorkbasketNotFoundException,
ClassificationNotFoundException, NotAuthorizedException {
validateObjectReference(newTaskImpl.getPrimaryObjRef(), "primary ObjectReference", "Task");
@ -1058,64 +1078,96 @@ public class TaskServiceImpl implements TaskService {
newTaskImpl.setBusinessProcessId(oldTaskImpl.getBusinessProcessId());
}
updateClassificationRelatedProperties(oldTaskImpl, newTaskImpl);
updateClassificationRelatedProperties(oldTaskImpl, newTaskImpl, prioDurationFromAttachments);
newTaskImpl.setModified(Instant.now());
}
private void updateClassificationRelatedProperties(TaskImpl oldTaskImpl, TaskImpl newTaskImpl)
private void updateClassificationRelatedProperties(TaskImpl oldTaskImpl, TaskImpl newTaskImpl,
PrioDurationHolder prioDurationFromAttachments)
throws WorkbasketNotFoundException, NotAuthorizedException, ClassificationNotFoundException {
// insert Classification specifications if Classification is given.
ClassificationSummary oldClassificationSummary = oldTaskImpl.getClassificationSummary();
ClassificationSummary newClassificationSummary = oldClassificationSummary;
String newClassificationKey = newTaskImpl.getClassificationKey();
Classification newClassification = null;
if (newClassificationKey != null && !newClassificationKey.equals(oldClassificationSummary.getKey())) {
Workbasket workbasket = workbasketService.getWorkbasket(newTaskImpl.getWorkbasketSummary().getId());
// set new classification
newClassification = this.classificationService.getClassification(newClassificationKey,
workbasket.getDomain());
newClassificationSummary = newClassification.asSummary();
ClassificationSummary newClassificationSummary = newTaskImpl.getClassificationSummary();
if (newClassificationSummary == null) {
newClassificationSummary = oldClassificationSummary;
}
newTaskImpl.setClassificationSummary(newClassificationSummary);
if (newClassificationSummary == null) { // newClassification is null -> take prio and duration from attachments
if (prioDurationFromAttachments.getDuration() != null) {
Instant due = newTaskImpl.getPlanned().plus(prioDurationFromAttachments.getDuration());
newTaskImpl.setDue(due);
}
if (prioDurationFromAttachments.getPrio() > Integer.MIN_VALUE) {
newTaskImpl.setPriority(prioDurationFromAttachments.getPrio());
}
} else {
Classification newClassification = null;
if (!oldClassificationSummary.getKey().equals(newClassificationSummary.getKey())) {
newClassification = this.classificationService
.getClassification(newClassificationSummary.getKey(),
newTaskImpl.getWorkbasketSummary().getDomain());
newClassificationSummary = newClassification.asSummary();
newTaskImpl.setClassificationSummary(newClassificationSummary);
}
if (newClassification != null) {
if (newClassification.getServiceLevel() != null) {
Duration serviceLevel = Duration.parse(newClassification.getServiceLevel());
Instant due = newTaskImpl.getPlanned().plus(serviceLevel);
if (newClassificationSummary.getServiceLevel() != null) {
Duration durationFromClassification = Duration.parse(newClassificationSummary.getServiceLevel());
Duration minDuration = prioDurationFromAttachments.getDuration();
if (minDuration != null) {
if (minDuration.compareTo(durationFromClassification) > 0) {
minDuration = durationFromClassification;
}
} else {
minDuration = durationFromClassification;
}
Instant due = newTaskImpl.getPlanned().plus(minDuration);
newTaskImpl.setDue(due);
}
if (newTaskImpl.getName() == null) {
newTaskImpl.setName(newClassification.getName());
newTaskImpl.setName(newClassificationSummary.getName());
}
if (newTaskImpl.getDescription() == null) {
if (newTaskImpl.getDescription() == null && newClassification != null) {
newTaskImpl.setDescription(newClassification.getDescription());
}
if (newTaskImpl.getPriority() == 0) {
newTaskImpl.setPriority(newClassification.getPriority());
}
int newPriority = Math.max(newClassificationSummary.getPriority(), prioDurationFromAttachments.getPrio());
newTaskImpl.setPriority(newPriority);
}
}
private void handleAttachmentsOnTaskUpdate(TaskImpl oldTaskImpl, TaskImpl newTaskImpl)
private PrioDurationHolder handleAttachmentsOnTaskUpdate(TaskImpl oldTaskImpl, TaskImpl newTaskImpl)
throws AttachmentPersistenceException {
Duration minDuration = MAX_DURATION;
int maxPrio = Integer.MIN_VALUE;
// Iterator for removing invalid current values directly. OldAttachments can be ignored.
Iterator<Attachment> i = newTaskImpl.getAttachments().iterator();
while (i.hasNext()) {
Attachment attachment = i.next();
if (attachment != null) {
boolean wasAlreadyRepresented = false;
boolean wasAlreadyPresent = false;
if (attachment.getId() != null) {
for (Attachment oldAttachment : oldTaskImpl.getAttachments()) {
if (oldAttachment != null && attachment.getId().equals(oldAttachment.getId())) {
wasAlreadyRepresented = true;
wasAlreadyPresent = true;
if (!attachment.equals(oldAttachment)) {
AttachmentImpl temp = (AttachmentImpl) attachment;
ClassificationSummary classification = attachment.getClassificationSummary();
if (classification != null) {
PrioDurationHolder newPrioDuration = getNewPrioDuration(maxPrio, minDuration,
classification.getPriority(), classification.getServiceLevel());
maxPrio = newPrioDuration.getPrio();
minDuration = newPrioDuration.getDuration();
}
temp.setModified(Instant.now());
attachmentMapper.update(temp);
LOGGER.debug("TaskService.updateTask() for TaskId={} UPDATED an Attachment={}.",
@ -1129,9 +1181,17 @@ public class TaskServiceImpl implements TaskService {
}
// ADD, when ID not set or not found in elements
if (!wasAlreadyRepresented) {
if (!wasAlreadyPresent) {
AttachmentImpl attachmentImpl = (AttachmentImpl) attachment;
initAttachment(attachmentImpl, newTaskImpl);
ClassificationSummary classification = attachment.getClassificationSummary();
if (classification != null) {
PrioDurationHolder newPrioDuration = getNewPrioDuration(maxPrio, minDuration,
classification.getPriority(), classification.getServiceLevel());
maxPrio = newPrioDuration.getPrio();
minDuration = newPrioDuration.getDuration();
}
try {
attachmentMapper.insert(attachmentImpl);
LOGGER.debug("TaskService.updateTask() for TaskId={} INSERTED an Attachment={}.",
@ -1168,6 +1228,32 @@ public class TaskServiceImpl implements TaskService {
}
}
}
if (minDuration != null && MAX_DURATION.equals(minDuration)) {
minDuration = null;
}
return new PrioDurationHolder(minDuration, maxPrio);
}
private PrioDurationHolder getNewPrioDuration(int prio, Duration duration, int prioFromClassification,
String serviceLevelFromClassification) {
Duration minDuration = duration;
int maxPrio = prio;
if (serviceLevelFromClassification != null) {
Duration currentDuration = Duration.parse(serviceLevelFromClassification);
if (duration != null) {
if (duration.compareTo(currentDuration) > 0) {
minDuration = currentDuration;
}
} else {
minDuration = currentDuration;
}
}
if (prioFromClassification > maxPrio) {
maxPrio = prioFromClassification;
}
return new PrioDurationHolder(minDuration, maxPrio);
}
private void initAttachment(AttachmentImpl attachment, Task newTask) {
@ -1185,4 +1271,40 @@ public class TaskServiceImpl implements TaskService {
}
}
/**
* hold a pair of priority and Duration.
*
* @author bbr
*/
static class PrioDurationHolder {
private Duration duration;
private int prio;
PrioDurationHolder(Duration duration, int prio) {
super();
this.duration = duration;
this.prio = prio;
}
public Duration getDuration() {
return duration;
}
public int getPrio() {
return prio;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("PrioDurationHolder [duration=");
builder.append(duration);
builder.append(", prio=");
builder.append(prio);
builder.append("]");
return builder.toString();
}
}
}

View File

@ -176,6 +176,8 @@ public interface QueryMapper {
@Result(property = "type", column = "TYPE"),
@Result(property = "domain", column = "DOMAIN"),
@Result(property = "name", column = "NAME"),
@Result(property = "priority", column = "PRIORITY"),
@Result(property = "serviceLevel", column = "SERVICE_LEVEL"),
@Result(property = "parentId", column = "PARENT_ID")})
List<ClassificationSummaryImpl> queryClassificationSummaries(ClassificationQueryImpl classificationQuery);

View File

@ -17,7 +17,7 @@ CREATE TABLE CLASSIFICATION(
MODIFIED TIMESTAMP NULL,
NAME VARCHAR(255) NULL,
DESCRIPTION VARCHAR(255) NULL,
PRIORITY INT NULL,
PRIORITY INT NOT NULL,
SERVICE_LEVEL VARCHAR(255) NULL,
APPLICATION_ENTRY_POINT VARCHAR(255) NULL,
CUSTOM_1 VARCHAR(255) NULL,

View File

@ -219,7 +219,7 @@ public class QueryClassificationAccTest extends AbstractAccTest {
.validInDomainEquals(Boolean.TRUE)
.priorityIn(1, 2, 3)
.list();
assertEquals(15, list.size());
assertEquals(14, list.size());
}

View File

@ -139,7 +139,7 @@ public class UpdateClassificationAccTest extends AbstractAccTest {
groupNames = {"group_1", "businessadmin"})
@Test(expected = ConcurrencyException.class)
public void testUpdateClassificationNotLatestAnymore()
throws ClassificationNotFoundException, NotAuthorizedException, ConcurrencyException {
throws ClassificationNotFoundException, NotAuthorizedException, ConcurrencyException, InterruptedException {
ClassificationService classificationService = taskanaEngine.getClassificationService();
Classification base = classificationService.getClassification("T2100", "DOMAIN_A");
Classification classification = classificationService.getClassification("T2100", "DOMAIN_A");
@ -148,6 +148,7 @@ public class UpdateClassificationAccTest extends AbstractAccTest {
base.setApplicationEntryPoint("SOME CHANGED POINT");
base.setDescription("AN OTHER DESCRIPTION");
base.setName("I AM UPDATED");
Thread.sleep(20); // to avoid identity of modified timestamps between classification and base
classificationService.updateClassification(base);
classification.setName("NOW IT´S MY TURN");

View File

@ -8,6 +8,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.sql.SQLException;
import java.time.Duration;
import java.util.Map;
import org.apache.ibatis.session.Configuration;
@ -243,6 +244,47 @@ public class CreateTaskAccTest extends AbstractAccTest {
assertNotNull(readTask.getAttachments().get(0).getObjectReference());
}
@WithAccessId(
userName = "user_1_1",
groupNames = {"group_1"})
@Test
public void testPrioDurationOfTaskFromAttachmentsAtCreate()
throws SQLException, NotAuthorizedException, InvalidArgumentException, ClassificationNotFoundException,
WorkbasketNotFoundException, TaskAlreadyExistException, InvalidWorkbasketException, TaskNotFoundException {
TaskService taskService = taskanaEngine.getTaskService();
Task newTask = taskService.newTask("USER_1_1", "DOMAIN_A");
newTask.setClassificationKey("L12010"); // prio 8, SL P7D
newTask.setPrimaryObjRef(createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
newTask.addAttachment(createAttachment("DOCTYPE_DEFAULT", // prio 99, SL P2000D
createObjectReference("COMPANY_A", "SYSTEM_B", "INSTANCE_B", "ArchiveId",
"12345678901234567890123456789012345678901234567890"),
"E-MAIL", "2018-01-15", createSimpleCustomProperties(3)));
newTask.addAttachment(createAttachment("L1060", // prio 1, SL P1D
createObjectReference("COMPANY_A", "SYSTEM_B", "INSTANCE_B", "ArchiveId",
"12345678901234567890123456789012345678901234567890"),
"E-MAIL", "2018-01-15", createSimpleCustomProperties(3)));
Task createdTask = taskService.createTask(newTask);
assertNotNull(createdTask.getId());
assertThat(createdTask.getCreator(), equalTo(CurrentUserContext.getUserid()));
Task readTask = taskService.getTask(createdTask.getId());
assertNotNull(readTask);
assertThat(readTask.getCreator(), equalTo(CurrentUserContext.getUserid()));
assertNotNull(readTask.getAttachments());
assertEquals(2, readTask.getAttachments().size());
assertNotNull(readTask.getAttachments().get(1).getCreated());
assertNotNull(readTask.getAttachments().get(1).getModified());
assertEquals(readTask.getAttachments().get(0).getCreated(), readTask.getAttachments().get(1).getModified());
// assertNotNull(readTask.getAttachments().get(0).getClassification());
assertNotNull(readTask.getAttachments().get(0).getObjectReference());
assertTrue(readTask.getPriority() == 99);
assertTrue(readTask.getDue().equals(readTask.getPlanned().plus(Duration.ofDays(1))));
}
@WithAccessId(
userName = "user_1_1",
groupNames = {"group_1"})

View File

@ -1,12 +1,15 @@
package acceptance.task;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.sql.SQLException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
@ -18,6 +21,8 @@ import org.junit.runner.RunWith;
import acceptance.AbstractAccTest;
import pro.taskana.Attachment;
import pro.taskana.Classification;
import pro.taskana.ClassificationSummary;
import pro.taskana.Task;
import pro.taskana.TaskService;
import pro.taskana.exceptions.AttachmentPersistenceException;
@ -26,11 +31,14 @@ import pro.taskana.exceptions.ConcurrencyException;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.InvalidWorkbasketException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.TaskAlreadyExistException;
import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.exceptions.WorkbasketNotFoundException;
import pro.taskana.impl.AttachmentImpl;
import pro.taskana.impl.TaskImpl;
import pro.taskana.security.CurrentUserContext;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
/**
* Acceptance test for the usecase of adding/removing an attachment of a task and update the result correctly.
@ -52,8 +60,9 @@ public class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
WorkbasketNotFoundException, InvalidArgumentException, ConcurrencyException, InvalidWorkbasketException,
AttachmentPersistenceException {
taskService = taskanaEngine.getTaskService();
task = taskService.getTask("TKI:000000000000000000000000000000000000");
attachment = createAttachment("DOCTYPE_DEFAULT",
task = taskService.getTask("TKI:000000000000000000000000000000000000"); // class T2000, prio 1, SL P1D
task.setClassificationKey("T2000");
attachment = createAttachment("DOCTYPE_DEFAULT", // prio 99, SL P2000D
createObjectReference("COMPANY_A", "SYSTEM_B", "INSTANCE_B", "ArchiveId",
"12345678901234567890123456789012345678901234567890"),
"E-MAIL", "2018-01-15", createSimpleCustomProperties(3));
@ -68,6 +77,8 @@ public class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
WorkbasketNotFoundException, InvalidArgumentException, ConcurrencyException, InvalidWorkbasketException,
AttachmentPersistenceException {
int attachmentCount = task.getAttachments().size();
assertTrue(task.getPriority() == 1);
assertTrue(task.getDue().equals(task.getPlanned().plus(Duration.ofDays(1))));
task.addAttachment(attachment);
task = taskService.updateTask(task);
@ -75,6 +86,8 @@ public class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
task = taskService.getTask(task.getId());
assertThat(task.getAttachments().size(), equalTo(attachmentCount + 1));
assertThat(task.getAttachments().get(0).getClassificationSummary().getKey(), equalTo("DOCTYPE_DEFAULT"));
assertTrue(task.getPriority() == 99);
assertTrue(task.getDue().equals(task.getPlanned().plus(Duration.ofDays(1))));
}
@Test(expected = AttachmentPersistenceException.class)
@ -114,11 +127,17 @@ public class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
attachmentCount = task.getAttachments().size();
Attachment updatedAttachment = task.getAttachments().get(0);
updatedAttachment.setChannel(newChannel);
Classification newClassification = taskanaEngine.getClassificationService()
.getClassification("CLI:000000000000000000000000000000000001"); // Prio 999, SL PT5H
updatedAttachment.setClassificationSummary(newClassification.asSummary());
task.addAttachment(updatedAttachment);
task = taskService.updateTask(task);
task = taskService.getTask(task.getId());
assertThat(task.getAttachments().size(), equalTo(attachmentCount));
assertThat(task.getAttachments().get(0).getChannel(), equalTo(newChannel));
assertTrue(task.getPriority() == 999);
assertTrue(task.getDue().equals(task.getPlanned().plus(Duration.ofHours(5))));
}
@Test
@ -173,6 +192,8 @@ public class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
assertThat(task.getAttachments().size(), equalTo(attachmentCount)); // locally, not persisted
task = taskService.getTask(task.getId());
assertThat(task.getAttachments().size(), equalTo(attachmentCount)); // persisted values not changed
assertTrue(task.getPriority() == 1);
assertTrue(task.getDue().equals(task.getPlanned().plus(Duration.ofDays(1))));
}
@Test
@ -182,7 +203,8 @@ public class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
AttachmentPersistenceException {
task.addAttachment(attachment);
task = taskService.updateTask(task);
assertTrue(task.getPriority() == 99);
assertTrue(task.getDue().equals(task.getPlanned().plus(Duration.ofDays(1))));
int attachmentCount = task.getAttachments().size();
Attachment attachmentToRemove = task.getAttachments().get(0);
task.removeAttachment(attachmentToRemove.getId());
@ -190,6 +212,8 @@ public class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
assertThat(task.getAttachments().size(), equalTo(attachmentCount - 1)); // locally, removed and not persisted
task = taskService.getTask(task.getId());
assertThat(task.getAttachments().size(), equalTo(attachmentCount - 1)); // persisted, values removed
assertTrue(task.getPriority() == 1);
assertTrue(task.getDue().equals(task.getPlanned().plus(Duration.ofDays(1))));
}
@Test
@ -221,18 +245,29 @@ public class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
AttachmentPersistenceException {
((TaskImpl) task).setAttachments(new ArrayList<>());
task = taskService.updateTask(task);
assertTrue(task.getPriority() == 1);
assertTrue(task.getDue().equals(task.getPlanned().plus(Duration.ofDays(1))));
Attachment attachment = this.attachment;
task.addAttachment(attachment);
task = taskService.updateTask(task);
assertTrue(task.getPriority() == 99);
assertTrue(task.getDue().equals(task.getPlanned().plus(Duration.ofDays(1))));
int attachmentCount = task.getAttachments().size();
String newChannel = attachment.getChannel() + "-X";
task.getAttachments().get(0).setChannel(newChannel);
Classification newClassification = taskanaEngine.getClassificationService()
.getClassification("CLI:000000000000000000000000000000000001"); // Prio 999, SL PT5H
task.getAttachments().get(0).setClassificationSummary(newClassification.asSummary());
task = taskService.updateTask(task);
task = taskService.getTask(task.getId());
assertThat(task.getAttachments().size(), equalTo(attachmentCount));
assertThat(task.getAttachments().get(0).getChannel(), equalTo(newChannel));
assertTrue(task.getPriority() == 999);
assertTrue(task.getDue().equals(task.getPlanned().plus(Duration.ofHours(5))));
}
@Test
@ -243,13 +278,16 @@ public class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
// setup test
assertThat(task.getAttachments().size(), equalTo(0));
task.addAttachment(attachment);
Attachment attachment2 = createAttachment("DOCTYPE_DEFAULT",
Attachment attachment2 = createAttachment("L10303", // prio 101, SL PT7H
createObjectReference("COMPANY_B", "SYSTEM_C", "INSTANCE_C", "ArchiveId",
"ABC45678901234567890123456789012345678901234567890"),
"ROHRPOST", "2018-01-15", createSimpleCustomProperties(4));
task.addAttachment(attachment2);
task = taskService.updateTask(task);
task = taskService.getTask(task.getId());
assertTrue(task.getPriority() == 101);
assertTrue(task.getDue().equals(task.getPlanned().plus(Duration.ofHours(7))));
assertThat(task.getAttachments().size(), equalTo(2));
List<Attachment> attachments = task.getAttachments();
@ -270,15 +308,22 @@ public class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
}
assertTrue(rohrpostFound && emailFound);
ClassificationSummary newClassificationSummary = taskanaEngine.getClassificationService()
.getClassification("CLI:100000000000000000000000000000000006") // Prio 5, SL P16D
.asSummary();
// modify existing attachment
for (Attachment att : task.getAttachments()) {
att.setClassificationSummary(newClassificationSummary);
if (att.getCustomAttributes().size() == 3) {
att.setChannel("FAX");
break;
}
}
// modify existing attachment and task classification
task.setClassificationKey("DOCTYPE_DEFAULT"); // Prio 99, SL P2000D
task = taskService.updateTask(task);
task = taskService.getTask(task.getId());
assertTrue(task.getPriority() == 99);
assertTrue(task.getDue().equals(task.getPlanned().plus(Duration.ofDays(16))));
rohrpostFound = false;
boolean faxFound = false;
@ -343,6 +388,47 @@ public class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
assertThat(task.getAttachments().get(0).getChannel(), equalTo("DHL"));
}
@WithAccessId(
userName = "user_1_1",
groupNames = {"group_1"})
@Test
public void testPrioDurationOfTaskFromAttachmentsAtUpdate()
throws SQLException, NotAuthorizedException, InvalidArgumentException, ClassificationNotFoundException,
WorkbasketNotFoundException, TaskAlreadyExistException, InvalidWorkbasketException, TaskNotFoundException {
TaskService taskService = taskanaEngine.getTaskService();
Task newTask = taskService.newTask("USER_1_1", "DOMAIN_A");
newTask.setClassificationKey("L12010"); // prio 8, SL P7D
newTask.setPrimaryObjRef(createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
newTask.addAttachment(createAttachment("DOCTYPE_DEFAULT", // prio 99, SL P2000D
createObjectReference("COMPANY_A", "SYSTEM_B", "INSTANCE_B", "ArchiveId",
"12345678901234567890123456789012345678901234567890"),
"E-MAIL", "2018-01-15", createSimpleCustomProperties(3)));
newTask.addAttachment(createAttachment("L1060", // prio 1, SL P1D
createObjectReference("COMPANY_A", "SYSTEM_B", "INSTANCE_B", "ArchiveId",
"12345678901234567890123456789012345678901234567890"),
"E-MAIL", "2018-01-15", createSimpleCustomProperties(3)));
Task createdTask = taskService.createTask(newTask);
assertNotNull(createdTask.getId());
assertThat(createdTask.getCreator(), equalTo(CurrentUserContext.getUserid()));
Task readTask = taskService.getTask(createdTask.getId());
assertNotNull(readTask);
assertThat(readTask.getCreator(), equalTo(CurrentUserContext.getUserid()));
assertNotNull(readTask.getAttachments());
assertEquals(2, readTask.getAttachments().size());
assertNotNull(readTask.getAttachments().get(1).getCreated());
assertNotNull(readTask.getAttachments().get(1).getModified());
assertEquals(readTask.getAttachments().get(0).getCreated(), readTask.getAttachments().get(1).getModified());
// assertNotNull(readTask.getAttachments().get(0).getClassification());
assertNotNull(readTask.getAttachments().get(0).getObjectReference());
assertTrue(readTask.getPriority() == 99);
assertTrue(readTask.getDue().equals(readTask.getPlanned().plus(Duration.ofDays(1))));
}
@AfterClass
public static void cleanUpClass() {
FileUtils.deleteRecursive("~/data", true);

View File

@ -1,25 +1,25 @@
-- ID, KEY, PARENT_ID, CATEGORY, TYPE, DOMAIN, VALID_IN_DOMAIN, CREATED, MODIFIED, NAME, DESCRIPTION, PRIORITY, SERVICE_LEVEL, APPLICATION_ENTRY_POINT, CUSTOM_1 - 8
-- ROOT CLASSIFICATIONS
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000001', 'L10000', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'OLD-Leistungsfall', 'OLD-Leistungsfall', 999, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000002', 'L10303', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Beratungsprotokoll', 'Beratungsprotokoll', 1, 'P1D', '', 'VNR,RVNR,KOLVNR, ANR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000003', 'L1050', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Widerruf', 'Widerruf', 1, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000004', 'L11010', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamikänderung', 'Dynamikänderung', 1, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000001', 'L10000', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'OLD-Leistungsfall', 'OLD-Leistungsfall', 999, 'PT5H', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000002', 'L10303', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Beratungsprotokoll', 'Beratungsprotokoll', 1, 'P2D', '', 'VNR,RVNR,KOLVNR, ANR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000003', 'L1050', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Widerruf', 'Widerruf', 1, 'P3D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000004', 'L11010', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamikänderung', 'Dynamikänderung', 7, 'P4D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000005', 'L110102', 'CLI:000000000000000000000000000000000004', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamik-Ablehnung', 'Dynamik-Ablehnung', 5, 'P5D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000006', 'L110105', 'CLI:000000000000000000000000000000000004', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamik-Ausschluss', 'Dynamik-Ausschluss', 5, 'P5D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000007', 'L110107', 'CLI:000000000000000000000000000000000004', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamik-Einschluss/Änd.', 'Dynamik-Einschluss/Änd.', 5, 'P5D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000008', 'L12010', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Gewährung-Policendarlehen', 'Gewährung-Policendarlehen', 1, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000009', 'L140101', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Zustimmungserklärung', 'Zustimmungserklärung', 2, 'P2D', '', 'VNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000010', 'T2100', '', 'MANUAL', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'T-Vertragstermin VERA', 'T-Vertragstermin VERA', 2, 'P2D', '', 'VNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000011', 'T6310', '', 'AUTOMATIC', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'T-GUK Honorarrechnung erstellen', 'Generali Unterstützungskasse Honorar wird fällig', 2, 'P2D', '', 'VNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000007', 'L110107', 'CLI:000000000000000000000000000000000004', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamik-Einschluss/Änd.', 'Dynamik-Einschluss/Änd.', 5, 'P6D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000008', 'L12010', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Gewährung-Policendarlehen', 'Gewährung-Policendarlehen', 8, 'P7D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000009', 'L140101', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Zustimmungserklärung', 'Zustimmungserklärung', 9, 'P8D', '', 'VNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000010', 'T2100', '', 'MANUAL', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'T-Vertragstermin VERA', 'T-Vertragstermin VERA', 2, 'P10D', '', 'VNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000011', 'T6310', '', 'AUTOMATIC', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'T-GUK Honorarrechnung erstellen', 'Generali Unterstützungskasse Honorar wird fällig', 2, 'P11D', '', 'VNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000013', 'DOCTYPE_DEFAULT', '', 'EXTERN', 'DOCUMENT', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'EP allgemein', 'EP allgemein', 99, 'P2000D', '', 'VNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000017', 'L1060', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Widerruf neu', 'Widerruf neu', 1, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000017', 'L1060', '', 'EXTERN', 'TASK', '', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Widerruf neu', 'Widerruf neu', 1, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
-- DOMAIN_A CLASSIFICATIONS
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000002', 'L10303', '', 'EXTERN', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Beratungsprotokoll', 'Beratungsprotokoll', 1, 'P1D', '', 'VNR,RVNR,KOLVNR, ANR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000003', 'L1050', '', 'EXTERN', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Widerruf', 'Widerruf', 1, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000004', 'L11010', '', 'EXTERN', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamikänderung', 'Dynamikänderung', 1, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000005', 'L110102', 'CLI:100000000000000000000000000000000004', 'EXTERN', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamik-Ablehnung', 'Dynamik-Ablehnung', 5, 'P5D', '', 'VNR,RVNR,KOLVNR', 'TEXT_1', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000006', 'L110105', 'CLI:100000000000000000000000000000000004', 'EXTERN', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamik-Ausschluss', 'Dynamik-Ausschluss', 5, 'P5D', '', 'VNR,RVNR,KOLVNR', 'TEXT_2', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000002', 'L10303', '', 'EXTERN', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Beratungsprotokoll', 'Beratungsprotokoll', 101, 'PT7H', '', 'VNR,RVNR,KOLVNR, ANR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000003', 'L1050', '', 'EXTERN', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Widerruf', 'Widerruf', 1, 'P13D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000004', 'L11010', '', 'EXTERN', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamikänderung', 'Dynamikänderung', 1, 'P14D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000005', 'L110102', 'CLI:100000000000000000000000000000000004', 'EXTERN', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamik-Ablehnung', 'Dynamik-Ablehnung', 5, 'P15D', '', 'VNR,RVNR,KOLVNR', 'TEXT_1', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000006', 'L110105', 'CLI:100000000000000000000000000000000004', 'EXTERN', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamik-Ausschluss', 'Dynamik-Ausschluss', 5, 'P16D', '', 'VNR,RVNR,KOLVNR', 'TEXT_2', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000007', 'L110107', 'CLI:100000000000000000000000000000000004', 'EXTERN', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamik-Einschluss/Änd.', 'Dynamik-Einschluss/Änd.', 5, 'P5D', '', 'VNR,RVNR,KOLVNR', 'TEXT_1', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000008', 'L12010', '', 'EXTERN', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Gewährung-Policendarlehen', 'Gewährung-Policendarlehen', 1, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000009', 'L140101', '', 'EXTERN', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Zustimmungserklärung', 'Zustimmungserklärung', 2, 'P2D', '', 'VNR', '', '', '', '', '', '', '');