diff --git a/lib/taskana-core/src/main/java/pro/taskana/BaseQuery.java b/lib/taskana-core/src/main/java/pro/taskana/BaseQuery.java index d5f3c7fc1..baa244b60 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/BaseQuery.java +++ b/lib/taskana-core/src/main/java/pro/taskana/BaseQuery.java @@ -39,6 +39,9 @@ public interface BaseQuery { * * @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 listValues(String dbColumnName, SortDirection sortDirection); diff --git a/lib/taskana-core/src/main/java/pro/taskana/ClassificationSummary.java b/lib/taskana-core/src/main/java/pro/taskana/ClassificationSummary.java index 16501edc1..8113ab8b0 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/ClassificationSummary.java +++ b/lib/taskana-core/src/main/java/pro/taskana/ClassificationSummary.java @@ -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(); } diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/ClassificationImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/ClassificationImpl.java index ee8e800f2..b7c60f16b 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/ClassificationImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/ClassificationImpl.java @@ -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; } diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/ClassificationSummaryImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/ClassificationSummaryImpl.java index 4fe5e7080..51771b462 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/ClassificationSummaryImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/ClassificationSummaryImpl.java @@ -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(); } diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java index 3f4952378..ec606d49d 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java @@ -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 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 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 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(); + } + } } diff --git a/lib/taskana-core/src/main/java/pro/taskana/mappings/QueryMapper.java b/lib/taskana-core/src/main/java/pro/taskana/mappings/QueryMapper.java index 5c0a6a9c6..5ee8537c3 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/mappings/QueryMapper.java +++ b/lib/taskana-core/src/main/java/pro/taskana/mappings/QueryMapper.java @@ -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 queryClassificationSummaries(ClassificationQueryImpl classificationQuery); diff --git a/lib/taskana-core/src/main/resources/sql/taskana-schema.sql b/lib/taskana-core/src/main/resources/sql/taskana-schema.sql index cd4531356..63a64e9b4 100644 --- a/lib/taskana-core/src/main/resources/sql/taskana-schema.sql +++ b/lib/taskana-core/src/main/resources/sql/taskana-schema.sql @@ -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, diff --git a/lib/taskana-core/src/test/java/acceptance/classification/QueryClassificationAccTest.java b/lib/taskana-core/src/test/java/acceptance/classification/QueryClassificationAccTest.java index a91a5878b..7ae496ca9 100644 --- a/lib/taskana-core/src/test/java/acceptance/classification/QueryClassificationAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/classification/QueryClassificationAccTest.java @@ -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()); } diff --git a/lib/taskana-core/src/test/java/acceptance/classification/UpdateClassificationAccTest.java b/lib/taskana-core/src/test/java/acceptance/classification/UpdateClassificationAccTest.java index cfc7b3328..152d98f94 100644 --- a/lib/taskana-core/src/test/java/acceptance/classification/UpdateClassificationAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/classification/UpdateClassificationAccTest.java @@ -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"); diff --git a/lib/taskana-core/src/test/java/acceptance/task/CreateTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/CreateTaskAccTest.java index e72297937..415e57624 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/CreateTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/CreateTaskAccTest.java @@ -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"}) diff --git a/lib/taskana-core/src/test/java/acceptance/task/UpdateTaskAttachmentsAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/UpdateTaskAttachmentsAccTest.java index 96d8a3e3d..5939105b9 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/UpdateTaskAttachmentsAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/UpdateTaskAttachmentsAccTest.java @@ -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 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); diff --git a/lib/taskana-core/src/test/resources/sql/classification.sql b/lib/taskana-core/src/test/resources/sql/classification.sql index c3e7bb92c..27a0f83cd 100644 --- a/lib/taskana-core/src/test/resources/sql/classification.sql +++ b/lib/taskana-core/src/test/resources/sql/classification.sql @@ -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', '', '', '', '', '', '', '');