diff --git a/lib/taskana-core/src/main/java/pro/taskana/CustomField.java b/lib/taskana-core/src/main/java/pro/taskana/CustomField.java index 82e7f9481..ecb3fa4db 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/CustomField.java +++ b/lib/taskana-core/src/main/java/pro/taskana/CustomField.java @@ -1,23 +1,23 @@ -package pro.taskana; - -/** - * This enum contains the fields CUSTOM_1 - CUSTOM_10 for the task entity. - */ -public enum CustomField { - CUSTOM_1, - CUSTOM_2, - CUSTOM_3, - CUSTOM_4, - CUSTOM_5, - CUSTOM_6, - CUSTOM_7, - CUSTOM_8, - CUSTOM_9, - CUSTOM_10, - CUSTOM_11, - CUSTOM_12, - CUSTOM_13, - CUSTOM_14, - CUSTOM_15, - CUSTOM_16 -} +package pro.taskana; + +/** + * This enum contains the fields CUSTOM_1 - CUSTOM_10 for the task entity. + */ +public enum CustomField { + CUSTOM_1, + CUSTOM_2, + CUSTOM_3, + CUSTOM_4, + CUSTOM_5, + CUSTOM_6, + CUSTOM_7, + CUSTOM_8, + CUSTOM_9, + CUSTOM_10, + CUSTOM_11, + CUSTOM_12, + CUSTOM_13, + CUSTOM_14, + CUSTOM_15, + CUSTOM_16 +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/TaskMonitorService.java b/lib/taskana-core/src/main/java/pro/taskana/TaskMonitorService.java index 50c055615..cba52aeaf 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/TaskMonitorService.java +++ b/lib/taskana-core/src/main/java/pro/taskana/TaskMonitorService.java @@ -1,683 +1,683 @@ -package pro.taskana; - -import java.util.List; -import java.util.Map; - -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.exceptions.NotAuthorizedException; -import pro.taskana.impl.SelectedItem; -import pro.taskana.impl.report.impl.CategoryReport; -import pro.taskana.impl.report.impl.ClassificationReport; -import pro.taskana.impl.report.impl.CustomFieldValueReport; -import pro.taskana.impl.report.impl.DetailedClassificationReport; -import pro.taskana.impl.report.impl.TaskStatusReport; -import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; -import pro.taskana.impl.report.impl.WorkbasketLevelReport; - -/** - * The Task Monitor Service manages operations on tasks regarding the monitoring. - */ -public interface TaskMonitorService { - - String DIMENSION_CLASSIFICATION_CATEGORY = "CLASSIFICATION_CATEGORY"; - String DIMENSION_CLASSIFICATION_KEY = "CLASSIFICATION_KEY"; - String DIMENSION_WORKBASKET_KEY = "WORKBASKET_KEY"; - - /** - * Returns a {@link WorkbasketLevelReport} grouped by workbaskets. The report contains the total numbers of tasks of - * the respective workbasket as well as the total number of all tasks. If no filter is required, the respective - * parameter should be null. The tasks of the report are filtered by workbaskets, states, categories, domains and - * values of a custom field. Tasks with Timestamp DUE = null are not considered. - * - * @param workbasketIds - * a list of workbasket ids to filter by workbaskets. To omit this filter, use null for this parameter - * @param states - * a list of states to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field. To omit this filter, use null for this - * parameter - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @return the report - * @throws InvalidArgumentException - * thrown if DaysToWorkingDaysConverter is initialized with null - */ - WorkbasketLevelReport getWorkbasketLevelReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues) - throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link WorkbasketLevelReport} grouped by workbaskets. For each workbasket the report contains the total - * number of tasks and the number of tasks of the respective cluster that are specified by the - * {@link TimeIntervalColumnHeader}s. By default the age of the tasks is counted in working days. Furthermore the - * Report contains a sum line that contains the total numbers of the different clusters and the total number of all - * tasks in this report. The tasks of the report are filtered by workbaskets, states, categories, domains and values - * of a custom field. If no filter is required, the respective parameter should be null. Tasks with Timestamp DUE = - * null are not considered. - * - * @param workbasketIds - * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this - * parameter - * @param states - * a list of states objects to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field. To omit this filter, use null for this - * parameter - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @param columnHeaders - * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past - * are represented as negative values and days in the future are represented as positive values. To avoid - * tasks are counted multiple times or not be listed in the report, these columnHeaders should not - * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, - * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These - * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. - * @return the report - * @throws InvalidArgumentException - * thrown if DaysToWorkingDaysConverter is initialized with null - */ - WorkbasketLevelReport getWorkbasketLevelReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues, - List columnHeaders) throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link WorkbasketLevelReport} grouped by workbaskets. For each workbasket the report contains the total - * number of tasks and the number of tasks of the respective cluster that are specified by the - * {@link TimeIntervalColumnHeader}s. It can be specified whether the age of the tasks is counted in days or in - * working days. Furthermore the report contains a sum line that contains the total numbers of the different - * clusters and the total number of all tasks. The tasks of the report are filtered by workbaskets, states, - * categories, domains and values of a custom field. If no filter is required, the respective parameter should be - * null. Tasks with Timestamp DUE = null are not considered. - * - * @param workbasketIds - * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this - * parameter - * @param states - * a list of states objects to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field. To omit this filter, use null for this - * parameter - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @param columnHeaders - * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past - * are represented as negative values and days in the future are represented as positive values. To avoid - * tasks are counted multiple times or not be listed in the report, these columnHeaders should not - * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, - * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These - * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. - * @param inWorkingDays - * a boolean parameter that specifies whether the age of the tasks should be counted in days or in - * working days - * @return the report - * @throws InvalidArgumentException - * thrown if DaysToWorkingDaysConverter is initialized with null - */ - WorkbasketLevelReport getWorkbasketLevelReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues, - List columnHeaders, boolean inWorkingDays) - throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link CategoryReport} grouped by categories. The report contains the total numbers of tasks of the - * respective category as well as the total number of all tasks. The tasks of the report are filtered by - * workbaskets, states, categories, domains and values of a custom field and values of a custom field. If no filter - * is required, the respective parameter should be null. Tasks with Timestamp DUE = null are not considered. - * - * @param workbasketIds - * a list of workbasket ids to filter by workbaskets. To omit this filter, use null for this parameter - * @param states - * a list of states to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field. To omit this filter, use null for this - * parameter - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @return the report - * @throws InvalidArgumentException - * thrown if DaysToWorkingDaysConverter is initialized with null - */ - CategoryReport getCategoryReport(List workbasketIds, List states, List categories, - List domains, CustomField customField, List customFieldValues) - throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link CategoryReport} grouped by categories. For each category the report contains the total number of - * tasks and the number of tasks of the respective cluster that are specified by the - * {@link TimeIntervalColumnHeader}s. By default the age of the tasks is counted in working days. Furthermore the - * Report contains a sum line that contains the total numbers of the different clusters and the total number of all - * tasks in this report. The tasks of the report are filtered by workbaskets, states, categories, domains and values - * of a custom field. If no filter is required, the respective parameter should be null. Tasks with Timestamp DUE = - * null are not considered. - * - * @param workbasketIds - * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this - * parameter - * @param states - * a list of states objects to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field. To omit this filter, use null for this - * parameter - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @param columnHeaders - * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past - * are represented as negative values and days in the future are represented as positive values. To avoid - * tasks are counted multiple times or not be listed in the report, these columnHeaders should not - * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, - * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These - * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. - * @return the report - * @throws InvalidArgumentException - * thrown if DaysToWorkingDaysConverter is initialized with null - */ - CategoryReport getCategoryReport(List workbasketIds, List states, List categories, - List domains, CustomField customField, List customFieldValues, - List columnHeaders) throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link CategoryReport} grouped by categories. For each category the report contains the total number of - * tasks and the number of tasks of the respective cluster that are specified by the - * {@link TimeIntervalColumnHeader}s. It can be specified whether the age of the tasks is counted in days or in - * working days. Furthermore the report contains a sum line that contains the total numbers of the different - * clusters and the total number of all tasks. The tasks of the report are filtered by workbaskets, states, - * categories, domains and values of a custom field. If no filter is required, the respective parameter should be - * null. Tasks with Timestamp DUE = null are not considered. - * - * @param workbasketIds - * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this - * parameter - * @param states - * a list of states objects to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field. To omit this filter, use null for this - * parameter - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @param columnHeaders - * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past - * are represented as negative values and days in the future are represented as positive values. To avoid - * tasks are counted multiple times or not be listed in the report, these columnHeaders should not - * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, - * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These - * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. - * @param inWorkingDays - * a boolean parameter that specifies whether the age of the tasks should be counted in days or in - * working days - * @return the report - * @throws InvalidArgumentException - * thrown if DaysToWorkingDaysConverter is initialized with null - */ - CategoryReport getCategoryReport(List workbasketIds, List states, List categories, - List domains, CustomField customField, List customFieldValues, - List columnHeaders, boolean inWorkingDays) - throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link ClassificationReport} grouped by classifications. The report contains the total numbers of tasks - * of the respective classification as well as the total number of all tasks. The tasks of the report are filtered - * by workbaskets, states, categories, domains and values of a custom field. If no filter is required, the - * respective parameter should be null. Tasks with Timestamp DUE = null are not considered. - * - * @param workbasketIds - * a list of workbasket ids to filter by workbaskets. To omit this filter, use null for this parameter - * @param states - * a list of states to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field. To omit this filter, use null for this - * parameter - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @return the ClassificationReport - * @throws InvalidArgumentException - * thrown if DaysToWorkingDaysConverter is initialized with null - */ - ClassificationReport getClassificationReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues) - throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link ClassificationReport} grouped by classifications. For each classification the report contains - * the total number of tasks and the number of tasks of the respective cluster that are specified by the - * {@link TimeIntervalColumnHeader}s. By default the age of the tasks is counted in working days. Furthermore the - * Report contains a sum line that contains the total numbers of the different clusters and the total number of all - * tasks in this report. The tasks of the report are filtered by workbaskets, states, categories, domains and values - * of a custom field. If no filter is required, the respective parameter should be null. Tasks with Timestamp DUE = - * null are not considered. - * - * @param workbasketIds - * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this - * parameter - * @param states - * a list of states objects to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field. To omit this filter, use null for this - * parameter - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @param columnHeaders - * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past - * are represented as negative values and days in the future are represented as positive values. To avoid - * tasks are counted multiple times or not be listed in the report, these columnHeaders should not - * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, - * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These - * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. - * @return the ClassificationReport - * @throws InvalidArgumentException - * thrown if DaysToWorkingDaysConverter is initialized with null - */ - ClassificationReport getClassificationReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues, - List columnHeaders) throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link ClassificationReport} grouped by classification. For each classification the report contains the - * total number of tasks and the number of tasks of the respective cluster that are specified by the - * {@link TimeIntervalColumnHeader}s. It can be specified whether the age of the tasks is counted in days or in - * working days. Furthermore the report contains a sum line that contains the total numbers of the different - * clusters and the total number of all tasks. The tasks of the report are filtered by workbaskets, states, - * categories, domains and values of a custom field. If no filter is required, the respective parameter should be - * null. Tasks with Timestamp DUE = null are not considered. - * - * @param workbasketIds - * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this - * parameter - * @param states - * a list of states objects to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field. To omit this filter, use null for this - * parameter - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @param columnHeaders - * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past - * are represented as negative values and days in the future are represented as positive values. To avoid - * tasks are counted multiple times or not be listed in the report, these columnHeaders should not - * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, - * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These - * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. - * @param inWorkingDays - * a boolean parameter that specifies whether the age of the tasks should be counted in days or in - * working days - * @return the ClassificationReport - * @throws InvalidArgumentException - * thrown if DaysToWorkingDaysConverter is initialized with null - */ - ClassificationReport getClassificationReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues, - List columnHeaders, boolean inWorkingDays) - throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link DetailedClassificationReport}. The report contains the total numbers of tasks of the respective - * classification as well as the total number of all tasks. Each ReportLine contains an additional list of - * ReportLines for the classifications of the attachments of the tasks. The tasks of the report are filtered by - * workbaskets, states, categories, domains and values of a custom field. If no filter is required, the respective - * parameter should be null. Tasks with Timestamp DUE = null are not considered. - * - * @param workbasketIds - * a list of workbasket ids to filter by workbaskets. To omit this filter, use null for this parameter - * @param states - * a list of states to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field. To omit this filter, use null for this - * parameter - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @return the DetailedClassificationReport - * @throws InvalidArgumentException - * thrown if DaysToWorkingDaysConverter is initialized with null - */ - DetailedClassificationReport getDetailedClassificationReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues) - throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link DetailedClassificationReport}. For each classification the report contains the total number of - * tasks and the number of tasks of the respective cluster that are specified by the - * {@link TimeIntervalColumnHeader}s. By default the age of the tasks is counted in working days. Each ReportLine - * contains an additional list of ReportLines for the classifications of the attachments of the tasks. Furthermore - * the Report contains a sum line that contains the total numbers of the different clusters and the total number of - * all tasks in this report. The tasks of the report are filtered by workbaskets, states, categories, domains and - * values of a custom field. If no filter is required, the respective parameter should be null. Tasks with Timestamp - * DUE = null are not considered. - * - * @param workbasketIds - * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this - * parameter - * @param states - * a list of states objects to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field. To omit this filter, use null for this - * parameter - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @param columnHeaders - * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past - * are represented as negative values and days in the future are represented as positive values. To avoid - * tasks are counted multiple times or not be listed in the report, these columnHeaders should not - * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, - * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These - * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. - * @return the DetailedClassificationReport - * @throws InvalidArgumentException - * thrown if DaysToWorkingDaysConverter is initialized with null - */ - DetailedClassificationReport getDetailedClassificationReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues, - List columnHeaders) throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link DetailedClassificationReport}. For each classification the report contains the total number of - * tasks and the number of tasks of the respective cluster that are specified by the - * {@link TimeIntervalColumnHeader}s. It can be specified whether the age of the tasks is counted in days or in - * working days. Each ReportLine contains an additional list of ReportLines for the classifications of the - * attachments of the tasks. Furthermore the report contains a sum line that contains the total numbers of the - * different clusters and the total number of all tasks. The tasks of the report are filtered by workbaskets, - * states, categories, domains and values of a custom field. If no filter is required, the respective parameter - * should be null. Tasks with Timestamp DUE = null are not considered. - * - * @param workbasketIds - * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this - * parameter - * @param states - * a list of states objects to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field. To omit this filter, use null for this - * parameter - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @param columnHeaders - * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past - * are represented as negative values and days in the future are represented as positive values. To avoid - * tasks are counted multiple times or not be listed in the report, these columnHeaders should not - * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, - * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These - * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. - * @param inWorkingDays - * a boolean parameter that specifies whether the age of the tasks should be counted in days or in - * working days - * @return the DetailedClassificationReport - * @throws InvalidArgumentException - * thrown if DaysToWorkingDaysConverter is initialized with null - */ - DetailedClassificationReport getDetailedClassificationReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues, - List columnHeaders, boolean inWorkingDays) - throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link CustomFieldValueReport} grouped by the value of a certain {@link CustomField}. The report - * contains the total numbers of tasks of the respective custom field as well as the total number of all tasks. The - * tasks of the report are filtered by workbaskets, states, categories, domains and values of a custom field. If no - * filter is required, the respective parameter should be null. Tasks with Timestamp DUE = null are not considered. - * - * @param workbasketIds - * a list of workbasket ids to filter by workbaskets. To omit this filter, use null for this parameter - * @param states - * a list of states to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @return the report - * @throws InvalidArgumentException - * thrown if customField is null - */ - CustomFieldValueReport getCustomFieldValueReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues) - throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link CustomFieldValueReport} grouped by the value of a certain {@link CustomField}. For each value of - * the custom field the report contains the total number of tasks and the number of tasks of the respective cluster - * that are specified by the {@link TimeIntervalColumnHeader}s. By default the age of the tasks is counted in - * working days. Furthermore the Report contains a sum line that contains the total numbers of the different - * clusters and the total number of all tasks in this report. The tasks of the report are filtered by workbaskets, - * states, categories, domains and values of a custom field. If no filter is required, the respective parameter - * should be null. Tasks with Timestamp DUE = null are not considered. - * - * @param workbasketIds - * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this - * parameter - * @param states - * a list of states objects to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @param columnHeaders - * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past - * are represented as negative values and days in the future are represented as positive values. To avoid - * tasks are counted multiple times or not be listed in the report, these columnHeaders should not - * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, - * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These - * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. - * @return the report - * @throws InvalidArgumentException - * thrown if customField is null - */ - CustomFieldValueReport getCustomFieldValueReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues, - List columnHeaders) throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a {@link CustomFieldValueReport} grouped by the value of a certain {@link CustomField}. For each value of - * the custom field the report contains the total number of tasks and the number of tasks of the respective cluster - * that are specified by the {@link TimeIntervalColumnHeader}s. It can be specified whether the age of the tasks is - * counted in days or in working days. Furthermore the report contains a sum line that contains the total numbers of - * the different clusters and the total number of all tasks. The tasks of the report are filtered by workbaskets, - * states, categories, domains and values of a custom field. If no filter is required, the respective parameter - * should be null. Tasks with Timestamp DUE = null are not considered. - * - * @param workbasketIds - * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this - * parameter - * @param states - * a list of states objects to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @param columnHeaders - * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past - * are represented as negative values and days in the future are represented as positive values. To avoid - * tasks are counted multiple times or not be listed in the report, these columnHeaders should not - * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, - * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These - * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. - * @param inWorkingDays - * a boolean parameter that specifies whether the age of the tasks should be counted in days or in - * working days - * @return the report - * @throws InvalidArgumentException - * thrown if customField is null - */ - CustomFieldValueReport getCustomFieldValueReport(List workbasketIds, List states, - List categories, - List domains, CustomField customField, List customFieldValues, - List columnHeaders, boolean inWorkingDays) - throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a list of all task ids in the selected items of a {@link pro.taskana.impl.report.Report}. By default the - * age of the tasks is counted in working days. The tasks of the report are filtered by workbaskets, states, - * categories, domains and values of a custom field. If no filter is required, the respective parameter should be - * null. Tasks with Timestamp DUE = null are not considered. - * - * @param workbasketIds - * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this - * parameter - * @param states - * a list of states objects to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param customField - * a custom field to filter by the values of the custom field. To omit this filter, use null for this - * parameter - * @param customFieldValues - * a list of custom field values to filter by the values of the custom field. To omit this filter, use - * null for this parameter - * @param columnHeaders - * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past - * are represented as negative values and days in the future are represented as positive values. To avoid - * tasks are counted multiple times or not be listed in the report, these columnHeaders should not - * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, - * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These - * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. - * @param inWorkingDays - * a boolean parameter that specifies whether the age of the tasks should be counted in days or in - * working days - * @param selectedItems - * a list of {@link SelectedItem}s that are selected from the report whose task ids should be determined. - * @param dimension - * defines the meaning of the key in the {@link SelectedItem}s. - * @return the list of task ids - * @throws InvalidArgumentException - * thrown if columnHeaders is null or if selectedItems is empty or null - */ - List getTaskIdsForSelectedItems(List workbasketIds, List states, List categories, - List domains, List classificationKeys, - List excludedClassificationKeys, CustomField customField, List customFieldValues, - List columnHeaders, boolean inWorkingDays, List selectedItems, - String dimension) - throws InvalidArgumentException, NotAuthorizedException; - - /** - * Returns a list of distinct custom attribute values for the selection from the entire task pool. - * - * @param workbasketIds - * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this - * parameter - * @param states - * a list of states objects to filter by states. To omit this filter, use null for this parameter - * @param categories - * a list of categories to filter by categories. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @param classificationIds - * a List of all classification ids to include in the selection. - * @param excludedClassificationIds - * a List of all classification ids to exclude from the selection. - * @param customAttributeFilter - * a Map containing a key value pair for the custom attributes to be applied as a filter criteria - * @param customAttributeName - * the name of the custom attribute to determine the existing values from. - * @return the list of existing values for the custom attribute with name customAttributeName in the filtered task - * pool. - * @throws InvalidArgumentException - * thrown if the customAttributeName is invalid/empty. - */ - List getCustomAttributeValuesForReport(List workbasketIds, List states, - List categories, List domains, List classificationIds, - List excludedClassificationIds, Map customAttributeFilter, - String customAttributeName) throws InvalidArgumentException, NotAuthorizedException; - - /** - * Overloaded method for {@link #getTaskStatusReport(List, List)}. This method omits all filters. - * - * @return the {@link TaskStatusReport} - */ - TaskStatusReport getTaskStatusReport() throws NotAuthorizedException; - - /** - * Overloaded method for {@link #getTaskStatusReport(List, List)}. This method applies a domain filter and omits the - * state filter. - * - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @return the {@link TaskStatusReport} - */ - TaskStatusReport getTaskStatusReport(List domains) throws NotAuthorizedException; - - /** - * Returns a {@link TaskStatusReport}. For each domain the report contains the total number of tasks, clustered in - * their task status. Furthermore the report contains a sum line that contains the total numbers of the different - * clusters and the total number of all tasks. - * - * @param states - * a list of states objects to filter by states. To omit this filter, use null for this parameter - * @param domains - * a list of domains to filter by domains. To omit this filter, use null for this parameter - * @return the {@link TaskStatusReport} - */ - TaskStatusReport getTaskStatusReport(List domains, List states) throws NotAuthorizedException; - -} +package pro.taskana; + +import java.util.List; +import java.util.Map; + +import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.impl.SelectedItem; +import pro.taskana.impl.report.impl.CategoryReport; +import pro.taskana.impl.report.impl.ClassificationReport; +import pro.taskana.impl.report.impl.CustomFieldValueReport; +import pro.taskana.impl.report.impl.DetailedClassificationReport; +import pro.taskana.impl.report.impl.TaskStatusReport; +import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; +import pro.taskana.impl.report.impl.WorkbasketLevelReport; + +/** + * The Task Monitor Service manages operations on tasks regarding the monitoring. + */ +public interface TaskMonitorService { + + String DIMENSION_CLASSIFICATION_CATEGORY = "CLASSIFICATION_CATEGORY"; + String DIMENSION_CLASSIFICATION_KEY = "CLASSIFICATION_KEY"; + String DIMENSION_WORKBASKET_KEY = "WORKBASKET_KEY"; + + /** + * Returns a {@link WorkbasketLevelReport} grouped by workbaskets. The report contains the total numbers of tasks of + * the respective workbasket as well as the total number of all tasks. If no filter is required, the respective + * parameter should be null. The tasks of the report are filtered by workbaskets, states, categories, domains and + * values of a custom field. Tasks with Timestamp DUE = null are not considered. + * + * @param workbasketIds + * a list of workbasket ids to filter by workbaskets. To omit this filter, use null for this parameter + * @param states + * a list of states to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field. To omit this filter, use null for this + * parameter + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @return the report + * @throws InvalidArgumentException + * thrown if DaysToWorkingDaysConverter is initialized with null + */ + WorkbasketLevelReport getWorkbasketLevelReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues) + throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link WorkbasketLevelReport} grouped by workbaskets. For each workbasket the report contains the total + * number of tasks and the number of tasks of the respective cluster that are specified by the + * {@link TimeIntervalColumnHeader}s. By default the age of the tasks is counted in working days. Furthermore the + * Report contains a sum line that contains the total numbers of the different clusters and the total number of all + * tasks in this report. The tasks of the report are filtered by workbaskets, states, categories, domains and values + * of a custom field. If no filter is required, the respective parameter should be null. Tasks with Timestamp DUE = + * null are not considered. + * + * @param workbasketIds + * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this + * parameter + * @param states + * a list of states objects to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field. To omit this filter, use null for this + * parameter + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @param columnHeaders + * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past + * are represented as negative values and days in the future are represented as positive values. To avoid + * tasks are counted multiple times or not be listed in the report, these columnHeaders should not + * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, + * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These + * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. + * @return the report + * @throws InvalidArgumentException + * thrown if DaysToWorkingDaysConverter is initialized with null + */ + WorkbasketLevelReport getWorkbasketLevelReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues, + List columnHeaders) throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link WorkbasketLevelReport} grouped by workbaskets. For each workbasket the report contains the total + * number of tasks and the number of tasks of the respective cluster that are specified by the + * {@link TimeIntervalColumnHeader}s. It can be specified whether the age of the tasks is counted in days or in + * working days. Furthermore the report contains a sum line that contains the total numbers of the different + * clusters and the total number of all tasks. The tasks of the report are filtered by workbaskets, states, + * categories, domains and values of a custom field. If no filter is required, the respective parameter should be + * null. Tasks with Timestamp DUE = null are not considered. + * + * @param workbasketIds + * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this + * parameter + * @param states + * a list of states objects to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field. To omit this filter, use null for this + * parameter + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @param columnHeaders + * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past + * are represented as negative values and days in the future are represented as positive values. To avoid + * tasks are counted multiple times or not be listed in the report, these columnHeaders should not + * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, + * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These + * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. + * @param inWorkingDays + * a boolean parameter that specifies whether the age of the tasks should be counted in days or in + * working days + * @return the report + * @throws InvalidArgumentException + * thrown if DaysToWorkingDaysConverter is initialized with null + */ + WorkbasketLevelReport getWorkbasketLevelReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues, + List columnHeaders, boolean inWorkingDays) + throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link CategoryReport} grouped by categories. The report contains the total numbers of tasks of the + * respective category as well as the total number of all tasks. The tasks of the report are filtered by + * workbaskets, states, categories, domains and values of a custom field and values of a custom field. If no filter + * is required, the respective parameter should be null. Tasks with Timestamp DUE = null are not considered. + * + * @param workbasketIds + * a list of workbasket ids to filter by workbaskets. To omit this filter, use null for this parameter + * @param states + * a list of states to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field. To omit this filter, use null for this + * parameter + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @return the report + * @throws InvalidArgumentException + * thrown if DaysToWorkingDaysConverter is initialized with null + */ + CategoryReport getCategoryReport(List workbasketIds, List states, List categories, + List domains, CustomField customField, List customFieldValues) + throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link CategoryReport} grouped by categories. For each category the report contains the total number of + * tasks and the number of tasks of the respective cluster that are specified by the + * {@link TimeIntervalColumnHeader}s. By default the age of the tasks is counted in working days. Furthermore the + * Report contains a sum line that contains the total numbers of the different clusters and the total number of all + * tasks in this report. The tasks of the report are filtered by workbaskets, states, categories, domains and values + * of a custom field. If no filter is required, the respective parameter should be null. Tasks with Timestamp DUE = + * null are not considered. + * + * @param workbasketIds + * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this + * parameter + * @param states + * a list of states objects to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field. To omit this filter, use null for this + * parameter + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @param columnHeaders + * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past + * are represented as negative values and days in the future are represented as positive values. To avoid + * tasks are counted multiple times or not be listed in the report, these columnHeaders should not + * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, + * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These + * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. + * @return the report + * @throws InvalidArgumentException + * thrown if DaysToWorkingDaysConverter is initialized with null + */ + CategoryReport getCategoryReport(List workbasketIds, List states, List categories, + List domains, CustomField customField, List customFieldValues, + List columnHeaders) throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link CategoryReport} grouped by categories. For each category the report contains the total number of + * tasks and the number of tasks of the respective cluster that are specified by the + * {@link TimeIntervalColumnHeader}s. It can be specified whether the age of the tasks is counted in days or in + * working days. Furthermore the report contains a sum line that contains the total numbers of the different + * clusters and the total number of all tasks. The tasks of the report are filtered by workbaskets, states, + * categories, domains and values of a custom field. If no filter is required, the respective parameter should be + * null. Tasks with Timestamp DUE = null are not considered. + * + * @param workbasketIds + * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this + * parameter + * @param states + * a list of states objects to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field. To omit this filter, use null for this + * parameter + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @param columnHeaders + * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past + * are represented as negative values and days in the future are represented as positive values. To avoid + * tasks are counted multiple times or not be listed in the report, these columnHeaders should not + * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, + * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These + * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. + * @param inWorkingDays + * a boolean parameter that specifies whether the age of the tasks should be counted in days or in + * working days + * @return the report + * @throws InvalidArgumentException + * thrown if DaysToWorkingDaysConverter is initialized with null + */ + CategoryReport getCategoryReport(List workbasketIds, List states, List categories, + List domains, CustomField customField, List customFieldValues, + List columnHeaders, boolean inWorkingDays) + throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link ClassificationReport} grouped by classifications. The report contains the total numbers of tasks + * of the respective classification as well as the total number of all tasks. The tasks of the report are filtered + * by workbaskets, states, categories, domains and values of a custom field. If no filter is required, the + * respective parameter should be null. Tasks with Timestamp DUE = null are not considered. + * + * @param workbasketIds + * a list of workbasket ids to filter by workbaskets. To omit this filter, use null for this parameter + * @param states + * a list of states to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field. To omit this filter, use null for this + * parameter + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @return the ClassificationReport + * @throws InvalidArgumentException + * thrown if DaysToWorkingDaysConverter is initialized with null + */ + ClassificationReport getClassificationReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues) + throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link ClassificationReport} grouped by classifications. For each classification the report contains + * the total number of tasks and the number of tasks of the respective cluster that are specified by the + * {@link TimeIntervalColumnHeader}s. By default the age of the tasks is counted in working days. Furthermore the + * Report contains a sum line that contains the total numbers of the different clusters and the total number of all + * tasks in this report. The tasks of the report are filtered by workbaskets, states, categories, domains and values + * of a custom field. If no filter is required, the respective parameter should be null. Tasks with Timestamp DUE = + * null are not considered. + * + * @param workbasketIds + * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this + * parameter + * @param states + * a list of states objects to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field. To omit this filter, use null for this + * parameter + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @param columnHeaders + * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past + * are represented as negative values and days in the future are represented as positive values. To avoid + * tasks are counted multiple times or not be listed in the report, these columnHeaders should not + * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, + * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These + * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. + * @return the ClassificationReport + * @throws InvalidArgumentException + * thrown if DaysToWorkingDaysConverter is initialized with null + */ + ClassificationReport getClassificationReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues, + List columnHeaders) throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link ClassificationReport} grouped by classification. For each classification the report contains the + * total number of tasks and the number of tasks of the respective cluster that are specified by the + * {@link TimeIntervalColumnHeader}s. It can be specified whether the age of the tasks is counted in days or in + * working days. Furthermore the report contains a sum line that contains the total numbers of the different + * clusters and the total number of all tasks. The tasks of the report are filtered by workbaskets, states, + * categories, domains and values of a custom field. If no filter is required, the respective parameter should be + * null. Tasks with Timestamp DUE = null are not considered. + * + * @param workbasketIds + * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this + * parameter + * @param states + * a list of states objects to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field. To omit this filter, use null for this + * parameter + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @param columnHeaders + * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past + * are represented as negative values and days in the future are represented as positive values. To avoid + * tasks are counted multiple times or not be listed in the report, these columnHeaders should not + * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, + * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These + * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. + * @param inWorkingDays + * a boolean parameter that specifies whether the age of the tasks should be counted in days or in + * working days + * @return the ClassificationReport + * @throws InvalidArgumentException + * thrown if DaysToWorkingDaysConverter is initialized with null + */ + ClassificationReport getClassificationReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues, + List columnHeaders, boolean inWorkingDays) + throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link DetailedClassificationReport}. The report contains the total numbers of tasks of the respective + * classification as well as the total number of all tasks. Each ReportLine contains an additional list of + * ReportLines for the classifications of the attachments of the tasks. The tasks of the report are filtered by + * workbaskets, states, categories, domains and values of a custom field. If no filter is required, the respective + * parameter should be null. Tasks with Timestamp DUE = null are not considered. + * + * @param workbasketIds + * a list of workbasket ids to filter by workbaskets. To omit this filter, use null for this parameter + * @param states + * a list of states to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field. To omit this filter, use null for this + * parameter + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @return the DetailedClassificationReport + * @throws InvalidArgumentException + * thrown if DaysToWorkingDaysConverter is initialized with null + */ + DetailedClassificationReport getDetailedClassificationReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues) + throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link DetailedClassificationReport}. For each classification the report contains the total number of + * tasks and the number of tasks of the respective cluster that are specified by the + * {@link TimeIntervalColumnHeader}s. By default the age of the tasks is counted in working days. Each ReportLine + * contains an additional list of ReportLines for the classifications of the attachments of the tasks. Furthermore + * the Report contains a sum line that contains the total numbers of the different clusters and the total number of + * all tasks in this report. The tasks of the report are filtered by workbaskets, states, categories, domains and + * values of a custom field. If no filter is required, the respective parameter should be null. Tasks with Timestamp + * DUE = null are not considered. + * + * @param workbasketIds + * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this + * parameter + * @param states + * a list of states objects to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field. To omit this filter, use null for this + * parameter + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @param columnHeaders + * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past + * are represented as negative values and days in the future are represented as positive values. To avoid + * tasks are counted multiple times or not be listed in the report, these columnHeaders should not + * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, + * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These + * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. + * @return the DetailedClassificationReport + * @throws InvalidArgumentException + * thrown if DaysToWorkingDaysConverter is initialized with null + */ + DetailedClassificationReport getDetailedClassificationReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues, + List columnHeaders) throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link DetailedClassificationReport}. For each classification the report contains the total number of + * tasks and the number of tasks of the respective cluster that are specified by the + * {@link TimeIntervalColumnHeader}s. It can be specified whether the age of the tasks is counted in days or in + * working days. Each ReportLine contains an additional list of ReportLines for the classifications of the + * attachments of the tasks. Furthermore the report contains a sum line that contains the total numbers of the + * different clusters and the total number of all tasks. The tasks of the report are filtered by workbaskets, + * states, categories, domains and values of a custom field. If no filter is required, the respective parameter + * should be null. Tasks with Timestamp DUE = null are not considered. + * + * @param workbasketIds + * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this + * parameter + * @param states + * a list of states objects to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field. To omit this filter, use null for this + * parameter + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @param columnHeaders + * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past + * are represented as negative values and days in the future are represented as positive values. To avoid + * tasks are counted multiple times or not be listed in the report, these columnHeaders should not + * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, + * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These + * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. + * @param inWorkingDays + * a boolean parameter that specifies whether the age of the tasks should be counted in days or in + * working days + * @return the DetailedClassificationReport + * @throws InvalidArgumentException + * thrown if DaysToWorkingDaysConverter is initialized with null + */ + DetailedClassificationReport getDetailedClassificationReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues, + List columnHeaders, boolean inWorkingDays) + throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link CustomFieldValueReport} grouped by the value of a certain {@link CustomField}. The report + * contains the total numbers of tasks of the respective custom field as well as the total number of all tasks. The + * tasks of the report are filtered by workbaskets, states, categories, domains and values of a custom field. If no + * filter is required, the respective parameter should be null. Tasks with Timestamp DUE = null are not considered. + * + * @param workbasketIds + * a list of workbasket ids to filter by workbaskets. To omit this filter, use null for this parameter + * @param states + * a list of states to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @return the report + * @throws InvalidArgumentException + * thrown if customField is null + */ + CustomFieldValueReport getCustomFieldValueReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues) + throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link CustomFieldValueReport} grouped by the value of a certain {@link CustomField}. For each value of + * the custom field the report contains the total number of tasks and the number of tasks of the respective cluster + * that are specified by the {@link TimeIntervalColumnHeader}s. By default the age of the tasks is counted in + * working days. Furthermore the Report contains a sum line that contains the total numbers of the different + * clusters and the total number of all tasks in this report. The tasks of the report are filtered by workbaskets, + * states, categories, domains and values of a custom field. If no filter is required, the respective parameter + * should be null. Tasks with Timestamp DUE = null are not considered. + * + * @param workbasketIds + * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this + * parameter + * @param states + * a list of states objects to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @param columnHeaders + * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past + * are represented as negative values and days in the future are represented as positive values. To avoid + * tasks are counted multiple times or not be listed in the report, these columnHeaders should not + * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, + * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These + * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. + * @return the report + * @throws InvalidArgumentException + * thrown if customField is null + */ + CustomFieldValueReport getCustomFieldValueReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues, + List columnHeaders) throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a {@link CustomFieldValueReport} grouped by the value of a certain {@link CustomField}. For each value of + * the custom field the report contains the total number of tasks and the number of tasks of the respective cluster + * that are specified by the {@link TimeIntervalColumnHeader}s. It can be specified whether the age of the tasks is + * counted in days or in working days. Furthermore the report contains a sum line that contains the total numbers of + * the different clusters and the total number of all tasks. The tasks of the report are filtered by workbaskets, + * states, categories, domains and values of a custom field. If no filter is required, the respective parameter + * should be null. Tasks with Timestamp DUE = null are not considered. + * + * @param workbasketIds + * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this + * parameter + * @param states + * a list of states objects to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @param columnHeaders + * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past + * are represented as negative values and days in the future are represented as positive values. To avoid + * tasks are counted multiple times or not be listed in the report, these columnHeaders should not + * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, + * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These + * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. + * @param inWorkingDays + * a boolean parameter that specifies whether the age of the tasks should be counted in days or in + * working days + * @return the report + * @throws InvalidArgumentException + * thrown if customField is null + */ + CustomFieldValueReport getCustomFieldValueReport(List workbasketIds, List states, + List categories, + List domains, CustomField customField, List customFieldValues, + List columnHeaders, boolean inWorkingDays) + throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a list of all task ids in the selected items of a {@link pro.taskana.impl.report.Report}. By default the + * age of the tasks is counted in working days. The tasks of the report are filtered by workbaskets, states, + * categories, domains and values of a custom field. If no filter is required, the respective parameter should be + * null. Tasks with Timestamp DUE = null are not considered. + * + * @param workbasketIds + * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this + * parameter + * @param states + * a list of states objects to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param customField + * a custom field to filter by the values of the custom field. To omit this filter, use null for this + * parameter + * @param customFieldValues + * a list of custom field values to filter by the values of the custom field. To omit this filter, use + * null for this parameter + * @param columnHeaders + * a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past + * are represented as negative values and days in the future are represented as positive values. To avoid + * tasks are counted multiple times or not be listed in the report, these columnHeaders should not + * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, + * lowerLimit and upperLimit have to be equal. The outer cluster of a report should have open ends. These + * open ends are represented with Integer.MIN_VALUE and Integer.MAX_VALUE. + * @param inWorkingDays + * a boolean parameter that specifies whether the age of the tasks should be counted in days or in + * working days + * @param selectedItems + * a list of {@link SelectedItem}s that are selected from the report whose task ids should be determined. + * @param dimension + * defines the meaning of the key in the {@link SelectedItem}s. + * @return the list of task ids + * @throws InvalidArgumentException + * thrown if columnHeaders is null or if selectedItems is empty or null + */ + List getTaskIdsForSelectedItems(List workbasketIds, List states, List categories, + List domains, List classificationKeys, + List excludedClassificationKeys, CustomField customField, List customFieldValues, + List columnHeaders, boolean inWorkingDays, List selectedItems, + String dimension) + throws InvalidArgumentException, NotAuthorizedException; + + /** + * Returns a list of distinct custom attribute values for the selection from the entire task pool. + * + * @param workbasketIds + * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this + * parameter + * @param states + * a list of states objects to filter by states. To omit this filter, use null for this parameter + * @param categories + * a list of categories to filter by categories. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @param classificationIds + * a List of all classification ids to include in the selection. + * @param excludedClassificationIds + * a List of all classification ids to exclude from the selection. + * @param customAttributeFilter + * a Map containing a key value pair for the custom attributes to be applied as a filter criteria + * @param customAttributeName + * the name of the custom attribute to determine the existing values from. + * @return the list of existing values for the custom attribute with name customAttributeName in the filtered task + * pool. + * @throws InvalidArgumentException + * thrown if the customAttributeName is invalid/empty. + */ + List getCustomAttributeValuesForReport(List workbasketIds, List states, + List categories, List domains, List classificationIds, + List excludedClassificationIds, Map customAttributeFilter, + String customAttributeName) throws InvalidArgumentException, NotAuthorizedException; + + /** + * Overloaded method for {@link #getTaskStatusReport(List, List)}. This method omits all filters. + * + * @return the {@link TaskStatusReport} + */ + TaskStatusReport getTaskStatusReport() throws NotAuthorizedException; + + /** + * Overloaded method for {@link #getTaskStatusReport(List, List)}. This method applies a domain filter and omits the + * state filter. + * + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @return the {@link TaskStatusReport} + */ + TaskStatusReport getTaskStatusReport(List domains) throws NotAuthorizedException; + + /** + * Returns a {@link TaskStatusReport}. For each domain the report contains the total number of tasks, clustered in + * their task status. Furthermore the report contains a sum line that contains the total numbers of the different + * clusters and the total number of all tasks. + * + * @param states + * a list of states objects to filter by states. To omit this filter, use null for this parameter + * @param domains + * a list of domains to filter by domains. To omit this filter, use null for this parameter + * @return the {@link TaskStatusReport} + */ + TaskStatusReport getTaskStatusReport(List domains, List states) throws NotAuthorizedException; + +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/exceptions/UnsupportedDatabaseException.java b/lib/taskana-core/src/main/java/pro/taskana/exceptions/UnsupportedDatabaseException.java index 69bb1c5ad..c679a5b48 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/exceptions/UnsupportedDatabaseException.java +++ b/lib/taskana-core/src/main/java/pro/taskana/exceptions/UnsupportedDatabaseException.java @@ -1,13 +1,13 @@ -package pro.taskana.exceptions; - -/** - * This exception will be thrown if the database name doesn't match to one of the desired databases. - */ -public class UnsupportedDatabaseException extends RuntimeException { - - public UnsupportedDatabaseException(String name) { - super("Database with '" + name + "' not found"); - } - - private static final long serialVersionUID = 1L; -} +package pro.taskana.exceptions; + +/** + * This exception will be thrown if the database name doesn't match to one of the desired databases. + */ +public class UnsupportedDatabaseException extends RuntimeException { + + public UnsupportedDatabaseException(String name) { + super("Database with '" + name + "' not found"); + } + + private static final long serialVersionUID = 1L; +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/DaysToWorkingDaysConverter.java b/lib/taskana-core/src/main/java/pro/taskana/impl/DaysToWorkingDaysConverter.java index 54b8d3c92..cf5d91771 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/DaysToWorkingDaysConverter.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/DaysToWorkingDaysConverter.java @@ -1,329 +1,329 @@ -package pro.taskana.impl; - -import java.time.DayOfWeek; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.impl.util.LoggerUtils; - -/** - * The DaysToWorkingDaysConverter 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 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. - */ -public final class DaysToWorkingDaysConverter { - - private static final Logger LOGGER = LoggerFactory.getLogger(TaskMonitorServiceImpl.class); - private static DaysToWorkingDaysConverter instance; - private static ArrayList positiveDaysToWorkingDays; - private static ArrayList negativeDaysToWorkingDays; - private static Instant dateCreated; - private static LocalDate easterSunday; - private static boolean germanHolidaysEnabled; - private static List customHolidays; - - private DaysToWorkingDaysConverter(List columnHeaders, - Instant referenceDate) { - easterSunday = getEasterSunday(LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).getYear()); - dateCreated = referenceDate; - positiveDaysToWorkingDays = generatePositiveDaysToWorkingDays(columnHeaders, referenceDate); - negativeDaysToWorkingDays = generateNegativeDaysToWorkingDays(columnHeaders, referenceDate); - } - - /** - * Initializes the DaysToWorkingDaysConverter for a list of {@link TimeIntervalColumnHeader}s and the current day. 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 - * @return an instance of the DaysToWorkingDaysConverter - * @throws InvalidArgumentException - * thrown if columnHeaders is null - */ - public static DaysToWorkingDaysConverter initialize(List columnHeaders) - throws InvalidArgumentException { - return initialize(columnHeaders, Instant.now()); - } - - /** - * Initializes the DaysToWorkingDaysConverter 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 - * @throws InvalidArgumentException - * thrown if columnHeaders or referenceDate is null - */ - public static DaysToWorkingDaysConverter initialize(List columnHeaders, - Instant referenceDate) throws InvalidArgumentException { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Initialize DaysToWorkingDaysConverter with columnHeaders: {}", - LoggerUtils.listToString(columnHeaders)); - } - if (columnHeaders == null) { - throw new InvalidArgumentException("TimeIntervalColumnHeaders can´t be used as NULL-Parameter"); - } - if (referenceDate == null) { - throw new InvalidArgumentException("ReferenceDate can´t be used as NULL-Parameter"); - } - int largesLowerLimit = getLargestLowerLimit(columnHeaders); - int smallestUpperLimit = getSmallestUpperLimit(columnHeaders); - if (instance == null - || !positiveDaysToWorkingDays.contains(largesLowerLimit) - || !negativeDaysToWorkingDays.contains(smallestUpperLimit) - || !dateCreated.truncatedTo(ChronoUnit.DAYS).equals(referenceDate.truncatedTo(ChronoUnit.DAYS))) { - - instance = new DaysToWorkingDaysConverter(columnHeaders, referenceDate); - LOGGER.debug("Create new converter for the values from {} until {} for the date: {}.", largesLowerLimit, - smallestUpperLimit, dateCreated); - } - return instance; - } - - /** - * Converts an integer, that represents the age in days, to the age in working days by using the table that was - * created by initialization. If the age in days is beyond the limits of the table, the integer will be returned - * unchanged. - * - * @param ageInDays - * represents the age in days - * @return the age in working days - */ - public int convertDaysToWorkingDays(int ageInDays) { - - int minDay = -(negativeDaysToWorkingDays.size() - 1); - int maxDay = positiveDaysToWorkingDays.size() - 1; - - if (ageInDays >= minDay && ageInDays <= 0) { - return negativeDaysToWorkingDays.get(-ageInDays); - } - if (ageInDays > 0 && ageInDays <= maxDay) { - return positiveDaysToWorkingDays.get(ageInDays); - } - - return ageInDays; - } - - /** - * Converts an integer, that represents the age in working days, to the age in days by using the table that was - * created by initialization. Because one age in working days could match to more than one age in days, the return - * value is a list of all days that match to the input parameter. If the age in working days is beyond the limits of - * the table, the integer will be returned unchanged. - * - * @param ageInWorkingDays - * represents the age in working days - * @return a list of age in days - */ - public ArrayList convertWorkingDaysToDays(int ageInWorkingDays) { - - ArrayList list = new ArrayList<>(); - - int minWorkingDay = negativeDaysToWorkingDays.get(negativeDaysToWorkingDays.size() - 1); - int maxWorkingDay = positiveDaysToWorkingDays.get(positiveDaysToWorkingDays.size() - 1); - - if (ageInWorkingDays >= minWorkingDay && ageInWorkingDays < 0) { - for (int ageInDays = 0; ageInDays < negativeDaysToWorkingDays.size(); ageInDays++) { - if (negativeDaysToWorkingDays.get(ageInDays) == ageInWorkingDays) { - list.add(-ageInDays); - } - } - return list; - } - if (ageInWorkingDays > 0 && ageInWorkingDays <= maxWorkingDay) { - for (int ageInDays = 0; ageInDays < positiveDaysToWorkingDays.size(); ageInDays++) { - if (positiveDaysToWorkingDays.get(ageInDays) == ageInWorkingDays) { - list.add(ageInDays); - } - } - return list; - } - - if (ageInWorkingDays == 0) { - list.add(0); - for (int ageInDays = 1; ageInDays < positiveDaysToWorkingDays.size(); ageInDays++) { - if (positiveDaysToWorkingDays.get(ageInDays) == ageInWorkingDays) { - list.add(ageInDays); - } - } - for (int ageInDays = 1; ageInDays < negativeDaysToWorkingDays.size(); ageInDays++) { - if (negativeDaysToWorkingDays.get(ageInDays) == ageInWorkingDays) { - list.add(-ageInDays); - } - } - return list; - } - - // If ageInWorkingDays is beyond the limits of the table, the value is returned unchanged. - list.add(ageInWorkingDays); - return list; - } - - public long convertWorkingDaysToDays(Instant startTime, long numberOfDays) { - int days = 0; - int workingDays = 0; - while (workingDays < numberOfDays) { - if (isWorkingDay(days, startTime)) { - workingDays++; - } - days++; - while (!isWorkingDay(days, startTime)) { - days++; - } - } - return days; - } - - private ArrayList generateNegativeDaysToWorkingDays( - List columnHeaders, Instant referenceDate) { - int minUpperLimit = getSmallestUpperLimit(columnHeaders); - ArrayList daysToWorkingDays = new ArrayList<>(); - daysToWorkingDays.add(0); - int day = -1; - int workingDay = 0; - while (workingDay > minUpperLimit) { - if (isWorkingDay(day, referenceDate)) { - workingDay--; - } - daysToWorkingDays.add(workingDay); - day--; - } - return daysToWorkingDays; - } - - private ArrayList generatePositiveDaysToWorkingDays( - List columnHeaders, Instant referenceDate) { - int maxLowerLimit = getLargestLowerLimit(columnHeaders); - ArrayList daysToWorkingDays = new ArrayList<>(); - daysToWorkingDays.add(0); - - int day = 1; - int workingDay = 0; - while (workingDay < maxLowerLimit) { - if (isWorkingDay(day, referenceDate)) { - workingDay++; - } - daysToWorkingDays.add(workingDay); - day++; - } - return daysToWorkingDays; - } - - private static int getSmallestUpperLimit(List columnHeaders) { - int smallestUpperLimit = 0; - for (TimeIntervalColumnHeader columnHeader : columnHeaders) { - if (columnHeader.getUpperAgeLimit() < smallestUpperLimit) { - smallestUpperLimit = columnHeader.getUpperAgeLimit(); - } - } - return smallestUpperLimit; - } - - private static int getLargestLowerLimit(List columnHeaders) { - int greatestLowerLimit = 0; - for (TimeIntervalColumnHeader columnHeader : columnHeaders) { - if (columnHeader.getUpperAgeLimit() > greatestLowerLimit) { - greatestLowerLimit = columnHeader.getLowerAgeLimit(); - } - } - return greatestLowerLimit; - } - - private boolean isWorkingDay(int day, Instant referenceDate) { - LocalDateTime dateTime = LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).plusDays(day); - if (dateTime.getDayOfWeek().equals(DayOfWeek.SATURDAY) - || dateTime.getDayOfWeek().equals(DayOfWeek.SUNDAY) - || isHoliday(dateTime.toLocalDate())) { - return false; - } - return true; - } - - private boolean isHoliday(LocalDate date) { - if (germanHolidaysEnabled) { - // Fix and movable holidays that are valid throughout Germany: New years day, Labour Day, Day of German - // Unity, Christmas, Good Friday, Easter Monday, Ascension Day, Whit Monday. - if (date.getDayOfMonth() == 1 && date.getMonthValue() == 1 - || date.getDayOfMonth() == 1 && date.getMonthValue() == 5 - || date.getDayOfMonth() == 3 && date.getMonthValue() == 10 - || date.getDayOfMonth() == 25 && date.getMonthValue() == 12 - || date.getDayOfMonth() == 26 && date.getMonthValue() == 12 - || easterSunday.minusDays(2).equals(date) - || easterSunday.plusDays(1).equals(date) - || easterSunday.plusDays(39).equals(date) - || easterSunday.plusDays(50).equals(date)) { - return true; - } - } - if (customHolidays != null) { - // Custom holidays that can be configured in the TaskanaEngineConfiguration - for (LocalDate customHoliday : customHolidays) { - if (date.equals(customHoliday)) { - return true; - } - } - } - return false; - } - - /** - * Computes the date of Easter Sunday for a given year. - * - * @param year - * for which the date of Easter Sunday should be calculated - * @return the date of Easter Sunday for the given year - */ - public LocalDate getEasterSunday(int year) { - // Formula to compute Easter Sunday by Gauss. - int a = year % 19; - int b = year % 4; - int c = year % 7; - int k = year / 100; - int p = (13 + 8 * k) / 25; - int q = k / 4; - int m = (15 - p + k - q) % 30; - int n = (4 + k - q) % 7; - int d = (19 * a + m) % 30; - - int e = (2 * b + 4 * c + 6 * d + n) % 7; - - if (d == 29 && e == 6) { - return LocalDate.of(year, 3, 15).plusDays(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, 22).plusDays(d + e); - } - - public static void setCustomHolidays(List holidays) { - customHolidays = holidays; - } - - public List getCustomHolidays() { - return customHolidays; - } - - public static void setGermanPublicHolidaysEnabled(boolean germanPublicHolidaysEnabled) { - germanHolidaysEnabled = germanPublicHolidaysEnabled; - } - - public boolean isGermanPublicHolidayEnabled() { - return germanHolidaysEnabled; - } - -} +package pro.taskana.impl; + +import java.time.DayOfWeek; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; +import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.impl.util.LoggerUtils; + +/** + * The DaysToWorkingDaysConverter 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 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. + */ +public final class DaysToWorkingDaysConverter { + + private static final Logger LOGGER = LoggerFactory.getLogger(TaskMonitorServiceImpl.class); + private static DaysToWorkingDaysConverter instance; + private static ArrayList positiveDaysToWorkingDays; + private static ArrayList negativeDaysToWorkingDays; + private static Instant dateCreated; + private static LocalDate easterSunday; + private static boolean germanHolidaysEnabled; + private static List customHolidays; + + private DaysToWorkingDaysConverter(List columnHeaders, + Instant referenceDate) { + easterSunday = getEasterSunday(LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).getYear()); + dateCreated = referenceDate; + positiveDaysToWorkingDays = generatePositiveDaysToWorkingDays(columnHeaders, referenceDate); + negativeDaysToWorkingDays = generateNegativeDaysToWorkingDays(columnHeaders, referenceDate); + } + + /** + * Initializes the DaysToWorkingDaysConverter for a list of {@link TimeIntervalColumnHeader}s and the current day. 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 + * @return an instance of the DaysToWorkingDaysConverter + * @throws InvalidArgumentException + * thrown if columnHeaders is null + */ + public static DaysToWorkingDaysConverter initialize(List columnHeaders) + throws InvalidArgumentException { + return initialize(columnHeaders, Instant.now()); + } + + /** + * Initializes the DaysToWorkingDaysConverter 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 + * @throws InvalidArgumentException + * thrown if columnHeaders or referenceDate is null + */ + public static DaysToWorkingDaysConverter initialize(List columnHeaders, + Instant referenceDate) throws InvalidArgumentException { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Initialize DaysToWorkingDaysConverter with columnHeaders: {}", + LoggerUtils.listToString(columnHeaders)); + } + if (columnHeaders == null) { + throw new InvalidArgumentException("TimeIntervalColumnHeaders can´t be used as NULL-Parameter"); + } + if (referenceDate == null) { + throw new InvalidArgumentException("ReferenceDate can´t be used as NULL-Parameter"); + } + int largesLowerLimit = getLargestLowerLimit(columnHeaders); + int smallestUpperLimit = getSmallestUpperLimit(columnHeaders); + if (instance == null + || !positiveDaysToWorkingDays.contains(largesLowerLimit) + || !negativeDaysToWorkingDays.contains(smallestUpperLimit) + || !dateCreated.truncatedTo(ChronoUnit.DAYS).equals(referenceDate.truncatedTo(ChronoUnit.DAYS))) { + + instance = new DaysToWorkingDaysConverter(columnHeaders, referenceDate); + LOGGER.debug("Create new converter for the values from {} until {} for the date: {}.", largesLowerLimit, + smallestUpperLimit, dateCreated); + } + return instance; + } + + /** + * Converts an integer, that represents the age in days, to the age in working days by using the table that was + * created by initialization. If the age in days is beyond the limits of the table, the integer will be returned + * unchanged. + * + * @param ageInDays + * represents the age in days + * @return the age in working days + */ + public int convertDaysToWorkingDays(int ageInDays) { + + int minDay = -(negativeDaysToWorkingDays.size() - 1); + int maxDay = positiveDaysToWorkingDays.size() - 1; + + if (ageInDays >= minDay && ageInDays <= 0) { + return negativeDaysToWorkingDays.get(-ageInDays); + } + if (ageInDays > 0 && ageInDays <= maxDay) { + return positiveDaysToWorkingDays.get(ageInDays); + } + + return ageInDays; + } + + /** + * Converts an integer, that represents the age in working days, to the age in days by using the table that was + * created by initialization. Because one age in working days could match to more than one age in days, the return + * value is a list of all days that match to the input parameter. If the age in working days is beyond the limits of + * the table, the integer will be returned unchanged. + * + * @param ageInWorkingDays + * represents the age in working days + * @return a list of age in days + */ + public ArrayList convertWorkingDaysToDays(int ageInWorkingDays) { + + ArrayList list = new ArrayList<>(); + + int minWorkingDay = negativeDaysToWorkingDays.get(negativeDaysToWorkingDays.size() - 1); + int maxWorkingDay = positiveDaysToWorkingDays.get(positiveDaysToWorkingDays.size() - 1); + + if (ageInWorkingDays >= minWorkingDay && ageInWorkingDays < 0) { + for (int ageInDays = 0; ageInDays < negativeDaysToWorkingDays.size(); ageInDays++) { + if (negativeDaysToWorkingDays.get(ageInDays) == ageInWorkingDays) { + list.add(-ageInDays); + } + } + return list; + } + if (ageInWorkingDays > 0 && ageInWorkingDays <= maxWorkingDay) { + for (int ageInDays = 0; ageInDays < positiveDaysToWorkingDays.size(); ageInDays++) { + if (positiveDaysToWorkingDays.get(ageInDays) == ageInWorkingDays) { + list.add(ageInDays); + } + } + return list; + } + + if (ageInWorkingDays == 0) { + list.add(0); + for (int ageInDays = 1; ageInDays < positiveDaysToWorkingDays.size(); ageInDays++) { + if (positiveDaysToWorkingDays.get(ageInDays) == ageInWorkingDays) { + list.add(ageInDays); + } + } + for (int ageInDays = 1; ageInDays < negativeDaysToWorkingDays.size(); ageInDays++) { + if (negativeDaysToWorkingDays.get(ageInDays) == ageInWorkingDays) { + list.add(-ageInDays); + } + } + return list; + } + + // If ageInWorkingDays is beyond the limits of the table, the value is returned unchanged. + list.add(ageInWorkingDays); + return list; + } + + public long convertWorkingDaysToDays(Instant startTime, long numberOfDays) { + int days = 0; + int workingDays = 0; + while (workingDays < numberOfDays) { + if (isWorkingDay(days, startTime)) { + workingDays++; + } + days++; + while (!isWorkingDay(days, startTime)) { + days++; + } + } + return days; + } + + private ArrayList generateNegativeDaysToWorkingDays( + List columnHeaders, Instant referenceDate) { + int minUpperLimit = getSmallestUpperLimit(columnHeaders); + ArrayList daysToWorkingDays = new ArrayList<>(); + daysToWorkingDays.add(0); + int day = -1; + int workingDay = 0; + while (workingDay > minUpperLimit) { + if (isWorkingDay(day, referenceDate)) { + workingDay--; + } + daysToWorkingDays.add(workingDay); + day--; + } + return daysToWorkingDays; + } + + private ArrayList generatePositiveDaysToWorkingDays( + List columnHeaders, Instant referenceDate) { + int maxLowerLimit = getLargestLowerLimit(columnHeaders); + ArrayList daysToWorkingDays = new ArrayList<>(); + daysToWorkingDays.add(0); + + int day = 1; + int workingDay = 0; + while (workingDay < maxLowerLimit) { + if (isWorkingDay(day, referenceDate)) { + workingDay++; + } + daysToWorkingDays.add(workingDay); + day++; + } + return daysToWorkingDays; + } + + private static int getSmallestUpperLimit(List columnHeaders) { + int smallestUpperLimit = 0; + for (TimeIntervalColumnHeader columnHeader : columnHeaders) { + if (columnHeader.getUpperAgeLimit() < smallestUpperLimit) { + smallestUpperLimit = columnHeader.getUpperAgeLimit(); + } + } + return smallestUpperLimit; + } + + private static int getLargestLowerLimit(List columnHeaders) { + int greatestLowerLimit = 0; + for (TimeIntervalColumnHeader columnHeader : columnHeaders) { + if (columnHeader.getUpperAgeLimit() > greatestLowerLimit) { + greatestLowerLimit = columnHeader.getLowerAgeLimit(); + } + } + return greatestLowerLimit; + } + + private boolean isWorkingDay(int day, Instant referenceDate) { + LocalDateTime dateTime = LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).plusDays(day); + if (dateTime.getDayOfWeek().equals(DayOfWeek.SATURDAY) + || dateTime.getDayOfWeek().equals(DayOfWeek.SUNDAY) + || isHoliday(dateTime.toLocalDate())) { + return false; + } + return true; + } + + private boolean isHoliday(LocalDate date) { + if (germanHolidaysEnabled) { + // Fix and movable holidays that are valid throughout Germany: New years day, Labour Day, Day of German + // Unity, Christmas, Good Friday, Easter Monday, Ascension Day, Whit Monday. + if (date.getDayOfMonth() == 1 && date.getMonthValue() == 1 + || date.getDayOfMonth() == 1 && date.getMonthValue() == 5 + || date.getDayOfMonth() == 3 && date.getMonthValue() == 10 + || date.getDayOfMonth() == 25 && date.getMonthValue() == 12 + || date.getDayOfMonth() == 26 && date.getMonthValue() == 12 + || easterSunday.minusDays(2).equals(date) + || easterSunday.plusDays(1).equals(date) + || easterSunday.plusDays(39).equals(date) + || easterSunday.plusDays(50).equals(date)) { + return true; + } + } + if (customHolidays != null) { + // Custom holidays that can be configured in the TaskanaEngineConfiguration + for (LocalDate customHoliday : customHolidays) { + if (date.equals(customHoliday)) { + return true; + } + } + } + return false; + } + + /** + * Computes the date of Easter Sunday for a given year. + * + * @param year + * for which the date of Easter Sunday should be calculated + * @return the date of Easter Sunday for the given year + */ + public LocalDate getEasterSunday(int year) { + // Formula to compute Easter Sunday by Gauss. + int a = year % 19; + int b = year % 4; + int c = year % 7; + int k = year / 100; + int p = (13 + 8 * k) / 25; + int q = k / 4; + int m = (15 - p + k - q) % 30; + int n = (4 + k - q) % 7; + int d = (19 * a + m) % 30; + + int e = (2 * b + 4 * c + 6 * d + n) % 7; + + if (d == 29 && e == 6) { + return LocalDate.of(year, 3, 15).plusDays(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, 22).plusDays(d + e); + } + + public static void setCustomHolidays(List holidays) { + customHolidays = holidays; + } + + public List getCustomHolidays() { + return customHolidays; + } + + public static void setGermanPublicHolidaysEnabled(boolean germanPublicHolidaysEnabled) { + germanHolidaysEnabled = germanPublicHolidaysEnabled; + } + + public boolean isGermanPublicHolidayEnabled() { + return germanHolidaysEnabled; + } + +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/SelectedItem.java b/lib/taskana-core/src/main/java/pro/taskana/impl/SelectedItem.java index 0fcd96ead..1d9aeb5e4 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/SelectedItem.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/SelectedItem.java @@ -1,52 +1,52 @@ -package pro.taskana.impl; - -/** - * An item that contains information of a selected item of a Report. It is used to get the task ids of the selected item - * of the Report. - */ -public class SelectedItem { - - private String key; - private String subKey; - private int upperAgeLimit; - private int lowerAgeLimit; - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public String getSubKey() { - return subKey; - } - - public void setSubKey(String subKey) { - this.subKey = subKey; - } - - public int getUpperAgeLimit() { - return upperAgeLimit; - } - - public void setUpperAgeLimit(int upperAgeLimit) { - this.upperAgeLimit = upperAgeLimit; - } - - public int getLowerAgeLimit() { - return lowerAgeLimit; - } - - public void setLowerAgeLimit(int lowerAgeLimit) { - this.lowerAgeLimit = lowerAgeLimit; - } - - @Override - public String toString() { - return "Key: " + this.key + ", SubKey: " + this.subKey + ", Limits: (" + this.lowerAgeLimit + "," - + this.getUpperAgeLimit() + ")"; - } - -} +package pro.taskana.impl; + +/** + * An item that contains information of a selected item of a Report. It is used to get the task ids of the selected item + * of the Report. + */ +public class SelectedItem { + + private String key; + private String subKey; + private int upperAgeLimit; + private int lowerAgeLimit; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getSubKey() { + return subKey; + } + + public void setSubKey(String subKey) { + this.subKey = subKey; + } + + public int getUpperAgeLimit() { + return upperAgeLimit; + } + + public void setUpperAgeLimit(int upperAgeLimit) { + this.upperAgeLimit = upperAgeLimit; + } + + public int getLowerAgeLimit() { + return lowerAgeLimit; + } + + public void setLowerAgeLimit(int lowerAgeLimit) { + this.lowerAgeLimit = lowerAgeLimit; + } + + @Override + public String toString() { + return "Key: " + this.key + ", SubKey: " + this.subKey + ", Limits: (" + this.lowerAgeLimit + "," + + this.getUpperAgeLimit() + ")"; + } + +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskMonitorServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskMonitorServiceImpl.java index a00681d89..d48241162 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskMonitorServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskMonitorServiceImpl.java @@ -1,439 +1,439 @@ -package pro.taskana.impl; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.CustomField; -import pro.taskana.TaskMonitorService; -import pro.taskana.TaskState; -import pro.taskana.TaskanaEngine; -import pro.taskana.TaskanaRole; -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.exceptions.NotAuthorizedException; -import pro.taskana.impl.report.impl.CategoryReport; -import pro.taskana.impl.report.impl.ClassificationReport; -import pro.taskana.impl.report.impl.CustomFieldValueReport; -import pro.taskana.impl.report.impl.DaysToWorkingDaysPreProcessor; -import pro.taskana.impl.report.impl.DetailedClassificationReport; -import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; -import pro.taskana.impl.report.impl.MonitorQueryItem; -import pro.taskana.impl.report.impl.TaskQueryItem; -import pro.taskana.impl.report.impl.TaskStatusReport; -import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; -import pro.taskana.impl.report.impl.WorkbasketLevelReport; -import pro.taskana.impl.util.LoggerUtils; -import pro.taskana.mappings.TaskMonitorMapper; - -/** - * This is the implementation of TaskMonitorService. - */ -public class TaskMonitorServiceImpl implements TaskMonitorService { - - private static final Logger LOGGER = LoggerFactory.getLogger(TaskMonitorServiceImpl.class); - private TaskanaEngineImpl taskanaEngineImpl; - private TaskMonitorMapper taskMonitorMapper; - - TaskMonitorServiceImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) { - super(); - this.taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; - this.taskMonitorMapper = taskMonitorMapper; - } - - @Override - public WorkbasketLevelReport getWorkbasketLevelReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues) - throws InvalidArgumentException, NotAuthorizedException { - return getWorkbasketLevelReport(workbasketIds, states, categories, domains, customField, customFieldValues, - Collections.emptyList(), false); - } - - @Override - public WorkbasketLevelReport getWorkbasketLevelReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues, - List columnHeaders) throws InvalidArgumentException, NotAuthorizedException { - return getWorkbasketLevelReport(workbasketIds, states, categories, domains, customField, customFieldValues, - columnHeaders, true); - } - - @Override - public WorkbasketLevelReport getWorkbasketLevelReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues, - List columnHeaders, boolean inWorkingDays) - throws InvalidArgumentException, NotAuthorizedException { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("entry to getWorkbasketLevelReport(workbasketIds = {}, states = {}, categories = {}, " - + "domains = {}, customField = {}, customFieldValues = {}, columnHeaders = {}, " - + "inWorkingDays = {})", LoggerUtils.listToString(workbasketIds), LoggerUtils.listToString(states), - LoggerUtils.listToString(categories), LoggerUtils.listToString(domains), customField, - LoggerUtils.listToString(customFieldValues), LoggerUtils.listToString(columnHeaders), - inWorkingDays); - } - taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); - try { - taskanaEngineImpl.openConnection(); - - configureDaysToWorkingDaysConverter(); - - WorkbasketLevelReport report = new WorkbasketLevelReport(columnHeaders); - List monitorQueryItems = taskMonitorMapper.getTaskCountOfWorkbaskets( - workbasketIds, states, categories, domains, customField, customFieldValues); - - report.addItems(monitorQueryItems, new DaysToWorkingDaysPreProcessor<>(columnHeaders, inWorkingDays)); - - return report; - - } finally { - taskanaEngineImpl.returnConnection(); - LOGGER.debug("exit from getWorkbasketLevelReport()."); - } - } - - @Override - public CategoryReport getCategoryReport(List workbasketIds, List states, List categories, - List domains, CustomField customField, List customFieldValues) - throws InvalidArgumentException, NotAuthorizedException { - return getCategoryReport(workbasketIds, states, categories, domains, customField, customFieldValues, - Collections.emptyList(), - false); - } - - @Override - public CategoryReport getCategoryReport(List workbasketIds, List states, List categories, - List domains, CustomField customField, List customFieldValues, - List columnHeaders) throws InvalidArgumentException, NotAuthorizedException { - return getCategoryReport(workbasketIds, states, categories, domains, customField, customFieldValues, - columnHeaders, true); - } - - @Override - public CategoryReport getCategoryReport(List workbasketIds, List states, List categories, - List domains, CustomField customField, List customFieldValues, - List columnHeaders, boolean inWorkingDays) - throws InvalidArgumentException, NotAuthorizedException { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("entry to getCategoryReport(workbasketIds = {}, states = {}, categories = {}, " - + "domains = {}, customField = {}, customFieldValues = {}, reportLineItemDefinitions = {}, " - + "inWorkingDays = {})", LoggerUtils.listToString(workbasketIds), LoggerUtils.listToString(states), - LoggerUtils.listToString(categories), LoggerUtils.listToString(domains), customField, - LoggerUtils.listToString(customFieldValues), LoggerUtils.listToString(columnHeaders), - inWorkingDays); - } - taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); - try { - taskanaEngineImpl.openConnection(); - - configureDaysToWorkingDaysConverter(); - - CategoryReport report = new CategoryReport(columnHeaders); - List monitorQueryItems = taskMonitorMapper.getTaskCountOfCategories( - workbasketIds, states, categories, domains, customField, customFieldValues); - - report.addItems(monitorQueryItems, new DaysToWorkingDaysPreProcessor<>(columnHeaders, inWorkingDays)); - - return report; - - } finally { - taskanaEngineImpl.returnConnection(); - LOGGER.debug("exit from getCategoryReport()."); - } - } - - @Override - public ClassificationReport getClassificationReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues) - throws InvalidArgumentException, NotAuthorizedException { - return getClassificationReport(workbasketIds, states, categories, domains, customField, customFieldValues, - Collections.emptyList(), false); - } - - @Override - public ClassificationReport getClassificationReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues, - List columnHeaders) throws InvalidArgumentException, NotAuthorizedException { - return getClassificationReport(workbasketIds, states, categories, domains, customField, customFieldValues, - columnHeaders, true); - } - - @Override - public ClassificationReport getClassificationReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues, - List columnHeaders, boolean inWorkingDays) - throws InvalidArgumentException, NotAuthorizedException { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("entry to getClassificationReport(workbasketIds = {}, states = {}, categories = {}, " - + "domains = {}, customField = {}, customFieldValues = {}, columnHeaders = {}, " - + "inWorkingDays = {})", LoggerUtils.listToString(workbasketIds), LoggerUtils.listToString(states), - LoggerUtils.listToString(categories), LoggerUtils.listToString(domains), customField, - LoggerUtils.listToString(customFieldValues), LoggerUtils.listToString(columnHeaders), - inWorkingDays); - } - taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); - try { - taskanaEngineImpl.openConnection(); - - configureDaysToWorkingDaysConverter(); - - ClassificationReport report = new ClassificationReport(columnHeaders); - List monitorQueryItems = taskMonitorMapper.getTaskCountOfClassifications( - workbasketIds, states, categories, domains, customField, customFieldValues); - - report.addItems(monitorQueryItems, new DaysToWorkingDaysPreProcessor<>(columnHeaders, inWorkingDays)); - - return report; - - } finally { - taskanaEngineImpl.returnConnection(); - LOGGER.debug("exit from getClassificationReport()."); - } - } - - @Override - public DetailedClassificationReport getDetailedClassificationReport(List workbasketIds, - List states, List categories, List domains, CustomField customField, - List customFieldValues) throws InvalidArgumentException, NotAuthorizedException { - return getDetailedClassificationReport(workbasketIds, states, categories, domains, customField, - customFieldValues, Collections.emptyList(), false); - } - - @Override - public DetailedClassificationReport getDetailedClassificationReport(List workbasketIds, - List states, List categories, List domains, CustomField customField, - List customFieldValues, List columnHeaders) - throws InvalidArgumentException, NotAuthorizedException { - return getDetailedClassificationReport(workbasketIds, states, categories, domains, customField, - customFieldValues, columnHeaders, true); - } - - @Override - public DetailedClassificationReport getDetailedClassificationReport(List workbasketIds, - List states, List categories, List domains, CustomField customField, - List customFieldValues, List columnHeaders, boolean inWorkingDays) - throws InvalidArgumentException, NotAuthorizedException { - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("entry to getDetailedClassificationReport(workbasketIds = {}, states = {}, " - + "categories = {}, domains = {}, customField = {}, customFieldValues = {}, " - + "columnHeaders = {}, inWorkingDays = {})", LoggerUtils.listToString(workbasketIds), - LoggerUtils.listToString(states), LoggerUtils.listToString(categories), - LoggerUtils.listToString(domains), customField, LoggerUtils.listToString(customFieldValues), - LoggerUtils.listToString(columnHeaders), inWorkingDays); - } - taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); - try { - taskanaEngineImpl.openConnection(); - - configureDaysToWorkingDaysConverter(); - - DetailedClassificationReport report = new DetailedClassificationReport(columnHeaders); - List detailedMonitorQueryItems = taskMonitorMapper - .getTaskCountOfDetailedClassifications(workbasketIds, states, categories, domains, customField, - customFieldValues); - - report.addItems(detailedMonitorQueryItems, - new DaysToWorkingDaysPreProcessor<>(columnHeaders, inWorkingDays)); - - return report; - - } finally { - taskanaEngineImpl.returnConnection(); - LOGGER.debug("exit from getDetailedClassificationReport()."); - } - } - - @Override - public CustomFieldValueReport getCustomFieldValueReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues) - throws InvalidArgumentException, NotAuthorizedException { - return getCustomFieldValueReport(workbasketIds, states, categories, domains, customField, customFieldValues, - Collections.emptyList(), false); - } - - @Override - public CustomFieldValueReport getCustomFieldValueReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues, - List columnHeaders) throws InvalidArgumentException, NotAuthorizedException { - return getCustomFieldValueReport(workbasketIds, states, categories, domains, customField, customFieldValues, - columnHeaders, true); - } - - @Override - public CustomFieldValueReport getCustomFieldValueReport(List workbasketIds, List states, - List categories, List domains, CustomField customField, List customFieldValues, - List columnHeaders, boolean inWorkingDays) - throws InvalidArgumentException, NotAuthorizedException { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("entry to getCustomFieldValueReport(workbasketIds = {}, states = {}, categories = {}, " - + "domains = {}, customField = {}, customFieldValues = {}, columnHeaders = {}, " - + "inWorkingDays = {})", LoggerUtils.listToString(workbasketIds), LoggerUtils.listToString(states), - LoggerUtils.listToString(categories), LoggerUtils.listToString(domains), customField, - LoggerUtils.listToString(customFieldValues), LoggerUtils.listToString(columnHeaders), - inWorkingDays); - } - taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); - try { - taskanaEngineImpl.openConnection(); - - if (customField == null) { - throw new InvalidArgumentException("CustomField can´t be used as NULL-Parameter"); - } - - configureDaysToWorkingDaysConverter(); - - CustomFieldValueReport report = new CustomFieldValueReport(columnHeaders); - List monitorQueryItems = taskMonitorMapper.getTaskCountOfCustomFieldValues( - workbasketIds, states, categories, domains, customField, customFieldValues); - - report.addItems(monitorQueryItems, new DaysToWorkingDaysPreProcessor<>(columnHeaders, inWorkingDays)); - - return report; - - } finally { - taskanaEngineImpl.returnConnection(); - LOGGER.debug("exit from getCustomFieldValueReport()."); - } - } - - @Override - public List getCustomAttributeValuesForReport(List workbasketIds, List states, - List categories, List domains, List classificationIds, - List excludedClassificationIds, Map customAttributeFilter, - String customAttributeName) throws InvalidArgumentException, NotAuthorizedException { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("entry to getCustomAttributeValuesForReport(workbasketIds = {}, states = {}, " - + "categories = {}, domains = {}, classificationIds = {}, excludedClassificationIds = {}, customAttributeName = {})", - LoggerUtils.listToString(workbasketIds), LoggerUtils.listToString(states), - LoggerUtils.listToString(categories), LoggerUtils.listToString(domains), - LoggerUtils.listToString(classificationIds), LoggerUtils.listToString(excludedClassificationIds), - customAttributeName); - } - taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); - try { - taskanaEngineImpl.openConnection(); - - if (customAttributeName == null || customAttributeName.isEmpty()) { - throw new InvalidArgumentException("customAttributeName must not be null."); - } - - List customAttributeValues = taskMonitorMapper.getCustomAttributeValuesForReport(workbasketIds, - states, - categories, domains, classificationIds, excludedClassificationIds, customAttributeFilter, - "CUSTOM_" + customAttributeName); - - return customAttributeValues; - - } finally { - taskanaEngineImpl.returnConnection(); - LOGGER.debug("exit from getCustomAttributeValuesForReport()."); - } - } - - @Override - public List getTaskIdsForSelectedItems(List workbasketIds, List states, - List categories, List domains, List classificationIds, - List excludedClassificationIds, CustomField customField, List customFieldValues, - List columnHeaders, boolean inWorkingDays, - List selectedItems, String dimension) throws InvalidArgumentException, NotAuthorizedException { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("entry to getTaskIdsForSelectedItems(workbasketIds = {}, states = {}, " - + "categories = {}, domains = {}, customField = {}, customFieldValues = {}, " - + "columnHeaders = {}, inWorkingDays = {}, selectedItems = {}, dimension = {})", - LoggerUtils.listToString(workbasketIds), LoggerUtils.listToString(states), - LoggerUtils.listToString(categories), LoggerUtils.listToString(domains), - LoggerUtils.listToString(classificationIds), LoggerUtils.listToString(excludedClassificationIds), - customField, - LoggerUtils.listToString(customFieldValues), LoggerUtils.listToString(columnHeaders), - inWorkingDays, LoggerUtils.listToString(selectedItems), dimension); - } - taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); - try { - taskanaEngineImpl.openConnection(); - if (columnHeaders == null) { - throw new InvalidArgumentException("ColumnHeader must not be null."); - } - if (selectedItems == null || selectedItems.size() == 0) { - throw new InvalidArgumentException( - "SelectedItems must not be null or empty."); - } - boolean joinWithAttachments = subKeyIsSet(selectedItems); - if (joinWithAttachments && !TaskMonitorService.DIMENSION_CLASSIFICATION_KEY.equals(dimension)) { - throw new InvalidArgumentException("SubKeys are supported for dimension CLASSIFICATION_KEY only."); - } - - configureDaysToWorkingDaysConverter(); - - if (inWorkingDays) { - selectedItems = convertWorkingDaysToDays(selectedItems, columnHeaders); - } - - List taskIds = taskMonitorMapper.getTaskIdsForSelectedItems(workbasketIds, states, - categories, domains, classificationIds, excludedClassificationIds, customField, customFieldValues, - dimension, selectedItems, joinWithAttachments); - - return taskIds; - - } finally { - taskanaEngineImpl.returnConnection(); - LOGGER.debug("exit from getTaskIdsForSelectedItems()."); - } - } - - @Override - public TaskStatusReport getTaskStatusReport() throws NotAuthorizedException { - return getTaskStatusReport(null, null); - } - - @Override - public TaskStatusReport getTaskStatusReport(List domains) throws NotAuthorizedException { - return getTaskStatusReport(domains, null); - } - - @Override - public TaskStatusReport getTaskStatusReport(List domains, List states) - throws NotAuthorizedException { - taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR, TaskanaRole.ADMIN); - try { - taskanaEngineImpl.openConnection(); - - List tasks = taskMonitorMapper.getTasksCountByState(domains, states); - TaskStatusReport report = new TaskStatusReport(states); - report.addItems(tasks); - return report; - - } finally { - taskanaEngineImpl.returnConnection(); - } - } - - private List convertWorkingDaysToDays(List selectedItems, - List columnHeaders) throws InvalidArgumentException { - - DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter.initialize(columnHeaders); - for (SelectedItem selectedItem : selectedItems) { - selectedItem - .setLowerAgeLimit(Collections.min(instance.convertWorkingDaysToDays(selectedItem.getLowerAgeLimit()))); - selectedItem - .setUpperAgeLimit(Collections.max(instance.convertWorkingDaysToDays(selectedItem.getUpperAgeLimit()))); - } - return selectedItems; - } - - private void configureDaysToWorkingDaysConverter() { - DaysToWorkingDaysConverter.setCustomHolidays(taskanaEngineImpl.getConfiguration().getCustomHolidays()); - DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled( - this.taskanaEngineImpl.getConfiguration().isGermanPublicHolidaysEnabled()); - } - - private boolean subKeyIsSet(List selectedItems) { - for (SelectedItem selectedItem : selectedItems) { - if (selectedItem.getSubKey() != null && !selectedItem.getSubKey().isEmpty()) { - return true; - } - } - return false; - } - -} +package pro.taskana.impl; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.CustomField; +import pro.taskana.TaskMonitorService; +import pro.taskana.TaskState; +import pro.taskana.TaskanaEngine; +import pro.taskana.TaskanaRole; +import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.impl.report.impl.CategoryReport; +import pro.taskana.impl.report.impl.ClassificationReport; +import pro.taskana.impl.report.impl.CustomFieldValueReport; +import pro.taskana.impl.report.impl.DaysToWorkingDaysPreProcessor; +import pro.taskana.impl.report.impl.DetailedClassificationReport; +import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; +import pro.taskana.impl.report.impl.MonitorQueryItem; +import pro.taskana.impl.report.impl.TaskQueryItem; +import pro.taskana.impl.report.impl.TaskStatusReport; +import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; +import pro.taskana.impl.report.impl.WorkbasketLevelReport; +import pro.taskana.impl.util.LoggerUtils; +import pro.taskana.mappings.TaskMonitorMapper; + +/** + * This is the implementation of TaskMonitorService. + */ +public class TaskMonitorServiceImpl implements TaskMonitorService { + + private static final Logger LOGGER = LoggerFactory.getLogger(TaskMonitorServiceImpl.class); + private TaskanaEngineImpl taskanaEngineImpl; + private TaskMonitorMapper taskMonitorMapper; + + TaskMonitorServiceImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) { + super(); + this.taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; + this.taskMonitorMapper = taskMonitorMapper; + } + + @Override + public WorkbasketLevelReport getWorkbasketLevelReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues) + throws InvalidArgumentException, NotAuthorizedException { + return getWorkbasketLevelReport(workbasketIds, states, categories, domains, customField, customFieldValues, + Collections.emptyList(), false); + } + + @Override + public WorkbasketLevelReport getWorkbasketLevelReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues, + List columnHeaders) throws InvalidArgumentException, NotAuthorizedException { + return getWorkbasketLevelReport(workbasketIds, states, categories, domains, customField, customFieldValues, + columnHeaders, true); + } + + @Override + public WorkbasketLevelReport getWorkbasketLevelReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues, + List columnHeaders, boolean inWorkingDays) + throws InvalidArgumentException, NotAuthorizedException { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("entry to getWorkbasketLevelReport(workbasketIds = {}, states = {}, categories = {}, " + + "domains = {}, customField = {}, customFieldValues = {}, columnHeaders = {}, " + + "inWorkingDays = {})", LoggerUtils.listToString(workbasketIds), LoggerUtils.listToString(states), + LoggerUtils.listToString(categories), LoggerUtils.listToString(domains), customField, + LoggerUtils.listToString(customFieldValues), LoggerUtils.listToString(columnHeaders), + inWorkingDays); + } + taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); + try { + taskanaEngineImpl.openConnection(); + + configureDaysToWorkingDaysConverter(); + + WorkbasketLevelReport report = new WorkbasketLevelReport(columnHeaders); + List monitorQueryItems = taskMonitorMapper.getTaskCountOfWorkbaskets( + workbasketIds, states, categories, domains, customField, customFieldValues); + + report.addItems(monitorQueryItems, new DaysToWorkingDaysPreProcessor<>(columnHeaders, inWorkingDays)); + + return report; + + } finally { + taskanaEngineImpl.returnConnection(); + LOGGER.debug("exit from getWorkbasketLevelReport()."); + } + } + + @Override + public CategoryReport getCategoryReport(List workbasketIds, List states, List categories, + List domains, CustomField customField, List customFieldValues) + throws InvalidArgumentException, NotAuthorizedException { + return getCategoryReport(workbasketIds, states, categories, domains, customField, customFieldValues, + Collections.emptyList(), + false); + } + + @Override + public CategoryReport getCategoryReport(List workbasketIds, List states, List categories, + List domains, CustomField customField, List customFieldValues, + List columnHeaders) throws InvalidArgumentException, NotAuthorizedException { + return getCategoryReport(workbasketIds, states, categories, domains, customField, customFieldValues, + columnHeaders, true); + } + + @Override + public CategoryReport getCategoryReport(List workbasketIds, List states, List categories, + List domains, CustomField customField, List customFieldValues, + List columnHeaders, boolean inWorkingDays) + throws InvalidArgumentException, NotAuthorizedException { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("entry to getCategoryReport(workbasketIds = {}, states = {}, categories = {}, " + + "domains = {}, customField = {}, customFieldValues = {}, reportLineItemDefinitions = {}, " + + "inWorkingDays = {})", LoggerUtils.listToString(workbasketIds), LoggerUtils.listToString(states), + LoggerUtils.listToString(categories), LoggerUtils.listToString(domains), customField, + LoggerUtils.listToString(customFieldValues), LoggerUtils.listToString(columnHeaders), + inWorkingDays); + } + taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); + try { + taskanaEngineImpl.openConnection(); + + configureDaysToWorkingDaysConverter(); + + CategoryReport report = new CategoryReport(columnHeaders); + List monitorQueryItems = taskMonitorMapper.getTaskCountOfCategories( + workbasketIds, states, categories, domains, customField, customFieldValues); + + report.addItems(monitorQueryItems, new DaysToWorkingDaysPreProcessor<>(columnHeaders, inWorkingDays)); + + return report; + + } finally { + taskanaEngineImpl.returnConnection(); + LOGGER.debug("exit from getCategoryReport()."); + } + } + + @Override + public ClassificationReport getClassificationReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues) + throws InvalidArgumentException, NotAuthorizedException { + return getClassificationReport(workbasketIds, states, categories, domains, customField, customFieldValues, + Collections.emptyList(), false); + } + + @Override + public ClassificationReport getClassificationReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues, + List columnHeaders) throws InvalidArgumentException, NotAuthorizedException { + return getClassificationReport(workbasketIds, states, categories, domains, customField, customFieldValues, + columnHeaders, true); + } + + @Override + public ClassificationReport getClassificationReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues, + List columnHeaders, boolean inWorkingDays) + throws InvalidArgumentException, NotAuthorizedException { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("entry to getClassificationReport(workbasketIds = {}, states = {}, categories = {}, " + + "domains = {}, customField = {}, customFieldValues = {}, columnHeaders = {}, " + + "inWorkingDays = {})", LoggerUtils.listToString(workbasketIds), LoggerUtils.listToString(states), + LoggerUtils.listToString(categories), LoggerUtils.listToString(domains), customField, + LoggerUtils.listToString(customFieldValues), LoggerUtils.listToString(columnHeaders), + inWorkingDays); + } + taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); + try { + taskanaEngineImpl.openConnection(); + + configureDaysToWorkingDaysConverter(); + + ClassificationReport report = new ClassificationReport(columnHeaders); + List monitorQueryItems = taskMonitorMapper.getTaskCountOfClassifications( + workbasketIds, states, categories, domains, customField, customFieldValues); + + report.addItems(monitorQueryItems, new DaysToWorkingDaysPreProcessor<>(columnHeaders, inWorkingDays)); + + return report; + + } finally { + taskanaEngineImpl.returnConnection(); + LOGGER.debug("exit from getClassificationReport()."); + } + } + + @Override + public DetailedClassificationReport getDetailedClassificationReport(List workbasketIds, + List states, List categories, List domains, CustomField customField, + List customFieldValues) throws InvalidArgumentException, NotAuthorizedException { + return getDetailedClassificationReport(workbasketIds, states, categories, domains, customField, + customFieldValues, Collections.emptyList(), false); + } + + @Override + public DetailedClassificationReport getDetailedClassificationReport(List workbasketIds, + List states, List categories, List domains, CustomField customField, + List customFieldValues, List columnHeaders) + throws InvalidArgumentException, NotAuthorizedException { + return getDetailedClassificationReport(workbasketIds, states, categories, domains, customField, + customFieldValues, columnHeaders, true); + } + + @Override + public DetailedClassificationReport getDetailedClassificationReport(List workbasketIds, + List states, List categories, List domains, CustomField customField, + List customFieldValues, List columnHeaders, boolean inWorkingDays) + throws InvalidArgumentException, NotAuthorizedException { + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("entry to getDetailedClassificationReport(workbasketIds = {}, states = {}, " + + "categories = {}, domains = {}, customField = {}, customFieldValues = {}, " + + "columnHeaders = {}, inWorkingDays = {})", LoggerUtils.listToString(workbasketIds), + LoggerUtils.listToString(states), LoggerUtils.listToString(categories), + LoggerUtils.listToString(domains), customField, LoggerUtils.listToString(customFieldValues), + LoggerUtils.listToString(columnHeaders), inWorkingDays); + } + taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); + try { + taskanaEngineImpl.openConnection(); + + configureDaysToWorkingDaysConverter(); + + DetailedClassificationReport report = new DetailedClassificationReport(columnHeaders); + List detailedMonitorQueryItems = taskMonitorMapper + .getTaskCountOfDetailedClassifications(workbasketIds, states, categories, domains, customField, + customFieldValues); + + report.addItems(detailedMonitorQueryItems, + new DaysToWorkingDaysPreProcessor<>(columnHeaders, inWorkingDays)); + + return report; + + } finally { + taskanaEngineImpl.returnConnection(); + LOGGER.debug("exit from getDetailedClassificationReport()."); + } + } + + @Override + public CustomFieldValueReport getCustomFieldValueReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues) + throws InvalidArgumentException, NotAuthorizedException { + return getCustomFieldValueReport(workbasketIds, states, categories, domains, customField, customFieldValues, + Collections.emptyList(), false); + } + + @Override + public CustomFieldValueReport getCustomFieldValueReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues, + List columnHeaders) throws InvalidArgumentException, NotAuthorizedException { + return getCustomFieldValueReport(workbasketIds, states, categories, domains, customField, customFieldValues, + columnHeaders, true); + } + + @Override + public CustomFieldValueReport getCustomFieldValueReport(List workbasketIds, List states, + List categories, List domains, CustomField customField, List customFieldValues, + List columnHeaders, boolean inWorkingDays) + throws InvalidArgumentException, NotAuthorizedException { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("entry to getCustomFieldValueReport(workbasketIds = {}, states = {}, categories = {}, " + + "domains = {}, customField = {}, customFieldValues = {}, columnHeaders = {}, " + + "inWorkingDays = {})", LoggerUtils.listToString(workbasketIds), LoggerUtils.listToString(states), + LoggerUtils.listToString(categories), LoggerUtils.listToString(domains), customField, + LoggerUtils.listToString(customFieldValues), LoggerUtils.listToString(columnHeaders), + inWorkingDays); + } + taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); + try { + taskanaEngineImpl.openConnection(); + + if (customField == null) { + throw new InvalidArgumentException("CustomField can´t be used as NULL-Parameter"); + } + + configureDaysToWorkingDaysConverter(); + + CustomFieldValueReport report = new CustomFieldValueReport(columnHeaders); + List monitorQueryItems = taskMonitorMapper.getTaskCountOfCustomFieldValues( + workbasketIds, states, categories, domains, customField, customFieldValues); + + report.addItems(monitorQueryItems, new DaysToWorkingDaysPreProcessor<>(columnHeaders, inWorkingDays)); + + return report; + + } finally { + taskanaEngineImpl.returnConnection(); + LOGGER.debug("exit from getCustomFieldValueReport()."); + } + } + + @Override + public List getCustomAttributeValuesForReport(List workbasketIds, List states, + List categories, List domains, List classificationIds, + List excludedClassificationIds, Map customAttributeFilter, + String customAttributeName) throws InvalidArgumentException, NotAuthorizedException { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("entry to getCustomAttributeValuesForReport(workbasketIds = {}, states = {}, " + + "categories = {}, domains = {}, classificationIds = {}, excludedClassificationIds = {}, customAttributeName = {})", + LoggerUtils.listToString(workbasketIds), LoggerUtils.listToString(states), + LoggerUtils.listToString(categories), LoggerUtils.listToString(domains), + LoggerUtils.listToString(classificationIds), LoggerUtils.listToString(excludedClassificationIds), + customAttributeName); + } + taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); + try { + taskanaEngineImpl.openConnection(); + + if (customAttributeName == null || customAttributeName.isEmpty()) { + throw new InvalidArgumentException("customAttributeName must not be null."); + } + + List customAttributeValues = taskMonitorMapper.getCustomAttributeValuesForReport(workbasketIds, + states, + categories, domains, classificationIds, excludedClassificationIds, customAttributeFilter, + "CUSTOM_" + customAttributeName); + + return customAttributeValues; + + } finally { + taskanaEngineImpl.returnConnection(); + LOGGER.debug("exit from getCustomAttributeValuesForReport()."); + } + } + + @Override + public List getTaskIdsForSelectedItems(List workbasketIds, List states, + List categories, List domains, List classificationIds, + List excludedClassificationIds, CustomField customField, List customFieldValues, + List columnHeaders, boolean inWorkingDays, + List selectedItems, String dimension) throws InvalidArgumentException, NotAuthorizedException { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("entry to getTaskIdsForSelectedItems(workbasketIds = {}, states = {}, " + + "categories = {}, domains = {}, customField = {}, customFieldValues = {}, " + + "columnHeaders = {}, inWorkingDays = {}, selectedItems = {}, dimension = {})", + LoggerUtils.listToString(workbasketIds), LoggerUtils.listToString(states), + LoggerUtils.listToString(categories), LoggerUtils.listToString(domains), + LoggerUtils.listToString(classificationIds), LoggerUtils.listToString(excludedClassificationIds), + customField, + LoggerUtils.listToString(customFieldValues), LoggerUtils.listToString(columnHeaders), + inWorkingDays, LoggerUtils.listToString(selectedItems), dimension); + } + taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); + try { + taskanaEngineImpl.openConnection(); + if (columnHeaders == null) { + throw new InvalidArgumentException("ColumnHeader must not be null."); + } + if (selectedItems == null || selectedItems.size() == 0) { + throw new InvalidArgumentException( + "SelectedItems must not be null or empty."); + } + boolean joinWithAttachments = subKeyIsSet(selectedItems); + if (joinWithAttachments && !TaskMonitorService.DIMENSION_CLASSIFICATION_KEY.equals(dimension)) { + throw new InvalidArgumentException("SubKeys are supported for dimension CLASSIFICATION_KEY only."); + } + + configureDaysToWorkingDaysConverter(); + + if (inWorkingDays) { + selectedItems = convertWorkingDaysToDays(selectedItems, columnHeaders); + } + + List taskIds = taskMonitorMapper.getTaskIdsForSelectedItems(workbasketIds, states, + categories, domains, classificationIds, excludedClassificationIds, customField, customFieldValues, + dimension, selectedItems, joinWithAttachments); + + return taskIds; + + } finally { + taskanaEngineImpl.returnConnection(); + LOGGER.debug("exit from getTaskIdsForSelectedItems()."); + } + } + + @Override + public TaskStatusReport getTaskStatusReport() throws NotAuthorizedException { + return getTaskStatusReport(null, null); + } + + @Override + public TaskStatusReport getTaskStatusReport(List domains) throws NotAuthorizedException { + return getTaskStatusReport(domains, null); + } + + @Override + public TaskStatusReport getTaskStatusReport(List domains, List states) + throws NotAuthorizedException { + taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR, TaskanaRole.ADMIN); + try { + taskanaEngineImpl.openConnection(); + + List tasks = taskMonitorMapper.getTasksCountByState(domains, states); + TaskStatusReport report = new TaskStatusReport(states); + report.addItems(tasks); + return report; + + } finally { + taskanaEngineImpl.returnConnection(); + } + } + + private List convertWorkingDaysToDays(List selectedItems, + List columnHeaders) throws InvalidArgumentException { + + DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter.initialize(columnHeaders); + for (SelectedItem selectedItem : selectedItems) { + selectedItem + .setLowerAgeLimit(Collections.min(instance.convertWorkingDaysToDays(selectedItem.getLowerAgeLimit()))); + selectedItem + .setUpperAgeLimit(Collections.max(instance.convertWorkingDaysToDays(selectedItem.getUpperAgeLimit()))); + } + return selectedItems; + } + + private void configureDaysToWorkingDaysConverter() { + DaysToWorkingDaysConverter.setCustomHolidays(taskanaEngineImpl.getConfiguration().getCustomHolidays()); + DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled( + this.taskanaEngineImpl.getConfiguration().isGermanPublicHolidaysEnabled()); + } + + private boolean subKeyIsSet(List selectedItems) { + for (SelectedItem selectedItem : selectedItems) { + if (selectedItem.getSubKey() != null && !selectedItem.getSubKey().isEmpty()) { + return true; + } + } + return false; + } + +} 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 f82f45561..81cc5bd34 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 @@ -1,1501 +1,1501 @@ -package pro.taskana.impl; - -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import org.apache.ibatis.exceptions.PersistenceException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.Attachment; -import pro.taskana.BulkOperationResults; -import pro.taskana.Classification; -import pro.taskana.ClassificationSummary; -import pro.taskana.ObjectReference; -import pro.taskana.Task; -import pro.taskana.TaskQuery; -import pro.taskana.TaskService; -import pro.taskana.TaskState; -import pro.taskana.TaskSummary; -import pro.taskana.TaskanaEngine; -import pro.taskana.TaskanaRole; -import pro.taskana.Workbasket; -import pro.taskana.WorkbasketPermission; -import pro.taskana.WorkbasketService; -import pro.taskana.WorkbasketSummary; -import pro.taskana.exceptions.AttachmentPersistenceException; -import pro.taskana.exceptions.ClassificationNotFoundException; -import pro.taskana.exceptions.ConcurrencyException; -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.exceptions.InvalidOwnerException; -import pro.taskana.exceptions.InvalidStateException; -import pro.taskana.exceptions.NotAuthorizedException; -import pro.taskana.exceptions.SystemException; -import pro.taskana.exceptions.TaskAlreadyExistException; -import pro.taskana.exceptions.TaskNotFoundException; -import pro.taskana.exceptions.TaskanaException; -import pro.taskana.exceptions.WorkbasketNotFoundException; -import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; -import pro.taskana.impl.util.IdGenerator; -import pro.taskana.impl.util.LoggerUtils; -import pro.taskana.mappings.AttachmentMapper; -import pro.taskana.mappings.CustomPropertySelector; -import pro.taskana.mappings.TaskMapper; -import pro.taskana.security.CurrentUserContext; - -/** - * This is the implementation of TaskService. - */ -public class TaskServiceImpl implements TaskService { - - private static final Logger LOGGER = LoggerFactory.getLogger(TaskServiceImpl.class); - private static final String ID_PREFIX_ATTACHMENT = "TAI"; - 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 DaysToWorkingDaysConverter converter; - private TaskanaEngineImpl taskanaEngine; - private WorkbasketService workbasketService; - private ClassificationServiceImpl classificationService; - private TaskMapper taskMapper; - private AttachmentMapper attachmentMapper; - - TaskServiceImpl(TaskanaEngine taskanaEngine, TaskMapper taskMapper, - AttachmentMapper attachmentMapper) { - super(); - try { - this.converter = DaysToWorkingDaysConverter - .initialize(Collections.singletonList(new TimeIntervalColumnHeader(0)), Instant.now()); - } catch (InvalidArgumentException e) { - throw new SystemException("Internal error. Cannot initialize DaysToWorkingDaysConverter", e.getCause()); - } - this.taskanaEngine = (TaskanaEngineImpl) taskanaEngine; - this.taskMapper = taskMapper; - this.workbasketService = taskanaEngine.getWorkbasketService(); - this.attachmentMapper = attachmentMapper; - this.classificationService = (ClassificationServiceImpl) taskanaEngine.getClassificationService(); - } - - @Override - public Task claim(String taskId) - throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException { - return claim(taskId, false); - } - - @Override - public Task forceClaim(String taskId) - throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException { - return claim(taskId, true); - } - - private Task claim(String taskId, boolean forceClaim) - throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException { - String userId = CurrentUserContext.getUserid(); - LOGGER.debug("entry to claim(id = {}, userId = {}, forceClaim = {})", taskId, userId, forceClaim); - TaskImpl task = null; - try { - 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 == TaskState.CLAIMED && !forceClaim && !task.getOwner().equals(userId)) { - throw new InvalidOwnerException( - "Task with id " + taskId + " is already claimed by " + task.getOwner() + "."); - } - Instant now = Instant.now(); - task.setOwner(userId); - task.setModified(now); - task.setClaimed(now); - task.setRead(true); - task.setState(TaskState.CLAIMED); - taskMapper.update(task); - LOGGER.debug("Task '{}' claimed by user '{}'.", taskId, userId); - } finally { - taskanaEngine.returnConnection(); - LOGGER.debug("exit from claim()"); - } - return task; - } - - @Override - public Task cancelClaim(String taskId) - throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException { - return this.cancelClaim(taskId, false); - } - - @Override - public Task forceCancelClaim(String taskId) - throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException { - return this.cancelClaim(taskId, true); - } - - private Task cancelClaim(String taskId, boolean forceUnclaim) - throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException { - String userId = CurrentUserContext.getUserid(); - LOGGER.debug("entry to cancelClaim(taskId = {}), userId = {}, forceUnclaim = {}", taskId, userId, - forceUnclaim); - TaskImpl task = null; - try { - 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 == TaskState.CLAIMED && !forceUnclaim && !userId.equals(task.getOwner())) { - throw new InvalidOwnerException( - "Task with id " + taskId + " is already claimed by " + task.getOwner() + "."); - } - Instant now = Instant.now(); - task.setOwner(null); - task.setModified(now); - task.setClaimed(null); - task.setRead(true); - task.setState(TaskState.READY); - taskMapper.update(task); - LOGGER.debug("Task '{}' unclaimed by user '{}'.", taskId, userId); - } finally { - taskanaEngine.returnConnection(); - LOGGER.debug("exit from cancelClaim()"); - } - return task; - } - - @Override - public Task completeTask(String taskId) - throws TaskNotFoundException, InvalidOwnerException, InvalidStateException, NotAuthorizedException { - return completeTask(taskId, false); - } - - @Override - public Task forceCompleteTask(String taskId) - throws TaskNotFoundException, InvalidOwnerException, InvalidStateException, NotAuthorizedException { - return completeTask(taskId, true); - } - - private Task completeTask(String taskId, boolean isForced) - throws TaskNotFoundException, InvalidOwnerException, InvalidStateException, NotAuthorizedException { - String userId = CurrentUserContext.getUserid(); - LOGGER.debug("entry to completeTask(id = {}, userId = {}, isForced = {})", taskId, userId, isForced); - TaskImpl task = null; - try { - taskanaEngine.openConnection(); - task = (TaskImpl) this.getTask(taskId); - - if (task.getState() == TaskState.COMPLETED) { - return task; - } - - // 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."); - } else if (!CurrentUserContext.getAccessIds().contains(task.getOwner())) { - throw new InvalidOwnerException( - "Owner of task " + taskId + " is " + task.getOwner() + ", but current User is " + userId); - } - } else { - // CLAIM-forced, if task was not already claimed before. - if (task.getClaimed() == null || task.getState() != TaskState.CLAIMED) { - task = (TaskImpl) this.forceClaim(taskId); - } - } - Instant now = Instant.now(); - task.setCompleted(now); - task.setModified(now); - task.setState(TaskState.COMPLETED); - task.setOwner(userId); - taskMapper.update(task); - LOGGER.debug("Task '{}' completed by user '{}'.", taskId, userId); - } finally { - taskanaEngine.returnConnection(); - LOGGER.debug("exit from completeTask()"); - } - return task; - } - - @Override - public BulkOperationResults completeTasks(List taskIds) - throws InvalidArgumentException { - try { - LOGGER.debug("entry to completeTasks(taskIds = {})", taskIds); - taskanaEngine.openConnection(); - - // Check pre-conditions with throwing Exceptions - if (taskIds == null) { - throw new InvalidArgumentException( - "TaskIds can´t be used as NULL-Parameter."); - } - - // process bulk-complete - BulkOperationResults bulkLog = new BulkOperationResults<>(); - if (!taskIds.isEmpty()) { - // remove null/empty taskIds with message - Iterator taskIdIterator = taskIds.iterator(); - while (taskIdIterator.hasNext()) { - String currentTaskId = taskIdIterator.next(); - if (currentTaskId == null || currentTaskId.isEmpty()) { - bulkLog.addError("", - new InvalidArgumentException("IDs with EMPTY or NULL value are not allowed and invalid.")); - taskIdIterator.remove(); - } - } - - // query for existing tasks, modify values and LOG missing ones. - List taskSummaries = this.createTaskQuery().idIn(taskIds.toArray(new String[0])).list(); - Instant now = Instant.now(); - taskIdIterator = taskIds.iterator(); - while (taskIdIterator.hasNext()) { - String currentTaskId = taskIdIterator.next(); - TaskSummaryImpl taskSummary = (TaskSummaryImpl) taskSummaries.stream() - .filter(ts -> currentTaskId.equals(ts.getTaskId())) - .findFirst() - .orElse(null); - if (taskSummary == null) { - bulkLog.addError(currentTaskId, new TaskNotFoundException(currentTaskId, "task with id " - + currentTaskId + " was not found.")); - taskIdIterator.remove(); - } else if (taskSummary.getClaimed() == null || taskSummary.getState() != TaskState.CLAIMED) { - bulkLog.addError(currentTaskId, new InvalidStateException(currentTaskId)); - taskIdIterator.remove(); - } else if (!CurrentUserContext.getAccessIds().contains(taskSummary.getOwner())) { - bulkLog.addError(currentTaskId, new InvalidOwnerException( - "TaskOwner is" + taskSummary.getOwner() + ", but current User is " - + CurrentUserContext.getUserid())); - taskIdIterator.remove(); - } else { - taskSummary.setCompleted(now); - taskSummary.setModified(now); - taskSummary.setState(TaskState.COMPLETED); - } - } - - if (!taskIds.isEmpty() && !taskSummaries.isEmpty()) { - taskMapper.updateCompleted(taskIds, (TaskSummaryImpl) taskSummaries.get(0)); - } - } - return bulkLog; - } finally { - taskanaEngine.returnConnection(); - LOGGER.debug("exit from to completeTasks(taskIds = {})", taskIds); - } - } - - @Override - public Task createTask(Task taskToCreate) - throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, - TaskAlreadyExistException, InvalidArgumentException { - LOGGER.debug("entry to createTask(task = {})", taskToCreate); - TaskImpl task = (TaskImpl) taskToCreate; - try { - taskanaEngine.openConnection(); - if (task.getId() != null && !task.getId().equals("")) { - throw new TaskAlreadyExistException(task.getId()); - } else { - LOGGER.debug("Task {} cannot be be found, so it can be created.", task.getId()); - Workbasket workbasket; - - if (task.getWorkbasketSummary().getId() != null) { - workbasket = workbasketService.getWorkbasket(task.getWorkbasketSummary().getId()); - } else if (task.getWorkbasketKey() != null) { - workbasket = workbasketService.getWorkbasket(task.getWorkbasketKey(), task.getDomain()); - } else { - throw new InvalidArgumentException("Cannot create a task outside a workbasket"); - } - - task.setWorkbasketSummary(workbasket.asSummary()); - task.setDomain(workbasket.getDomain()); - - workbasketService.checkAuthorization(task.getWorkbasketSummary().getId(), - WorkbasketPermission.APPEND); - - // we do use the key and not the ID to make sure that we use the classification from the right domain. - // otherwise we would have to check the classification and its domain for validity. - String classificationKey = task.getClassificationKey(); - if (classificationKey == null || classificationKey.length() == 0) { - throw new InvalidArgumentException("classificationKey of task must not be empty"); - } - - Classification classification = this.classificationService.getClassification(classificationKey, - workbasket.getDomain()); - task.setClassificationSummary(classification.asSummary()); - validateObjectReference(task.getPrimaryObjRef(), "primary ObjectReference", "Task"); - PrioDurationHolder prioDurationFromAttachments = handleAttachments(task); - standardSettings(task, classification, prioDurationFromAttachments); - this.taskMapper.insert(task); - LOGGER.debug("Method createTask() created Task '{}'.", task.getId()); - } - return task; - } finally { - taskanaEngine.returnConnection(); - LOGGER.debug("exit from createTask(task = {})", task); - } - } - - @Override - public Task getTask(String id) throws TaskNotFoundException, NotAuthorizedException { - LOGGER.debug("entry to getTaskById(id = {})", id); - TaskImpl resultTask = null; - try { - taskanaEngine.openConnection(); - - resultTask = taskMapper.findById(id); - if (resultTask != null) { - WorkbasketQueryImpl query = (WorkbasketQueryImpl) workbasketService.createWorkbasketQuery(); - query.setUsedToAugmentTasks(true); - String workbasketId = resultTask.getWorkbasketSummary().getId(); - List workbaskets = query - .idIn(workbasketId) - .list(); - if (workbaskets.isEmpty()) { - String currentUser = CurrentUserContext.getUserid(); - throw new NotAuthorizedException( - "The current user " + currentUser + " has no read permission for workbasket " + workbasketId); - } else { - resultTask.setWorkbasketSummary(workbaskets.get(0)); - } - - List attachmentImpls = attachmentMapper.findAttachmentsByTaskId(resultTask.getId()); - if (attachmentImpls == null) { - attachmentImpls = new ArrayList<>(); - } - - List classifications; - classifications = findClassificationForTaskImplAndAttachments(resultTask, attachmentImpls); - List attachments = addClassificationSummariesToAttachments(resultTask, attachmentImpls, - classifications); - resultTask.setAttachments(attachments); - - String classificationId = resultTask.getClassificationSummary().getId(); - ClassificationSummary classification = classifications.stream() - .filter(c -> c.getId().equals(classificationId)) - .findFirst() - .orElse(null); - if (classification == null) { - throw new SystemException( - "Could not find a Classification for task " + resultTask.getId()); - } - - resultTask.setClassificationSummary(classification); - return resultTask; - } else { - throw new TaskNotFoundException(id, "Task with id " + id + " was not found"); - } - } finally { - taskanaEngine.returnConnection(); - LOGGER.debug("exit from getTaskById(). Returning result {} ", resultTask); - } - } - - @Override - public Task transfer(String taskId, String destinationWorkbasketId) - throws TaskNotFoundException, WorkbasketNotFoundException, NotAuthorizedException, InvalidStateException { - LOGGER.debug("entry to transfer(taskId = {}, destinationWorkbasketId = {})", taskId, destinationWorkbasketId); - TaskImpl task = null; - try { - taskanaEngine.openConnection(); - task = (TaskImpl) getTask(taskId); - - if (task.getState() == TaskState.COMPLETED) { - throw new InvalidStateException("Completed task with id " + task.getId() + " cannot be transferred."); - } - - // transfer requires TRANSFER in source and APPEND on destination workbasket - workbasketService.checkAuthorization(destinationWorkbasketId, WorkbasketPermission.APPEND); - workbasketService.checkAuthorization(task.getWorkbasketSummary().getId(), - WorkbasketPermission.TRANSFER); - - Workbasket destinationWorkbasket = workbasketService.getWorkbasket(destinationWorkbasketId); - - // reset read flag and set transferred flag - task.setRead(false); - task.setTransferred(true); - - // transfer task from source to destination workbasket - task.setWorkbasketSummary(destinationWorkbasket.asSummary()); - task.setModified(Instant.now()); - task.setState(TaskState.READY); - task.setOwner(null); - taskMapper.update(task); - LOGGER.debug("Method transfer() transferred Task '{}' to destination workbasket {}", taskId, - destinationWorkbasketId); - return task; - } finally { - taskanaEngine.returnConnection(); - LOGGER.debug("exit from transfer(). Returning result {} ", task); - } - } - - @Override - public Task transfer(String taskId, String destinationWorkbasketKey, String domain) - throws TaskNotFoundException, WorkbasketNotFoundException, NotAuthorizedException, InvalidStateException { - LOGGER.debug("entry to transfer(taskId = {}, destinationWorkbasketKey = {}, domain = {})", taskId, - destinationWorkbasketKey, domain); - TaskImpl task = null; - try { - taskanaEngine.openConnection(); - task = (TaskImpl) getTask(taskId); - - if (task.getState() == TaskState.COMPLETED) { - throw new InvalidStateException("Completed task with id " + task.getId() + " cannot be transferred."); - } - - // transfer requires TRANSFER in source and APPEND on destination workbasket - workbasketService.checkAuthorization(destinationWorkbasketKey, domain, WorkbasketPermission.APPEND); - workbasketService.checkAuthorization(task.getWorkbasketSummary().getId(), - WorkbasketPermission.TRANSFER); - - Workbasket destinationWorkbasket = workbasketService.getWorkbasket(destinationWorkbasketKey, domain); - - // reset read flag and set transferred flag - task.setRead(false); - task.setTransferred(true); - - // transfer task from source to destination workbasket - task.setWorkbasketSummary(destinationWorkbasket.asSummary()); - task.setModified(Instant.now()); - task.setState(TaskState.READY); - task.setOwner(null); - taskMapper.update(task); - LOGGER.debug("Method transfer() transferred Task '{}' to destination workbasket {}", taskId, - destinationWorkbasket.getId()); - return task; - } finally { - taskanaEngine.returnConnection(); - LOGGER.debug("exit from transfer(). Returning result {} ", task); - } - } - - @Override - public BulkOperationResults transferTasks(String destinationWorkbasketId, - List taskIds) throws NotAuthorizedException, InvalidArgumentException, WorkbasketNotFoundException { - try { - taskanaEngine.openConnection(); - LOGGER.debug("entry to transferBulk(targetWbId = {}, taskIds = {})", destinationWorkbasketId, taskIds); - // Check pre-conditions with trowing Exceptions - if (destinationWorkbasketId == null || destinationWorkbasketId.isEmpty()) { - throw new InvalidArgumentException( - "DestinationWorkbasketId must not be null or empty."); - } - Workbasket destinationWorkbasket = workbasketService.getWorkbasket(destinationWorkbasketId); - - return transferTasks(taskIds, destinationWorkbasket); - } finally { - LOGGER.debug("exit from transferBulk(targetWbKey = {}, taskIds = {})", destinationWorkbasketId, taskIds); - taskanaEngine.returnConnection(); - } - } - - @Override - public BulkOperationResults transferTasks(String destinationWorkbasketKey, - String destinationWorkbasketDomain, List taskIds) - throws NotAuthorizedException, InvalidArgumentException, WorkbasketNotFoundException { - try { - taskanaEngine.openConnection(); - LOGGER.debug("entry to transferBulk(targetWbKey = {}, domain = {}, taskIds = {})", destinationWorkbasketKey, - destinationWorkbasketDomain, taskIds); - // Check pre-conditions with trowing Exceptions - if (destinationWorkbasketKey == null || destinationWorkbasketDomain == null) { - throw new InvalidArgumentException( - "DestinationWorkbasketKey or domain can´t be used as NULL-Parameter."); - } - Workbasket destinationWorkbasket = workbasketService.getWorkbasket(destinationWorkbasketKey, - destinationWorkbasketDomain); - - return transferTasks(taskIds, destinationWorkbasket); - } finally { - LOGGER.debug("exit from transferBulk(targetWbKey = {}, taskIds = {})", destinationWorkbasketKey, - destinationWorkbasketDomain, taskIds); - taskanaEngine.returnConnection(); - } - } - - private BulkOperationResults transferTasks(List taskIdsToBeTransferred, - Workbasket destinationWorkbasket) - throws InvalidArgumentException, WorkbasketNotFoundException, NotAuthorizedException { - - workbasketService.checkAuthorization(destinationWorkbasket.getId(), WorkbasketPermission.APPEND); - - // Check pre-conditions with trowing Exceptions - if (taskIdsToBeTransferred == null) { - throw new InvalidArgumentException("TaskIds must not be null."); - } - BulkOperationResults bulkLog = new BulkOperationResults<>(); - - // convert to ArrayList if necessary to prevent a UnsupportedOperationException while removing - List taskIds = new ArrayList<>(taskIdsToBeTransferred); - - // check tasks Ids exist and not empty - log and remove - Iterator taskIdIterator = taskIds.iterator(); - while (taskIdIterator.hasNext()) { - String currentTaskId = taskIdIterator.next(); - if (currentTaskId == null || currentTaskId.equals("")) { - bulkLog.addError("", - new InvalidArgumentException("IDs with EMPTY or NULL value are not allowed.")); - taskIdIterator.remove(); - } - } - - // Check pre-conditions with trowing Exceptions after removing invalid invalid arguments. - if (taskIds.isEmpty()) { - throw new InvalidArgumentException("TaskIds must not contain only invalid arguments."); - } - - // query for existing tasks. use taskMapper.findExistingTasks because this method - // returns only the required information. - List taskSummaries; - if (taskIds.isEmpty()) { - taskSummaries = new ArrayList<>(); - } else { - taskSummaries = taskMapper.findExistingTasks(taskIds); - } - // check source WB (read)+transfer - Set workbasketIds = new HashSet<>(); - taskSummaries.forEach(t -> workbasketIds.add(t.getWorkbasketId())); - WorkbasketQueryImpl query = (WorkbasketQueryImpl) workbasketService.createWorkbasketQuery(); - query.setUsedToAugmentTasks(true); - List sourceWorkbaskets; - if (taskSummaries.isEmpty()) { - sourceWorkbaskets = new ArrayList<>(); - } else { - sourceWorkbaskets = query - .callerHasPermission(WorkbasketPermission.TRANSFER) - .idIn(workbasketIds.toArray(new String[0])) - .list(); - } - taskIdIterator = taskIds.iterator(); - while (taskIdIterator.hasNext()) { - String currentTaskId = taskIdIterator.next(); - MinimalTaskSummary taskSummary = taskSummaries.stream() - .filter(t -> currentTaskId.equals(t.getTaskId())) - .findFirst() - .orElse(null); - if (taskSummary == null) { - bulkLog.addError(currentTaskId, - new TaskNotFoundException(currentTaskId, "Task with id " + currentTaskId + " was not found.")); - taskIdIterator.remove(); - } else if (taskSummary.getTaskState() == TaskState.COMPLETED) { - bulkLog.addError(currentTaskId, - new InvalidStateException("Completed task with id " + currentTaskId + " cannot be transferred.")); - taskIdIterator.remove(); - } else if (sourceWorkbaskets.stream() - .noneMatch(wb -> taskSummary.getWorkbasketId().equals(wb.getId()))) { - bulkLog.addError(currentTaskId, - new NotAuthorizedException( - "The workbasket of this task got not TRANSFER permissions. TaskId=" + currentTaskId)); - taskIdIterator.remove(); - } - } - - // filter taskSummaries and update values - taskSummaries = taskSummaries.stream().filter(ts -> taskIds.contains(ts.getTaskId())).collect( - Collectors.toList()); - if (!taskSummaries.isEmpty()) { - Instant now = Instant.now(); - TaskSummaryImpl updateObject = new TaskSummaryImpl(); - updateObject.setRead(false); - updateObject.setTransferred(true); - updateObject.setWorkbasketSummary(destinationWorkbasket.asSummary()); - updateObject.setDomain(destinationWorkbasket.getDomain()); - updateObject.setModified(now); - updateObject.setState(TaskState.READY); - updateObject.setOwner(null); - taskMapper.updateTransfered(taskIds, updateObject); - } - return bulkLog; - } - - @Override - public Task setTaskRead(String taskId, boolean isRead) - throws TaskNotFoundException, NotAuthorizedException { - LOGGER.debug("entry to setTaskRead(taskId = {}, isRead = {})", taskId, isRead); - TaskImpl task = null; - try { - taskanaEngine.openConnection(); - task = (TaskImpl) getTask(taskId); - task.setRead(isRead); - task.setModified(Instant.now()); - taskMapper.update(task); - LOGGER.debug("Method setTaskRead() set read property of Task '{}' to {} ", task, isRead); - return task; - } finally { - taskanaEngine.returnConnection(); - LOGGER.debug("exit from setTaskRead(taskId, isRead). Returning result {} ", task); - } - } - - @Override - public TaskQuery createTaskQuery() { - return new TaskQueryImpl(taskanaEngine); - } - - @Override - public Task updateTask(Task task) - throws InvalidArgumentException, TaskNotFoundException, ConcurrencyException, WorkbasketNotFoundException, - ClassificationNotFoundException, NotAuthorizedException, AttachmentPersistenceException { - String userId = CurrentUserContext.getUserid(); - LOGGER.debug("entry to updateTask(task = {}, userId = {})", task, userId); - TaskImpl newTaskImpl = (TaskImpl) task; - TaskImpl oldTaskImpl = null; - try { - taskanaEngine.openConnection(); - oldTaskImpl = (TaskImpl) getTask(newTaskImpl.getId()); - PrioDurationHolder prioDurationFromAttachments = handleAttachmentsOnTaskUpdate(oldTaskImpl, newTaskImpl); - standardUpdateActions(oldTaskImpl, newTaskImpl, prioDurationFromAttachments); - - taskMapper.update(newTaskImpl); - LOGGER.debug("Method updateTask() updated task '{}' for user '{}'.", task.getId(), userId); - - } finally { - taskanaEngine.returnConnection(); - LOGGER.debug("exit from claim()"); - } - return task; - } - - private void standardSettings(TaskImpl task, Classification classification, - PrioDurationHolder prioDurationFromAttachments) { - Instant now = Instant.now(); - task.setId(IdGenerator.generateWithPrefix(ID_PREFIX_TASK)); - task.setState(TaskState.READY); - task.setCreated(now); - task.setModified(now); - task.setRead(false); - task.setTransferred(false); - - String creator = CurrentUserContext.getUserid(); - if (taskanaEngine.getConfiguration().isSecurityEnabled()) { - if (creator == null) { - throw new SystemException( - "TaskanaSecurity is enabled, but the current UserId is NULL while creating a Task."); - } - } - task.setCreator(creator); - - if (task.getPlanned() == null) { - task.setPlanned(now); - } - - // if no business process id is provided, a unique id is created. - if (task.getBusinessProcessId() == null) { - task.setBusinessProcessId(IdGenerator.generateWithPrefix(ID_PREFIX_BUSINESS_PROCESS)); - } - - // insert Classification specifications if Classification is given. - - if (classification != null) { - PrioDurationHolder finalPrioDuration = getNewPrioDuration(prioDurationFromAttachments.getPrio(), - prioDurationFromAttachments.getDuration(), - classification.getPriority(), classification.getServiceLevel()); - Duration finalDuration = finalPrioDuration.getDuration(); - if (finalDuration != null && !MAX_DURATION.equals(finalDuration)) { - long days = converter.convertWorkingDaysToDays(task.getPlanned(), finalDuration.toDays()); - Instant due = task.getPlanned().plus(Duration.ofDays(days)); - task.setDue(due); - } - task.setPriority(finalPrioDuration.getPrio()); - - } - - if (task.getName() == null) { - task.setName(classification.getName()); - } - - if (task.getDescription() == null) { - task.setDescription(classification.getDescription()); - } - - // insert Attachments if needed - List attachments = task.getAttachments(); - if (attachments != null) { - for (Attachment attachment : attachments) { - AttachmentImpl attachmentImpl = (AttachmentImpl) attachment; - attachmentImpl.setId(IdGenerator.generateWithPrefix(ID_PREFIX_ATTACHMENT)); - attachmentImpl.setTaskId(task.getId()); - attachmentImpl.setCreated(now); - attachmentImpl.setModified(now); - attachmentMapper.insert(attachmentImpl); - } - } - } - - List augmentTaskSummariesByContainedSummaries(List taskSummaries) { - LOGGER.debug("entry to augmentTaskSummariesByContainedSummaries()"); - List result = new ArrayList<>(); - if (taskSummaries == null || taskSummaries.isEmpty()) { - return result; - } - - Set taskIdSet = taskSummaries.stream().map(TaskSummaryImpl::getTaskId).collect(Collectors.toSet()); - String[] taskIdArray = taskIdSet.toArray(new String[0]); - - LOGGER.debug("augmentTaskSummariesByContainedSummaries() about to query for attachments "); - List attachmentSummaries = attachmentMapper - .findAttachmentSummariesByTaskIds(taskIdArray); - - List classifications = findClassificationsForTasksAndAttachments(taskSummaries, - attachmentSummaries); - - addClassificationSummariesToTaskSummaries(taskSummaries, classifications); - addWorkbasketSummariesToTaskSummaries(taskSummaries); - addAttachmentSummariesToTaskSummaries(taskSummaries, attachmentSummaries, classifications); - result.addAll(taskSummaries); - LOGGER.debug("exit from to augmentTaskSummariesByContainedSummaries()"); - return result; - } - - private void addClassificationSummariesToTaskSummaries(List tasks, - List classifications) { - if (tasks == null || tasks.isEmpty()) { - return; - } - // assign query results to appropriate tasks. - for (TaskSummaryImpl task : tasks) { - String classificationId = task.getClassificationSummary().getId(); - ClassificationSummary aClassification = classifications.stream() - .filter(c -> c.getId().equals(classificationId)) - .findFirst() - .orElse(null); - if (aClassification == null) { - throw new SystemException( - "Did not find a Classification for task (Id=" + task.getTaskId() + ",classification=" - + task.getClassificationSummary().getId() + ")"); - } - // set the classification on the task object - task.setClassificationSummary(aClassification); - } - } - - private List findClassificationsForTasksAndAttachments( - List taskSummaries, List attachmentSummaries) { - LOGGER.debug("entry to getClassificationsForTasksAndAttachments()"); - if (taskSummaries == null || taskSummaries.isEmpty()) { - return new ArrayList<>(); - } - - Set classificationIdSet = taskSummaries.stream().map(t -> t.getClassificationSummary().getId()).collect( - Collectors.toSet()); - - if (attachmentSummaries != null && !attachmentSummaries.isEmpty()) { - for (AttachmentSummaryImpl att : attachmentSummaries) { - classificationIdSet.add(att.getClassificationSummary().getId()); - } - } - return queryClassificationsForTasksAndAttachments(classificationIdSet); - } - - private List findClassificationForTaskImplAndAttachments(TaskImpl task, - List attachmentImpls) { - - Set classificationIdSet = new HashSet<>(Arrays.asList(task.getClassificationSummary().getId())); - if (attachmentImpls != null && !attachmentImpls.isEmpty()) { - for (AttachmentImpl att : attachmentImpls) { - classificationIdSet.add(att.getClassificationSummary().getId()); - } - } - - return queryClassificationsForTasksAndAttachments(classificationIdSet); - - } - - private List queryClassificationsForTasksAndAttachments(Set classificationIdSet) { - - String[] classificationIdArray = classificationIdSet.toArray(new String[0]); - - LOGGER.debug("getClassificationsForTasksAndAttachments() about to query classifications and exit"); - // perform classification query - return this.classificationService.createClassificationQuery() - .idIn(classificationIdArray) - .list(); - } - - private void addWorkbasketSummariesToTaskSummaries(List taskSummaries) { - LOGGER.debug("entry to addWorkbasketSummariesToTaskSummaries()"); - if (taskSummaries == null || taskSummaries.isEmpty()) { - return; - } - // calculate parameters for workbasket query: workbasket keys - Set workbasketIdSet = taskSummaries.stream().map(t -> t.getWorkbasketSummary().getId()).collect( - Collectors.toSet()); - String[] workbasketIdArray = workbasketIdSet.toArray(new String[0]); - // perform workbasket query - LOGGER.debug("addWorkbasketSummariesToTaskSummaries() about to query workbaskets"); - WorkbasketQueryImpl query = (WorkbasketQueryImpl) workbasketService.createWorkbasketQuery(); - query.setUsedToAugmentTasks(true); - - List workbaskets = query - .idIn(workbasketIdArray) - .list(); - // assign query results to appropriate tasks. - Iterator taskIterator = taskSummaries.iterator(); - while (taskIterator.hasNext()) { - TaskSummaryImpl task = taskIterator.next(); - String workbasketId = task.getWorkbasketSummaryImpl().getId(); - - // find the appropriate workbasket from the query result - WorkbasketSummary aWorkbasket = workbaskets.stream() - .filter(x -> workbasketId != null && workbasketId.equals(x.getId())) - .findFirst() - .orElse(null); - if (aWorkbasket == null) { - LOGGER.warn("Could not find a Workbasket for task {}.", task.getTaskId()); - taskIterator.remove(); - continue; - } - // set the classification on the task object - task.setWorkbasketSummary(aWorkbasket); - } - LOGGER.debug("exit from addWorkbasketSummariesToTaskSummaries()"); - } - - private void addAttachmentSummariesToTaskSummaries(List taskSummaries, - List attachmentSummaries, List classifications) { - if (taskSummaries == null || taskSummaries.isEmpty()) { - return; - } - - // augment attachment summaries by classification summaries - // Note: - // the mapper sets for each Attachment summary the property classificationSummary.key from the - // CLASSIFICATION_KEY property in the DB - addClassificationSummariesToAttachmentSummaries(attachmentSummaries, taskSummaries, classifications); - // assign attachment summaries to task summaries - for (TaskSummaryImpl task : taskSummaries) { - for (AttachmentSummaryImpl attachment : attachmentSummaries) { - if (attachment.getTaskId() != null && attachment.getTaskId().equals(task.getTaskId())) { - task.addAttachmentSummary(attachment); - } - } - } - - } - - private void addClassificationSummariesToAttachmentSummaries(List attachmentSummaries, - List taskSummaries, List classifications) { - // prereq: in each attachmentSummary, the classificationSummary.key property is set. - if (attachmentSummaries == null || attachmentSummaries.isEmpty() || taskSummaries == null - || taskSummaries.isEmpty()) { - return; - } - // iterate over all attachment summaries an add the appropriate classification summary to each - for (AttachmentSummaryImpl att : attachmentSummaries) { - String classificationId = att.getClassificationSummary().getId(); - ClassificationSummary aClassification = classifications.stream() - .filter(x -> classificationId != null && classificationId.equals(x.getId())) - .findFirst() - .orElse(null); - if (aClassification == null) { - throw new SystemException("Could not find a Classification for attachment " + att); - } - att.setClassificationSummary(aClassification); - } - } - - private List addClassificationSummariesToAttachments(TaskImpl task, - List attachmentImpls, List classifications) { - if (attachmentImpls == null || attachmentImpls.isEmpty()) { - return new ArrayList<>(); - } - - List result = new ArrayList<>(); - for (AttachmentImpl att : attachmentImpls) { - // find the associated task to use the correct domain - ClassificationSummary aClassification = classifications.stream() - .filter(c -> c != null & c.getId().equals(att.getClassificationSummary().getId())) - .findFirst() - .orElse(null); - - if (aClassification == null) { - throw new SystemException("Could not find a Classification for attachment " + att); - } - att.setClassificationSummary(aClassification); - result.add(att); - } - return result; - } - - @Override - public Task newTask(String workbasketId) { - TaskImpl task = new TaskImpl(); - WorkbasketSummaryImpl wb = new WorkbasketSummaryImpl(); - wb.setId(workbasketId); - task.setWorkbasketSummary(wb); - return task; - } - - @Override - public Task newTask(String workbasketKey, String domain) { - TaskImpl task = new TaskImpl(); - WorkbasketSummaryImpl wb = new WorkbasketSummaryImpl(); - wb.setKey(workbasketKey); - wb.setDomain(domain); - task.setWorkbasketSummary(wb); - return task; - } - - @Override - public Attachment newAttachment() { - return new AttachmentImpl(); - } - - @Override - public void deleteTask(String taskId) throws TaskNotFoundException, InvalidStateException, NotAuthorizedException { - deleteTask(taskId, false); - } - - @Override - public void forceDeleteTask(String taskId) - throws TaskNotFoundException, InvalidStateException, NotAuthorizedException { - deleteTask(taskId, true); - } - - private void deleteTask(String taskId, boolean forceDelete) - throws TaskNotFoundException, InvalidStateException, NotAuthorizedException { - LOGGER.debug("entry to deleteTask(taskId = {} , forceDelete = {})", taskId, forceDelete); - taskanaEngine.checkRoleMembership(TaskanaRole.ADMIN); - TaskImpl task = null; - try { - taskanaEngine.openConnection(); - task = (TaskImpl) getTask(taskId); - - if (!TaskState.COMPLETED.equals(task.getState()) && !forceDelete) { - throw new InvalidStateException("Cannot delete Task " + taskId + " because it is not completed."); - } - taskMapper.delete(taskId); - LOGGER.debug("Task {} deleted.", taskId); - } finally { - taskanaEngine.returnConnection(); - LOGGER.debug("exit from deleteTask()."); - } - } - - @Override - public BulkOperationResults deleteTasks(List taskIds) - throws InvalidArgumentException { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("entry to deleteTasks(tasks = {})", LoggerUtils.listToString(taskIds)); - } - try { - taskanaEngine.openConnection(); - if (taskIds == null) { - throw new InvalidArgumentException("TaskIds can´t be NULL as parameter for deleteTasks()."); - } - BulkOperationResults bulkLog = new BulkOperationResults<>(); - - List taskSummaries = taskMapper.findExistingTasks(taskIds); - - Iterator taskIdIterator = taskIds.iterator(); - while (taskIdIterator.hasNext()) { - String currentTaskId = taskIdIterator.next(); - if (currentTaskId == null || currentTaskId.equals("")) { - bulkLog.addError("", - new InvalidArgumentException("IDs with EMPTY or NULL value are not allowed.")); - taskIdIterator.remove(); - } else { - MinimalTaskSummary foundSummary = taskSummaries.stream() - .filter(taskState -> currentTaskId.equals(taskState.getTaskId())) - .findFirst() - .orElse(null); - if (foundSummary == null) { - bulkLog.addError(currentTaskId, new TaskNotFoundException(currentTaskId, - "Task with id " + currentTaskId + " was not found.")); - taskIdIterator.remove(); - } else { - if (!TaskState.COMPLETED.equals(foundSummary.getTaskState())) { - bulkLog.addError(currentTaskId, new InvalidStateException(currentTaskId)); - taskIdIterator.remove(); - } - } - } - } - if (!taskIds.isEmpty()) { - taskMapper.deleteMultiple(taskIds); - } - return bulkLog; - } finally { - LOGGER.debug("exit from deleteTasks()"); - taskanaEngine.returnConnection(); - } - } - - @Override - public List updateTasks(ObjectReference selectionCriteria, - Map customFieldsToUpdate) throws InvalidArgumentException { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("entry to updateTasks(selectionCriteria = {}, customFieldsToUpdate = {})", selectionCriteria, - customFieldsToUpdate); - } - - if (customFieldsToUpdate == null || customFieldsToUpdate.isEmpty()) { - throw new InvalidArgumentException("The customFieldsToUpdate argument to updateTasks must not be empty."); - } - validateObjectReference(selectionCriteria, "ObjectReference", "updateTasks call"); - - Set allowedKeys = new HashSet<>( - Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16")); - - try { - taskanaEngine.openConnection(); - - CustomPropertySelector fieldSelector = new CustomPropertySelector(); - TaskImpl newTask = new TaskImpl(); - newTask.setModified(Instant.now()); - for (Map.Entry entry : customFieldsToUpdate.entrySet()) { - String key = entry.getKey(); - if (!allowedKeys.contains(key)) { - throw new InvalidArgumentException( - "The customFieldsToUpdate argument to updateTasks contains invalid key " + key); - } else { - fieldSelector.setCustomProperty(key, true); - newTask.setCustomAttribute(key, entry.getValue()); - } - } - - // use query in order to find only those tasks that are visible to the current user - List taskSummaries = createTaskQuery() - .primaryObjectReferenceCompanyIn(selectionCriteria.getCompany()) - .primaryObjectReferenceSystemIn(selectionCriteria.getSystem()) - .primaryObjectReferenceSystemInstanceIn(selectionCriteria.getSystemInstance()) - .primaryObjectReferenceTypeIn(selectionCriteria.getType()) - .primaryObjectReferenceValueIn(selectionCriteria.getValue()) - .list(); - - List taskIds = new ArrayList<>(); - if (!taskSummaries.isEmpty()) { - taskIds = taskSummaries.stream().map(TaskSummary::getTaskId).collect(Collectors.toList()); - taskMapper.updateTasks(taskIds, newTask, fieldSelector); - LOGGER.debug("updateTasks() updated the following tasks: {} ", - LoggerUtils.listToString(taskIds)); - } else { - LOGGER.debug("updateTasks() found no tasks for update "); - } - return taskIds; - } finally { - LOGGER.debug("exit from deleteTasks()."); - taskanaEngine.returnConnection(); - } - - } - - private void validateObjectReference(ObjectReference objRef, String objRefType, String objName) - throws InvalidArgumentException { - // check that all values in the ObjectReference are set correctly - if (objRef == null) { - throw new InvalidArgumentException(objRefType + " of " + objName + " must not be null"); - } else if (objRef.getCompany() == null || objRef.getCompany().length() == 0) { - throw new InvalidArgumentException( - "Company of " + objRefType + " of " + objName + MUST_NOT_BE_EMPTY); - } else if (objRef.getSystem() == null || objRef.getSystem().length() == 0) { - throw new InvalidArgumentException( - "System of " + objRefType + " of " + objName + MUST_NOT_BE_EMPTY); - } else if (objRef.getSystemInstance() == null || objRef.getSystemInstance().length() == 0) { - throw new InvalidArgumentException( - "SystemInstance of " + objRefType + " of " + objName + MUST_NOT_BE_EMPTY); - } else if (objRef.getType() == null || objRef.getType().length() == 0) { - throw new InvalidArgumentException("Type of " + objRefType + " of " + objName + MUST_NOT_BE_EMPTY); - } else if (objRef.getValue() == null || objRef.getValue().length() == 0) { - throw new InvalidArgumentException("Value of" + objRefType + " of " + objName + MUST_NOT_BE_EMPTY); - } - } - - private PrioDurationHolder handleAttachments(TaskImpl task) throws InvalidArgumentException { - List attachments = task.getAttachments(); - if (attachments == null || attachments.isEmpty()) { - 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(); - if (attachment == null) { - i.remove(); - } else { - ObjectReference objRef = attachment.getObjectReference(); - validateObjectReference(objRef, "ObjectReference", "Attachment"); - 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, - PrioDurationHolder prioDurationFromAttachments) - throws InvalidArgumentException, ConcurrencyException, ClassificationNotFoundException { - validateObjectReference(newTaskImpl.getPrimaryObjRef(), "primary ObjectReference", "Task"); - if (oldTaskImpl.getModified() != null && !oldTaskImpl.getModified().equals(newTaskImpl.getModified()) - || oldTaskImpl.getClaimed() != null && !oldTaskImpl.getClaimed().equals(newTaskImpl.getClaimed()) - || oldTaskImpl.getState() != null && !oldTaskImpl.getState().equals(newTaskImpl.getState())) { - throw new ConcurrencyException("The task has already been updated by another user"); - } - - String newWorkbasketKey = newTaskImpl.getWorkbasketKey(); - if (newWorkbasketKey != null && !newWorkbasketKey.equals(oldTaskImpl.getWorkbasketKey())) { - throw new InvalidArgumentException("A task's Workbasket cannot be changed via update of the task"); - } - - if (newTaskImpl.getPlanned() == null) { - newTaskImpl.setPlanned(oldTaskImpl.getPlanned()); - } - - // if no business process id is provided, use the id of the old task. - if (newTaskImpl.getBusinessProcessId() == null) { - newTaskImpl.setBusinessProcessId(oldTaskImpl.getBusinessProcessId()); - } - - updateClassificationRelatedProperties(oldTaskImpl, newTaskImpl, prioDurationFromAttachments); - - newTaskImpl.setModified(Instant.now()); - } - - private void updateClassificationRelatedProperties(TaskImpl oldTaskImpl, TaskImpl newTaskImpl, - PrioDurationHolder prioDurationFromAttachments) - throws ClassificationNotFoundException { - // insert Classification specifications if Classification is given. - ClassificationSummary oldClassificationSummary = oldTaskImpl.getClassificationSummary(); - ClassificationSummary newClassificationSummary = newTaskImpl.getClassificationSummary(); - if (newClassificationSummary == null) { - newClassificationSummary = oldClassificationSummary; - } - - if (newClassificationSummary == null) { // newClassification is null -> take prio and duration from attachments - if (prioDurationFromAttachments.getDuration() != null) { - long days = converter.convertWorkingDaysToDays(newTaskImpl.getPlanned(), - prioDurationFromAttachments.getDuration().toDays()); - Instant due = newTaskImpl.getPlanned().plus(Duration.ofDays(days)); - 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 (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; - } - - long days = converter.convertWorkingDaysToDays(newTaskImpl.getPlanned(), minDuration.toDays()); - Instant due = newTaskImpl.getPlanned().plus(Duration.ofDays(days)); - - newTaskImpl.setDue(due); - } - - if (newTaskImpl.getName() == null) { - newTaskImpl.setName(newClassificationSummary.getName()); - } - - if (newTaskImpl.getDescription() == null && newClassification != null) { - newTaskImpl.setDescription(newClassification.getDescription()); - } - - int newPriority = Math.max(newClassificationSummary.getPriority(), prioDurationFromAttachments.getPrio()); - newTaskImpl.setPriority(newPriority); - - } - - } - - 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 wasAlreadyPresent = false; - if (attachment.getId() != null) { - for (Attachment oldAttachment : oldTaskImpl.getAttachments()) { - if (oldAttachment != null && attachment.getId().equals(oldAttachment.getId())) { - 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={}.", - newTaskImpl.getId(), - attachment); - break; - } - - } - } - } - - // ADD, when ID not set or not found in elements - 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={}.", - newTaskImpl.getId(), - attachmentImpl); - } catch (PersistenceException e) { - throw new AttachmentPersistenceException( - "Cannot insert the Attachement " + attachmentImpl.getId() + " for Task " - + newTaskImpl.getId() + " because it already exists.", - e.getCause()); - } - - } - } else { - i.remove(); - } - } - - // DELETE, when an Attachment was only represented before - for (Attachment oldAttachment : oldTaskImpl.getAttachments()) { - if (oldAttachment != null) { - boolean isRepresented = false; - for (Attachment newAttachment : newTaskImpl.getAttachments()) { - if (newAttachment != null && oldAttachment.getId().equals(newAttachment.getId())) { - isRepresented = true; - break; - } - } - if (!isRepresented) { - attachmentMapper.deleteAttachment(oldAttachment.getId()); - LOGGER.debug("TaskService.updateTask() for TaskId={} DELETED an Attachment={}.", - newTaskImpl.getId(), - oldAttachment); - } - } - } - if (minDuration != null && MAX_DURATION.equals(minDuration)) { - minDuration = null; - } - return new PrioDurationHolder(minDuration, maxPrio); - } - - private PrioDurationHolder handleAttachmentsOnClassificationUpdate(Task task) { - - Duration minDuration = MAX_DURATION; - int maxPrio = Integer.MIN_VALUE; - - // Iterator for removing invalid current values directly. OldAttachments can be ignored. - Iterator i = task.getAttachments().iterator(); - while (i.hasNext()) { - Attachment attachment = i.next(); - if (attachment != null) { - ClassificationSummary classification = attachment.getClassificationSummary(); - if (classification != null) { - PrioDurationHolder newPrioDuration = getNewPrioDuration(maxPrio, minDuration, - classification.getPriority(), classification.getServiceLevel()); - maxPrio = newPrioDuration.getPrio(); - minDuration = newPrioDuration.getDuration(); - } - - } - } - 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) { - if (attachment.getId() == null) { - attachment.setId(IdGenerator.generateWithPrefix(ID_PREFIX_ATTACHMENT)); - } - if (attachment.getCreated() == null) { - attachment.setCreated(Instant.now()); - } - if (attachment.getModified() == null) { - attachment.setModified(attachment.getCreated()); - } - if (attachment.getTaskId() == null) { - attachment.setTaskId(newTask.getId()); - } - } - - BulkOperationResults classificationChanged(String taskId, String classificationId) - throws ClassificationNotFoundException { - LOGGER.debug("entry to classificationChanged(taskId = {} , classificationId = {} )", taskId, classificationId); - TaskImpl task = null; - BulkOperationResults bulkLog = new BulkOperationResults<>(); - try { - taskanaEngine.openConnection(); - if (taskId == null || taskId.isEmpty() || classificationId == null || classificationId.isEmpty()) { - return bulkLog; - } - - task = taskMapper.findById(taskId); - - List attachmentImpls = attachmentMapper.findAttachmentsByTaskId(task.getId()); - if (attachmentImpls == null) { - attachmentImpls = new ArrayList<>(); - } - List attachments = augmentAttachmentsByClassification(attachmentImpls, bulkLog); - task.setAttachments(attachments); - - Classification classification = classificationService.getClassification(classificationId); - task.setClassificationSummary(classification.asSummary()); - - PrioDurationHolder prioDurationFromAttachments = handleAttachmentsOnClassificationUpdate(task); - - updateClassificationRelatedProperties(task, task, prioDurationFromAttachments); - - task.setModified(Instant.now()); - taskMapper.update(task); - return bulkLog; - } finally { - taskanaEngine.returnConnection(); - LOGGER.debug("exit from deleteTask(). "); - } - - } - - private List augmentAttachmentsByClassification(List attachmentImpls, - BulkOperationResults bulkLog) { - List result = new ArrayList<>(); - if (attachmentImpls == null || attachmentImpls.isEmpty()) { - return result; - } - Set classificationIds = attachmentImpls.stream().map(t -> t.getClassificationSummary().getId()).collect( - Collectors.toSet()); - List classifications = classificationService.createClassificationQuery() - .idIn(classificationIds.toArray(new String[0])) - .list(); - for (AttachmentImpl att : attachmentImpls) { - ClassificationSummary classificationSummary = classifications.stream() - .filter(cl -> cl.getId().equals(att.getClassificationSummary().getId())) - .findFirst() - .orElse(null); - if (classificationSummary == null) { - String id = att.getClassificationSummary().getId(); - bulkLog.addError(att.getClassificationSummary().getId(), new ClassificationNotFoundException(id, - "When processing task updates due to change of classification, the classification with id " + id - + " was not found.")); - } else { - att.setClassificationSummary(classificationSummary); - result.add(att); - } - } - - return result; - } - - /** - * 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(); - } - } - -} +package pro.taskana.impl; + +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.ibatis.exceptions.PersistenceException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.Attachment; +import pro.taskana.BulkOperationResults; +import pro.taskana.Classification; +import pro.taskana.ClassificationSummary; +import pro.taskana.ObjectReference; +import pro.taskana.Task; +import pro.taskana.TaskQuery; +import pro.taskana.TaskService; +import pro.taskana.TaskState; +import pro.taskana.TaskSummary; +import pro.taskana.TaskanaEngine; +import pro.taskana.TaskanaRole; +import pro.taskana.Workbasket; +import pro.taskana.WorkbasketPermission; +import pro.taskana.WorkbasketService; +import pro.taskana.WorkbasketSummary; +import pro.taskana.exceptions.AttachmentPersistenceException; +import pro.taskana.exceptions.ClassificationNotFoundException; +import pro.taskana.exceptions.ConcurrencyException; +import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.exceptions.InvalidOwnerException; +import pro.taskana.exceptions.InvalidStateException; +import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.SystemException; +import pro.taskana.exceptions.TaskAlreadyExistException; +import pro.taskana.exceptions.TaskNotFoundException; +import pro.taskana.exceptions.TaskanaException; +import pro.taskana.exceptions.WorkbasketNotFoundException; +import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; +import pro.taskana.impl.util.IdGenerator; +import pro.taskana.impl.util.LoggerUtils; +import pro.taskana.mappings.AttachmentMapper; +import pro.taskana.mappings.CustomPropertySelector; +import pro.taskana.mappings.TaskMapper; +import pro.taskana.security.CurrentUserContext; + +/** + * This is the implementation of TaskService. + */ +public class TaskServiceImpl implements TaskService { + + private static final Logger LOGGER = LoggerFactory.getLogger(TaskServiceImpl.class); + private static final String ID_PREFIX_ATTACHMENT = "TAI"; + 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 DaysToWorkingDaysConverter converter; + private TaskanaEngineImpl taskanaEngine; + private WorkbasketService workbasketService; + private ClassificationServiceImpl classificationService; + private TaskMapper taskMapper; + private AttachmentMapper attachmentMapper; + + TaskServiceImpl(TaskanaEngine taskanaEngine, TaskMapper taskMapper, + AttachmentMapper attachmentMapper) { + super(); + try { + this.converter = DaysToWorkingDaysConverter + .initialize(Collections.singletonList(new TimeIntervalColumnHeader(0)), Instant.now()); + } catch (InvalidArgumentException e) { + throw new SystemException("Internal error. Cannot initialize DaysToWorkingDaysConverter", e.getCause()); + } + this.taskanaEngine = (TaskanaEngineImpl) taskanaEngine; + this.taskMapper = taskMapper; + this.workbasketService = taskanaEngine.getWorkbasketService(); + this.attachmentMapper = attachmentMapper; + this.classificationService = (ClassificationServiceImpl) taskanaEngine.getClassificationService(); + } + + @Override + public Task claim(String taskId) + throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException { + return claim(taskId, false); + } + + @Override + public Task forceClaim(String taskId) + throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException { + return claim(taskId, true); + } + + private Task claim(String taskId, boolean forceClaim) + throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException { + String userId = CurrentUserContext.getUserid(); + LOGGER.debug("entry to claim(id = {}, userId = {}, forceClaim = {})", taskId, userId, forceClaim); + TaskImpl task = null; + try { + 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 == TaskState.CLAIMED && !forceClaim && !task.getOwner().equals(userId)) { + throw new InvalidOwnerException( + "Task with id " + taskId + " is already claimed by " + task.getOwner() + "."); + } + Instant now = Instant.now(); + task.setOwner(userId); + task.setModified(now); + task.setClaimed(now); + task.setRead(true); + task.setState(TaskState.CLAIMED); + taskMapper.update(task); + LOGGER.debug("Task '{}' claimed by user '{}'.", taskId, userId); + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from claim()"); + } + return task; + } + + @Override + public Task cancelClaim(String taskId) + throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException { + return this.cancelClaim(taskId, false); + } + + @Override + public Task forceCancelClaim(String taskId) + throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException { + return this.cancelClaim(taskId, true); + } + + private Task cancelClaim(String taskId, boolean forceUnclaim) + throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException { + String userId = CurrentUserContext.getUserid(); + LOGGER.debug("entry to cancelClaim(taskId = {}), userId = {}, forceUnclaim = {}", taskId, userId, + forceUnclaim); + TaskImpl task = null; + try { + 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 == TaskState.CLAIMED && !forceUnclaim && !userId.equals(task.getOwner())) { + throw new InvalidOwnerException( + "Task with id " + taskId + " is already claimed by " + task.getOwner() + "."); + } + Instant now = Instant.now(); + task.setOwner(null); + task.setModified(now); + task.setClaimed(null); + task.setRead(true); + task.setState(TaskState.READY); + taskMapper.update(task); + LOGGER.debug("Task '{}' unclaimed by user '{}'.", taskId, userId); + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from cancelClaim()"); + } + return task; + } + + @Override + public Task completeTask(String taskId) + throws TaskNotFoundException, InvalidOwnerException, InvalidStateException, NotAuthorizedException { + return completeTask(taskId, false); + } + + @Override + public Task forceCompleteTask(String taskId) + throws TaskNotFoundException, InvalidOwnerException, InvalidStateException, NotAuthorizedException { + return completeTask(taskId, true); + } + + private Task completeTask(String taskId, boolean isForced) + throws TaskNotFoundException, InvalidOwnerException, InvalidStateException, NotAuthorizedException { + String userId = CurrentUserContext.getUserid(); + LOGGER.debug("entry to completeTask(id = {}, userId = {}, isForced = {})", taskId, userId, isForced); + TaskImpl task = null; + try { + taskanaEngine.openConnection(); + task = (TaskImpl) this.getTask(taskId); + + if (task.getState() == TaskState.COMPLETED) { + return task; + } + + // 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."); + } else if (!CurrentUserContext.getAccessIds().contains(task.getOwner())) { + throw new InvalidOwnerException( + "Owner of task " + taskId + " is " + task.getOwner() + ", but current User is " + userId); + } + } else { + // CLAIM-forced, if task was not already claimed before. + if (task.getClaimed() == null || task.getState() != TaskState.CLAIMED) { + task = (TaskImpl) this.forceClaim(taskId); + } + } + Instant now = Instant.now(); + task.setCompleted(now); + task.setModified(now); + task.setState(TaskState.COMPLETED); + task.setOwner(userId); + taskMapper.update(task); + LOGGER.debug("Task '{}' completed by user '{}'.", taskId, userId); + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from completeTask()"); + } + return task; + } + + @Override + public BulkOperationResults completeTasks(List taskIds) + throws InvalidArgumentException { + try { + LOGGER.debug("entry to completeTasks(taskIds = {})", taskIds); + taskanaEngine.openConnection(); + + // Check pre-conditions with throwing Exceptions + if (taskIds == null) { + throw new InvalidArgumentException( + "TaskIds can´t be used as NULL-Parameter."); + } + + // process bulk-complete + BulkOperationResults bulkLog = new BulkOperationResults<>(); + if (!taskIds.isEmpty()) { + // remove null/empty taskIds with message + Iterator taskIdIterator = taskIds.iterator(); + while (taskIdIterator.hasNext()) { + String currentTaskId = taskIdIterator.next(); + if (currentTaskId == null || currentTaskId.isEmpty()) { + bulkLog.addError("", + new InvalidArgumentException("IDs with EMPTY or NULL value are not allowed and invalid.")); + taskIdIterator.remove(); + } + } + + // query for existing tasks, modify values and LOG missing ones. + List taskSummaries = this.createTaskQuery().idIn(taskIds.toArray(new String[0])).list(); + Instant now = Instant.now(); + taskIdIterator = taskIds.iterator(); + while (taskIdIterator.hasNext()) { + String currentTaskId = taskIdIterator.next(); + TaskSummaryImpl taskSummary = (TaskSummaryImpl) taskSummaries.stream() + .filter(ts -> currentTaskId.equals(ts.getTaskId())) + .findFirst() + .orElse(null); + if (taskSummary == null) { + bulkLog.addError(currentTaskId, new TaskNotFoundException(currentTaskId, "task with id " + + currentTaskId + " was not found.")); + taskIdIterator.remove(); + } else if (taskSummary.getClaimed() == null || taskSummary.getState() != TaskState.CLAIMED) { + bulkLog.addError(currentTaskId, new InvalidStateException(currentTaskId)); + taskIdIterator.remove(); + } else if (!CurrentUserContext.getAccessIds().contains(taskSummary.getOwner())) { + bulkLog.addError(currentTaskId, new InvalidOwnerException( + "TaskOwner is" + taskSummary.getOwner() + ", but current User is " + + CurrentUserContext.getUserid())); + taskIdIterator.remove(); + } else { + taskSummary.setCompleted(now); + taskSummary.setModified(now); + taskSummary.setState(TaskState.COMPLETED); + } + } + + if (!taskIds.isEmpty() && !taskSummaries.isEmpty()) { + taskMapper.updateCompleted(taskIds, (TaskSummaryImpl) taskSummaries.get(0)); + } + } + return bulkLog; + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from to completeTasks(taskIds = {})", taskIds); + } + } + + @Override + public Task createTask(Task taskToCreate) + throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, + TaskAlreadyExistException, InvalidArgumentException { + LOGGER.debug("entry to createTask(task = {})", taskToCreate); + TaskImpl task = (TaskImpl) taskToCreate; + try { + taskanaEngine.openConnection(); + if (task.getId() != null && !task.getId().equals("")) { + throw new TaskAlreadyExistException(task.getId()); + } else { + LOGGER.debug("Task {} cannot be be found, so it can be created.", task.getId()); + Workbasket workbasket; + + if (task.getWorkbasketSummary().getId() != null) { + workbasket = workbasketService.getWorkbasket(task.getWorkbasketSummary().getId()); + } else if (task.getWorkbasketKey() != null) { + workbasket = workbasketService.getWorkbasket(task.getWorkbasketKey(), task.getDomain()); + } else { + throw new InvalidArgumentException("Cannot create a task outside a workbasket"); + } + + task.setWorkbasketSummary(workbasket.asSummary()); + task.setDomain(workbasket.getDomain()); + + workbasketService.checkAuthorization(task.getWorkbasketSummary().getId(), + WorkbasketPermission.APPEND); + + // we do use the key and not the ID to make sure that we use the classification from the right domain. + // otherwise we would have to check the classification and its domain for validity. + String classificationKey = task.getClassificationKey(); + if (classificationKey == null || classificationKey.length() == 0) { + throw new InvalidArgumentException("classificationKey of task must not be empty"); + } + + Classification classification = this.classificationService.getClassification(classificationKey, + workbasket.getDomain()); + task.setClassificationSummary(classification.asSummary()); + validateObjectReference(task.getPrimaryObjRef(), "primary ObjectReference", "Task"); + PrioDurationHolder prioDurationFromAttachments = handleAttachments(task); + standardSettings(task, classification, prioDurationFromAttachments); + this.taskMapper.insert(task); + LOGGER.debug("Method createTask() created Task '{}'.", task.getId()); + } + return task; + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from createTask(task = {})", task); + } + } + + @Override + public Task getTask(String id) throws TaskNotFoundException, NotAuthorizedException { + LOGGER.debug("entry to getTaskById(id = {})", id); + TaskImpl resultTask = null; + try { + taskanaEngine.openConnection(); + + resultTask = taskMapper.findById(id); + if (resultTask != null) { + WorkbasketQueryImpl query = (WorkbasketQueryImpl) workbasketService.createWorkbasketQuery(); + query.setUsedToAugmentTasks(true); + String workbasketId = resultTask.getWorkbasketSummary().getId(); + List workbaskets = query + .idIn(workbasketId) + .list(); + if (workbaskets.isEmpty()) { + String currentUser = CurrentUserContext.getUserid(); + throw new NotAuthorizedException( + "The current user " + currentUser + " has no read permission for workbasket " + workbasketId); + } else { + resultTask.setWorkbasketSummary(workbaskets.get(0)); + } + + List attachmentImpls = attachmentMapper.findAttachmentsByTaskId(resultTask.getId()); + if (attachmentImpls == null) { + attachmentImpls = new ArrayList<>(); + } + + List classifications; + classifications = findClassificationForTaskImplAndAttachments(resultTask, attachmentImpls); + List attachments = addClassificationSummariesToAttachments(resultTask, attachmentImpls, + classifications); + resultTask.setAttachments(attachments); + + String classificationId = resultTask.getClassificationSummary().getId(); + ClassificationSummary classification = classifications.stream() + .filter(c -> c.getId().equals(classificationId)) + .findFirst() + .orElse(null); + if (classification == null) { + throw new SystemException( + "Could not find a Classification for task " + resultTask.getId()); + } + + resultTask.setClassificationSummary(classification); + return resultTask; + } else { + throw new TaskNotFoundException(id, "Task with id " + id + " was not found"); + } + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from getTaskById(). Returning result {} ", resultTask); + } + } + + @Override + public Task transfer(String taskId, String destinationWorkbasketId) + throws TaskNotFoundException, WorkbasketNotFoundException, NotAuthorizedException, InvalidStateException { + LOGGER.debug("entry to transfer(taskId = {}, destinationWorkbasketId = {})", taskId, destinationWorkbasketId); + TaskImpl task = null; + try { + taskanaEngine.openConnection(); + task = (TaskImpl) getTask(taskId); + + if (task.getState() == TaskState.COMPLETED) { + throw new InvalidStateException("Completed task with id " + task.getId() + " cannot be transferred."); + } + + // transfer requires TRANSFER in source and APPEND on destination workbasket + workbasketService.checkAuthorization(destinationWorkbasketId, WorkbasketPermission.APPEND); + workbasketService.checkAuthorization(task.getWorkbasketSummary().getId(), + WorkbasketPermission.TRANSFER); + + Workbasket destinationWorkbasket = workbasketService.getWorkbasket(destinationWorkbasketId); + + // reset read flag and set transferred flag + task.setRead(false); + task.setTransferred(true); + + // transfer task from source to destination workbasket + task.setWorkbasketSummary(destinationWorkbasket.asSummary()); + task.setModified(Instant.now()); + task.setState(TaskState.READY); + task.setOwner(null); + taskMapper.update(task); + LOGGER.debug("Method transfer() transferred Task '{}' to destination workbasket {}", taskId, + destinationWorkbasketId); + return task; + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from transfer(). Returning result {} ", task); + } + } + + @Override + public Task transfer(String taskId, String destinationWorkbasketKey, String domain) + throws TaskNotFoundException, WorkbasketNotFoundException, NotAuthorizedException, InvalidStateException { + LOGGER.debug("entry to transfer(taskId = {}, destinationWorkbasketKey = {}, domain = {})", taskId, + destinationWorkbasketKey, domain); + TaskImpl task = null; + try { + taskanaEngine.openConnection(); + task = (TaskImpl) getTask(taskId); + + if (task.getState() == TaskState.COMPLETED) { + throw new InvalidStateException("Completed task with id " + task.getId() + " cannot be transferred."); + } + + // transfer requires TRANSFER in source and APPEND on destination workbasket + workbasketService.checkAuthorization(destinationWorkbasketKey, domain, WorkbasketPermission.APPEND); + workbasketService.checkAuthorization(task.getWorkbasketSummary().getId(), + WorkbasketPermission.TRANSFER); + + Workbasket destinationWorkbasket = workbasketService.getWorkbasket(destinationWorkbasketKey, domain); + + // reset read flag and set transferred flag + task.setRead(false); + task.setTransferred(true); + + // transfer task from source to destination workbasket + task.setWorkbasketSummary(destinationWorkbasket.asSummary()); + task.setModified(Instant.now()); + task.setState(TaskState.READY); + task.setOwner(null); + taskMapper.update(task); + LOGGER.debug("Method transfer() transferred Task '{}' to destination workbasket {}", taskId, + destinationWorkbasket.getId()); + return task; + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from transfer(). Returning result {} ", task); + } + } + + @Override + public BulkOperationResults transferTasks(String destinationWorkbasketId, + List taskIds) throws NotAuthorizedException, InvalidArgumentException, WorkbasketNotFoundException { + try { + taskanaEngine.openConnection(); + LOGGER.debug("entry to transferBulk(targetWbId = {}, taskIds = {})", destinationWorkbasketId, taskIds); + // Check pre-conditions with trowing Exceptions + if (destinationWorkbasketId == null || destinationWorkbasketId.isEmpty()) { + throw new InvalidArgumentException( + "DestinationWorkbasketId must not be null or empty."); + } + Workbasket destinationWorkbasket = workbasketService.getWorkbasket(destinationWorkbasketId); + + return transferTasks(taskIds, destinationWorkbasket); + } finally { + LOGGER.debug("exit from transferBulk(targetWbKey = {}, taskIds = {})", destinationWorkbasketId, taskIds); + taskanaEngine.returnConnection(); + } + } + + @Override + public BulkOperationResults transferTasks(String destinationWorkbasketKey, + String destinationWorkbasketDomain, List taskIds) + throws NotAuthorizedException, InvalidArgumentException, WorkbasketNotFoundException { + try { + taskanaEngine.openConnection(); + LOGGER.debug("entry to transferBulk(targetWbKey = {}, domain = {}, taskIds = {})", destinationWorkbasketKey, + destinationWorkbasketDomain, taskIds); + // Check pre-conditions with trowing Exceptions + if (destinationWorkbasketKey == null || destinationWorkbasketDomain == null) { + throw new InvalidArgumentException( + "DestinationWorkbasketKey or domain can´t be used as NULL-Parameter."); + } + Workbasket destinationWorkbasket = workbasketService.getWorkbasket(destinationWorkbasketKey, + destinationWorkbasketDomain); + + return transferTasks(taskIds, destinationWorkbasket); + } finally { + LOGGER.debug("exit from transferBulk(targetWbKey = {}, taskIds = {})", destinationWorkbasketKey, + destinationWorkbasketDomain, taskIds); + taskanaEngine.returnConnection(); + } + } + + private BulkOperationResults transferTasks(List taskIdsToBeTransferred, + Workbasket destinationWorkbasket) + throws InvalidArgumentException, WorkbasketNotFoundException, NotAuthorizedException { + + workbasketService.checkAuthorization(destinationWorkbasket.getId(), WorkbasketPermission.APPEND); + + // Check pre-conditions with trowing Exceptions + if (taskIdsToBeTransferred == null) { + throw new InvalidArgumentException("TaskIds must not be null."); + } + BulkOperationResults bulkLog = new BulkOperationResults<>(); + + // convert to ArrayList if necessary to prevent a UnsupportedOperationException while removing + List taskIds = new ArrayList<>(taskIdsToBeTransferred); + + // check tasks Ids exist and not empty - log and remove + Iterator taskIdIterator = taskIds.iterator(); + while (taskIdIterator.hasNext()) { + String currentTaskId = taskIdIterator.next(); + if (currentTaskId == null || currentTaskId.equals("")) { + bulkLog.addError("", + new InvalidArgumentException("IDs with EMPTY or NULL value are not allowed.")); + taskIdIterator.remove(); + } + } + + // Check pre-conditions with trowing Exceptions after removing invalid invalid arguments. + if (taskIds.isEmpty()) { + throw new InvalidArgumentException("TaskIds must not contain only invalid arguments."); + } + + // query for existing tasks. use taskMapper.findExistingTasks because this method + // returns only the required information. + List taskSummaries; + if (taskIds.isEmpty()) { + taskSummaries = new ArrayList<>(); + } else { + taskSummaries = taskMapper.findExistingTasks(taskIds); + } + // check source WB (read)+transfer + Set workbasketIds = new HashSet<>(); + taskSummaries.forEach(t -> workbasketIds.add(t.getWorkbasketId())); + WorkbasketQueryImpl query = (WorkbasketQueryImpl) workbasketService.createWorkbasketQuery(); + query.setUsedToAugmentTasks(true); + List sourceWorkbaskets; + if (taskSummaries.isEmpty()) { + sourceWorkbaskets = new ArrayList<>(); + } else { + sourceWorkbaskets = query + .callerHasPermission(WorkbasketPermission.TRANSFER) + .idIn(workbasketIds.toArray(new String[0])) + .list(); + } + taskIdIterator = taskIds.iterator(); + while (taskIdIterator.hasNext()) { + String currentTaskId = taskIdIterator.next(); + MinimalTaskSummary taskSummary = taskSummaries.stream() + .filter(t -> currentTaskId.equals(t.getTaskId())) + .findFirst() + .orElse(null); + if (taskSummary == null) { + bulkLog.addError(currentTaskId, + new TaskNotFoundException(currentTaskId, "Task with id " + currentTaskId + " was not found.")); + taskIdIterator.remove(); + } else if (taskSummary.getTaskState() == TaskState.COMPLETED) { + bulkLog.addError(currentTaskId, + new InvalidStateException("Completed task with id " + currentTaskId + " cannot be transferred.")); + taskIdIterator.remove(); + } else if (sourceWorkbaskets.stream() + .noneMatch(wb -> taskSummary.getWorkbasketId().equals(wb.getId()))) { + bulkLog.addError(currentTaskId, + new NotAuthorizedException( + "The workbasket of this task got not TRANSFER permissions. TaskId=" + currentTaskId)); + taskIdIterator.remove(); + } + } + + // filter taskSummaries and update values + taskSummaries = taskSummaries.stream().filter(ts -> taskIds.contains(ts.getTaskId())).collect( + Collectors.toList()); + if (!taskSummaries.isEmpty()) { + Instant now = Instant.now(); + TaskSummaryImpl updateObject = new TaskSummaryImpl(); + updateObject.setRead(false); + updateObject.setTransferred(true); + updateObject.setWorkbasketSummary(destinationWorkbasket.asSummary()); + updateObject.setDomain(destinationWorkbasket.getDomain()); + updateObject.setModified(now); + updateObject.setState(TaskState.READY); + updateObject.setOwner(null); + taskMapper.updateTransfered(taskIds, updateObject); + } + return bulkLog; + } + + @Override + public Task setTaskRead(String taskId, boolean isRead) + throws TaskNotFoundException, NotAuthorizedException { + LOGGER.debug("entry to setTaskRead(taskId = {}, isRead = {})", taskId, isRead); + TaskImpl task = null; + try { + taskanaEngine.openConnection(); + task = (TaskImpl) getTask(taskId); + task.setRead(isRead); + task.setModified(Instant.now()); + taskMapper.update(task); + LOGGER.debug("Method setTaskRead() set read property of Task '{}' to {} ", task, isRead); + return task; + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from setTaskRead(taskId, isRead). Returning result {} ", task); + } + } + + @Override + public TaskQuery createTaskQuery() { + return new TaskQueryImpl(taskanaEngine); + } + + @Override + public Task updateTask(Task task) + throws InvalidArgumentException, TaskNotFoundException, ConcurrencyException, WorkbasketNotFoundException, + ClassificationNotFoundException, NotAuthorizedException, AttachmentPersistenceException { + String userId = CurrentUserContext.getUserid(); + LOGGER.debug("entry to updateTask(task = {}, userId = {})", task, userId); + TaskImpl newTaskImpl = (TaskImpl) task; + TaskImpl oldTaskImpl = null; + try { + taskanaEngine.openConnection(); + oldTaskImpl = (TaskImpl) getTask(newTaskImpl.getId()); + PrioDurationHolder prioDurationFromAttachments = handleAttachmentsOnTaskUpdate(oldTaskImpl, newTaskImpl); + standardUpdateActions(oldTaskImpl, newTaskImpl, prioDurationFromAttachments); + + taskMapper.update(newTaskImpl); + LOGGER.debug("Method updateTask() updated task '{}' for user '{}'.", task.getId(), userId); + + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from claim()"); + } + return task; + } + + private void standardSettings(TaskImpl task, Classification classification, + PrioDurationHolder prioDurationFromAttachments) { + Instant now = Instant.now(); + task.setId(IdGenerator.generateWithPrefix(ID_PREFIX_TASK)); + task.setState(TaskState.READY); + task.setCreated(now); + task.setModified(now); + task.setRead(false); + task.setTransferred(false); + + String creator = CurrentUserContext.getUserid(); + if (taskanaEngine.getConfiguration().isSecurityEnabled()) { + if (creator == null) { + throw new SystemException( + "TaskanaSecurity is enabled, but the current UserId is NULL while creating a Task."); + } + } + task.setCreator(creator); + + if (task.getPlanned() == null) { + task.setPlanned(now); + } + + // if no business process id is provided, a unique id is created. + if (task.getBusinessProcessId() == null) { + task.setBusinessProcessId(IdGenerator.generateWithPrefix(ID_PREFIX_BUSINESS_PROCESS)); + } + + // insert Classification specifications if Classification is given. + + if (classification != null) { + PrioDurationHolder finalPrioDuration = getNewPrioDuration(prioDurationFromAttachments.getPrio(), + prioDurationFromAttachments.getDuration(), + classification.getPriority(), classification.getServiceLevel()); + Duration finalDuration = finalPrioDuration.getDuration(); + if (finalDuration != null && !MAX_DURATION.equals(finalDuration)) { + long days = converter.convertWorkingDaysToDays(task.getPlanned(), finalDuration.toDays()); + Instant due = task.getPlanned().plus(Duration.ofDays(days)); + task.setDue(due); + } + task.setPriority(finalPrioDuration.getPrio()); + + } + + if (task.getName() == null) { + task.setName(classification.getName()); + } + + if (task.getDescription() == null) { + task.setDescription(classification.getDescription()); + } + + // insert Attachments if needed + List attachments = task.getAttachments(); + if (attachments != null) { + for (Attachment attachment : attachments) { + AttachmentImpl attachmentImpl = (AttachmentImpl) attachment; + attachmentImpl.setId(IdGenerator.generateWithPrefix(ID_PREFIX_ATTACHMENT)); + attachmentImpl.setTaskId(task.getId()); + attachmentImpl.setCreated(now); + attachmentImpl.setModified(now); + attachmentMapper.insert(attachmentImpl); + } + } + } + + List augmentTaskSummariesByContainedSummaries(List taskSummaries) { + LOGGER.debug("entry to augmentTaskSummariesByContainedSummaries()"); + List result = new ArrayList<>(); + if (taskSummaries == null || taskSummaries.isEmpty()) { + return result; + } + + Set taskIdSet = taskSummaries.stream().map(TaskSummaryImpl::getTaskId).collect(Collectors.toSet()); + String[] taskIdArray = taskIdSet.toArray(new String[0]); + + LOGGER.debug("augmentTaskSummariesByContainedSummaries() about to query for attachments "); + List attachmentSummaries = attachmentMapper + .findAttachmentSummariesByTaskIds(taskIdArray); + + List classifications = findClassificationsForTasksAndAttachments(taskSummaries, + attachmentSummaries); + + addClassificationSummariesToTaskSummaries(taskSummaries, classifications); + addWorkbasketSummariesToTaskSummaries(taskSummaries); + addAttachmentSummariesToTaskSummaries(taskSummaries, attachmentSummaries, classifications); + result.addAll(taskSummaries); + LOGGER.debug("exit from to augmentTaskSummariesByContainedSummaries()"); + return result; + } + + private void addClassificationSummariesToTaskSummaries(List tasks, + List classifications) { + if (tasks == null || tasks.isEmpty()) { + return; + } + // assign query results to appropriate tasks. + for (TaskSummaryImpl task : tasks) { + String classificationId = task.getClassificationSummary().getId(); + ClassificationSummary aClassification = classifications.stream() + .filter(c -> c.getId().equals(classificationId)) + .findFirst() + .orElse(null); + if (aClassification == null) { + throw new SystemException( + "Did not find a Classification for task (Id=" + task.getTaskId() + ",classification=" + + task.getClassificationSummary().getId() + ")"); + } + // set the classification on the task object + task.setClassificationSummary(aClassification); + } + } + + private List findClassificationsForTasksAndAttachments( + List taskSummaries, List attachmentSummaries) { + LOGGER.debug("entry to getClassificationsForTasksAndAttachments()"); + if (taskSummaries == null || taskSummaries.isEmpty()) { + return new ArrayList<>(); + } + + Set classificationIdSet = taskSummaries.stream().map(t -> t.getClassificationSummary().getId()).collect( + Collectors.toSet()); + + if (attachmentSummaries != null && !attachmentSummaries.isEmpty()) { + for (AttachmentSummaryImpl att : attachmentSummaries) { + classificationIdSet.add(att.getClassificationSummary().getId()); + } + } + return queryClassificationsForTasksAndAttachments(classificationIdSet); + } + + private List findClassificationForTaskImplAndAttachments(TaskImpl task, + List attachmentImpls) { + + Set classificationIdSet = new HashSet<>(Arrays.asList(task.getClassificationSummary().getId())); + if (attachmentImpls != null && !attachmentImpls.isEmpty()) { + for (AttachmentImpl att : attachmentImpls) { + classificationIdSet.add(att.getClassificationSummary().getId()); + } + } + + return queryClassificationsForTasksAndAttachments(classificationIdSet); + + } + + private List queryClassificationsForTasksAndAttachments(Set classificationIdSet) { + + String[] classificationIdArray = classificationIdSet.toArray(new String[0]); + + LOGGER.debug("getClassificationsForTasksAndAttachments() about to query classifications and exit"); + // perform classification query + return this.classificationService.createClassificationQuery() + .idIn(classificationIdArray) + .list(); + } + + private void addWorkbasketSummariesToTaskSummaries(List taskSummaries) { + LOGGER.debug("entry to addWorkbasketSummariesToTaskSummaries()"); + if (taskSummaries == null || taskSummaries.isEmpty()) { + return; + } + // calculate parameters for workbasket query: workbasket keys + Set workbasketIdSet = taskSummaries.stream().map(t -> t.getWorkbasketSummary().getId()).collect( + Collectors.toSet()); + String[] workbasketIdArray = workbasketIdSet.toArray(new String[0]); + // perform workbasket query + LOGGER.debug("addWorkbasketSummariesToTaskSummaries() about to query workbaskets"); + WorkbasketQueryImpl query = (WorkbasketQueryImpl) workbasketService.createWorkbasketQuery(); + query.setUsedToAugmentTasks(true); + + List workbaskets = query + .idIn(workbasketIdArray) + .list(); + // assign query results to appropriate tasks. + Iterator taskIterator = taskSummaries.iterator(); + while (taskIterator.hasNext()) { + TaskSummaryImpl task = taskIterator.next(); + String workbasketId = task.getWorkbasketSummaryImpl().getId(); + + // find the appropriate workbasket from the query result + WorkbasketSummary aWorkbasket = workbaskets.stream() + .filter(x -> workbasketId != null && workbasketId.equals(x.getId())) + .findFirst() + .orElse(null); + if (aWorkbasket == null) { + LOGGER.warn("Could not find a Workbasket for task {}.", task.getTaskId()); + taskIterator.remove(); + continue; + } + // set the classification on the task object + task.setWorkbasketSummary(aWorkbasket); + } + LOGGER.debug("exit from addWorkbasketSummariesToTaskSummaries()"); + } + + private void addAttachmentSummariesToTaskSummaries(List taskSummaries, + List attachmentSummaries, List classifications) { + if (taskSummaries == null || taskSummaries.isEmpty()) { + return; + } + + // augment attachment summaries by classification summaries + // Note: + // the mapper sets for each Attachment summary the property classificationSummary.key from the + // CLASSIFICATION_KEY property in the DB + addClassificationSummariesToAttachmentSummaries(attachmentSummaries, taskSummaries, classifications); + // assign attachment summaries to task summaries + for (TaskSummaryImpl task : taskSummaries) { + for (AttachmentSummaryImpl attachment : attachmentSummaries) { + if (attachment.getTaskId() != null && attachment.getTaskId().equals(task.getTaskId())) { + task.addAttachmentSummary(attachment); + } + } + } + + } + + private void addClassificationSummariesToAttachmentSummaries(List attachmentSummaries, + List taskSummaries, List classifications) { + // prereq: in each attachmentSummary, the classificationSummary.key property is set. + if (attachmentSummaries == null || attachmentSummaries.isEmpty() || taskSummaries == null + || taskSummaries.isEmpty()) { + return; + } + // iterate over all attachment summaries an add the appropriate classification summary to each + for (AttachmentSummaryImpl att : attachmentSummaries) { + String classificationId = att.getClassificationSummary().getId(); + ClassificationSummary aClassification = classifications.stream() + .filter(x -> classificationId != null && classificationId.equals(x.getId())) + .findFirst() + .orElse(null); + if (aClassification == null) { + throw new SystemException("Could not find a Classification for attachment " + att); + } + att.setClassificationSummary(aClassification); + } + } + + private List addClassificationSummariesToAttachments(TaskImpl task, + List attachmentImpls, List classifications) { + if (attachmentImpls == null || attachmentImpls.isEmpty()) { + return new ArrayList<>(); + } + + List result = new ArrayList<>(); + for (AttachmentImpl att : attachmentImpls) { + // find the associated task to use the correct domain + ClassificationSummary aClassification = classifications.stream() + .filter(c -> c != null & c.getId().equals(att.getClassificationSummary().getId())) + .findFirst() + .orElse(null); + + if (aClassification == null) { + throw new SystemException("Could not find a Classification for attachment " + att); + } + att.setClassificationSummary(aClassification); + result.add(att); + } + return result; + } + + @Override + public Task newTask(String workbasketId) { + TaskImpl task = new TaskImpl(); + WorkbasketSummaryImpl wb = new WorkbasketSummaryImpl(); + wb.setId(workbasketId); + task.setWorkbasketSummary(wb); + return task; + } + + @Override + public Task newTask(String workbasketKey, String domain) { + TaskImpl task = new TaskImpl(); + WorkbasketSummaryImpl wb = new WorkbasketSummaryImpl(); + wb.setKey(workbasketKey); + wb.setDomain(domain); + task.setWorkbasketSummary(wb); + return task; + } + + @Override + public Attachment newAttachment() { + return new AttachmentImpl(); + } + + @Override + public void deleteTask(String taskId) throws TaskNotFoundException, InvalidStateException, NotAuthorizedException { + deleteTask(taskId, false); + } + + @Override + public void forceDeleteTask(String taskId) + throws TaskNotFoundException, InvalidStateException, NotAuthorizedException { + deleteTask(taskId, true); + } + + private void deleteTask(String taskId, boolean forceDelete) + throws TaskNotFoundException, InvalidStateException, NotAuthorizedException { + LOGGER.debug("entry to deleteTask(taskId = {} , forceDelete = {})", taskId, forceDelete); + taskanaEngine.checkRoleMembership(TaskanaRole.ADMIN); + TaskImpl task = null; + try { + taskanaEngine.openConnection(); + task = (TaskImpl) getTask(taskId); + + if (!TaskState.COMPLETED.equals(task.getState()) && !forceDelete) { + throw new InvalidStateException("Cannot delete Task " + taskId + " because it is not completed."); + } + taskMapper.delete(taskId); + LOGGER.debug("Task {} deleted.", taskId); + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from deleteTask()."); + } + } + + @Override + public BulkOperationResults deleteTasks(List taskIds) + throws InvalidArgumentException { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("entry to deleteTasks(tasks = {})", LoggerUtils.listToString(taskIds)); + } + try { + taskanaEngine.openConnection(); + if (taskIds == null) { + throw new InvalidArgumentException("TaskIds can´t be NULL as parameter for deleteTasks()."); + } + BulkOperationResults bulkLog = new BulkOperationResults<>(); + + List taskSummaries = taskMapper.findExistingTasks(taskIds); + + Iterator taskIdIterator = taskIds.iterator(); + while (taskIdIterator.hasNext()) { + String currentTaskId = taskIdIterator.next(); + if (currentTaskId == null || currentTaskId.equals("")) { + bulkLog.addError("", + new InvalidArgumentException("IDs with EMPTY or NULL value are not allowed.")); + taskIdIterator.remove(); + } else { + MinimalTaskSummary foundSummary = taskSummaries.stream() + .filter(taskState -> currentTaskId.equals(taskState.getTaskId())) + .findFirst() + .orElse(null); + if (foundSummary == null) { + bulkLog.addError(currentTaskId, new TaskNotFoundException(currentTaskId, + "Task with id " + currentTaskId + " was not found.")); + taskIdIterator.remove(); + } else { + if (!TaskState.COMPLETED.equals(foundSummary.getTaskState())) { + bulkLog.addError(currentTaskId, new InvalidStateException(currentTaskId)); + taskIdIterator.remove(); + } + } + } + } + if (!taskIds.isEmpty()) { + taskMapper.deleteMultiple(taskIds); + } + return bulkLog; + } finally { + LOGGER.debug("exit from deleteTasks()"); + taskanaEngine.returnConnection(); + } + } + + @Override + public List updateTasks(ObjectReference selectionCriteria, + Map customFieldsToUpdate) throws InvalidArgumentException { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("entry to updateTasks(selectionCriteria = {}, customFieldsToUpdate = {})", selectionCriteria, + customFieldsToUpdate); + } + + if (customFieldsToUpdate == null || customFieldsToUpdate.isEmpty()) { + throw new InvalidArgumentException("The customFieldsToUpdate argument to updateTasks must not be empty."); + } + validateObjectReference(selectionCriteria, "ObjectReference", "updateTasks call"); + + Set allowedKeys = new HashSet<>( + Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16")); + + try { + taskanaEngine.openConnection(); + + CustomPropertySelector fieldSelector = new CustomPropertySelector(); + TaskImpl newTask = new TaskImpl(); + newTask.setModified(Instant.now()); + for (Map.Entry entry : customFieldsToUpdate.entrySet()) { + String key = entry.getKey(); + if (!allowedKeys.contains(key)) { + throw new InvalidArgumentException( + "The customFieldsToUpdate argument to updateTasks contains invalid key " + key); + } else { + fieldSelector.setCustomProperty(key, true); + newTask.setCustomAttribute(key, entry.getValue()); + } + } + + // use query in order to find only those tasks that are visible to the current user + List taskSummaries = createTaskQuery() + .primaryObjectReferenceCompanyIn(selectionCriteria.getCompany()) + .primaryObjectReferenceSystemIn(selectionCriteria.getSystem()) + .primaryObjectReferenceSystemInstanceIn(selectionCriteria.getSystemInstance()) + .primaryObjectReferenceTypeIn(selectionCriteria.getType()) + .primaryObjectReferenceValueIn(selectionCriteria.getValue()) + .list(); + + List taskIds = new ArrayList<>(); + if (!taskSummaries.isEmpty()) { + taskIds = taskSummaries.stream().map(TaskSummary::getTaskId).collect(Collectors.toList()); + taskMapper.updateTasks(taskIds, newTask, fieldSelector); + LOGGER.debug("updateTasks() updated the following tasks: {} ", + LoggerUtils.listToString(taskIds)); + } else { + LOGGER.debug("updateTasks() found no tasks for update "); + } + return taskIds; + } finally { + LOGGER.debug("exit from deleteTasks()."); + taskanaEngine.returnConnection(); + } + + } + + private void validateObjectReference(ObjectReference objRef, String objRefType, String objName) + throws InvalidArgumentException { + // check that all values in the ObjectReference are set correctly + if (objRef == null) { + throw new InvalidArgumentException(objRefType + " of " + objName + " must not be null"); + } else if (objRef.getCompany() == null || objRef.getCompany().length() == 0) { + throw new InvalidArgumentException( + "Company of " + objRefType + " of " + objName + MUST_NOT_BE_EMPTY); + } else if (objRef.getSystem() == null || objRef.getSystem().length() == 0) { + throw new InvalidArgumentException( + "System of " + objRefType + " of " + objName + MUST_NOT_BE_EMPTY); + } else if (objRef.getSystemInstance() == null || objRef.getSystemInstance().length() == 0) { + throw new InvalidArgumentException( + "SystemInstance of " + objRefType + " of " + objName + MUST_NOT_BE_EMPTY); + } else if (objRef.getType() == null || objRef.getType().length() == 0) { + throw new InvalidArgumentException("Type of " + objRefType + " of " + objName + MUST_NOT_BE_EMPTY); + } else if (objRef.getValue() == null || objRef.getValue().length() == 0) { + throw new InvalidArgumentException("Value of" + objRefType + " of " + objName + MUST_NOT_BE_EMPTY); + } + } + + private PrioDurationHolder handleAttachments(TaskImpl task) throws InvalidArgumentException { + List attachments = task.getAttachments(); + if (attachments == null || attachments.isEmpty()) { + 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(); + if (attachment == null) { + i.remove(); + } else { + ObjectReference objRef = attachment.getObjectReference(); + validateObjectReference(objRef, "ObjectReference", "Attachment"); + 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, + PrioDurationHolder prioDurationFromAttachments) + throws InvalidArgumentException, ConcurrencyException, ClassificationNotFoundException { + validateObjectReference(newTaskImpl.getPrimaryObjRef(), "primary ObjectReference", "Task"); + if (oldTaskImpl.getModified() != null && !oldTaskImpl.getModified().equals(newTaskImpl.getModified()) + || oldTaskImpl.getClaimed() != null && !oldTaskImpl.getClaimed().equals(newTaskImpl.getClaimed()) + || oldTaskImpl.getState() != null && !oldTaskImpl.getState().equals(newTaskImpl.getState())) { + throw new ConcurrencyException("The task has already been updated by another user"); + } + + String newWorkbasketKey = newTaskImpl.getWorkbasketKey(); + if (newWorkbasketKey != null && !newWorkbasketKey.equals(oldTaskImpl.getWorkbasketKey())) { + throw new InvalidArgumentException("A task's Workbasket cannot be changed via update of the task"); + } + + if (newTaskImpl.getPlanned() == null) { + newTaskImpl.setPlanned(oldTaskImpl.getPlanned()); + } + + // if no business process id is provided, use the id of the old task. + if (newTaskImpl.getBusinessProcessId() == null) { + newTaskImpl.setBusinessProcessId(oldTaskImpl.getBusinessProcessId()); + } + + updateClassificationRelatedProperties(oldTaskImpl, newTaskImpl, prioDurationFromAttachments); + + newTaskImpl.setModified(Instant.now()); + } + + private void updateClassificationRelatedProperties(TaskImpl oldTaskImpl, TaskImpl newTaskImpl, + PrioDurationHolder prioDurationFromAttachments) + throws ClassificationNotFoundException { + // insert Classification specifications if Classification is given. + ClassificationSummary oldClassificationSummary = oldTaskImpl.getClassificationSummary(); + ClassificationSummary newClassificationSummary = newTaskImpl.getClassificationSummary(); + if (newClassificationSummary == null) { + newClassificationSummary = oldClassificationSummary; + } + + if (newClassificationSummary == null) { // newClassification is null -> take prio and duration from attachments + if (prioDurationFromAttachments.getDuration() != null) { + long days = converter.convertWorkingDaysToDays(newTaskImpl.getPlanned(), + prioDurationFromAttachments.getDuration().toDays()); + Instant due = newTaskImpl.getPlanned().plus(Duration.ofDays(days)); + 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 (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; + } + + long days = converter.convertWorkingDaysToDays(newTaskImpl.getPlanned(), minDuration.toDays()); + Instant due = newTaskImpl.getPlanned().plus(Duration.ofDays(days)); + + newTaskImpl.setDue(due); + } + + if (newTaskImpl.getName() == null) { + newTaskImpl.setName(newClassificationSummary.getName()); + } + + if (newTaskImpl.getDescription() == null && newClassification != null) { + newTaskImpl.setDescription(newClassification.getDescription()); + } + + int newPriority = Math.max(newClassificationSummary.getPriority(), prioDurationFromAttachments.getPrio()); + newTaskImpl.setPriority(newPriority); + + } + + } + + 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 wasAlreadyPresent = false; + if (attachment.getId() != null) { + for (Attachment oldAttachment : oldTaskImpl.getAttachments()) { + if (oldAttachment != null && attachment.getId().equals(oldAttachment.getId())) { + 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={}.", + newTaskImpl.getId(), + attachment); + break; + } + + } + } + } + + // ADD, when ID not set or not found in elements + 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={}.", + newTaskImpl.getId(), + attachmentImpl); + } catch (PersistenceException e) { + throw new AttachmentPersistenceException( + "Cannot insert the Attachement " + attachmentImpl.getId() + " for Task " + + newTaskImpl.getId() + " because it already exists.", + e.getCause()); + } + + } + } else { + i.remove(); + } + } + + // DELETE, when an Attachment was only represented before + for (Attachment oldAttachment : oldTaskImpl.getAttachments()) { + if (oldAttachment != null) { + boolean isRepresented = false; + for (Attachment newAttachment : newTaskImpl.getAttachments()) { + if (newAttachment != null && oldAttachment.getId().equals(newAttachment.getId())) { + isRepresented = true; + break; + } + } + if (!isRepresented) { + attachmentMapper.deleteAttachment(oldAttachment.getId()); + LOGGER.debug("TaskService.updateTask() for TaskId={} DELETED an Attachment={}.", + newTaskImpl.getId(), + oldAttachment); + } + } + } + if (minDuration != null && MAX_DURATION.equals(minDuration)) { + minDuration = null; + } + return new PrioDurationHolder(minDuration, maxPrio); + } + + private PrioDurationHolder handleAttachmentsOnClassificationUpdate(Task task) { + + Duration minDuration = MAX_DURATION; + int maxPrio = Integer.MIN_VALUE; + + // Iterator for removing invalid current values directly. OldAttachments can be ignored. + Iterator i = task.getAttachments().iterator(); + while (i.hasNext()) { + Attachment attachment = i.next(); + if (attachment != null) { + ClassificationSummary classification = attachment.getClassificationSummary(); + if (classification != null) { + PrioDurationHolder newPrioDuration = getNewPrioDuration(maxPrio, minDuration, + classification.getPriority(), classification.getServiceLevel()); + maxPrio = newPrioDuration.getPrio(); + minDuration = newPrioDuration.getDuration(); + } + + } + } + 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) { + if (attachment.getId() == null) { + attachment.setId(IdGenerator.generateWithPrefix(ID_PREFIX_ATTACHMENT)); + } + if (attachment.getCreated() == null) { + attachment.setCreated(Instant.now()); + } + if (attachment.getModified() == null) { + attachment.setModified(attachment.getCreated()); + } + if (attachment.getTaskId() == null) { + attachment.setTaskId(newTask.getId()); + } + } + + BulkOperationResults classificationChanged(String taskId, String classificationId) + throws ClassificationNotFoundException { + LOGGER.debug("entry to classificationChanged(taskId = {} , classificationId = {} )", taskId, classificationId); + TaskImpl task = null; + BulkOperationResults bulkLog = new BulkOperationResults<>(); + try { + taskanaEngine.openConnection(); + if (taskId == null || taskId.isEmpty() || classificationId == null || classificationId.isEmpty()) { + return bulkLog; + } + + task = taskMapper.findById(taskId); + + List attachmentImpls = attachmentMapper.findAttachmentsByTaskId(task.getId()); + if (attachmentImpls == null) { + attachmentImpls = new ArrayList<>(); + } + List attachments = augmentAttachmentsByClassification(attachmentImpls, bulkLog); + task.setAttachments(attachments); + + Classification classification = classificationService.getClassification(classificationId); + task.setClassificationSummary(classification.asSummary()); + + PrioDurationHolder prioDurationFromAttachments = handleAttachmentsOnClassificationUpdate(task); + + updateClassificationRelatedProperties(task, task, prioDurationFromAttachments); + + task.setModified(Instant.now()); + taskMapper.update(task); + return bulkLog; + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from deleteTask(). "); + } + + } + + private List augmentAttachmentsByClassification(List attachmentImpls, + BulkOperationResults bulkLog) { + List result = new ArrayList<>(); + if (attachmentImpls == null || attachmentImpls.isEmpty()) { + return result; + } + Set classificationIds = attachmentImpls.stream().map(t -> t.getClassificationSummary().getId()).collect( + Collectors.toSet()); + List classifications = classificationService.createClassificationQuery() + .idIn(classificationIds.toArray(new String[0])) + .list(); + for (AttachmentImpl att : attachmentImpls) { + ClassificationSummary classificationSummary = classifications.stream() + .filter(cl -> cl.getId().equals(att.getClassificationSummary().getId())) + .findFirst() + .orElse(null); + if (classificationSummary == null) { + String id = att.getClassificationSummary().getId(); + bulkLog.addError(att.getClassificationSummary().getId(), new ClassificationNotFoundException(id, + "When processing task updates due to change of classification, the classification with id " + id + + " was not found.")); + } else { + att.setClassificationSummary(classificationSummary); + result.add(att); + } + } + + return result; + } + + /** + * 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/TaskMonitorMapper.java b/lib/taskana-core/src/main/java/pro/taskana/mappings/TaskMonitorMapper.java index 0357a2085..102850e91 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/mappings/TaskMonitorMapper.java +++ b/lib/taskana-core/src/main/java/pro/taskana/mappings/TaskMonitorMapper.java @@ -1,334 +1,334 @@ -package pro.taskana.mappings; - -import java.util.List; -import java.util.Map; - -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Result; -import org.apache.ibatis.annotations.Results; -import org.apache.ibatis.annotations.Select; - -import pro.taskana.CustomField; -import pro.taskana.TaskState; -import pro.taskana.impl.SelectedItem; -import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; -import pro.taskana.impl.report.impl.MonitorQueryItem; -import pro.taskana.impl.report.impl.TaskQueryItem; - -/** - * This class is the mybatis mapping of task monitoring. - */ -public interface TaskMonitorMapper { - - @Select("") - @Results({ - @Result(column = "WORKBASKET_KEY", property = "key"), - @Result(column = "AGE_IN_DAYS", property = "ageInDays"), - @Result(column = "NUMBER_OF_TASKS", property = "numberOfTasks")}) - List getTaskCountOfWorkbaskets(@Param("workbasketIds") List workbasketIds, - @Param("states") List states, - @Param("categories") List categories, - @Param("domains") List domains, - @Param("customField") CustomField customField, - @Param("customFieldValues") List customFieldValues); - - @Select("") - @Results({ - @Result(column = "CLASSIFICATION_CATEGORY", property = "key"), - @Result(column = "AGE_IN_DAYS", property = "ageInDays"), - @Result(column = "NUMBER_OF_TASKS", property = "numberOfTasks")}) - List getTaskCountOfCategories(@Param("workbasketIds") List workbasketIds, - @Param("states") List states, - @Param("categories") List categories, - @Param("domains") List domains, - @Param("customField") CustomField customField, - @Param("customFieldValues") List customFieldValues); - - @Select("") - @Results({ - @Result(column = "CLASSIFICATION_KEY", property = "key"), - @Result(column = "AGE_IN_DAYS", property = "ageInDays"), - @Result(column = "NUMBER_OF_TASKS", property = "numberOfTasks")}) - List getTaskCountOfClassifications(@Param("workbasketIds") List workbasketIds, - @Param("states") List states, - @Param("categories") List categories, - @Param("domains") List domains, - @Param("customField") CustomField customField, - @Param("customFieldValues") List customFieldValues); - - @Select("") - @Results({ - @Result(column = "TASK_CLASSIFICATION_KEY", property = "key"), - @Result(column = "ATTACHMENT_CLASSIFICATION_KEY", property = "attachmentKey"), - @Result(column = "AGE_IN_DAYS", property = "ageInDays"), - @Result(column = "NUMBER_OF_TASKS", property = "numberOfTasks")}) - List getTaskCountOfDetailedClassifications( - @Param("workbasketIds") List workbasketIds, - @Param("states") List states, - @Param("categories") List categories, - @Param("domains") List domains, - @Param("customField") CustomField customField, - @Param("customFieldValues") List customFieldValues); - - @Select("") - @Results({ - @Result(column = "CUSTOM_FIELD", property = "key"), - @Result(column = "AGE_IN_DAYS", property = "ageInDays"), - @Result(column = "NUMBER_OF_TASKS", property = "numberOfTasks")}) - List getTaskCountOfCustomFieldValues(@Param("workbasketIds") List workbasketIds, - @Param("states") List states, - @Param("categories") List categories, - @Param("domains") List domains, - @Param("customField") CustomField customField, - @Param("customFieldValues") List customFieldValues); - - @Select("") - List getTaskIdsForSelectedItems(@Param("workbasketIds") List workbasketIds, - @Param("states") List states, - @Param("categories") List categories, @Param("domains") List domains, - @Param("classificationIds") List classificationIds, - @Param("excludedClassificationIds") List excludedClassificationIds, - @Param("customField") CustomField customField, @Param("customFieldValues") List customFieldValues, - @Param("groupedBy") String groupedBy, @Param("selectedItems") List selectedItems, - @Param("joinWithAttachments") boolean joinWithAttachments); - - @Select("") - @Results({ - @Result(column = "DOMAIN", property = "domain"), - @Result(column = "STATE", property = "state"), - @Result(column = "COUNT", property = "count"), - }) - List getTasksCountByState(@Param("domains") List domains, - @Param("states") List states); - - @Select("") - List getCustomAttributeValuesForReport(@Param("workbasketIds") List workbasketIds, - @Param("states") List states, - @Param("categories") List categories, @Param("domains") List domains, - @Param("classificationIds") List classificationIds, - @Param("excludedClassificationIds") List excludedClassificationIds, - @Param("customAttributeFilter") Map customAttributeFilter, - @Param("customAttributeName") String customAttributeName); - -} +package pro.taskana.mappings; + +import java.util.List; +import java.util.Map; + +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.Select; + +import pro.taskana.CustomField; +import pro.taskana.TaskState; +import pro.taskana.impl.SelectedItem; +import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; +import pro.taskana.impl.report.impl.MonitorQueryItem; +import pro.taskana.impl.report.impl.TaskQueryItem; + +/** + * This class is the mybatis mapping of task monitoring. + */ +public interface TaskMonitorMapper { + + @Select("") + @Results({ + @Result(column = "WORKBASKET_KEY", property = "key"), + @Result(column = "AGE_IN_DAYS", property = "ageInDays"), + @Result(column = "NUMBER_OF_TASKS", property = "numberOfTasks")}) + List getTaskCountOfWorkbaskets(@Param("workbasketIds") List workbasketIds, + @Param("states") List states, + @Param("categories") List categories, + @Param("domains") List domains, + @Param("customField") CustomField customField, + @Param("customFieldValues") List customFieldValues); + + @Select("") + @Results({ + @Result(column = "CLASSIFICATION_CATEGORY", property = "key"), + @Result(column = "AGE_IN_DAYS", property = "ageInDays"), + @Result(column = "NUMBER_OF_TASKS", property = "numberOfTasks")}) + List getTaskCountOfCategories(@Param("workbasketIds") List workbasketIds, + @Param("states") List states, + @Param("categories") List categories, + @Param("domains") List domains, + @Param("customField") CustomField customField, + @Param("customFieldValues") List customFieldValues); + + @Select("") + @Results({ + @Result(column = "CLASSIFICATION_KEY", property = "key"), + @Result(column = "AGE_IN_DAYS", property = "ageInDays"), + @Result(column = "NUMBER_OF_TASKS", property = "numberOfTasks")}) + List getTaskCountOfClassifications(@Param("workbasketIds") List workbasketIds, + @Param("states") List states, + @Param("categories") List categories, + @Param("domains") List domains, + @Param("customField") CustomField customField, + @Param("customFieldValues") List customFieldValues); + + @Select("") + @Results({ + @Result(column = "TASK_CLASSIFICATION_KEY", property = "key"), + @Result(column = "ATTACHMENT_CLASSIFICATION_KEY", property = "attachmentKey"), + @Result(column = "AGE_IN_DAYS", property = "ageInDays"), + @Result(column = "NUMBER_OF_TASKS", property = "numberOfTasks")}) + List getTaskCountOfDetailedClassifications( + @Param("workbasketIds") List workbasketIds, + @Param("states") List states, + @Param("categories") List categories, + @Param("domains") List domains, + @Param("customField") CustomField customField, + @Param("customFieldValues") List customFieldValues); + + @Select("") + @Results({ + @Result(column = "CUSTOM_FIELD", property = "key"), + @Result(column = "AGE_IN_DAYS", property = "ageInDays"), + @Result(column = "NUMBER_OF_TASKS", property = "numberOfTasks")}) + List getTaskCountOfCustomFieldValues(@Param("workbasketIds") List workbasketIds, + @Param("states") List states, + @Param("categories") List categories, + @Param("domains") List domains, + @Param("customField") CustomField customField, + @Param("customFieldValues") List customFieldValues); + + @Select("") + List getTaskIdsForSelectedItems(@Param("workbasketIds") List workbasketIds, + @Param("states") List states, + @Param("categories") List categories, @Param("domains") List domains, + @Param("classificationIds") List classificationIds, + @Param("excludedClassificationIds") List excludedClassificationIds, + @Param("customField") CustomField customField, @Param("customFieldValues") List customFieldValues, + @Param("groupedBy") String groupedBy, @Param("selectedItems") List selectedItems, + @Param("joinWithAttachments") boolean joinWithAttachments); + + @Select("") + @Results({ + @Result(column = "DOMAIN", property = "domain"), + @Result(column = "STATE", property = "state"), + @Result(column = "COUNT", property = "count"), + }) + List getTasksCountByState(@Param("domains") List domains, + @Param("states") List states); + + @Select("") + List getCustomAttributeValuesForReport(@Param("workbasketIds") List workbasketIds, + @Param("states") List states, + @Param("categories") List categories, @Param("domains") List domains, + @Param("classificationIds") List classificationIds, + @Param("excludedClassificationIds") List excludedClassificationIds, + @Param("customAttributeFilter") Map customAttributeFilter, + @Param("customAttributeName") String customAttributeName); + +} diff --git a/lib/taskana-core/src/test/java/acceptance/monitoring/GetTaskIdsOfCategoryReportAccTest.java b/lib/taskana-core/src/test/java/acceptance/monitoring/GetTaskIdsOfCategoryReportAccTest.java index 109da6ef8..7abe72336 100644 --- a/lib/taskana-core/src/test/java/acceptance/monitoring/GetTaskIdsOfCategoryReportAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/monitoring/GetTaskIdsOfCategoryReportAccTest.java @@ -1,366 +1,366 @@ -package acceptance.monitoring; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import javax.sql.DataSource; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import pro.taskana.CustomField; -import pro.taskana.TaskMonitorService; -import pro.taskana.TaskState; -import pro.taskana.TaskanaEngine; -import pro.taskana.TaskanaEngine.ConnectionManagementMode; -import pro.taskana.configuration.TaskanaEngineConfiguration; -import pro.taskana.database.TestDataGenerator; -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.exceptions.NotAuthorizedException; -import pro.taskana.impl.SelectedItem; -import pro.taskana.impl.TaskanaEngineImpl; -import pro.taskana.impl.configuration.DBCleaner; -import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; -import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; -import pro.taskana.security.JAASRunner; -import pro.taskana.security.WithAccessId; - -/** - * Acceptance test for all "get task ids of category report" scenarios. - */ -@RunWith(JAASRunner.class) -public class GetTaskIdsOfCategoryReportAccTest { - - protected static TaskanaEngineConfiguration taskanaEngineConfiguration; - protected static TaskanaEngine taskanaEngine; - - @BeforeClass - public static void setupTest() throws Exception { - resetDb(); - } - - public static void resetDb() throws SQLException, IOException { - DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, true); - dataSource = TaskanaEngineConfigurationTest.getDataSource(); - taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); - taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); - taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); - ((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); - cleaner.clearDb(dataSource, false); - TestDataGenerator testDataGenerator = new TestDataGenerator(); - testDataGenerator.generateMonitoringTestData(dataSource); - } - - @Test(expected = NotAuthorizedException.class) - public void testRoleCheck() throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List columnHeaders = getListOfColumnHeaders(); - - List selectedItems = new ArrayList<>(); - taskMonitorService.getTaskIdsForSelectedItems(null, null, null, null, null, - null, null, null, - columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetTaskIdsOfCategoryReport() throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List columnHeaders = getListOfColumnHeaders(); - - List selectedItems = new ArrayList<>(); - - SelectedItem s1 = new SelectedItem(); - s1.setKey("EXTERN"); - s1.setLowerAgeLimit(-5); - s1.setUpperAgeLimit(-2); - selectedItems.add(s1); - - SelectedItem s2 = new SelectedItem(); - s2.setKey("AUTOMATIC"); - s2.setLowerAgeLimit(Integer.MIN_VALUE); - s2.setUpperAgeLimit(-11); - selectedItems.add(s2); - - SelectedItem s3 = new SelectedItem(); - s3.setKey("MANUAL"); - s3.setLowerAgeLimit(0); - s3.setUpperAgeLimit(0); - selectedItems.add(s3); - - List ids = taskMonitorService.getTaskIdsForSelectedItems(null, null, null, null, null, - null, null, null, - columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); - - assertEquals(11, ids.size()); - assertTrue(ids.contains("TKI:000000000000000000000000000000000006")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000020")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000021")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000022")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000023")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000024")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000026")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000027")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000028")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000031")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000032")); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetTaskIdsOfCategoryReportWithWorkbasketFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List columnHeaders = getListOfColumnHeaders(); - - List selectedItems = new ArrayList<>(); - - SelectedItem s1 = new SelectedItem(); - s1.setKey("EXTERN"); - s1.setLowerAgeLimit(-5); - s1.setUpperAgeLimit(-2); - selectedItems.add(s1); - - SelectedItem s2 = new SelectedItem(); - s2.setKey("AUTOMATIC"); - s2.setLowerAgeLimit(Integer.MIN_VALUE); - s2.setUpperAgeLimit(-11); - selectedItems.add(s2); - - SelectedItem s3 = new SelectedItem(); - s3.setKey("MANUAL"); - s3.setLowerAgeLimit(0); - s3.setUpperAgeLimit(0); - selectedItems.add(s3); - - List ids = taskMonitorService.getTaskIdsForSelectedItems(workbasketIds, null, null, null, null, - null, null, null, - columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); - - assertEquals(4, ids.size()); - assertTrue(ids.contains("TKI:000000000000000000000000000000000006")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000020")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000026")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000031")); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetTaskIdsOfCategoryReportWithStateFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List states = Collections.singletonList(TaskState.READY); - List columnHeaders = getListOfColumnHeaders(); - - List selectedItems = new ArrayList<>(); - - SelectedItem s1 = new SelectedItem(); - s1.setKey("EXTERN"); - s1.setLowerAgeLimit(-5); - s1.setUpperAgeLimit(-2); - selectedItems.add(s1); - - SelectedItem s2 = new SelectedItem(); - s2.setKey("AUTOMATIC"); - s2.setLowerAgeLimit(Integer.MIN_VALUE); - s2.setUpperAgeLimit(-11); - selectedItems.add(s2); - - SelectedItem s3 = new SelectedItem(); - s3.setKey("MANUAL"); - s3.setLowerAgeLimit(0); - s3.setUpperAgeLimit(0); - selectedItems.add(s3); - - List ids = taskMonitorService.getTaskIdsForSelectedItems(null, states, null, null, null, - null, null, null, - columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); - - assertEquals(11, ids.size()); - assertTrue(ids.contains("TKI:000000000000000000000000000000000006")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000020")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000021")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000022")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000023")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000024")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000026")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000027")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000028")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000031")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000032")); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetTaskIdsOfCategoryReportWithCategoryFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List categories = Arrays.asList("AUTOMATIC", "MANUAL"); - List columnHeaders = getListOfColumnHeaders(); - - List selectedItems = new ArrayList<>(); - - SelectedItem s1 = new SelectedItem(); - s1.setKey("AUTOMATIC"); - s1.setLowerAgeLimit(Integer.MIN_VALUE); - s1.setUpperAgeLimit(-11); - selectedItems.add(s1); - - SelectedItem s2 = new SelectedItem(); - s2.setKey("MANUAL"); - s2.setLowerAgeLimit(0); - s2.setUpperAgeLimit(0); - selectedItems.add(s2); - - List ids = taskMonitorService.getTaskIdsForSelectedItems(null, null, categories, null, null, - null, null, null, - columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); - - assertEquals(3, ids.size()); - assertTrue(ids.contains("TKI:000000000000000000000000000000000006")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000031")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000032")); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetTaskIdsOfCategoryReportWithDomainFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List domains = Collections.singletonList("DOMAIN_A"); - List columnHeaders = getListOfColumnHeaders(); - - List selectedItems = new ArrayList<>(); - - SelectedItem s1 = new SelectedItem(); - s1.setKey("EXTERN"); - s1.setLowerAgeLimit(-5); - s1.setUpperAgeLimit(-2); - selectedItems.add(s1); - - SelectedItem s2 = new SelectedItem(); - s2.setKey("AUTOMATIC"); - s2.setLowerAgeLimit(Integer.MIN_VALUE); - s2.setUpperAgeLimit(-11); - selectedItems.add(s2); - - SelectedItem s3 = new SelectedItem(); - s3.setKey("MANUAL"); - s3.setLowerAgeLimit(0); - s3.setUpperAgeLimit(0); - selectedItems.add(s3); - - List ids = taskMonitorService.getTaskIdsForSelectedItems(null, null, null, domains, null, - null, null, null, - columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); - - assertEquals(4, ids.size()); - assertTrue(ids.contains("TKI:000000000000000000000000000000000020")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000021")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000022")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000028")); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetTaskIdsOfCategoryReportWithCustomFieldValueFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - List columnHeaders = getListOfColumnHeaders(); - - List selectedItems = new ArrayList<>(); - - SelectedItem s1 = new SelectedItem(); - s1.setKey("EXTERN"); - s1.setLowerAgeLimit(-5); - s1.setUpperAgeLimit(-2); - selectedItems.add(s1); - - SelectedItem s2 = new SelectedItem(); - s2.setKey("AUTOMATIC"); - s2.setLowerAgeLimit(Integer.MIN_VALUE); - s2.setUpperAgeLimit(-11); - selectedItems.add(s2); - - SelectedItem s3 = new SelectedItem(); - s3.setKey("MANUAL"); - s3.setLowerAgeLimit(0); - s3.setUpperAgeLimit(0); - selectedItems.add(s3); - - List ids = taskMonitorService.getTaskIdsForSelectedItems(null, null, null, null, null, null, - customField, - customFieldValues, - columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); - - assertEquals(5, ids.size()); - assertTrue(ids.contains("TKI:000000000000000000000000000000000020")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000024")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000027")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000031")); - assertTrue(ids.contains("TKI:000000000000000000000000000000000032")); - } - - @WithAccessId( - userName = "monitor") - @Test(expected = InvalidArgumentException.class) - public void testThrowsExceptionIfSubKeysAreUsed() throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List columnHeaders = getListOfColumnHeaders(); - - List selectedItems = new ArrayList<>(); - - SelectedItem s1 = new SelectedItem(); - s1.setKey("EXTERN"); - s1.setSubKey("INVALID"); - s1.setLowerAgeLimit(-5); - s1.setUpperAgeLimit(-2); - selectedItems.add(s1); - - taskMonitorService.getTaskIdsForSelectedItems(null, null, null, null, null, - null, null, null, - columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); - } - - private List getListOfColumnHeaders() { - List columnHeaders = new ArrayList<>(); - columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); - columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); - columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); - columnHeaders.add(new TimeIntervalColumnHeader(-1)); - columnHeaders.add(new TimeIntervalColumnHeader(0)); - columnHeaders.add(new TimeIntervalColumnHeader(1)); - columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); - columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); - columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); - return columnHeaders; - } - -} +package acceptance.monitoring; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.sql.DataSource; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import pro.taskana.CustomField; +import pro.taskana.TaskMonitorService; +import pro.taskana.TaskState; +import pro.taskana.TaskanaEngine; +import pro.taskana.TaskanaEngine.ConnectionManagementMode; +import pro.taskana.configuration.TaskanaEngineConfiguration; +import pro.taskana.database.TestDataGenerator; +import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.impl.SelectedItem; +import pro.taskana.impl.TaskanaEngineImpl; +import pro.taskana.impl.configuration.DBCleaner; +import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; +import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; +import pro.taskana.security.JAASRunner; +import pro.taskana.security.WithAccessId; + +/** + * Acceptance test for all "get task ids of category report" scenarios. + */ +@RunWith(JAASRunner.class) +public class GetTaskIdsOfCategoryReportAccTest { + + protected static TaskanaEngineConfiguration taskanaEngineConfiguration; + protected static TaskanaEngine taskanaEngine; + + @BeforeClass + public static void setupTest() throws Exception { + resetDb(); + } + + public static void resetDb() throws SQLException, IOException { + DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); + DBCleaner cleaner = new DBCleaner(); + cleaner.clearDb(dataSource, true); + dataSource = TaskanaEngineConfigurationTest.getDataSource(); + taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); + taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); + taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); + ((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); + cleaner.clearDb(dataSource, false); + TestDataGenerator testDataGenerator = new TestDataGenerator(); + testDataGenerator.generateMonitoringTestData(dataSource); + } + + @Test(expected = NotAuthorizedException.class) + public void testRoleCheck() throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List columnHeaders = getListOfColumnHeaders(); + + List selectedItems = new ArrayList<>(); + taskMonitorService.getTaskIdsForSelectedItems(null, null, null, null, null, + null, null, null, + columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetTaskIdsOfCategoryReport() throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List columnHeaders = getListOfColumnHeaders(); + + List selectedItems = new ArrayList<>(); + + SelectedItem s1 = new SelectedItem(); + s1.setKey("EXTERN"); + s1.setLowerAgeLimit(-5); + s1.setUpperAgeLimit(-2); + selectedItems.add(s1); + + SelectedItem s2 = new SelectedItem(); + s2.setKey("AUTOMATIC"); + s2.setLowerAgeLimit(Integer.MIN_VALUE); + s2.setUpperAgeLimit(-11); + selectedItems.add(s2); + + SelectedItem s3 = new SelectedItem(); + s3.setKey("MANUAL"); + s3.setLowerAgeLimit(0); + s3.setUpperAgeLimit(0); + selectedItems.add(s3); + + List ids = taskMonitorService.getTaskIdsForSelectedItems(null, null, null, null, null, + null, null, null, + columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); + + assertEquals(11, ids.size()); + assertTrue(ids.contains("TKI:000000000000000000000000000000000006")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000020")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000021")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000022")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000023")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000024")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000026")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000027")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000028")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000031")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000032")); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetTaskIdsOfCategoryReportWithWorkbasketFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List columnHeaders = getListOfColumnHeaders(); + + List selectedItems = new ArrayList<>(); + + SelectedItem s1 = new SelectedItem(); + s1.setKey("EXTERN"); + s1.setLowerAgeLimit(-5); + s1.setUpperAgeLimit(-2); + selectedItems.add(s1); + + SelectedItem s2 = new SelectedItem(); + s2.setKey("AUTOMATIC"); + s2.setLowerAgeLimit(Integer.MIN_VALUE); + s2.setUpperAgeLimit(-11); + selectedItems.add(s2); + + SelectedItem s3 = new SelectedItem(); + s3.setKey("MANUAL"); + s3.setLowerAgeLimit(0); + s3.setUpperAgeLimit(0); + selectedItems.add(s3); + + List ids = taskMonitorService.getTaskIdsForSelectedItems(workbasketIds, null, null, null, null, + null, null, null, + columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); + + assertEquals(4, ids.size()); + assertTrue(ids.contains("TKI:000000000000000000000000000000000006")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000020")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000026")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000031")); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetTaskIdsOfCategoryReportWithStateFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List states = Collections.singletonList(TaskState.READY); + List columnHeaders = getListOfColumnHeaders(); + + List selectedItems = new ArrayList<>(); + + SelectedItem s1 = new SelectedItem(); + s1.setKey("EXTERN"); + s1.setLowerAgeLimit(-5); + s1.setUpperAgeLimit(-2); + selectedItems.add(s1); + + SelectedItem s2 = new SelectedItem(); + s2.setKey("AUTOMATIC"); + s2.setLowerAgeLimit(Integer.MIN_VALUE); + s2.setUpperAgeLimit(-11); + selectedItems.add(s2); + + SelectedItem s3 = new SelectedItem(); + s3.setKey("MANUAL"); + s3.setLowerAgeLimit(0); + s3.setUpperAgeLimit(0); + selectedItems.add(s3); + + List ids = taskMonitorService.getTaskIdsForSelectedItems(null, states, null, null, null, + null, null, null, + columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); + + assertEquals(11, ids.size()); + assertTrue(ids.contains("TKI:000000000000000000000000000000000006")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000020")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000021")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000022")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000023")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000024")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000026")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000027")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000028")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000031")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000032")); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetTaskIdsOfCategoryReportWithCategoryFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List categories = Arrays.asList("AUTOMATIC", "MANUAL"); + List columnHeaders = getListOfColumnHeaders(); + + List selectedItems = new ArrayList<>(); + + SelectedItem s1 = new SelectedItem(); + s1.setKey("AUTOMATIC"); + s1.setLowerAgeLimit(Integer.MIN_VALUE); + s1.setUpperAgeLimit(-11); + selectedItems.add(s1); + + SelectedItem s2 = new SelectedItem(); + s2.setKey("MANUAL"); + s2.setLowerAgeLimit(0); + s2.setUpperAgeLimit(0); + selectedItems.add(s2); + + List ids = taskMonitorService.getTaskIdsForSelectedItems(null, null, categories, null, null, + null, null, null, + columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); + + assertEquals(3, ids.size()); + assertTrue(ids.contains("TKI:000000000000000000000000000000000006")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000031")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000032")); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetTaskIdsOfCategoryReportWithDomainFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List domains = Collections.singletonList("DOMAIN_A"); + List columnHeaders = getListOfColumnHeaders(); + + List selectedItems = new ArrayList<>(); + + SelectedItem s1 = new SelectedItem(); + s1.setKey("EXTERN"); + s1.setLowerAgeLimit(-5); + s1.setUpperAgeLimit(-2); + selectedItems.add(s1); + + SelectedItem s2 = new SelectedItem(); + s2.setKey("AUTOMATIC"); + s2.setLowerAgeLimit(Integer.MIN_VALUE); + s2.setUpperAgeLimit(-11); + selectedItems.add(s2); + + SelectedItem s3 = new SelectedItem(); + s3.setKey("MANUAL"); + s3.setLowerAgeLimit(0); + s3.setUpperAgeLimit(0); + selectedItems.add(s3); + + List ids = taskMonitorService.getTaskIdsForSelectedItems(null, null, null, domains, null, + null, null, null, + columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); + + assertEquals(4, ids.size()); + assertTrue(ids.contains("TKI:000000000000000000000000000000000020")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000021")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000022")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000028")); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetTaskIdsOfCategoryReportWithCustomFieldValueFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + List columnHeaders = getListOfColumnHeaders(); + + List selectedItems = new ArrayList<>(); + + SelectedItem s1 = new SelectedItem(); + s1.setKey("EXTERN"); + s1.setLowerAgeLimit(-5); + s1.setUpperAgeLimit(-2); + selectedItems.add(s1); + + SelectedItem s2 = new SelectedItem(); + s2.setKey("AUTOMATIC"); + s2.setLowerAgeLimit(Integer.MIN_VALUE); + s2.setUpperAgeLimit(-11); + selectedItems.add(s2); + + SelectedItem s3 = new SelectedItem(); + s3.setKey("MANUAL"); + s3.setLowerAgeLimit(0); + s3.setUpperAgeLimit(0); + selectedItems.add(s3); + + List ids = taskMonitorService.getTaskIdsForSelectedItems(null, null, null, null, null, null, + customField, + customFieldValues, + columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); + + assertEquals(5, ids.size()); + assertTrue(ids.contains("TKI:000000000000000000000000000000000020")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000024")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000027")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000031")); + assertTrue(ids.contains("TKI:000000000000000000000000000000000032")); + } + + @WithAccessId( + userName = "monitor") + @Test(expected = InvalidArgumentException.class) + public void testThrowsExceptionIfSubKeysAreUsed() throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List columnHeaders = getListOfColumnHeaders(); + + List selectedItems = new ArrayList<>(); + + SelectedItem s1 = new SelectedItem(); + s1.setKey("EXTERN"); + s1.setSubKey("INVALID"); + s1.setLowerAgeLimit(-5); + s1.setUpperAgeLimit(-2); + selectedItems.add(s1); + + taskMonitorService.getTaskIdsForSelectedItems(null, null, null, null, null, + null, null, null, + columnHeaders, true, selectedItems, TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); + } + + private List getListOfColumnHeaders() { + List columnHeaders = new ArrayList<>(); + columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); + columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); + columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); + columnHeaders.add(new TimeIntervalColumnHeader(-1)); + columnHeaders.add(new TimeIntervalColumnHeader(0)); + columnHeaders.add(new TimeIntervalColumnHeader(1)); + columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); + columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); + columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); + return columnHeaders; + } + +} diff --git a/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideCategoryReportAccTest.java b/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideCategoryReportAccTest.java index f228dacf9..25f276681 100644 --- a/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideCategoryReportAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideCategoryReportAccTest.java @@ -1,428 +1,428 @@ -package acceptance.monitoring; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.IntStream; - -import javax.sql.DataSource; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.CustomField; -import pro.taskana.TaskMonitorService; -import pro.taskana.TaskState; -import pro.taskana.TaskanaEngine; -import pro.taskana.TaskanaEngine.ConnectionManagementMode; -import pro.taskana.configuration.TaskanaEngineConfiguration; -import pro.taskana.database.TestDataGenerator; -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.exceptions.NotAuthorizedException; -import pro.taskana.impl.TaskanaEngineImpl; -import pro.taskana.impl.configuration.DBCleaner; -import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; -import pro.taskana.impl.report.impl.CategoryReport; -import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; -import pro.taskana.security.JAASRunner; -import pro.taskana.security.WithAccessId; - -/** - * Acceptance test for all "category report" scenarios. - */ -@RunWith(JAASRunner.class) -public class ProvideCategoryReportAccTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(ProvideCategoryReportAccTest.class); - protected static TaskanaEngineConfiguration taskanaEngineConfiguration; - protected static TaskanaEngine taskanaEngine; - - @BeforeClass - public static void setupTest() throws Exception { - resetDb(); - } - - public static void resetDb() throws SQLException, IOException { - DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, true); - dataSource = TaskanaEngineConfigurationTest.getDataSource(); - taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); - taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); - taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); - ((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); - cleaner.clearDb(dataSource, false); - TestDataGenerator testDataGenerator = new TestDataGenerator(); - testDataGenerator.generateMonitoringTestData(dataSource); - } - - @Test(expected = NotAuthorizedException.class) - public void testRoleCheck() throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - taskMonitorService.getCategoryReport(null, null, null, null, null, null); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetTotalNumbersOfTasksOfCategoryReport() throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - CategoryReport report = taskMonitorService.getCategoryReport(null, null, null, null, null, null); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - assertEquals(33, report.getRow("EXTERN").getTotalValue()); - assertEquals(7, report.getRow("AUTOMATIC").getTotalValue()); - assertEquals(10, report.getRow("MANUAL").getTotalValue()); - assertEquals(0, report.getRow("EXTERN").getCells().length); - assertEquals(0, report.getRow("AUTOMATIC").getCells().length); - assertEquals(0, report.getRow("MANUAL").getCells().length); - assertEquals(50, report.getSumRow().getTotalValue()); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetCategoryReportWithReportLineItemDefinitions() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List columnHeaders = getListOfColumnHeaders(); - - CategoryReport report = taskMonitorService.getCategoryReport(null, null, null, null, null, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - int sumLineCount = IntStream.of(report.getSumRow().getCells()).sum(); - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - assertEquals(33, report.getRow("EXTERN").getTotalValue()); - assertEquals(7, report.getRow("AUTOMATIC").getTotalValue()); - assertEquals(10, report.getRow("MANUAL").getTotalValue()); - - int[] sumRow = report.getSumRow().getCells(); - assertArrayEquals(new int[] {10, 9, 11, 0, 4, 0, 7, 4, 5}, sumRow); - assertEquals(50, report.getSumRow().getTotalValue()); - assertEquals(50, sumLineCount); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCategoryReport() throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List columnHeaders = getShortListOfColumnHeaders(); - - CategoryReport report = taskMonitorService.getCategoryReport(null, null, null, null, null, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("EXTERN").getCells(); - assertArrayEquals(new int[] {15, 8, 2, 6, 2}, row1); - - int[] row2 = report.getRow("AUTOMATIC").getCells(); - assertArrayEquals(new int[] {2, 1, 0, 1, 3}, row2); - - int[] row3 = report.getRow("MANUAL").getCells(); - assertArrayEquals(new int[] {2, 2, 2, 0, 4}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCategoryReportNotInWorkingDays() throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List columnHeaders = getShortListOfColumnHeaders(); - - CategoryReport report = taskMonitorService.getCategoryReport(null, null, null, null, null, null, - columnHeaders, false); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("EXTERN").getCells(); - assertArrayEquals(new int[] {23, 0, 2, 0, 8}, row1); - - int[] row2 = report.getRow("AUTOMATIC").getCells(); - assertArrayEquals(new int[] {3, 0, 0, 0, 4}, row2); - - int[] row3 = report.getRow("MANUAL").getCells(); - assertArrayEquals(new int[] {4, 0, 2, 0, 4}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCategoryReportWithWorkbasketFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List columnHeaders = getShortListOfColumnHeaders(); - - CategoryReport report = taskMonitorService.getCategoryReport(workbasketIds, null, null, null, null, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("EXTERN").getCells(); - assertArrayEquals(new int[] {10, 2, 0, 0, 0}, row1); - - int[] row2 = report.getRow("AUTOMATIC").getCells(); - assertArrayEquals(new int[] {2, 1, 0, 1, 1}, row2); - - int[] row3 = report.getRow("MANUAL").getCells(); - assertArrayEquals(new int[] {1, 0, 1, 0, 1}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCategoryReportWithStateFilter() throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List states = Collections.singletonList(TaskState.READY); - List columnHeaders = getShortListOfColumnHeaders(); - - CategoryReport report = taskMonitorService.getCategoryReport(null, states, null, null, null, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("EXTERN").getCells(); - assertArrayEquals(new int[] {15, 8, 2, 6, 0}, row1); - - int[] row2 = report.getRow("AUTOMATIC").getCells(); - assertArrayEquals(new int[] {2, 1, 0, 1, 0}, row2); - - int[] row3 = report.getRow("MANUAL").getCells(); - assertArrayEquals(new int[] {2, 2, 2, 0, 0}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCategoryReportWithCategoryFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List categories = Arrays.asList("AUTOMATIC", "MANUAL"); - List columnHeaders = getShortListOfColumnHeaders(); - - CategoryReport report = taskMonitorService.getCategoryReport(null, null, categories, null, null, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(2, report.rowSize()); - - int[] row1 = report.getRow("AUTOMATIC").getCells(); - assertArrayEquals(new int[] {2, 1, 0, 1, 3}, row1); - - int[] row2 = report.getRow("MANUAL").getCells(); - assertArrayEquals(new int[] {2, 2, 2, 0, 4}, row2); - - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCategoryReportWithDomainFilter() throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List domains = Collections.singletonList("DOMAIN_A"); - List columnHeaders = getShortListOfColumnHeaders(); - - CategoryReport report = taskMonitorService.getCategoryReport(null, null, null, domains, null, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("EXTERN").getCells(); - assertArrayEquals(new int[] {8, 4, 2, 4, 0}, row1); - - int[] row2 = report.getRow("AUTOMATIC").getCells(); - assertArrayEquals(new int[] {1, 0, 0, 1, 1}, row2); - - int[] row3 = report.getRow("MANUAL").getCells(); - assertArrayEquals(new int[] {2, 0, 0, 0, 3}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCategoryReportWithCustomFieldValueFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - List columnHeaders = getShortListOfColumnHeaders(); - - CategoryReport report = taskMonitorService.getCategoryReport(null, null, null, null, customField, - customFieldValues, columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("EXTERN").getCells(); - assertArrayEquals(new int[] {9, 3, 1, 3, 0}, row1); - - int[] row2 = report.getRow("AUTOMATIC").getCells(); - assertArrayEquals(new int[] {1, 0, 0, 1, 1}, row2); - - int[] row3 = report.getRow("MANUAL").getCells(); - assertArrayEquals(new int[] {1, 1, 2, 0, 2}, row3); - } - - private List getListOfColumnHeaders() { - List columnHeaders = new ArrayList<>(); - columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); - columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); - columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); - columnHeaders.add(new TimeIntervalColumnHeader(-1)); - columnHeaders.add(new TimeIntervalColumnHeader(0)); - columnHeaders.add(new TimeIntervalColumnHeader(1)); - columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); - columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); - columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); - return columnHeaders; - } - - private List getShortListOfColumnHeaders() { - List columnHeaders = new ArrayList<>(); - columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -6)); - columnHeaders.add(new TimeIntervalColumnHeader(-5, -1)); - columnHeaders.add(new TimeIntervalColumnHeader(0)); - columnHeaders.add(new TimeIntervalColumnHeader(1, 5)); - columnHeaders.add(new TimeIntervalColumnHeader(6, Integer.MAX_VALUE)); - return columnHeaders; - } - - private String reportToString(CategoryReport report) { - return reportToString(report, null); - } - - private String reportToString(CategoryReport report, - List columnHeaders) { - String formatColumWidth = "| %-7s "; - String formatFirstColumn = "| %-36s %-4s "; - String formatFirstColumnFirstLine = "| %-29s %12s "; - String formatFirstColumnSumLine = "| %-36s %-5s"; - int reportWidth = columnHeaders == null ? 46 : columnHeaders.size() * 10 + 46; - - StringBuilder builder = new StringBuilder(); - builder.append("\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - builder.append(String.format(formatFirstColumnFirstLine, "Categories", "Total")); - if (columnHeaders != null) { - for (TimeIntervalColumnHeader def : columnHeaders) { - if (def.getLowerAgeLimit() == Integer.MIN_VALUE) { - builder.append(String.format(formatColumWidth, "< " + def.getUpperAgeLimit())); - } else if (def.getUpperAgeLimit() == Integer.MAX_VALUE) { - builder.append(String.format(formatColumWidth, "> " + def.getLowerAgeLimit())); - } else if (def.getLowerAgeLimit() == def.getUpperAgeLimit()) { - if (def.getLowerAgeLimit() == 0) { - builder.append(String.format(formatColumWidth, "today")); - } else { - builder.append(String.format(formatColumWidth, def.getLowerAgeLimit())); - } - } else { - builder.append( - String.format(formatColumWidth, def.getLowerAgeLimit() + ".." + def.getUpperAgeLimit())); - } - } - } - builder.append("|\n"); - - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - - for (String rl : report.rowTitles()) { - builder - .append(String.format(formatFirstColumn, rl, report.getRow(rl).getTotalValue())); - if (columnHeaders != null) { - for (int cell : report.getRow(rl).getCells()) { - builder.append(String.format(formatColumWidth, cell)); - } - } - builder.append("|\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - } - builder.append(String.format(formatFirstColumnSumLine, "Total", report.getSumRow().getTotalValue())); - for (int cell : report.getSumRow().getCells()) { - builder.append(String.format(formatColumWidth, cell)); - } - builder.append("|\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - return builder.toString(); - } - -} +package acceptance.monitoring; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.IntStream; + +import javax.sql.DataSource; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.CustomField; +import pro.taskana.TaskMonitorService; +import pro.taskana.TaskState; +import pro.taskana.TaskanaEngine; +import pro.taskana.TaskanaEngine.ConnectionManagementMode; +import pro.taskana.configuration.TaskanaEngineConfiguration; +import pro.taskana.database.TestDataGenerator; +import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.impl.TaskanaEngineImpl; +import pro.taskana.impl.configuration.DBCleaner; +import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; +import pro.taskana.impl.report.impl.CategoryReport; +import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; +import pro.taskana.security.JAASRunner; +import pro.taskana.security.WithAccessId; + +/** + * Acceptance test for all "category report" scenarios. + */ +@RunWith(JAASRunner.class) +public class ProvideCategoryReportAccTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProvideCategoryReportAccTest.class); + protected static TaskanaEngineConfiguration taskanaEngineConfiguration; + protected static TaskanaEngine taskanaEngine; + + @BeforeClass + public static void setupTest() throws Exception { + resetDb(); + } + + public static void resetDb() throws SQLException, IOException { + DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); + DBCleaner cleaner = new DBCleaner(); + cleaner.clearDb(dataSource, true); + dataSource = TaskanaEngineConfigurationTest.getDataSource(); + taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); + taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); + taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); + ((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); + cleaner.clearDb(dataSource, false); + TestDataGenerator testDataGenerator = new TestDataGenerator(); + testDataGenerator.generateMonitoringTestData(dataSource); + } + + @Test(expected = NotAuthorizedException.class) + public void testRoleCheck() throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + taskMonitorService.getCategoryReport(null, null, null, null, null, null); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetTotalNumbersOfTasksOfCategoryReport() throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + CategoryReport report = taskMonitorService.getCategoryReport(null, null, null, null, null, null); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + assertEquals(33, report.getRow("EXTERN").getTotalValue()); + assertEquals(7, report.getRow("AUTOMATIC").getTotalValue()); + assertEquals(10, report.getRow("MANUAL").getTotalValue()); + assertEquals(0, report.getRow("EXTERN").getCells().length); + assertEquals(0, report.getRow("AUTOMATIC").getCells().length); + assertEquals(0, report.getRow("MANUAL").getCells().length); + assertEquals(50, report.getSumRow().getTotalValue()); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetCategoryReportWithReportLineItemDefinitions() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List columnHeaders = getListOfColumnHeaders(); + + CategoryReport report = taskMonitorService.getCategoryReport(null, null, null, null, null, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + int sumLineCount = IntStream.of(report.getSumRow().getCells()).sum(); + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + assertEquals(33, report.getRow("EXTERN").getTotalValue()); + assertEquals(7, report.getRow("AUTOMATIC").getTotalValue()); + assertEquals(10, report.getRow("MANUAL").getTotalValue()); + + int[] sumRow = report.getSumRow().getCells(); + assertArrayEquals(new int[] {10, 9, 11, 0, 4, 0, 7, 4, 5}, sumRow); + assertEquals(50, report.getSumRow().getTotalValue()); + assertEquals(50, sumLineCount); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCategoryReport() throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List columnHeaders = getShortListOfColumnHeaders(); + + CategoryReport report = taskMonitorService.getCategoryReport(null, null, null, null, null, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("EXTERN").getCells(); + assertArrayEquals(new int[] {15, 8, 2, 6, 2}, row1); + + int[] row2 = report.getRow("AUTOMATIC").getCells(); + assertArrayEquals(new int[] {2, 1, 0, 1, 3}, row2); + + int[] row3 = report.getRow("MANUAL").getCells(); + assertArrayEquals(new int[] {2, 2, 2, 0, 4}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCategoryReportNotInWorkingDays() throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List columnHeaders = getShortListOfColumnHeaders(); + + CategoryReport report = taskMonitorService.getCategoryReport(null, null, null, null, null, null, + columnHeaders, false); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("EXTERN").getCells(); + assertArrayEquals(new int[] {23, 0, 2, 0, 8}, row1); + + int[] row2 = report.getRow("AUTOMATIC").getCells(); + assertArrayEquals(new int[] {3, 0, 0, 0, 4}, row2); + + int[] row3 = report.getRow("MANUAL").getCells(); + assertArrayEquals(new int[] {4, 0, 2, 0, 4}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCategoryReportWithWorkbasketFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List columnHeaders = getShortListOfColumnHeaders(); + + CategoryReport report = taskMonitorService.getCategoryReport(workbasketIds, null, null, null, null, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("EXTERN").getCells(); + assertArrayEquals(new int[] {10, 2, 0, 0, 0}, row1); + + int[] row2 = report.getRow("AUTOMATIC").getCells(); + assertArrayEquals(new int[] {2, 1, 0, 1, 1}, row2); + + int[] row3 = report.getRow("MANUAL").getCells(); + assertArrayEquals(new int[] {1, 0, 1, 0, 1}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCategoryReportWithStateFilter() throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List states = Collections.singletonList(TaskState.READY); + List columnHeaders = getShortListOfColumnHeaders(); + + CategoryReport report = taskMonitorService.getCategoryReport(null, states, null, null, null, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("EXTERN").getCells(); + assertArrayEquals(new int[] {15, 8, 2, 6, 0}, row1); + + int[] row2 = report.getRow("AUTOMATIC").getCells(); + assertArrayEquals(new int[] {2, 1, 0, 1, 0}, row2); + + int[] row3 = report.getRow("MANUAL").getCells(); + assertArrayEquals(new int[] {2, 2, 2, 0, 0}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCategoryReportWithCategoryFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List categories = Arrays.asList("AUTOMATIC", "MANUAL"); + List columnHeaders = getShortListOfColumnHeaders(); + + CategoryReport report = taskMonitorService.getCategoryReport(null, null, categories, null, null, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(2, report.rowSize()); + + int[] row1 = report.getRow("AUTOMATIC").getCells(); + assertArrayEquals(new int[] {2, 1, 0, 1, 3}, row1); + + int[] row2 = report.getRow("MANUAL").getCells(); + assertArrayEquals(new int[] {2, 2, 2, 0, 4}, row2); + + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCategoryReportWithDomainFilter() throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List domains = Collections.singletonList("DOMAIN_A"); + List columnHeaders = getShortListOfColumnHeaders(); + + CategoryReport report = taskMonitorService.getCategoryReport(null, null, null, domains, null, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("EXTERN").getCells(); + assertArrayEquals(new int[] {8, 4, 2, 4, 0}, row1); + + int[] row2 = report.getRow("AUTOMATIC").getCells(); + assertArrayEquals(new int[] {1, 0, 0, 1, 1}, row2); + + int[] row3 = report.getRow("MANUAL").getCells(); + assertArrayEquals(new int[] {2, 0, 0, 0, 3}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCategoryReportWithCustomFieldValueFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + List columnHeaders = getShortListOfColumnHeaders(); + + CategoryReport report = taskMonitorService.getCategoryReport(null, null, null, null, customField, + customFieldValues, columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("EXTERN").getCells(); + assertArrayEquals(new int[] {9, 3, 1, 3, 0}, row1); + + int[] row2 = report.getRow("AUTOMATIC").getCells(); + assertArrayEquals(new int[] {1, 0, 0, 1, 1}, row2); + + int[] row3 = report.getRow("MANUAL").getCells(); + assertArrayEquals(new int[] {1, 1, 2, 0, 2}, row3); + } + + private List getListOfColumnHeaders() { + List columnHeaders = new ArrayList<>(); + columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); + columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); + columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); + columnHeaders.add(new TimeIntervalColumnHeader(-1)); + columnHeaders.add(new TimeIntervalColumnHeader(0)); + columnHeaders.add(new TimeIntervalColumnHeader(1)); + columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); + columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); + columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); + return columnHeaders; + } + + private List getShortListOfColumnHeaders() { + List columnHeaders = new ArrayList<>(); + columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -6)); + columnHeaders.add(new TimeIntervalColumnHeader(-5, -1)); + columnHeaders.add(new TimeIntervalColumnHeader(0)); + columnHeaders.add(new TimeIntervalColumnHeader(1, 5)); + columnHeaders.add(new TimeIntervalColumnHeader(6, Integer.MAX_VALUE)); + return columnHeaders; + } + + private String reportToString(CategoryReport report) { + return reportToString(report, null); + } + + private String reportToString(CategoryReport report, + List columnHeaders) { + String formatColumWidth = "| %-7s "; + String formatFirstColumn = "| %-36s %-4s "; + String formatFirstColumnFirstLine = "| %-29s %12s "; + String formatFirstColumnSumLine = "| %-36s %-5s"; + int reportWidth = columnHeaders == null ? 46 : columnHeaders.size() * 10 + 46; + + StringBuilder builder = new StringBuilder(); + builder.append("\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + builder.append(String.format(formatFirstColumnFirstLine, "Categories", "Total")); + if (columnHeaders != null) { + for (TimeIntervalColumnHeader def : columnHeaders) { + if (def.getLowerAgeLimit() == Integer.MIN_VALUE) { + builder.append(String.format(formatColumWidth, "< " + def.getUpperAgeLimit())); + } else if (def.getUpperAgeLimit() == Integer.MAX_VALUE) { + builder.append(String.format(formatColumWidth, "> " + def.getLowerAgeLimit())); + } else if (def.getLowerAgeLimit() == def.getUpperAgeLimit()) { + if (def.getLowerAgeLimit() == 0) { + builder.append(String.format(formatColumWidth, "today")); + } else { + builder.append(String.format(formatColumWidth, def.getLowerAgeLimit())); + } + } else { + builder.append( + String.format(formatColumWidth, def.getLowerAgeLimit() + ".." + def.getUpperAgeLimit())); + } + } + } + builder.append("|\n"); + + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + + for (String rl : report.rowTitles()) { + builder + .append(String.format(formatFirstColumn, rl, report.getRow(rl).getTotalValue())); + if (columnHeaders != null) { + for (int cell : report.getRow(rl).getCells()) { + builder.append(String.format(formatColumWidth, cell)); + } + } + builder.append("|\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + } + builder.append(String.format(formatFirstColumnSumLine, "Total", report.getSumRow().getTotalValue())); + for (int cell : report.getSumRow().getCells()) { + builder.append(String.format(formatColumWidth, cell)); + } + builder.append("|\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + return builder.toString(); + } + +} diff --git a/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideClassificationReportAccTest.java b/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideClassificationReportAccTest.java index 49841de16..44c569736 100644 --- a/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideClassificationReportAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideClassificationReportAccTest.java @@ -1,482 +1,482 @@ -package acceptance.monitoring; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.IntStream; - -import javax.sql.DataSource; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.CustomField; -import pro.taskana.TaskMonitorService; -import pro.taskana.TaskState; -import pro.taskana.TaskanaEngine; -import pro.taskana.TaskanaEngine.ConnectionManagementMode; -import pro.taskana.configuration.TaskanaEngineConfiguration; -import pro.taskana.database.TestDataGenerator; -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.exceptions.NotAuthorizedException; -import pro.taskana.impl.TaskanaEngineImpl; -import pro.taskana.impl.configuration.DBCleaner; -import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; -import pro.taskana.impl.report.impl.ClassificationReport; -import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; -import pro.taskana.security.JAASRunner; -import pro.taskana.security.WithAccessId; - -/** - * Acceptance test for all "classification report" scenarios. - */ -@RunWith(JAASRunner.class) -public class ProvideClassificationReportAccTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(ProvideClassificationReportAccTest.class); - protected static TaskanaEngineConfiguration taskanaEngineConfiguration; - protected static TaskanaEngine taskanaEngine; - - @BeforeClass - public static void setupTest() throws Exception { - resetDb(); - } - - public static void resetDb() throws SQLException, IOException { - DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, true); - dataSource = TaskanaEngineConfigurationTest.getDataSource(); - taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); - taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); - taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); - ((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); - cleaner.clearDb(dataSource, false); - TestDataGenerator testDataGenerator = new TestDataGenerator(); - testDataGenerator.generateMonitoringTestData(dataSource); - } - - @Test(expected = NotAuthorizedException.class) - public void testRoleCheck() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - taskMonitorService.getClassificationReport(null, null, null, null, null, null); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetTotalNumbersOfTasksOfClassificationReport() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - ClassificationReport report = taskMonitorService.getClassificationReport(null, null, null, null, null, null); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - assertEquals(10, report.getRow("L10000").getTotalValue()); - assertEquals(10, report.getRow("L20000").getTotalValue()); - assertEquals(7, report.getRow("L30000").getTotalValue()); - assertEquals(10, report.getRow("L40000").getTotalValue()); - assertEquals(13, report.getRow("L50000").getTotalValue()); - assertEquals(0, report.getRow("L10000").getCells().length); - assertEquals(0, report.getRow("L20000").getCells().length); - assertEquals(0, report.getRow("L30000").getCells().length); - assertEquals(0, report.getRow("L40000").getCells().length); - assertEquals(0, report.getRow("L50000").getCells().length); - assertEquals(50, report.getSumRow().getTotalValue()); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetClassificationReportWithReportLineItemDefinitions() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List reportLineItemDefinitions = getListOfColumnsHeaders(); - - ClassificationReport report = taskMonitorService.getClassificationReport(null, null, null, null, null, null, - reportLineItemDefinitions); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, reportLineItemDefinitions)); - } - - int sumLineCount = IntStream.of(report.getSumRow().getCells()).sum(); - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - assertEquals(10, report.getRow("L10000").getTotalValue()); - assertEquals(10, report.getRow("L20000").getTotalValue()); - assertEquals(7, report.getRow("L30000").getTotalValue()); - assertEquals(10, report.getRow("L40000").getTotalValue()); - assertEquals(13, report.getRow("L50000").getTotalValue()); - - assertEquals(10, report.getSumRow().getCells()[0]); - assertEquals(9, report.getSumRow().getCells()[1]); - assertEquals(11, report.getSumRow().getCells()[2]); - assertEquals(0, report.getSumRow().getCells()[3]); - assertEquals(4, report.getSumRow().getCells()[4]); - assertEquals(0, report.getSumRow().getCells()[5]); - assertEquals(7, report.getSumRow().getCells()[6]); - assertEquals(4, report.getSumRow().getCells()[7]); - assertEquals(5, report.getSumRow().getCells()[8]); - assertEquals(50, report.getSumRow().getTotalValue()); - assertEquals(50, sumLineCount); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfClassificationReport() throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List columnHeaders = getShortListOfColumnHeaders(); - - ClassificationReport report = taskMonitorService.getClassificationReport(null, null, null, null, null, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - int[] row1 = report.getRow("L10000").getCells(); - assertArrayEquals(new int[] {7, 2, 1, 0, 0}, row1); - - int[] row2 = report.getRow("L20000").getCells(); - assertArrayEquals(new int[] {5, 3, 1, 1, 0}, row2); - - int[] row3 = report.getRow("L30000").getCells(); - assertArrayEquals(new int[] {2, 1, 0, 1, 3}, row3); - - int[] row4 = report.getRow("L40000").getCells(); - assertArrayEquals(new int[] {2, 2, 2, 0, 4}, row4); - - int[] row5 = report.getRow("L50000").getCells(); - assertArrayEquals(new int[] {3, 3, 0, 5, 2}, row5); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfClassificationReportNotInWorkingDays() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List reportLineItemDefinitions = getShortListOfColumnHeaders(); - - ClassificationReport report = taskMonitorService.getClassificationReport(null, null, null, null, null, null, - reportLineItemDefinitions, false); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, reportLineItemDefinitions)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - int[] row1 = report.getRow("L10000").getCells(); - assertArrayEquals(new int[] {9, 0, 1, 0, 0}, row1); - - int[] row2 = report.getRow("L20000").getCells(); - assertArrayEquals(new int[] {8, 0, 1, 0, 1}, row2); - - int[] row3 = report.getRow("L30000").getCells(); - assertArrayEquals(new int[] {3, 0, 0, 0, 4}, row3); - - int[] row4 = report.getRow("L40000").getCells(); - assertArrayEquals(new int[] {4, 0, 2, 0, 4}, row4); - - int[] row5 = report.getRow("L50000").getCells(); - assertArrayEquals(new int[] {6, 0, 0, 0, 7}, row5); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfClassificationReportWithWorkbasketFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List columnHeaders = getShortListOfColumnHeaders(); - - ClassificationReport report = taskMonitorService.getClassificationReport(workbasketIds, null, null, null, null, - null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - int[] row1 = report.getRow("L10000").getCells(); - assertArrayEquals(new int[] {6, 0, 0, 0, 0}, row1); - - int[] row2 = report.getRow("L20000").getCells(); - assertArrayEquals(new int[] {2, 0, 0, 0, 0}, row2); - - int[] row3 = report.getRow("L30000").getCells(); - assertArrayEquals(new int[] {2, 1, 0, 1, 1}, row3); - - int[] row4 = report.getRow("L40000").getCells(); - assertArrayEquals(new int[] {1, 0, 1, 0, 1}, row4); - - int[] row5 = report.getRow("L50000").getCells(); - assertArrayEquals(new int[] {2, 2, 0, 0, 0}, row5); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfClassificationReportWithStateFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List states = Collections.singletonList(TaskState.READY); - List columnHeaders = getShortListOfColumnHeaders(); - - ClassificationReport report = taskMonitorService.getClassificationReport(null, states, null, null, null, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - int[] row1 = report.getRow("L10000").getCells(); - assertArrayEquals(new int[] {7, 2, 1, 0, 0}, row1); - - int[] row2 = report.getRow("L20000").getCells(); - assertArrayEquals(new int[] {5, 3, 1, 1, 0}, row2); - - int[] row3 = report.getRow("L30000").getCells(); - assertArrayEquals(new int[] {2, 1, 0, 1, 0}, row3); - - int[] row4 = report.getRow("L40000").getCells(); - assertArrayEquals(new int[] {2, 2, 2, 0, 0}, row4); - - int[] row5 = report.getRow("L50000").getCells(); - assertArrayEquals(new int[] {3, 3, 0, 5, 0}, row5); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfClassificationReportWithCategoryFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List categories = Arrays.asList("AUTOMATIC", "MANUAL"); - List columnHeaders = getShortListOfColumnHeaders(); - - ClassificationReport report = taskMonitorService.getClassificationReport(null, null, categories, null, null, - null, columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(2, report.rowSize()); - - int[] row1 = report.getRow("L30000").getCells(); - assertArrayEquals(new int[] {2, 1, 0, 1, 3}, row1); - - int[] row2 = report.getRow("L40000").getCells(); - assertArrayEquals(new int[] {2, 2, 2, 0, 4}, row2); - - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfClassificationReportWithDomainFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List domains = Collections.singletonList("DOMAIN_A"); - List columnHeaders = getShortListOfColumnHeaders(); - - ClassificationReport report = taskMonitorService.getClassificationReport(null, null, null, domains, null, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - int[] row1 = report.getRow("L10000").getCells(); - assertArrayEquals(new int[] {5, 2, 1, 0, 0}, row1); - - int[] row2 = report.getRow("L20000").getCells(); - assertArrayEquals(new int[] {3, 1, 1, 1, 0}, row2); - - int[] row3 = report.getRow("L30000").getCells(); - assertArrayEquals(new int[] {1, 0, 0, 1, 1}, row3); - - int[] row4 = report.getRow("L40000").getCells(); - assertArrayEquals(new int[] {2, 0, 0, 0, 3}, row4); - - int[] row5 = report.getRow("L50000").getCells(); - assertArrayEquals(new int[] {0, 1, 0, 3, 0}, row5); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfClassificationReportWithCustomFieldValueFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - List columnHeaders = getShortListOfColumnHeaders(); - - ClassificationReport report = taskMonitorService.getClassificationReport(null, null, null, null, customField, - customFieldValues, columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - int[] row1 = report.getRow("L10000").getCells(); - assertArrayEquals(new int[] {4, 0, 0, 0, 0}, row1); - - int[] row2 = report.getRow("L20000").getCells(); - assertArrayEquals(new int[] {4, 1, 1, 1, 0}, row2); - - int[] row3 = report.getRow("L30000").getCells(); - assertArrayEquals(new int[] {1, 0, 0, 1, 1}, row3); - - int[] row4 = report.getRow("L40000").getCells(); - assertArrayEquals(new int[] {1, 1, 2, 0, 2}, row4); - - int[] row5 = report.getRow("L50000").getCells(); - assertArrayEquals(new int[] {1, 2, 0, 2, 0}, row5); - } - - private List getListOfColumnsHeaders() { - List columnHeaders = new ArrayList<>(); - columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); - columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); - columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); - columnHeaders.add(new TimeIntervalColumnHeader(-1)); - columnHeaders.add(new TimeIntervalColumnHeader(0)); - columnHeaders.add(new TimeIntervalColumnHeader(1)); - columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); - columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); - columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); - return columnHeaders; - } - - private List getShortListOfColumnHeaders() { - List reportLineItemDefinitions = new ArrayList<>(); - reportLineItemDefinitions.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -6)); - reportLineItemDefinitions.add(new TimeIntervalColumnHeader(-5, -1)); - reportLineItemDefinitions.add(new TimeIntervalColumnHeader(0)); - reportLineItemDefinitions.add(new TimeIntervalColumnHeader(1, 5)); - reportLineItemDefinitions.add(new TimeIntervalColumnHeader(6, Integer.MAX_VALUE)); - return reportLineItemDefinitions; - } - - private String reportToString(ClassificationReport report) { - return reportToString(report, null); - } - - private String reportToString(ClassificationReport report, List columnHeaders) { - String formatColumWidth = "| %-7s "; - String formatFirstColumn = "| %-36s %-4s "; - String formatFirstColumnFirstLine = "| %-29s %12s "; - String formatFirstColumnSumLine = "| %-36s %-5s"; - int reportWidth = columnHeaders == null ? 46 : columnHeaders.size() * 10 + 46; - - StringBuilder builder = new StringBuilder(); - builder.append("\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - builder.append(String.format(formatFirstColumnFirstLine, "Classifications", "Total")); - if (columnHeaders != null) { - for (TimeIntervalColumnHeader def : columnHeaders) { - if (def.getLowerAgeLimit() == Integer.MIN_VALUE) { - builder.append(String.format(formatColumWidth, "< " + def.getUpperAgeLimit())); - } else if (def.getUpperAgeLimit() == Integer.MAX_VALUE) { - builder.append(String.format(formatColumWidth, "> " + def.getLowerAgeLimit())); - } else if (def.getLowerAgeLimit() == def.getUpperAgeLimit()) { - if (def.getLowerAgeLimit() == 0) { - builder.append(String.format(formatColumWidth, "today")); - } else { - builder.append(String.format(formatColumWidth, def.getLowerAgeLimit())); - } - } else { - builder.append( - String.format(formatColumWidth, def.getLowerAgeLimit() + ".." + def.getUpperAgeLimit())); - } - } - } - builder.append("|\n"); - - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - - for (String rl : report.rowTitles()) { - builder - .append(String.format(formatFirstColumn, rl, report.getRow(rl).getTotalValue())); - if (columnHeaders != null) { - for (int cell : report.getRow(rl).getCells()) { - builder.append(String.format(formatColumWidth, cell)); - } - } - builder.append("|\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - } - builder.append(String.format(formatFirstColumnSumLine, "Total", report.getSumRow().getTotalValue())); - for (int cell : report.getSumRow().getCells()) { - builder.append(String.format(formatColumWidth, cell)); - } - builder.append("|\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - return builder.toString(); - } - -} +package acceptance.monitoring; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.IntStream; + +import javax.sql.DataSource; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.CustomField; +import pro.taskana.TaskMonitorService; +import pro.taskana.TaskState; +import pro.taskana.TaskanaEngine; +import pro.taskana.TaskanaEngine.ConnectionManagementMode; +import pro.taskana.configuration.TaskanaEngineConfiguration; +import pro.taskana.database.TestDataGenerator; +import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.impl.TaskanaEngineImpl; +import pro.taskana.impl.configuration.DBCleaner; +import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; +import pro.taskana.impl.report.impl.ClassificationReport; +import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; +import pro.taskana.security.JAASRunner; +import pro.taskana.security.WithAccessId; + +/** + * Acceptance test for all "classification report" scenarios. + */ +@RunWith(JAASRunner.class) +public class ProvideClassificationReportAccTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProvideClassificationReportAccTest.class); + protected static TaskanaEngineConfiguration taskanaEngineConfiguration; + protected static TaskanaEngine taskanaEngine; + + @BeforeClass + public static void setupTest() throws Exception { + resetDb(); + } + + public static void resetDb() throws SQLException, IOException { + DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); + DBCleaner cleaner = new DBCleaner(); + cleaner.clearDb(dataSource, true); + dataSource = TaskanaEngineConfigurationTest.getDataSource(); + taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); + taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); + taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); + ((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); + cleaner.clearDb(dataSource, false); + TestDataGenerator testDataGenerator = new TestDataGenerator(); + testDataGenerator.generateMonitoringTestData(dataSource); + } + + @Test(expected = NotAuthorizedException.class) + public void testRoleCheck() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + taskMonitorService.getClassificationReport(null, null, null, null, null, null); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetTotalNumbersOfTasksOfClassificationReport() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + ClassificationReport report = taskMonitorService.getClassificationReport(null, null, null, null, null, null); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + assertEquals(10, report.getRow("L10000").getTotalValue()); + assertEquals(10, report.getRow("L20000").getTotalValue()); + assertEquals(7, report.getRow("L30000").getTotalValue()); + assertEquals(10, report.getRow("L40000").getTotalValue()); + assertEquals(13, report.getRow("L50000").getTotalValue()); + assertEquals(0, report.getRow("L10000").getCells().length); + assertEquals(0, report.getRow("L20000").getCells().length); + assertEquals(0, report.getRow("L30000").getCells().length); + assertEquals(0, report.getRow("L40000").getCells().length); + assertEquals(0, report.getRow("L50000").getCells().length); + assertEquals(50, report.getSumRow().getTotalValue()); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetClassificationReportWithReportLineItemDefinitions() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List reportLineItemDefinitions = getListOfColumnsHeaders(); + + ClassificationReport report = taskMonitorService.getClassificationReport(null, null, null, null, null, null, + reportLineItemDefinitions); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, reportLineItemDefinitions)); + } + + int sumLineCount = IntStream.of(report.getSumRow().getCells()).sum(); + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + assertEquals(10, report.getRow("L10000").getTotalValue()); + assertEquals(10, report.getRow("L20000").getTotalValue()); + assertEquals(7, report.getRow("L30000").getTotalValue()); + assertEquals(10, report.getRow("L40000").getTotalValue()); + assertEquals(13, report.getRow("L50000").getTotalValue()); + + assertEquals(10, report.getSumRow().getCells()[0]); + assertEquals(9, report.getSumRow().getCells()[1]); + assertEquals(11, report.getSumRow().getCells()[2]); + assertEquals(0, report.getSumRow().getCells()[3]); + assertEquals(4, report.getSumRow().getCells()[4]); + assertEquals(0, report.getSumRow().getCells()[5]); + assertEquals(7, report.getSumRow().getCells()[6]); + assertEquals(4, report.getSumRow().getCells()[7]); + assertEquals(5, report.getSumRow().getCells()[8]); + assertEquals(50, report.getSumRow().getTotalValue()); + assertEquals(50, sumLineCount); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfClassificationReport() throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List columnHeaders = getShortListOfColumnHeaders(); + + ClassificationReport report = taskMonitorService.getClassificationReport(null, null, null, null, null, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + int[] row1 = report.getRow("L10000").getCells(); + assertArrayEquals(new int[] {7, 2, 1, 0, 0}, row1); + + int[] row2 = report.getRow("L20000").getCells(); + assertArrayEquals(new int[] {5, 3, 1, 1, 0}, row2); + + int[] row3 = report.getRow("L30000").getCells(); + assertArrayEquals(new int[] {2, 1, 0, 1, 3}, row3); + + int[] row4 = report.getRow("L40000").getCells(); + assertArrayEquals(new int[] {2, 2, 2, 0, 4}, row4); + + int[] row5 = report.getRow("L50000").getCells(); + assertArrayEquals(new int[] {3, 3, 0, 5, 2}, row5); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfClassificationReportNotInWorkingDays() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List reportLineItemDefinitions = getShortListOfColumnHeaders(); + + ClassificationReport report = taskMonitorService.getClassificationReport(null, null, null, null, null, null, + reportLineItemDefinitions, false); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, reportLineItemDefinitions)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + int[] row1 = report.getRow("L10000").getCells(); + assertArrayEquals(new int[] {9, 0, 1, 0, 0}, row1); + + int[] row2 = report.getRow("L20000").getCells(); + assertArrayEquals(new int[] {8, 0, 1, 0, 1}, row2); + + int[] row3 = report.getRow("L30000").getCells(); + assertArrayEquals(new int[] {3, 0, 0, 0, 4}, row3); + + int[] row4 = report.getRow("L40000").getCells(); + assertArrayEquals(new int[] {4, 0, 2, 0, 4}, row4); + + int[] row5 = report.getRow("L50000").getCells(); + assertArrayEquals(new int[] {6, 0, 0, 0, 7}, row5); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfClassificationReportWithWorkbasketFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List columnHeaders = getShortListOfColumnHeaders(); + + ClassificationReport report = taskMonitorService.getClassificationReport(workbasketIds, null, null, null, null, + null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + int[] row1 = report.getRow("L10000").getCells(); + assertArrayEquals(new int[] {6, 0, 0, 0, 0}, row1); + + int[] row2 = report.getRow("L20000").getCells(); + assertArrayEquals(new int[] {2, 0, 0, 0, 0}, row2); + + int[] row3 = report.getRow("L30000").getCells(); + assertArrayEquals(new int[] {2, 1, 0, 1, 1}, row3); + + int[] row4 = report.getRow("L40000").getCells(); + assertArrayEquals(new int[] {1, 0, 1, 0, 1}, row4); + + int[] row5 = report.getRow("L50000").getCells(); + assertArrayEquals(new int[] {2, 2, 0, 0, 0}, row5); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfClassificationReportWithStateFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List states = Collections.singletonList(TaskState.READY); + List columnHeaders = getShortListOfColumnHeaders(); + + ClassificationReport report = taskMonitorService.getClassificationReport(null, states, null, null, null, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + int[] row1 = report.getRow("L10000").getCells(); + assertArrayEquals(new int[] {7, 2, 1, 0, 0}, row1); + + int[] row2 = report.getRow("L20000").getCells(); + assertArrayEquals(new int[] {5, 3, 1, 1, 0}, row2); + + int[] row3 = report.getRow("L30000").getCells(); + assertArrayEquals(new int[] {2, 1, 0, 1, 0}, row3); + + int[] row4 = report.getRow("L40000").getCells(); + assertArrayEquals(new int[] {2, 2, 2, 0, 0}, row4); + + int[] row5 = report.getRow("L50000").getCells(); + assertArrayEquals(new int[] {3, 3, 0, 5, 0}, row5); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfClassificationReportWithCategoryFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List categories = Arrays.asList("AUTOMATIC", "MANUAL"); + List columnHeaders = getShortListOfColumnHeaders(); + + ClassificationReport report = taskMonitorService.getClassificationReport(null, null, categories, null, null, + null, columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(2, report.rowSize()); + + int[] row1 = report.getRow("L30000").getCells(); + assertArrayEquals(new int[] {2, 1, 0, 1, 3}, row1); + + int[] row2 = report.getRow("L40000").getCells(); + assertArrayEquals(new int[] {2, 2, 2, 0, 4}, row2); + + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfClassificationReportWithDomainFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List domains = Collections.singletonList("DOMAIN_A"); + List columnHeaders = getShortListOfColumnHeaders(); + + ClassificationReport report = taskMonitorService.getClassificationReport(null, null, null, domains, null, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + int[] row1 = report.getRow("L10000").getCells(); + assertArrayEquals(new int[] {5, 2, 1, 0, 0}, row1); + + int[] row2 = report.getRow("L20000").getCells(); + assertArrayEquals(new int[] {3, 1, 1, 1, 0}, row2); + + int[] row3 = report.getRow("L30000").getCells(); + assertArrayEquals(new int[] {1, 0, 0, 1, 1}, row3); + + int[] row4 = report.getRow("L40000").getCells(); + assertArrayEquals(new int[] {2, 0, 0, 0, 3}, row4); + + int[] row5 = report.getRow("L50000").getCells(); + assertArrayEquals(new int[] {0, 1, 0, 3, 0}, row5); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfClassificationReportWithCustomFieldValueFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + List columnHeaders = getShortListOfColumnHeaders(); + + ClassificationReport report = taskMonitorService.getClassificationReport(null, null, null, null, customField, + customFieldValues, columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + int[] row1 = report.getRow("L10000").getCells(); + assertArrayEquals(new int[] {4, 0, 0, 0, 0}, row1); + + int[] row2 = report.getRow("L20000").getCells(); + assertArrayEquals(new int[] {4, 1, 1, 1, 0}, row2); + + int[] row3 = report.getRow("L30000").getCells(); + assertArrayEquals(new int[] {1, 0, 0, 1, 1}, row3); + + int[] row4 = report.getRow("L40000").getCells(); + assertArrayEquals(new int[] {1, 1, 2, 0, 2}, row4); + + int[] row5 = report.getRow("L50000").getCells(); + assertArrayEquals(new int[] {1, 2, 0, 2, 0}, row5); + } + + private List getListOfColumnsHeaders() { + List columnHeaders = new ArrayList<>(); + columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); + columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); + columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); + columnHeaders.add(new TimeIntervalColumnHeader(-1)); + columnHeaders.add(new TimeIntervalColumnHeader(0)); + columnHeaders.add(new TimeIntervalColumnHeader(1)); + columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); + columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); + columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); + return columnHeaders; + } + + private List getShortListOfColumnHeaders() { + List reportLineItemDefinitions = new ArrayList<>(); + reportLineItemDefinitions.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -6)); + reportLineItemDefinitions.add(new TimeIntervalColumnHeader(-5, -1)); + reportLineItemDefinitions.add(new TimeIntervalColumnHeader(0)); + reportLineItemDefinitions.add(new TimeIntervalColumnHeader(1, 5)); + reportLineItemDefinitions.add(new TimeIntervalColumnHeader(6, Integer.MAX_VALUE)); + return reportLineItemDefinitions; + } + + private String reportToString(ClassificationReport report) { + return reportToString(report, null); + } + + private String reportToString(ClassificationReport report, List columnHeaders) { + String formatColumWidth = "| %-7s "; + String formatFirstColumn = "| %-36s %-4s "; + String formatFirstColumnFirstLine = "| %-29s %12s "; + String formatFirstColumnSumLine = "| %-36s %-5s"; + int reportWidth = columnHeaders == null ? 46 : columnHeaders.size() * 10 + 46; + + StringBuilder builder = new StringBuilder(); + builder.append("\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + builder.append(String.format(formatFirstColumnFirstLine, "Classifications", "Total")); + if (columnHeaders != null) { + for (TimeIntervalColumnHeader def : columnHeaders) { + if (def.getLowerAgeLimit() == Integer.MIN_VALUE) { + builder.append(String.format(formatColumWidth, "< " + def.getUpperAgeLimit())); + } else if (def.getUpperAgeLimit() == Integer.MAX_VALUE) { + builder.append(String.format(formatColumWidth, "> " + def.getLowerAgeLimit())); + } else if (def.getLowerAgeLimit() == def.getUpperAgeLimit()) { + if (def.getLowerAgeLimit() == 0) { + builder.append(String.format(formatColumWidth, "today")); + } else { + builder.append(String.format(formatColumWidth, def.getLowerAgeLimit())); + } + } else { + builder.append( + String.format(formatColumWidth, def.getLowerAgeLimit() + ".." + def.getUpperAgeLimit())); + } + } + } + builder.append("|\n"); + + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + + for (String rl : report.rowTitles()) { + builder + .append(String.format(formatFirstColumn, rl, report.getRow(rl).getTotalValue())); + if (columnHeaders != null) { + for (int cell : report.getRow(rl).getCells()) { + builder.append(String.format(formatColumWidth, cell)); + } + } + builder.append("|\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + } + builder.append(String.format(formatFirstColumnSumLine, "Total", report.getSumRow().getTotalValue())); + for (int cell : report.getSumRow().getCells()) { + builder.append(String.format(formatColumWidth, cell)); + } + builder.append("|\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + return builder.toString(); + } + +} diff --git a/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideCustomFieldValueReportAccTest.java b/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideCustomFieldValueReportAccTest.java index 993999797..03118fd37 100644 --- a/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideCustomFieldValueReportAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideCustomFieldValueReportAccTest.java @@ -1,474 +1,474 @@ -package acceptance.monitoring; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import javax.sql.DataSource; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.CustomField; -import pro.taskana.TaskMonitorService; -import pro.taskana.TaskState; -import pro.taskana.TaskanaEngine; -import pro.taskana.TaskanaEngine.ConnectionManagementMode; -import pro.taskana.configuration.TaskanaEngineConfiguration; -import pro.taskana.database.TestDataGenerator; -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.exceptions.NotAuthorizedException; -import pro.taskana.impl.configuration.DBCleaner; -import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; -import pro.taskana.impl.report.impl.CustomFieldValueReport; -import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; -import pro.taskana.security.JAASRunner; -import pro.taskana.security.WithAccessId; - -/** - * Acceptance test for all "classification report" scenarios. - */ -@RunWith(JAASRunner.class) -public class ProvideCustomFieldValueReportAccTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(ProvideCustomFieldValueReportAccTest.class); - protected static TaskanaEngineConfiguration taskanaEngineConfiguration; - protected static TaskanaEngine taskanaEngine; - - @BeforeClass - public static void setupTest() throws Exception { - resetDb(); - } - - public static void resetDb() throws SQLException, IOException { - DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, true); - dataSource = TaskanaEngineConfigurationTest.getDataSource(); - taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); - taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); - taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); - taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); - cleaner.clearDb(dataSource, false); - TestDataGenerator testDataGenerator = new TestDataGenerator(); - testDataGenerator.generateMonitoringTestData(dataSource); - } - - @Test(expected = NotAuthorizedException.class) - public void testRoleCheck() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - CustomField customField = CustomField.CUSTOM_1; - - taskMonitorService.getCustomFieldValueReport(null, null, null, null, - customField, null); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetTotalNumbersOfTasksOfCustomFieldValueReportForCustom1() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - CustomField customField = CustomField.CUSTOM_1; - - CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, null, - customField, null); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - assertEquals(25, report.getRow("Geschaeftsstelle A").getTotalValue()); - assertEquals(10, report.getRow("Geschaeftsstelle B").getTotalValue()); - assertEquals(15, report.getRow("Geschaeftsstelle C").getTotalValue()); - assertEquals(0, report.getRow("Geschaeftsstelle A").getCells().length); - assertEquals(0, report.getRow("Geschaeftsstelle B").getCells().length); - assertEquals(0, report.getRow("Geschaeftsstelle C").getCells().length); - - assertEquals(50, report.getSumRow().getTotalValue()); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetTotalNumbersOfTasksOfCustomFieldValueReportForCustom2() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - CustomField customField = CustomField.CUSTOM_2; - - CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, null, - customField, null); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report)); - } - - assertNotNull(report); - assertEquals(2, report.rowSize()); - - assertEquals(21, report.getRow("Vollkasko").getTotalValue()); - assertEquals(29, report.getRow("Teilkasko").getTotalValue()); - - assertEquals(0, report.getRow("Vollkasko").getCells().length); - assertEquals(0, report.getRow("Teilkasko").getCells().length); - - assertEquals(50, report.getSumRow().getTotalValue()); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetCustomFieldValueReportWithReportLineItemDefinitions() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - CustomField customField = CustomField.CUSTOM_1; - List columnHeaders = getListOfColumnHeaders(); - - CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, null, - customField, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - assertEquals(25, report.getRow("Geschaeftsstelle A").getTotalValue()); - assertEquals(10, report.getRow("Geschaeftsstelle B").getTotalValue()); - assertEquals(15, report.getRow("Geschaeftsstelle C").getTotalValue()); - - assertArrayEquals(new int[] {10, 9, 11, 0, 4, 0, 7, 4, 5}, report.getSumRow().getCells()); - - assertEquals(50, report.getSumRow().getTotalValue()); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCustomFieldValueReport() throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - CustomField customField = CustomField.CUSTOM_1; - List columnHeaders = getShortListOfColumnHeaders(); - - CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, null, - customField, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); - assertArrayEquals(new int[] {11, 4, 3, 4, 3}, row1); - - int[] row2 = report.getRow("Geschaeftsstelle B").getCells(); - assertArrayEquals(new int[] {5, 3, 0, 2, 0}, row2); - - int[] row3 = report.getRow("Geschaeftsstelle C").getCells(); - assertArrayEquals(new int[] {3, 4, 1, 1, 6}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCustomFieldValueReportNotInWorkingDays() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - CustomField customField = CustomField.CUSTOM_1; - List columnHeaders = getShortListOfColumnHeaders(); - - CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, null, - customField, null, - columnHeaders, false); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); - assertArrayEquals(new int[] {15, 0, 3, 0, 7}, row1); - - int[] row2 = report.getRow("Geschaeftsstelle B").getCells(); - assertArrayEquals(new int[] {8, 0, 0, 0, 2}, row2); - - int[] row3 = report.getRow("Geschaeftsstelle C").getCells(); - assertArrayEquals(new int[] {7, 0, 1, 0, 7}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCustomFieldValueReportWithWorkbasketFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - CustomField customField = CustomField.CUSTOM_1; - List columnHeaders = getShortListOfColumnHeaders(); - - CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(workbasketIds, null, null, null, - customField, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); - assertArrayEquals(new int[] {6, 1, 1, 1, 1}, row1); - - int[] row2 = report.getRow("Geschaeftsstelle B").getCells(); - assertArrayEquals(new int[] {4, 1, 0, 0, 0}, row2); - - int[] row3 = report.getRow("Geschaeftsstelle C").getCells(); - assertArrayEquals(new int[] {3, 1, 0, 0, 1}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCustomFieldValueReportWithStateFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List states = Collections.singletonList(TaskState.READY); - CustomField customField = CustomField.CUSTOM_1; - List columnHeaders = getShortListOfColumnHeaders(); - - CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, states, null, null, - customField, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); - assertArrayEquals(new int[] {11, 4, 3, 4, 0}, row1); - - int[] row2 = report.getRow("Geschaeftsstelle B").getCells(); - assertArrayEquals(new int[] {5, 3, 0, 2, 0}, row2); - - int[] row3 = report.getRow("Geschaeftsstelle C").getCells(); - assertArrayEquals(new int[] {3, 4, 1, 1, 0}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCustomFieldValueReportWithCategoryFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List categories = Arrays.asList("AUTOMATIC", "MANUAL"); - CustomField customField = CustomField.CUSTOM_1; - - List columnHeaders = getShortListOfColumnHeaders(); - - CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, categories, null, - customField, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); - assertArrayEquals(new int[] {2, 1, 2, 1, 3}, row1); - - int[] row2 = report.getRow("Geschaeftsstelle B").getCells(); - assertArrayEquals(new int[] {2, 0, 0, 0, 0}, row2); - - int[] row3 = report.getRow("Geschaeftsstelle C").getCells(); - assertArrayEquals(new int[] {0, 2, 0, 0, 4}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCustomFieldValueReportWithDomainFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List domains = Collections.singletonList("DOMAIN_A"); - CustomField customField = CustomField.CUSTOM_1; - List columnHeaders = getShortListOfColumnHeaders(); - - CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, domains, - customField, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); - assertArrayEquals(new int[] {8, 1, 1, 4, 1}, row1); - - int[] row2 = report.getRow("Geschaeftsstelle B").getCells(); - assertArrayEquals(new int[] {2, 2, 0, 1, 0}, row2); - - int[] row3 = report.getRow("Geschaeftsstelle C").getCells(); - assertArrayEquals(new int[] {1, 1, 1, 0, 3}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfCustomFieldValueReportWithCustomFieldValueFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - List columnHeaders = getShortListOfColumnHeaders(); - - CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, null, - customField, - customFieldValues, columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(1, report.rowSize()); - - int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); - assertArrayEquals(new int[] {11, 4, 3, 4, 3}, row1); - } - - private List getListOfColumnHeaders() { - List columnHeaders = new ArrayList<>(); - columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); - columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); - columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); - columnHeaders.add(new TimeIntervalColumnHeader(-1)); - columnHeaders.add(new TimeIntervalColumnHeader(0)); - columnHeaders.add(new TimeIntervalColumnHeader(1)); - columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); - columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); - columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); - return columnHeaders; - } - - private List getShortListOfColumnHeaders() { - List columnHeaders = new ArrayList<>(); - columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -6)); - columnHeaders.add(new TimeIntervalColumnHeader(-5, -1)); - columnHeaders.add(new TimeIntervalColumnHeader(0)); - columnHeaders.add(new TimeIntervalColumnHeader(1, 5)); - columnHeaders.add(new TimeIntervalColumnHeader(6, Integer.MAX_VALUE)); - return columnHeaders; - } - - private String reportToString(CustomFieldValueReport report) { - return reportToString(report, null); - } - - private String reportToString(CustomFieldValueReport report, List columnHeaders) { - String formatColumWidth = "| %-7s "; - String formatFirstColumn = "| %-36s %-4s "; - String formatFirstColumnFirstLine = "| %-29s %12s "; - String formatFirstColumnSumLine = "| %-36s %-5s"; - int reportWidth = columnHeaders == null ? 46 : columnHeaders.size() * 10 + 46; - - StringBuilder builder = new StringBuilder(); - builder.append("\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - builder.append(String.format(formatFirstColumnFirstLine, "Custom field values", "Total")); - if (columnHeaders != null) { - for (TimeIntervalColumnHeader def : columnHeaders) { - if (def.getLowerAgeLimit() == Integer.MIN_VALUE) { - builder.append(String.format(formatColumWidth, "< " + def.getUpperAgeLimit())); - } else if (def.getUpperAgeLimit() == Integer.MAX_VALUE) { - builder.append(String.format(formatColumWidth, "> " + def.getLowerAgeLimit())); - } else if (def.getLowerAgeLimit() == def.getUpperAgeLimit()) { - if (def.getLowerAgeLimit() == 0) { - builder.append(String.format(formatColumWidth, "today")); - } else { - builder.append(String.format(formatColumWidth, def.getLowerAgeLimit())); - } - } else { - builder.append( - String.format(formatColumWidth, def.getLowerAgeLimit() + ".." + def.getUpperAgeLimit())); - } - } - } - builder.append("|\n"); - - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - - for (String rl : report.rowTitles()) { - builder - .append(String.format(formatFirstColumn, rl, report.getRow(rl).getTotalValue())); - if (columnHeaders != null) { - for (int cell : report.getRow(rl).getCells()) { - builder.append(String.format(formatColumWidth, cell)); - } - } - builder.append("|\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - } - builder.append(String.format(formatFirstColumnSumLine, "Total", report.getSumRow().getTotalValue())); - for (int cell : report.getSumRow().getCells()) { - builder.append(String.format(formatColumWidth, cell)); - } - builder.append("|\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - return builder.toString(); - } - -} +package acceptance.monitoring; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.sql.DataSource; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.CustomField; +import pro.taskana.TaskMonitorService; +import pro.taskana.TaskState; +import pro.taskana.TaskanaEngine; +import pro.taskana.TaskanaEngine.ConnectionManagementMode; +import pro.taskana.configuration.TaskanaEngineConfiguration; +import pro.taskana.database.TestDataGenerator; +import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.impl.configuration.DBCleaner; +import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; +import pro.taskana.impl.report.impl.CustomFieldValueReport; +import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; +import pro.taskana.security.JAASRunner; +import pro.taskana.security.WithAccessId; + +/** + * Acceptance test for all "classification report" scenarios. + */ +@RunWith(JAASRunner.class) +public class ProvideCustomFieldValueReportAccTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProvideCustomFieldValueReportAccTest.class); + protected static TaskanaEngineConfiguration taskanaEngineConfiguration; + protected static TaskanaEngine taskanaEngine; + + @BeforeClass + public static void setupTest() throws Exception { + resetDb(); + } + + public static void resetDb() throws SQLException, IOException { + DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); + DBCleaner cleaner = new DBCleaner(); + cleaner.clearDb(dataSource, true); + dataSource = TaskanaEngineConfigurationTest.getDataSource(); + taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); + taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); + taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); + taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); + cleaner.clearDb(dataSource, false); + TestDataGenerator testDataGenerator = new TestDataGenerator(); + testDataGenerator.generateMonitoringTestData(dataSource); + } + + @Test(expected = NotAuthorizedException.class) + public void testRoleCheck() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + CustomField customField = CustomField.CUSTOM_1; + + taskMonitorService.getCustomFieldValueReport(null, null, null, null, + customField, null); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetTotalNumbersOfTasksOfCustomFieldValueReportForCustom1() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + CustomField customField = CustomField.CUSTOM_1; + + CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, null, + customField, null); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + assertEquals(25, report.getRow("Geschaeftsstelle A").getTotalValue()); + assertEquals(10, report.getRow("Geschaeftsstelle B").getTotalValue()); + assertEquals(15, report.getRow("Geschaeftsstelle C").getTotalValue()); + assertEquals(0, report.getRow("Geschaeftsstelle A").getCells().length); + assertEquals(0, report.getRow("Geschaeftsstelle B").getCells().length); + assertEquals(0, report.getRow("Geschaeftsstelle C").getCells().length); + + assertEquals(50, report.getSumRow().getTotalValue()); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetTotalNumbersOfTasksOfCustomFieldValueReportForCustom2() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + CustomField customField = CustomField.CUSTOM_2; + + CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, null, + customField, null); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report)); + } + + assertNotNull(report); + assertEquals(2, report.rowSize()); + + assertEquals(21, report.getRow("Vollkasko").getTotalValue()); + assertEquals(29, report.getRow("Teilkasko").getTotalValue()); + + assertEquals(0, report.getRow("Vollkasko").getCells().length); + assertEquals(0, report.getRow("Teilkasko").getCells().length); + + assertEquals(50, report.getSumRow().getTotalValue()); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetCustomFieldValueReportWithReportLineItemDefinitions() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + CustomField customField = CustomField.CUSTOM_1; + List columnHeaders = getListOfColumnHeaders(); + + CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, null, + customField, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + assertEquals(25, report.getRow("Geschaeftsstelle A").getTotalValue()); + assertEquals(10, report.getRow("Geschaeftsstelle B").getTotalValue()); + assertEquals(15, report.getRow("Geschaeftsstelle C").getTotalValue()); + + assertArrayEquals(new int[] {10, 9, 11, 0, 4, 0, 7, 4, 5}, report.getSumRow().getCells()); + + assertEquals(50, report.getSumRow().getTotalValue()); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCustomFieldValueReport() throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + CustomField customField = CustomField.CUSTOM_1; + List columnHeaders = getShortListOfColumnHeaders(); + + CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, null, + customField, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); + assertArrayEquals(new int[] {11, 4, 3, 4, 3}, row1); + + int[] row2 = report.getRow("Geschaeftsstelle B").getCells(); + assertArrayEquals(new int[] {5, 3, 0, 2, 0}, row2); + + int[] row3 = report.getRow("Geschaeftsstelle C").getCells(); + assertArrayEquals(new int[] {3, 4, 1, 1, 6}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCustomFieldValueReportNotInWorkingDays() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + CustomField customField = CustomField.CUSTOM_1; + List columnHeaders = getShortListOfColumnHeaders(); + + CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, null, + customField, null, + columnHeaders, false); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); + assertArrayEquals(new int[] {15, 0, 3, 0, 7}, row1); + + int[] row2 = report.getRow("Geschaeftsstelle B").getCells(); + assertArrayEquals(new int[] {8, 0, 0, 0, 2}, row2); + + int[] row3 = report.getRow("Geschaeftsstelle C").getCells(); + assertArrayEquals(new int[] {7, 0, 1, 0, 7}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCustomFieldValueReportWithWorkbasketFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + CustomField customField = CustomField.CUSTOM_1; + List columnHeaders = getShortListOfColumnHeaders(); + + CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(workbasketIds, null, null, null, + customField, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); + assertArrayEquals(new int[] {6, 1, 1, 1, 1}, row1); + + int[] row2 = report.getRow("Geschaeftsstelle B").getCells(); + assertArrayEquals(new int[] {4, 1, 0, 0, 0}, row2); + + int[] row3 = report.getRow("Geschaeftsstelle C").getCells(); + assertArrayEquals(new int[] {3, 1, 0, 0, 1}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCustomFieldValueReportWithStateFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List states = Collections.singletonList(TaskState.READY); + CustomField customField = CustomField.CUSTOM_1; + List columnHeaders = getShortListOfColumnHeaders(); + + CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, states, null, null, + customField, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); + assertArrayEquals(new int[] {11, 4, 3, 4, 0}, row1); + + int[] row2 = report.getRow("Geschaeftsstelle B").getCells(); + assertArrayEquals(new int[] {5, 3, 0, 2, 0}, row2); + + int[] row3 = report.getRow("Geschaeftsstelle C").getCells(); + assertArrayEquals(new int[] {3, 4, 1, 1, 0}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCustomFieldValueReportWithCategoryFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List categories = Arrays.asList("AUTOMATIC", "MANUAL"); + CustomField customField = CustomField.CUSTOM_1; + + List columnHeaders = getShortListOfColumnHeaders(); + + CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, categories, null, + customField, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); + assertArrayEquals(new int[] {2, 1, 2, 1, 3}, row1); + + int[] row2 = report.getRow("Geschaeftsstelle B").getCells(); + assertArrayEquals(new int[] {2, 0, 0, 0, 0}, row2); + + int[] row3 = report.getRow("Geschaeftsstelle C").getCells(); + assertArrayEquals(new int[] {0, 2, 0, 0, 4}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCustomFieldValueReportWithDomainFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List domains = Collections.singletonList("DOMAIN_A"); + CustomField customField = CustomField.CUSTOM_1; + List columnHeaders = getShortListOfColumnHeaders(); + + CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, domains, + customField, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); + assertArrayEquals(new int[] {8, 1, 1, 4, 1}, row1); + + int[] row2 = report.getRow("Geschaeftsstelle B").getCells(); + assertArrayEquals(new int[] {2, 2, 0, 1, 0}, row2); + + int[] row3 = report.getRow("Geschaeftsstelle C").getCells(); + assertArrayEquals(new int[] {1, 1, 1, 0, 3}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfCustomFieldValueReportWithCustomFieldValueFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + List columnHeaders = getShortListOfColumnHeaders(); + + CustomFieldValueReport report = taskMonitorService.getCustomFieldValueReport(null, null, null, null, + customField, + customFieldValues, columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(1, report.rowSize()); + + int[] row1 = report.getRow("Geschaeftsstelle A").getCells(); + assertArrayEquals(new int[] {11, 4, 3, 4, 3}, row1); + } + + private List getListOfColumnHeaders() { + List columnHeaders = new ArrayList<>(); + columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); + columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); + columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); + columnHeaders.add(new TimeIntervalColumnHeader(-1)); + columnHeaders.add(new TimeIntervalColumnHeader(0)); + columnHeaders.add(new TimeIntervalColumnHeader(1)); + columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); + columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); + columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); + return columnHeaders; + } + + private List getShortListOfColumnHeaders() { + List columnHeaders = new ArrayList<>(); + columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -6)); + columnHeaders.add(new TimeIntervalColumnHeader(-5, -1)); + columnHeaders.add(new TimeIntervalColumnHeader(0)); + columnHeaders.add(new TimeIntervalColumnHeader(1, 5)); + columnHeaders.add(new TimeIntervalColumnHeader(6, Integer.MAX_VALUE)); + return columnHeaders; + } + + private String reportToString(CustomFieldValueReport report) { + return reportToString(report, null); + } + + private String reportToString(CustomFieldValueReport report, List columnHeaders) { + String formatColumWidth = "| %-7s "; + String formatFirstColumn = "| %-36s %-4s "; + String formatFirstColumnFirstLine = "| %-29s %12s "; + String formatFirstColumnSumLine = "| %-36s %-5s"; + int reportWidth = columnHeaders == null ? 46 : columnHeaders.size() * 10 + 46; + + StringBuilder builder = new StringBuilder(); + builder.append("\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + builder.append(String.format(formatFirstColumnFirstLine, "Custom field values", "Total")); + if (columnHeaders != null) { + for (TimeIntervalColumnHeader def : columnHeaders) { + if (def.getLowerAgeLimit() == Integer.MIN_VALUE) { + builder.append(String.format(formatColumWidth, "< " + def.getUpperAgeLimit())); + } else if (def.getUpperAgeLimit() == Integer.MAX_VALUE) { + builder.append(String.format(formatColumWidth, "> " + def.getLowerAgeLimit())); + } else if (def.getLowerAgeLimit() == def.getUpperAgeLimit()) { + if (def.getLowerAgeLimit() == 0) { + builder.append(String.format(formatColumWidth, "today")); + } else { + builder.append(String.format(formatColumWidth, def.getLowerAgeLimit())); + } + } else { + builder.append( + String.format(formatColumWidth, def.getLowerAgeLimit() + ".." + def.getUpperAgeLimit())); + } + } + } + builder.append("|\n"); + + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + + for (String rl : report.rowTitles()) { + builder + .append(String.format(formatFirstColumn, rl, report.getRow(rl).getTotalValue())); + if (columnHeaders != null) { + for (int cell : report.getRow(rl).getCells()) { + builder.append(String.format(formatColumWidth, cell)); + } + } + builder.append("|\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + } + builder.append(String.format(formatFirstColumnSumLine, "Total", report.getSumRow().getTotalValue())); + for (int cell : report.getSumRow().getCells()) { + builder.append(String.format(formatColumWidth, cell)); + } + builder.append("|\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + return builder.toString(); + } + +} diff --git a/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideDetailedClassificationReportAccTest.java b/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideDetailedClassificationReportAccTest.java index d8dba1e23..4d7f5dc64 100644 --- a/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideDetailedClassificationReportAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideDetailedClassificationReportAccTest.java @@ -1,671 +1,671 @@ -package acceptance.monitoring; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import javax.sql.DataSource; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.CustomField; -import pro.taskana.TaskMonitorService; -import pro.taskana.TaskState; -import pro.taskana.TaskanaEngine; -import pro.taskana.TaskanaEngine.ConnectionManagementMode; -import pro.taskana.configuration.TaskanaEngineConfiguration; -import pro.taskana.database.TestDataGenerator; -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.exceptions.NotAuthorizedException; -import pro.taskana.impl.TaskanaEngineImpl; -import pro.taskana.impl.configuration.DBCleaner; -import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; -import pro.taskana.impl.report.ReportRow; -import pro.taskana.impl.report.impl.DetailedClassificationReport; -import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; -import pro.taskana.impl.report.impl.DetailedReportRow; -import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; -import pro.taskana.security.JAASRunner; -import pro.taskana.security.WithAccessId; - -/** - * Acceptance test for all "detailed classification report" scenarios. - */ -@RunWith(JAASRunner.class) -public class ProvideDetailedClassificationReportAccTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(ProvideDetailedClassificationReportAccTest.class); - protected static TaskanaEngineConfiguration taskanaEngineConfiguration; - protected static TaskanaEngine taskanaEngine; - - @BeforeClass - public static void setupTest() throws Exception { - resetDb(); - } - - public static void resetDb() throws SQLException, IOException { - DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, true); - dataSource = TaskanaEngineConfigurationTest.getDataSource(); - taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); - taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); - taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); - ((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); - cleaner.clearDb(dataSource, false); - TestDataGenerator testDataGenerator = new TestDataGenerator(); - testDataGenerator.generateMonitoringTestData(dataSource); - } - - @Test(expected = NotAuthorizedException.class) - public void testRoleCheck() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - taskMonitorService.getDetailedClassificationReport(null, null, null, null, - null, null); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetTotalNumbersOfTasksOfDetailedClassificationReport() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, null, null, - null, null); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - DetailedReportRow row1 = report.getRow("L10000"); - assertEquals(10, row1.getTotalValue()); - assertEquals(3, row1.getDetailRows().get("L11000").getTotalValue()); - assertEquals(7, row1.getDetailRows().get("N/A").getTotalValue()); - assertEquals(0, row1.getCells().length); - assertEquals(2, row1.getDetailRows().size()); - - DetailedReportRow row2 = report.getRow("L20000"); - assertEquals(10, row2.getTotalValue()); - assertEquals(4, row2.getDetailRows().get("L22000").getTotalValue()); - assertEquals(6, row2.getDetailRows().get("N/A").getTotalValue()); - assertEquals(0, row2.getCells().length); - assertEquals(2, row2.getDetailRows().size()); - - DetailedReportRow row3 = report.getRow("L30000"); - assertEquals(7, row3.getTotalValue()); - assertEquals(3, row3.getDetailRows().get("L33000").getTotalValue()); - assertEquals(1, row3.getDetailRows().get("L99000").getTotalValue()); - assertEquals(3, row3.getDetailRows().get("N/A").getTotalValue()); - assertEquals(0, row3.getCells().length); - assertEquals(3, row3.getDetailRows().size()); - - DetailedReportRow row4 = report.getRow("L40000"); - assertEquals(10, row4.getTotalValue()); - assertEquals(10, row4.getDetailRows().get("N/A").getTotalValue()); - assertEquals(0, row4.getCells().length); - assertEquals(1, row4.getDetailRows().size()); - - DetailedReportRow row5 = report.getRow("L50000"); - assertEquals(13, row5.getTotalValue()); - assertEquals(13, row5.getDetailRows().get("N/A").getTotalValue()); - assertEquals(0, row5.getCells().length); - assertEquals(1, row5.getDetailRows().size()); - - assertEquals(50, report.getSumRow().getTotalValue()); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetDetailedClassificationReportWithReportLineItemDefinitions() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List columnHeaders = getListOfColumnHeaders(); - - DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, null, null, - null, null, columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - assertEquals(10, report.getRow("L10000").getTotalValue()); - assertEquals(10, report.getRow("L20000").getTotalValue()); - assertEquals(7, report.getRow("L30000").getTotalValue()); - assertEquals(10, report.getRow("L40000").getTotalValue()); - assertEquals(13, report.getRow("L50000").getTotalValue()); - - int[] sumRow = report.getSumRow().getCells(); - assertArrayEquals(new int[] {10, 9, 11, 0, 4, 0, 7, 4, 5}, sumRow); - assertEquals(50, report.getSumRow().getTotalValue()); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfDetailedClassificationReport() throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List reportLineItemDefinitions = getShortListOfColumnHeaders(); - - DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, null, null, - null, null, reportLineItemDefinitions); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, reportLineItemDefinitions)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - DetailedReportRow line1 = report.getRow("L10000"); - assertArrayEquals(new int[] {7, 2, 1, 0, 0}, line1.getCells()); - - ReportRow detailedLine1 = line1.getDetailRows().get("L11000"); - assertArrayEquals(new int[] {2, 0, 1, 0, 0}, detailedLine1.getCells()); - - ReportRow detailedLineNoAttachment1 = line1.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {5, 2, 0, 0, 0}, detailedLineNoAttachment1.getCells()); - - DetailedReportRow line2 = report.getRow("L20000"); - assertArrayEquals(new int[] {5, 3, 1, 1, 0}, line2.getCells()); - - ReportRow detailedLine2 = line2.getDetailRows().get("L22000"); - assertArrayEquals(new int[] {1, 1, 1, 1, 0}, detailedLine2.getCells()); - - ReportRow detailedLineNoAttachment2 = line2.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {4, 2, 0, 0, 0}, detailedLineNoAttachment2.getCells()); - - DetailedReportRow line3 = report.getRow("L30000"); - assertArrayEquals(new int[] {2, 1, 0, 1, 3}, line3.getCells()); - - ReportRow detailedLine3a = line3.getDetailRows().get("L33000"); - assertArrayEquals(new int[] {0, 1, 0, 1, 1}, detailedLine3a.getCells()); - - ReportRow detailedLine3b = line3.getDetailRows().get("L99000"); - assertArrayEquals(new int[] {0, 0, 0, 0, 1}, detailedLine3b.getCells()); - - ReportRow detailedLineNoAttachment3 = line3.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {2, 0, 0, 0, 1}, detailedLineNoAttachment3.getCells()); - - DetailedReportRow line4 = report.getRow("L40000"); - assertArrayEquals(new int[] {2, 2, 2, 0, 4}, line4.getCells()); - - ReportRow detailedLineNoAttachment4 = line4.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {2, 2, 2, 0, 4}, detailedLineNoAttachment4.getCells()); - - DetailedReportRow line5 = report.getRow("L50000"); - assertArrayEquals(new int[] {3, 3, 0, 5, 2}, line5.getCells()); - - ReportRow detailedLineNoAttachment5 = line5.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {3, 3, 0, 5, 2}, detailedLineNoAttachment5.getCells()); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfDetailedClassificationReportWithWorkbasketFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List reportLineItemDefinitions = getShortListOfColumnHeaders(); - - DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(workbasketIds, null, - null, null, null, null, reportLineItemDefinitions); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, reportLineItemDefinitions)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - DetailedReportRow line1 = report.getRow("L10000"); - assertArrayEquals(new int[] {6, 0, 0, 0, 0}, line1.getCells()); - - ReportRow detailedLine1 = line1.getDetailRows().get("L11000"); - assertArrayEquals(new int[] {2, 0, 0, 0, 0}, detailedLine1.getCells()); - - ReportRow detailedLineNoAttachment1 = line1.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {4, 0, 0, 0, 0}, detailedLineNoAttachment1.getCells()); - - DetailedReportRow line2 = report.getRow("L20000"); - assertArrayEquals(new int[] {2, 0, 0, 0, 0}, line2.getCells()); - - ReportRow detailedLine2 = line2.getDetailRows().get("L22000"); - assertArrayEquals(new int[] {1, 0, 0, 0, 0}, detailedLine2.getCells()); - - ReportRow detailedLineNoAttachment2 = line2.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {1, 0, 0, 0, 0}, detailedLineNoAttachment2.getCells()); - - DetailedReportRow line3 = report.getRow("L30000"); - assertArrayEquals(new int[] {2, 1, 0, 1, 1}, line3.getCells()); - - ReportRow detailedLine3a = line3.getDetailRows().get("L33000"); - assertArrayEquals(new int[] {0, 1, 0, 1, 1}, detailedLine3a.getCells()); - - ReportRow detailedLineNoAttachment3 = line3.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {2, 0, 0, 0, 0}, detailedLineNoAttachment3.getCells()); - - DetailedReportRow line4 = report.getRow("L40000"); - assertArrayEquals(new int[] {1, 0, 1, 0, 1}, line4.getCells()); - - ReportRow detailedLineNoAttachment4 = line4.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {1, 0, 1, 0, 1}, detailedLineNoAttachment4.getCells()); - - DetailedReportRow line5 = report.getRow("L50000"); - assertArrayEquals(new int[] {2, 2, 0, 0, 0}, line5.getCells()); - - ReportRow detailedLineNoAttachment5 = line5.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {2, 2, 0, 0, 0}, detailedLineNoAttachment5.getCells()); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfDetailedClassificationReportWithStateFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List states = Collections.singletonList(TaskState.READY); - List columnHeaders = getShortListOfColumnHeaders(); - - DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, states, null, - null, null, null, columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - DetailedReportRow line1 = report.getRow("L10000"); - assertArrayEquals(new int[] {7, 2, 1, 0, 0}, line1.getCells()); - - ReportRow detailedLine1 = line1.getDetailRows().get("L11000"); - assertArrayEquals(new int[] {2, 0, 1, 0, 0}, detailedLine1.getCells()); - - ReportRow detailedLineNoAttachment1 = line1.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {5, 2, 0, 0, 0}, detailedLineNoAttachment1.getCells()); - - DetailedReportRow line2 = report.getRow("L20000"); - assertArrayEquals(new int[] {5, 3, 1, 1, 0}, line2.getCells()); - - ReportRow detailedLine2 = line2.getDetailRows().get("L22000"); - assertArrayEquals(new int[] {1, 1, 1, 1, 0}, detailedLine2.getCells()); - - ReportRow detailedLineNoAttachment2 = line2.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {4, 2, 0, 0, 0}, detailedLineNoAttachment2.getCells()); - - DetailedReportRow line3 = report.getRow("L30000"); - assertArrayEquals(new int[] {2, 1, 0, 1, 0}, line3.getCells()); - - ReportRow detailedLine3a = line3.getDetailRows().get("L33000"); - assertArrayEquals(new int[] {0, 1, 0, 1, 0}, detailedLine3a.getCells()); - - ReportRow detailedLineNoAttachment3 = line3.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {2, 0, 0, 0, 0}, detailedLineNoAttachment3.getCells()); - - DetailedReportRow line4 = report.getRow("L40000"); - assertArrayEquals(new int[] {2, 2, 2, 0, 0}, line4.getCells()); - - ReportRow detailedLineNoAttachment4 = line4.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {2, 2, 2, 0, 0}, detailedLineNoAttachment4.getCells()); - - DetailedReportRow line5 = report.getRow("L50000"); - assertArrayEquals(new int[] {3, 3, 0, 5, 0}, line5.getCells()); - - ReportRow detailedLineNoAttachment5 = line5.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {3, 3, 0, 5, 0}, detailedLineNoAttachment5.getCells()); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfDetailedClassificationReportNotInWorkingDays() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List columnHeaders = getShortListOfColumnHeaders(); - - DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, null, null, - null, null, columnHeaders, false); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - DetailedReportRow line1 = report.getRow("L10000"); - assertArrayEquals(new int[] {9, 0, 1, 0, 0}, line1.getCells()); - - ReportRow detailedLine1 = line1.getDetailRows().get("L11000"); - assertArrayEquals(new int[] {2, 0, 1, 0, 0}, detailedLine1.getCells()); - - ReportRow detailedLineNoAttachment1 = line1.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {7, 0, 0, 0, 0}, detailedLineNoAttachment1.getCells()); - - DetailedReportRow line2 = report.getRow("L20000"); - assertArrayEquals(new int[] {8, 0, 1, 0, 1}, line2.getCells()); - - ReportRow detailedLine2 = line2.getDetailRows().get("L22000"); - assertArrayEquals(new int[] {2, 0, 1, 0, 1}, detailedLine2.getCells()); - - ReportRow detailedLineNoAttachment2 = line2.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {6, 0, 0, 0, 0}, detailedLineNoAttachment2.getCells()); - - DetailedReportRow line3 = report.getRow("L30000"); - assertArrayEquals(new int[] {3, 0, 0, 0, 4}, line3.getCells()); - - ReportRow detailedLine3a = line3.getDetailRows().get("L33000"); - assertArrayEquals(new int[] {1, 0, 0, 0, 2}, detailedLine3a.getCells()); - - ReportRow detailedLine3b = line3.getDetailRows().get("L99000"); - assertArrayEquals(new int[] {0, 0, 0, 0, 1}, detailedLine3b.getCells()); - - ReportRow detailedLineNoAttachment3 = line3.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {2, 0, 0, 0, 1}, detailedLineNoAttachment3.getCells()); - - DetailedReportRow line4 = report.getRow("L40000"); - assertArrayEquals(new int[] {4, 0, 2, 0, 4}, line4.getCells()); - - ReportRow detailedLineNoAttachment4 = line4.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {4, 0, 2, 0, 4}, detailedLineNoAttachment4.getCells()); - - DetailedReportRow line5 = report.getRow("L50000"); - assertArrayEquals(new int[] {6, 0, 0, 0, 7}, line5.getCells()); - - ReportRow detailedLineNoAttachment5 = line5.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {6, 0, 0, 0, 7}, detailedLineNoAttachment5.getCells()); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfDetailedClassificationReportWithCategoryFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List categories = Arrays.asList("AUTOMATIC", "MANUAL"); - List columnHeaders = getShortListOfColumnHeaders(); - - DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, categories, - null, null, null, columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(2, report.rowSize()); - - DetailedReportRow line1 = report.getRow("L30000"); - assertArrayEquals(new int[] {2, 1, 0, 1, 3}, line1.getCells()); - - ReportRow detailedLine1a = line1.getDetailRows().get("L33000"); - assertArrayEquals(new int[] {0, 1, 0, 1, 1}, detailedLine1a.getCells()); - - ReportRow detailedLine1b = line1.getDetailRows().get("L99000"); - assertArrayEquals(new int[] {0, 0, 0, 0, 1}, detailedLine1b.getCells()); - - ReportRow detailedLine1WithoutAttachment = line1.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {2, 0, 0, 0, 1}, detailedLine1WithoutAttachment.getCells()); - - DetailedReportRow line2 = report.getRow("L40000"); - assertArrayEquals(new int[] {2, 2, 2, 0, 4}, line2.getCells()); - - ReportRow detailedLine2WithoutAttachment = line2.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {2, 2, 2, 0, 4}, detailedLine2WithoutAttachment.getCells()); - - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfDetailedClassificationReportWithDomainFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List domains = Collections.singletonList("DOMAIN_A"); - List columnHeaders = getShortListOfColumnHeaders(); - - DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, null, - domains, null, null, columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - DetailedReportRow line1 = report.getRow("L10000"); - assertArrayEquals(new int[] {5, 2, 1, 0, 0}, line1.getCells()); - - ReportRow detailedLine1 = line1.getDetailRows().get("L11000"); - assertArrayEquals(new int[] {1, 0, 1, 0, 0}, detailedLine1.getCells()); - - ReportRow detailedLineNoAttachment1 = line1.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {4, 2, 0, 0, 0}, detailedLineNoAttachment1.getCells()); - - DetailedReportRow line2 = report.getRow("L20000"); - assertArrayEquals(new int[] {3, 1, 1, 1, 0}, line2.getCells()); - - ReportRow detailedLine2 = line2.getDetailRows().get("L22000"); - assertArrayEquals(new int[] {1, 0, 1, 1, 0}, detailedLine2.getCells()); - - ReportRow detailedLineNoAttachment2 = line2.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {2, 1, 0, 0, 0}, detailedLineNoAttachment2.getCells()); - - DetailedReportRow line3 = report.getRow("L30000"); - assertArrayEquals(new int[] {1, 0, 0, 1, 1}, line3.getCells()); - - ReportRow detailedLine3 = line3.getDetailRows().get("L33000"); - assertArrayEquals(new int[] {0, 0, 0, 1, 1}, detailedLine3.getCells()); - - ReportRow detailedLineNoAttachment3 = line3.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {1, 0, 0, 0, 0}, detailedLineNoAttachment3.getCells()); - - DetailedReportRow line4 = report.getRow("L40000"); - assertArrayEquals(new int[] {2, 0, 0, 0, 3}, line4.getCells()); - - ReportRow detailedLineNoAttachment4 = line4.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {2, 0, 0, 0, 3}, detailedLineNoAttachment4.getCells()); - - DetailedReportRow line5 = report.getRow("L50000"); - assertArrayEquals(new int[] {0, 1, 0, 3, 0}, line5.getCells()); - - ReportRow detailedLineNoAttachment5 = line5.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {0, 1, 0, 3, 0}, detailedLineNoAttachment5.getCells()); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfDetailedClassificationReportWithCustomFieldValueFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - List columnHeaders = getShortListOfColumnHeaders(); - - DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, - null, null, customField, customFieldValues, columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(5, report.rowSize()); - - DetailedReportRow line1 = report.getRow("L10000"); - assertArrayEquals(new int[] {4, 0, 0, 0, 0}, line1.getCells()); - - ReportRow detailedLine1 = line1.getDetailRows().get("L11000"); - assertArrayEquals(new int[] {1, 0, 0, 0, 0}, detailedLine1.getCells()); - - ReportRow detailedLineNoAttachment1 = line1.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {3, 0, 0, 0, 0}, detailedLineNoAttachment1.getCells()); - - DetailedReportRow line2 = report.getRow("L20000"); - assertArrayEquals(new int[] {4, 1, 1, 1, 0}, line2.getCells()); - - ReportRow detailedLine2 = line2.getDetailRows().get("L22000"); - assertArrayEquals(new int[] {1, 1, 1, 1, 0}, detailedLine2.getCells()); - - ReportRow detailedLineNoAttachment2 = line2.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {3, 0, 0, 0, 0}, detailedLineNoAttachment2.getCells()); - - DetailedReportRow line3 = report.getRow("L30000"); - assertArrayEquals(new int[] {1, 0, 0, 1, 1}, line3.getCells()); - - ReportRow detailedLine3a = line3.getDetailRows().get("L33000"); - assertArrayEquals(new int[] {0, 0, 0, 1, 0}, detailedLine3a.getCells()); - - ReportRow detailedLineNoAttachment3 = line3.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {1, 0, 0, 0, 1}, detailedLineNoAttachment3.getCells()); - - DetailedReportRow line4 = report.getRow("L40000"); - assertArrayEquals(new int[] {1, 1, 2, 0, 2}, line4.getCells()); - - ReportRow detailedLineNoAttachment4 = line4.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {1, 1, 2, 0, 2}, detailedLineNoAttachment4.getCells()); - - DetailedReportRow line5 = report.getRow("L50000"); - assertArrayEquals(new int[] {1, 2, 0, 2, 0}, line5.getCells()); - - ReportRow detailedLineNoAttachment5 = line5.getDetailRows().get("N/A"); - assertArrayEquals(new int[] {1, 2, 0, 2, 0}, detailedLineNoAttachment5.getCells()); - } - - private List getListOfColumnHeaders() { - List columnHeaders = new ArrayList<>(); - columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); - columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); - columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); - columnHeaders.add(new TimeIntervalColumnHeader(-1)); - columnHeaders.add(new TimeIntervalColumnHeader(0)); - columnHeaders.add(new TimeIntervalColumnHeader(1)); - columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); - columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); - columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); - return columnHeaders; - } - - private List getShortListOfColumnHeaders() { - List columnHeaders = new ArrayList<>(); - columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -6)); - columnHeaders.add(new TimeIntervalColumnHeader(-5, -1)); - columnHeaders.add(new TimeIntervalColumnHeader(0)); - columnHeaders.add(new TimeIntervalColumnHeader(1, 5)); - columnHeaders.add(new TimeIntervalColumnHeader(6, Integer.MAX_VALUE)); - return columnHeaders; - } - - private String reportToString(DetailedClassificationReport report) { - return reportToString(report, null); - } - - private String reportToString(DetailedClassificationReport report, List columnHeaders) { - String formatColumWidth = "| %-7s "; - String formatFirstColumn = "| %-36s %-4s "; - String formatFirstColumnFirstLine = "| %-29s %12s "; - String formatFirstColumnDetailLines = "| + %-34s %-4s "; - String formatFirstColumnSumLine = "| %-36s %-5s"; - int reportWidth = columnHeaders == null ? 46 : columnHeaders.size() * 10 + 46; - - StringBuilder builder = new StringBuilder(); - builder.append("\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - builder.append(String.format(formatFirstColumnFirstLine, "Classifications + Attachments", "Total")); - if (columnHeaders != null) { - for (TimeIntervalColumnHeader def : columnHeaders) { - if (def.getLowerAgeLimit() == Integer.MIN_VALUE) { - builder.append(String.format(formatColumWidth, "< " + def.getUpperAgeLimit())); - } else if (def.getUpperAgeLimit() == Integer.MAX_VALUE) { - builder.append(String.format(formatColumWidth, "> " + def.getLowerAgeLimit())); - } else if (def.getLowerAgeLimit() == def.getUpperAgeLimit()) { - if (def.getLowerAgeLimit() == 0) { - builder.append(String.format(formatColumWidth, "today")); - } else { - builder.append(String.format(formatColumWidth, def.getLowerAgeLimit())); - } - } else { - builder.append( - String.format(formatColumWidth, def.getLowerAgeLimit() + ".." + def.getUpperAgeLimit())); - } - } - } - builder.append("|\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - - for (String rl : report.rowTitles()) { - builder - .append(String.format(formatFirstColumn, rl, report.getRow(rl).getTotalValue())); - if (columnHeaders != null) { - for (int cell : report.getRow(rl).getCells()) { - builder.append(String.format(formatColumWidth, cell)); - } - } - builder.append("|\n"); - for (String detaileLine : report.getRow(rl).getDetailRows().keySet()) { - ReportRow reportLine = report.getRow(rl).getDetailRows().get(detaileLine); - builder.append( - String.format(formatFirstColumnDetailLines, detaileLine, reportLine.getTotalValue())); - for (int cell : reportLine.getCells()) { - builder.append(String.format(formatColumWidth, cell)); - } - builder.append("|\n"); - } - - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - } - builder.append(String.format(formatFirstColumnSumLine, "Total", report.getSumRow().getTotalValue())); - for (int cell : report.getSumRow().getCells()) { - builder.append(String.format(formatColumWidth, cell)); - } - builder.append("|\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - return builder.toString(); - } - -} +package acceptance.monitoring; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.sql.DataSource; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.CustomField; +import pro.taskana.TaskMonitorService; +import pro.taskana.TaskState; +import pro.taskana.TaskanaEngine; +import pro.taskana.TaskanaEngine.ConnectionManagementMode; +import pro.taskana.configuration.TaskanaEngineConfiguration; +import pro.taskana.database.TestDataGenerator; +import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.impl.TaskanaEngineImpl; +import pro.taskana.impl.configuration.DBCleaner; +import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; +import pro.taskana.impl.report.ReportRow; +import pro.taskana.impl.report.impl.DetailedClassificationReport; +import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; +import pro.taskana.impl.report.impl.DetailedReportRow; +import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; +import pro.taskana.security.JAASRunner; +import pro.taskana.security.WithAccessId; + +/** + * Acceptance test for all "detailed classification report" scenarios. + */ +@RunWith(JAASRunner.class) +public class ProvideDetailedClassificationReportAccTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProvideDetailedClassificationReportAccTest.class); + protected static TaskanaEngineConfiguration taskanaEngineConfiguration; + protected static TaskanaEngine taskanaEngine; + + @BeforeClass + public static void setupTest() throws Exception { + resetDb(); + } + + public static void resetDb() throws SQLException, IOException { + DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); + DBCleaner cleaner = new DBCleaner(); + cleaner.clearDb(dataSource, true); + dataSource = TaskanaEngineConfigurationTest.getDataSource(); + taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); + taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); + taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); + ((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); + cleaner.clearDb(dataSource, false); + TestDataGenerator testDataGenerator = new TestDataGenerator(); + testDataGenerator.generateMonitoringTestData(dataSource); + } + + @Test(expected = NotAuthorizedException.class) + public void testRoleCheck() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + taskMonitorService.getDetailedClassificationReport(null, null, null, null, + null, null); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetTotalNumbersOfTasksOfDetailedClassificationReport() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, null, null, + null, null); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + DetailedReportRow row1 = report.getRow("L10000"); + assertEquals(10, row1.getTotalValue()); + assertEquals(3, row1.getDetailRows().get("L11000").getTotalValue()); + assertEquals(7, row1.getDetailRows().get("N/A").getTotalValue()); + assertEquals(0, row1.getCells().length); + assertEquals(2, row1.getDetailRows().size()); + + DetailedReportRow row2 = report.getRow("L20000"); + assertEquals(10, row2.getTotalValue()); + assertEquals(4, row2.getDetailRows().get("L22000").getTotalValue()); + assertEquals(6, row2.getDetailRows().get("N/A").getTotalValue()); + assertEquals(0, row2.getCells().length); + assertEquals(2, row2.getDetailRows().size()); + + DetailedReportRow row3 = report.getRow("L30000"); + assertEquals(7, row3.getTotalValue()); + assertEquals(3, row3.getDetailRows().get("L33000").getTotalValue()); + assertEquals(1, row3.getDetailRows().get("L99000").getTotalValue()); + assertEquals(3, row3.getDetailRows().get("N/A").getTotalValue()); + assertEquals(0, row3.getCells().length); + assertEquals(3, row3.getDetailRows().size()); + + DetailedReportRow row4 = report.getRow("L40000"); + assertEquals(10, row4.getTotalValue()); + assertEquals(10, row4.getDetailRows().get("N/A").getTotalValue()); + assertEquals(0, row4.getCells().length); + assertEquals(1, row4.getDetailRows().size()); + + DetailedReportRow row5 = report.getRow("L50000"); + assertEquals(13, row5.getTotalValue()); + assertEquals(13, row5.getDetailRows().get("N/A").getTotalValue()); + assertEquals(0, row5.getCells().length); + assertEquals(1, row5.getDetailRows().size()); + + assertEquals(50, report.getSumRow().getTotalValue()); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetDetailedClassificationReportWithReportLineItemDefinitions() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List columnHeaders = getListOfColumnHeaders(); + + DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, null, null, + null, null, columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + assertEquals(10, report.getRow("L10000").getTotalValue()); + assertEquals(10, report.getRow("L20000").getTotalValue()); + assertEquals(7, report.getRow("L30000").getTotalValue()); + assertEquals(10, report.getRow("L40000").getTotalValue()); + assertEquals(13, report.getRow("L50000").getTotalValue()); + + int[] sumRow = report.getSumRow().getCells(); + assertArrayEquals(new int[] {10, 9, 11, 0, 4, 0, 7, 4, 5}, sumRow); + assertEquals(50, report.getSumRow().getTotalValue()); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfDetailedClassificationReport() throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List reportLineItemDefinitions = getShortListOfColumnHeaders(); + + DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, null, null, + null, null, reportLineItemDefinitions); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, reportLineItemDefinitions)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + DetailedReportRow line1 = report.getRow("L10000"); + assertArrayEquals(new int[] {7, 2, 1, 0, 0}, line1.getCells()); + + ReportRow detailedLine1 = line1.getDetailRows().get("L11000"); + assertArrayEquals(new int[] {2, 0, 1, 0, 0}, detailedLine1.getCells()); + + ReportRow detailedLineNoAttachment1 = line1.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {5, 2, 0, 0, 0}, detailedLineNoAttachment1.getCells()); + + DetailedReportRow line2 = report.getRow("L20000"); + assertArrayEquals(new int[] {5, 3, 1, 1, 0}, line2.getCells()); + + ReportRow detailedLine2 = line2.getDetailRows().get("L22000"); + assertArrayEquals(new int[] {1, 1, 1, 1, 0}, detailedLine2.getCells()); + + ReportRow detailedLineNoAttachment2 = line2.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {4, 2, 0, 0, 0}, detailedLineNoAttachment2.getCells()); + + DetailedReportRow line3 = report.getRow("L30000"); + assertArrayEquals(new int[] {2, 1, 0, 1, 3}, line3.getCells()); + + ReportRow detailedLine3a = line3.getDetailRows().get("L33000"); + assertArrayEquals(new int[] {0, 1, 0, 1, 1}, detailedLine3a.getCells()); + + ReportRow detailedLine3b = line3.getDetailRows().get("L99000"); + assertArrayEquals(new int[] {0, 0, 0, 0, 1}, detailedLine3b.getCells()); + + ReportRow detailedLineNoAttachment3 = line3.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {2, 0, 0, 0, 1}, detailedLineNoAttachment3.getCells()); + + DetailedReportRow line4 = report.getRow("L40000"); + assertArrayEquals(new int[] {2, 2, 2, 0, 4}, line4.getCells()); + + ReportRow detailedLineNoAttachment4 = line4.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {2, 2, 2, 0, 4}, detailedLineNoAttachment4.getCells()); + + DetailedReportRow line5 = report.getRow("L50000"); + assertArrayEquals(new int[] {3, 3, 0, 5, 2}, line5.getCells()); + + ReportRow detailedLineNoAttachment5 = line5.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {3, 3, 0, 5, 2}, detailedLineNoAttachment5.getCells()); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfDetailedClassificationReportWithWorkbasketFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List reportLineItemDefinitions = getShortListOfColumnHeaders(); + + DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(workbasketIds, null, + null, null, null, null, reportLineItemDefinitions); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, reportLineItemDefinitions)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + DetailedReportRow line1 = report.getRow("L10000"); + assertArrayEquals(new int[] {6, 0, 0, 0, 0}, line1.getCells()); + + ReportRow detailedLine1 = line1.getDetailRows().get("L11000"); + assertArrayEquals(new int[] {2, 0, 0, 0, 0}, detailedLine1.getCells()); + + ReportRow detailedLineNoAttachment1 = line1.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {4, 0, 0, 0, 0}, detailedLineNoAttachment1.getCells()); + + DetailedReportRow line2 = report.getRow("L20000"); + assertArrayEquals(new int[] {2, 0, 0, 0, 0}, line2.getCells()); + + ReportRow detailedLine2 = line2.getDetailRows().get("L22000"); + assertArrayEquals(new int[] {1, 0, 0, 0, 0}, detailedLine2.getCells()); + + ReportRow detailedLineNoAttachment2 = line2.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {1, 0, 0, 0, 0}, detailedLineNoAttachment2.getCells()); + + DetailedReportRow line3 = report.getRow("L30000"); + assertArrayEquals(new int[] {2, 1, 0, 1, 1}, line3.getCells()); + + ReportRow detailedLine3a = line3.getDetailRows().get("L33000"); + assertArrayEquals(new int[] {0, 1, 0, 1, 1}, detailedLine3a.getCells()); + + ReportRow detailedLineNoAttachment3 = line3.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {2, 0, 0, 0, 0}, detailedLineNoAttachment3.getCells()); + + DetailedReportRow line4 = report.getRow("L40000"); + assertArrayEquals(new int[] {1, 0, 1, 0, 1}, line4.getCells()); + + ReportRow detailedLineNoAttachment4 = line4.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {1, 0, 1, 0, 1}, detailedLineNoAttachment4.getCells()); + + DetailedReportRow line5 = report.getRow("L50000"); + assertArrayEquals(new int[] {2, 2, 0, 0, 0}, line5.getCells()); + + ReportRow detailedLineNoAttachment5 = line5.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {2, 2, 0, 0, 0}, detailedLineNoAttachment5.getCells()); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfDetailedClassificationReportWithStateFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List states = Collections.singletonList(TaskState.READY); + List columnHeaders = getShortListOfColumnHeaders(); + + DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, states, null, + null, null, null, columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + DetailedReportRow line1 = report.getRow("L10000"); + assertArrayEquals(new int[] {7, 2, 1, 0, 0}, line1.getCells()); + + ReportRow detailedLine1 = line1.getDetailRows().get("L11000"); + assertArrayEquals(new int[] {2, 0, 1, 0, 0}, detailedLine1.getCells()); + + ReportRow detailedLineNoAttachment1 = line1.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {5, 2, 0, 0, 0}, detailedLineNoAttachment1.getCells()); + + DetailedReportRow line2 = report.getRow("L20000"); + assertArrayEquals(new int[] {5, 3, 1, 1, 0}, line2.getCells()); + + ReportRow detailedLine2 = line2.getDetailRows().get("L22000"); + assertArrayEquals(new int[] {1, 1, 1, 1, 0}, detailedLine2.getCells()); + + ReportRow detailedLineNoAttachment2 = line2.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {4, 2, 0, 0, 0}, detailedLineNoAttachment2.getCells()); + + DetailedReportRow line3 = report.getRow("L30000"); + assertArrayEquals(new int[] {2, 1, 0, 1, 0}, line3.getCells()); + + ReportRow detailedLine3a = line3.getDetailRows().get("L33000"); + assertArrayEquals(new int[] {0, 1, 0, 1, 0}, detailedLine3a.getCells()); + + ReportRow detailedLineNoAttachment3 = line3.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {2, 0, 0, 0, 0}, detailedLineNoAttachment3.getCells()); + + DetailedReportRow line4 = report.getRow("L40000"); + assertArrayEquals(new int[] {2, 2, 2, 0, 0}, line4.getCells()); + + ReportRow detailedLineNoAttachment4 = line4.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {2, 2, 2, 0, 0}, detailedLineNoAttachment4.getCells()); + + DetailedReportRow line5 = report.getRow("L50000"); + assertArrayEquals(new int[] {3, 3, 0, 5, 0}, line5.getCells()); + + ReportRow detailedLineNoAttachment5 = line5.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {3, 3, 0, 5, 0}, detailedLineNoAttachment5.getCells()); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfDetailedClassificationReportNotInWorkingDays() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List columnHeaders = getShortListOfColumnHeaders(); + + DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, null, null, + null, null, columnHeaders, false); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + DetailedReportRow line1 = report.getRow("L10000"); + assertArrayEquals(new int[] {9, 0, 1, 0, 0}, line1.getCells()); + + ReportRow detailedLine1 = line1.getDetailRows().get("L11000"); + assertArrayEquals(new int[] {2, 0, 1, 0, 0}, detailedLine1.getCells()); + + ReportRow detailedLineNoAttachment1 = line1.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {7, 0, 0, 0, 0}, detailedLineNoAttachment1.getCells()); + + DetailedReportRow line2 = report.getRow("L20000"); + assertArrayEquals(new int[] {8, 0, 1, 0, 1}, line2.getCells()); + + ReportRow detailedLine2 = line2.getDetailRows().get("L22000"); + assertArrayEquals(new int[] {2, 0, 1, 0, 1}, detailedLine2.getCells()); + + ReportRow detailedLineNoAttachment2 = line2.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {6, 0, 0, 0, 0}, detailedLineNoAttachment2.getCells()); + + DetailedReportRow line3 = report.getRow("L30000"); + assertArrayEquals(new int[] {3, 0, 0, 0, 4}, line3.getCells()); + + ReportRow detailedLine3a = line3.getDetailRows().get("L33000"); + assertArrayEquals(new int[] {1, 0, 0, 0, 2}, detailedLine3a.getCells()); + + ReportRow detailedLine3b = line3.getDetailRows().get("L99000"); + assertArrayEquals(new int[] {0, 0, 0, 0, 1}, detailedLine3b.getCells()); + + ReportRow detailedLineNoAttachment3 = line3.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {2, 0, 0, 0, 1}, detailedLineNoAttachment3.getCells()); + + DetailedReportRow line4 = report.getRow("L40000"); + assertArrayEquals(new int[] {4, 0, 2, 0, 4}, line4.getCells()); + + ReportRow detailedLineNoAttachment4 = line4.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {4, 0, 2, 0, 4}, detailedLineNoAttachment4.getCells()); + + DetailedReportRow line5 = report.getRow("L50000"); + assertArrayEquals(new int[] {6, 0, 0, 0, 7}, line5.getCells()); + + ReportRow detailedLineNoAttachment5 = line5.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {6, 0, 0, 0, 7}, detailedLineNoAttachment5.getCells()); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfDetailedClassificationReportWithCategoryFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List categories = Arrays.asList("AUTOMATIC", "MANUAL"); + List columnHeaders = getShortListOfColumnHeaders(); + + DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, categories, + null, null, null, columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(2, report.rowSize()); + + DetailedReportRow line1 = report.getRow("L30000"); + assertArrayEquals(new int[] {2, 1, 0, 1, 3}, line1.getCells()); + + ReportRow detailedLine1a = line1.getDetailRows().get("L33000"); + assertArrayEquals(new int[] {0, 1, 0, 1, 1}, detailedLine1a.getCells()); + + ReportRow detailedLine1b = line1.getDetailRows().get("L99000"); + assertArrayEquals(new int[] {0, 0, 0, 0, 1}, detailedLine1b.getCells()); + + ReportRow detailedLine1WithoutAttachment = line1.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {2, 0, 0, 0, 1}, detailedLine1WithoutAttachment.getCells()); + + DetailedReportRow line2 = report.getRow("L40000"); + assertArrayEquals(new int[] {2, 2, 2, 0, 4}, line2.getCells()); + + ReportRow detailedLine2WithoutAttachment = line2.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {2, 2, 2, 0, 4}, detailedLine2WithoutAttachment.getCells()); + + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfDetailedClassificationReportWithDomainFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List domains = Collections.singletonList("DOMAIN_A"); + List columnHeaders = getShortListOfColumnHeaders(); + + DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, null, + domains, null, null, columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + DetailedReportRow line1 = report.getRow("L10000"); + assertArrayEquals(new int[] {5, 2, 1, 0, 0}, line1.getCells()); + + ReportRow detailedLine1 = line1.getDetailRows().get("L11000"); + assertArrayEquals(new int[] {1, 0, 1, 0, 0}, detailedLine1.getCells()); + + ReportRow detailedLineNoAttachment1 = line1.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {4, 2, 0, 0, 0}, detailedLineNoAttachment1.getCells()); + + DetailedReportRow line2 = report.getRow("L20000"); + assertArrayEquals(new int[] {3, 1, 1, 1, 0}, line2.getCells()); + + ReportRow detailedLine2 = line2.getDetailRows().get("L22000"); + assertArrayEquals(new int[] {1, 0, 1, 1, 0}, detailedLine2.getCells()); + + ReportRow detailedLineNoAttachment2 = line2.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {2, 1, 0, 0, 0}, detailedLineNoAttachment2.getCells()); + + DetailedReportRow line3 = report.getRow("L30000"); + assertArrayEquals(new int[] {1, 0, 0, 1, 1}, line3.getCells()); + + ReportRow detailedLine3 = line3.getDetailRows().get("L33000"); + assertArrayEquals(new int[] {0, 0, 0, 1, 1}, detailedLine3.getCells()); + + ReportRow detailedLineNoAttachment3 = line3.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {1, 0, 0, 0, 0}, detailedLineNoAttachment3.getCells()); + + DetailedReportRow line4 = report.getRow("L40000"); + assertArrayEquals(new int[] {2, 0, 0, 0, 3}, line4.getCells()); + + ReportRow detailedLineNoAttachment4 = line4.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {2, 0, 0, 0, 3}, detailedLineNoAttachment4.getCells()); + + DetailedReportRow line5 = report.getRow("L50000"); + assertArrayEquals(new int[] {0, 1, 0, 3, 0}, line5.getCells()); + + ReportRow detailedLineNoAttachment5 = line5.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {0, 1, 0, 3, 0}, detailedLineNoAttachment5.getCells()); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfDetailedClassificationReportWithCustomFieldValueFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + List columnHeaders = getShortListOfColumnHeaders(); + + DetailedClassificationReport report = taskMonitorService.getDetailedClassificationReport(null, null, + null, null, customField, customFieldValues, columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(5, report.rowSize()); + + DetailedReportRow line1 = report.getRow("L10000"); + assertArrayEquals(new int[] {4, 0, 0, 0, 0}, line1.getCells()); + + ReportRow detailedLine1 = line1.getDetailRows().get("L11000"); + assertArrayEquals(new int[] {1, 0, 0, 0, 0}, detailedLine1.getCells()); + + ReportRow detailedLineNoAttachment1 = line1.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {3, 0, 0, 0, 0}, detailedLineNoAttachment1.getCells()); + + DetailedReportRow line2 = report.getRow("L20000"); + assertArrayEquals(new int[] {4, 1, 1, 1, 0}, line2.getCells()); + + ReportRow detailedLine2 = line2.getDetailRows().get("L22000"); + assertArrayEquals(new int[] {1, 1, 1, 1, 0}, detailedLine2.getCells()); + + ReportRow detailedLineNoAttachment2 = line2.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {3, 0, 0, 0, 0}, detailedLineNoAttachment2.getCells()); + + DetailedReportRow line3 = report.getRow("L30000"); + assertArrayEquals(new int[] {1, 0, 0, 1, 1}, line3.getCells()); + + ReportRow detailedLine3a = line3.getDetailRows().get("L33000"); + assertArrayEquals(new int[] {0, 0, 0, 1, 0}, detailedLine3a.getCells()); + + ReportRow detailedLineNoAttachment3 = line3.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {1, 0, 0, 0, 1}, detailedLineNoAttachment3.getCells()); + + DetailedReportRow line4 = report.getRow("L40000"); + assertArrayEquals(new int[] {1, 1, 2, 0, 2}, line4.getCells()); + + ReportRow detailedLineNoAttachment4 = line4.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {1, 1, 2, 0, 2}, detailedLineNoAttachment4.getCells()); + + DetailedReportRow line5 = report.getRow("L50000"); + assertArrayEquals(new int[] {1, 2, 0, 2, 0}, line5.getCells()); + + ReportRow detailedLineNoAttachment5 = line5.getDetailRows().get("N/A"); + assertArrayEquals(new int[] {1, 2, 0, 2, 0}, detailedLineNoAttachment5.getCells()); + } + + private List getListOfColumnHeaders() { + List columnHeaders = new ArrayList<>(); + columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); + columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); + columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); + columnHeaders.add(new TimeIntervalColumnHeader(-1)); + columnHeaders.add(new TimeIntervalColumnHeader(0)); + columnHeaders.add(new TimeIntervalColumnHeader(1)); + columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); + columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); + columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); + return columnHeaders; + } + + private List getShortListOfColumnHeaders() { + List columnHeaders = new ArrayList<>(); + columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -6)); + columnHeaders.add(new TimeIntervalColumnHeader(-5, -1)); + columnHeaders.add(new TimeIntervalColumnHeader(0)); + columnHeaders.add(new TimeIntervalColumnHeader(1, 5)); + columnHeaders.add(new TimeIntervalColumnHeader(6, Integer.MAX_VALUE)); + return columnHeaders; + } + + private String reportToString(DetailedClassificationReport report) { + return reportToString(report, null); + } + + private String reportToString(DetailedClassificationReport report, List columnHeaders) { + String formatColumWidth = "| %-7s "; + String formatFirstColumn = "| %-36s %-4s "; + String formatFirstColumnFirstLine = "| %-29s %12s "; + String formatFirstColumnDetailLines = "| + %-34s %-4s "; + String formatFirstColumnSumLine = "| %-36s %-5s"; + int reportWidth = columnHeaders == null ? 46 : columnHeaders.size() * 10 + 46; + + StringBuilder builder = new StringBuilder(); + builder.append("\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + builder.append(String.format(formatFirstColumnFirstLine, "Classifications + Attachments", "Total")); + if (columnHeaders != null) { + for (TimeIntervalColumnHeader def : columnHeaders) { + if (def.getLowerAgeLimit() == Integer.MIN_VALUE) { + builder.append(String.format(formatColumWidth, "< " + def.getUpperAgeLimit())); + } else if (def.getUpperAgeLimit() == Integer.MAX_VALUE) { + builder.append(String.format(formatColumWidth, "> " + def.getLowerAgeLimit())); + } else if (def.getLowerAgeLimit() == def.getUpperAgeLimit()) { + if (def.getLowerAgeLimit() == 0) { + builder.append(String.format(formatColumWidth, "today")); + } else { + builder.append(String.format(formatColumWidth, def.getLowerAgeLimit())); + } + } else { + builder.append( + String.format(formatColumWidth, def.getLowerAgeLimit() + ".." + def.getUpperAgeLimit())); + } + } + } + builder.append("|\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + + for (String rl : report.rowTitles()) { + builder + .append(String.format(formatFirstColumn, rl, report.getRow(rl).getTotalValue())); + if (columnHeaders != null) { + for (int cell : report.getRow(rl).getCells()) { + builder.append(String.format(formatColumWidth, cell)); + } + } + builder.append("|\n"); + for (String detaileLine : report.getRow(rl).getDetailRows().keySet()) { + ReportRow reportLine = report.getRow(rl).getDetailRows().get(detaileLine); + builder.append( + String.format(formatFirstColumnDetailLines, detaileLine, reportLine.getTotalValue())); + for (int cell : reportLine.getCells()) { + builder.append(String.format(formatColumWidth, cell)); + } + builder.append("|\n"); + } + + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + } + builder.append(String.format(formatFirstColumnSumLine, "Total", report.getSumRow().getTotalValue())); + for (int cell : report.getSumRow().getCells()) { + builder.append(String.format(formatColumWidth, cell)); + } + builder.append("|\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + return builder.toString(); + } + +} diff --git a/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideWorkbasketLevelReportAccTest.java b/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideWorkbasketLevelReportAccTest.java index 5aafb8ba3..0ccf0dd50 100644 --- a/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideWorkbasketLevelReportAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/monitoring/ProvideWorkbasketLevelReportAccTest.java @@ -1,432 +1,432 @@ -package acceptance.monitoring; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.IntStream; - -import javax.sql.DataSource; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.CustomField; -import pro.taskana.TaskMonitorService; -import pro.taskana.TaskState; -import pro.taskana.TaskanaEngine; -import pro.taskana.TaskanaEngine.ConnectionManagementMode; -import pro.taskana.configuration.TaskanaEngineConfiguration; -import pro.taskana.database.TestDataGenerator; -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.exceptions.NotAuthorizedException; -import pro.taskana.impl.configuration.DBCleaner; -import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; -import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; -import pro.taskana.impl.report.impl.WorkbasketLevelReport; -import pro.taskana.security.JAASRunner; -import pro.taskana.security.WithAccessId; - -/** - * Acceptance test for all "workbasket level report" scenarios. - */ -@RunWith(JAASRunner.class) -public class ProvideWorkbasketLevelReportAccTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(ProvideWorkbasketLevelReportAccTest.class); - protected static TaskanaEngineConfiguration taskanaEngineConfiguration; - protected static TaskanaEngine taskanaEngine; - - @BeforeClass - public static void setupTest() throws Exception { - resetDb(); - } - - public static void resetDb() throws SQLException, IOException { - DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, true); - dataSource = TaskanaEngineConfigurationTest.getDataSource(); - taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); - taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); - taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); - taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); - cleaner.clearDb(dataSource, false); - TestDataGenerator testDataGenerator = new TestDataGenerator(); - testDataGenerator.generateMonitoringTestData(dataSource); - } - - @Test(expected = NotAuthorizedException.class) - public void testRoleCheck() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetTotalNumbersOfTasksOfWorkbasketLevelReport() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - assertEquals(20, report.getRow("USER_1_1").getTotalValue()); - assertEquals(20, report.getRow("USER_1_2").getTotalValue()); - assertEquals(10, report.getRow("USER_1_3").getTotalValue()); - - assertEquals(50, report.getSumRow().getTotalValue()); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testGetWorkbasketLevelReportWithReportLineItemDefinitions() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List columnHeaders = getListOfColumnHeaders(); - - WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - int sumLineCount = IntStream.of(report.getSumRow().getCells()).sum(); - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - assertEquals(20, report.getRow("USER_1_1").getTotalValue()); - assertEquals(20, report.getRow("USER_1_2").getTotalValue()); - assertEquals(10, report.getRow("USER_1_3").getTotalValue()); - - int[] sumRow = report.getSumRow().getCells(); - assertArrayEquals(new int[] {10, 9, 11, 0, 4, 0, 7, 4, 5}, sumRow); - - assertEquals(50, report.getSumRow().getTotalValue()); - assertEquals(50, sumLineCount); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfWorkbasketLevelReport() throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List columnHeaders = getShortListOfColumnHeaders(); - - WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("USER_1_1").getCells(); - assertArrayEquals(new int[] {13, 3, 1, 1, 2}, row1); - - int[] row2 = report.getRow("USER_1_2").getCells(); - assertArrayEquals(new int[] {4, 6, 3, 6, 1}, row2); - - int[] row3 = report.getRow("USER_1_3").getCells(); - assertArrayEquals(new int[] {2, 2, 0, 0, 6}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfWorkbasketLevelReportNotInWorkingDays() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List columnHeaders = getShortListOfColumnHeaders(); - - WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null, - columnHeaders, false); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("USER_1_1").getCells(); - assertArrayEquals(new int[] {16, 0, 1, 0, 3}, row1); - - int[] row2 = report.getRow("USER_1_2").getCells(); - assertArrayEquals(new int[] {10, 0, 3, 0, 7}, row2); - - int[] row3 = report.getRow("USER_1_3").getCells(); - assertArrayEquals(new int[] {4, 0, 0, 0, 6}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfWorkbasketLevelReportWithWorkbasketFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List columnHeaders = getShortListOfColumnHeaders(); - - WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(workbasketIds, null, null, null, - null, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(1, report.rowSize()); - - int[] row1 = report.getRow("USER_1_1").getCells(); - assertArrayEquals(new int[] {13, 3, 1, 1, 2}, row1); - - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfWorkbasketLevelReportWithStateFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List states = Collections.singletonList(TaskState.READY); - List columnHeaders = getShortListOfColumnHeaders(); - - WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, states, null, null, null, null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("USER_1_1").getCells(); - assertArrayEquals(new int[] {13, 3, 1, 1, 0}, row1); - - int[] row2 = report.getRow("USER_1_2").getCells(); - assertArrayEquals(new int[] {4, 6, 3, 6, 0}, row2); - - int[] row3 = report.getRow("USER_1_3").getCells(); - assertArrayEquals(new int[] {2, 2, 0, 0, 0}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfWorkbasketLevelReportWithCategoryFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List categories = Arrays.asList("AUTOMATIC", "MANUAL"); - List columnHeaders = getShortListOfColumnHeaders(); - - WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, categories, null, null, - null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("USER_1_1").getCells(); - assertArrayEquals(new int[] {3, 1, 1, 1, 2}, row1); - - int[] row2 = report.getRow("USER_1_2").getCells(); - assertArrayEquals(new int[] {1, 1, 1, 0, 1}, row2); - - int[] row3 = report.getRow("USER_1_3").getCells(); - assertArrayEquals(new int[] {0, 1, 0, 0, 4}, row3); - - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfWorkbasketLevelReportWithDomainFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - List domains = Collections.singletonList("DOMAIN_A"); - List columnHeaders = getShortListOfColumnHeaders(); - - WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, domains, null, - null, - columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("USER_1_1").getCells(); - assertArrayEquals(new int[] {8, 1, 0, 1, 2}, row1); - - int[] row2 = report.getRow("USER_1_2").getCells(); - assertArrayEquals(new int[] {2, 2, 2, 4, 0}, row2); - - int[] row3 = report.getRow("USER_1_3").getCells(); - assertArrayEquals(new int[] {1, 1, 0, 0, 2}, row3); - } - - @WithAccessId( - userName = "monitor") - @Test - public void testEachItemOfWorkbasketLevelReportWithCustomFieldValueFilter() - throws InvalidArgumentException, NotAuthorizedException { - TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); - - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - List columnHeaders = getShortListOfColumnHeaders(); - - WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, - customField, customFieldValues, columnHeaders); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(reportToString(report, columnHeaders)); - } - - assertNotNull(report); - assertEquals(3, report.rowSize()); - - int[] row1 = report.getRow("USER_1_1").getCells(); - assertArrayEquals(new int[] {6, 1, 1, 1, 1}, row1); - - int[] row2 = report.getRow("USER_1_2").getCells(); - assertArrayEquals(new int[] {3, 2, 2, 3, 1}, row2); - - int[] row3 = report.getRow("USER_1_3").getCells(); - assertArrayEquals(new int[] {2, 1, 0, 0, 1}, row3); - } - - private List getListOfColumnHeaders() { - List columnHeaders = new ArrayList<>(); - columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); - columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); - columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); - columnHeaders.add(new TimeIntervalColumnHeader(-1)); - columnHeaders.add(new TimeIntervalColumnHeader(0)); - columnHeaders.add(new TimeIntervalColumnHeader(1)); - columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); - columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); - columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); - return columnHeaders; - } - - private List getShortListOfColumnHeaders() { - List columnHeaders = new ArrayList<>(); - columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -6)); - columnHeaders.add(new TimeIntervalColumnHeader(-5, -1)); - columnHeaders.add(new TimeIntervalColumnHeader(0)); - columnHeaders.add(new TimeIntervalColumnHeader(1, 5)); - columnHeaders.add(new TimeIntervalColumnHeader(6, Integer.MAX_VALUE)); - return columnHeaders; - } - - private String reportToString(WorkbasketLevelReport report) { - return reportToString(report, null); - } - - private String reportToString(WorkbasketLevelReport report, - List reportLineItemDefinitions) { - String formatColumWidth = "| %-7s "; - String formatFirstColumn = "| %-36s %-4s "; - String formatFirstColumnFirstLine = "| %-29s %12s "; - String formatFirstColumnSumLine = "| %-36s %-5s"; - int reportWidth = reportLineItemDefinitions == null ? 46 : reportLineItemDefinitions.size() * 10 + 46; - - StringBuilder builder = new StringBuilder(); - builder.append("\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - builder.append(String.format(formatFirstColumnFirstLine, "Workbasket levels", "Total")); - if (reportLineItemDefinitions != null) { - for (TimeIntervalColumnHeader def : reportLineItemDefinitions) { - if (def.getLowerAgeLimit() == Integer.MIN_VALUE) { - builder.append(String.format(formatColumWidth, "< " + def.getUpperAgeLimit())); - } else if (def.getUpperAgeLimit() == Integer.MAX_VALUE) { - builder.append(String.format(formatColumWidth, "> " + def.getLowerAgeLimit())); - } else if (def.getLowerAgeLimit() == def.getUpperAgeLimit()) { - if (def.getLowerAgeLimit() == 0) { - builder.append(String.format(formatColumWidth, "today")); - } else { - builder.append(String.format(formatColumWidth, def.getLowerAgeLimit())); - } - } else { - builder.append( - String.format(formatColumWidth, def.getLowerAgeLimit() + ".." + def.getUpperAgeLimit())); - } - } - } - builder.append("|\n"); - - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - - for (String rl : report.rowTitles()) { - builder - .append(String.format(formatFirstColumn, rl, report.getRow(rl).getTotalValue())); - if (reportLineItemDefinitions != null) { - for (int cell : report.getRow(rl).getCells()) { - builder.append(String.format(formatColumWidth, cell)); - } - } - builder.append("|\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - } - builder.append(String.format(formatFirstColumnSumLine, "Total", report.getSumRow().getTotalValue())); - for (int cell : report.getSumRow().getCells()) { - builder.append(String.format(formatColumWidth, cell)); - } - builder.append("|\n"); - for (int i = 0; i < reportWidth; i++) { - builder.append("-"); - } - builder.append("\n"); - return builder.toString(); - } - -} +package acceptance.monitoring; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.IntStream; + +import javax.sql.DataSource; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.CustomField; +import pro.taskana.TaskMonitorService; +import pro.taskana.TaskState; +import pro.taskana.TaskanaEngine; +import pro.taskana.TaskanaEngine.ConnectionManagementMode; +import pro.taskana.configuration.TaskanaEngineConfiguration; +import pro.taskana.database.TestDataGenerator; +import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.impl.configuration.DBCleaner; +import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; +import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; +import pro.taskana.impl.report.impl.WorkbasketLevelReport; +import pro.taskana.security.JAASRunner; +import pro.taskana.security.WithAccessId; + +/** + * Acceptance test for all "workbasket level report" scenarios. + */ +@RunWith(JAASRunner.class) +public class ProvideWorkbasketLevelReportAccTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProvideWorkbasketLevelReportAccTest.class); + protected static TaskanaEngineConfiguration taskanaEngineConfiguration; + protected static TaskanaEngine taskanaEngine; + + @BeforeClass + public static void setupTest() throws Exception { + resetDb(); + } + + public static void resetDb() throws SQLException, IOException { + DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); + DBCleaner cleaner = new DBCleaner(); + cleaner.clearDb(dataSource, true); + dataSource = TaskanaEngineConfigurationTest.getDataSource(); + taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); + taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); + taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); + taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); + cleaner.clearDb(dataSource, false); + TestDataGenerator testDataGenerator = new TestDataGenerator(); + testDataGenerator.generateMonitoringTestData(dataSource); + } + + @Test(expected = NotAuthorizedException.class) + public void testRoleCheck() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetTotalNumbersOfTasksOfWorkbasketLevelReport() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + assertEquals(20, report.getRow("USER_1_1").getTotalValue()); + assertEquals(20, report.getRow("USER_1_2").getTotalValue()); + assertEquals(10, report.getRow("USER_1_3").getTotalValue()); + + assertEquals(50, report.getSumRow().getTotalValue()); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testGetWorkbasketLevelReportWithReportLineItemDefinitions() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List columnHeaders = getListOfColumnHeaders(); + + WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + int sumLineCount = IntStream.of(report.getSumRow().getCells()).sum(); + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + assertEquals(20, report.getRow("USER_1_1").getTotalValue()); + assertEquals(20, report.getRow("USER_1_2").getTotalValue()); + assertEquals(10, report.getRow("USER_1_3").getTotalValue()); + + int[] sumRow = report.getSumRow().getCells(); + assertArrayEquals(new int[] {10, 9, 11, 0, 4, 0, 7, 4, 5}, sumRow); + + assertEquals(50, report.getSumRow().getTotalValue()); + assertEquals(50, sumLineCount); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfWorkbasketLevelReport() throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List columnHeaders = getShortListOfColumnHeaders(); + + WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("USER_1_1").getCells(); + assertArrayEquals(new int[] {13, 3, 1, 1, 2}, row1); + + int[] row2 = report.getRow("USER_1_2").getCells(); + assertArrayEquals(new int[] {4, 6, 3, 6, 1}, row2); + + int[] row3 = report.getRow("USER_1_3").getCells(); + assertArrayEquals(new int[] {2, 2, 0, 0, 6}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfWorkbasketLevelReportNotInWorkingDays() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List columnHeaders = getShortListOfColumnHeaders(); + + WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null, + columnHeaders, false); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("USER_1_1").getCells(); + assertArrayEquals(new int[] {16, 0, 1, 0, 3}, row1); + + int[] row2 = report.getRow("USER_1_2").getCells(); + assertArrayEquals(new int[] {10, 0, 3, 0, 7}, row2); + + int[] row3 = report.getRow("USER_1_3").getCells(); + assertArrayEquals(new int[] {4, 0, 0, 0, 6}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfWorkbasketLevelReportWithWorkbasketFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List columnHeaders = getShortListOfColumnHeaders(); + + WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(workbasketIds, null, null, null, + null, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(1, report.rowSize()); + + int[] row1 = report.getRow("USER_1_1").getCells(); + assertArrayEquals(new int[] {13, 3, 1, 1, 2}, row1); + + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfWorkbasketLevelReportWithStateFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List states = Collections.singletonList(TaskState.READY); + List columnHeaders = getShortListOfColumnHeaders(); + + WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, states, null, null, null, null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("USER_1_1").getCells(); + assertArrayEquals(new int[] {13, 3, 1, 1, 0}, row1); + + int[] row2 = report.getRow("USER_1_2").getCells(); + assertArrayEquals(new int[] {4, 6, 3, 6, 0}, row2); + + int[] row3 = report.getRow("USER_1_3").getCells(); + assertArrayEquals(new int[] {2, 2, 0, 0, 0}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfWorkbasketLevelReportWithCategoryFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List categories = Arrays.asList("AUTOMATIC", "MANUAL"); + List columnHeaders = getShortListOfColumnHeaders(); + + WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, categories, null, null, + null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("USER_1_1").getCells(); + assertArrayEquals(new int[] {3, 1, 1, 1, 2}, row1); + + int[] row2 = report.getRow("USER_1_2").getCells(); + assertArrayEquals(new int[] {1, 1, 1, 0, 1}, row2); + + int[] row3 = report.getRow("USER_1_3").getCells(); + assertArrayEquals(new int[] {0, 1, 0, 0, 4}, row3); + + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfWorkbasketLevelReportWithDomainFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List domains = Collections.singletonList("DOMAIN_A"); + List columnHeaders = getShortListOfColumnHeaders(); + + WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, domains, null, + null, + columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("USER_1_1").getCells(); + assertArrayEquals(new int[] {8, 1, 0, 1, 2}, row1); + + int[] row2 = report.getRow("USER_1_2").getCells(); + assertArrayEquals(new int[] {2, 2, 2, 4, 0}, row2); + + int[] row3 = report.getRow("USER_1_3").getCells(); + assertArrayEquals(new int[] {1, 1, 0, 0, 2}, row3); + } + + @WithAccessId( + userName = "monitor") + @Test + public void testEachItemOfWorkbasketLevelReportWithCustomFieldValueFilter() + throws InvalidArgumentException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + List columnHeaders = getShortListOfColumnHeaders(); + + WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, + customField, customFieldValues, columnHeaders); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(reportToString(report, columnHeaders)); + } + + assertNotNull(report); + assertEquals(3, report.rowSize()); + + int[] row1 = report.getRow("USER_1_1").getCells(); + assertArrayEquals(new int[] {6, 1, 1, 1, 1}, row1); + + int[] row2 = report.getRow("USER_1_2").getCells(); + assertArrayEquals(new int[] {3, 2, 2, 3, 1}, row2); + + int[] row3 = report.getRow("USER_1_3").getCells(); + assertArrayEquals(new int[] {2, 1, 0, 0, 1}, row3); + } + + private List getListOfColumnHeaders() { + List columnHeaders = new ArrayList<>(); + columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); + columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); + columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); + columnHeaders.add(new TimeIntervalColumnHeader(-1)); + columnHeaders.add(new TimeIntervalColumnHeader(0)); + columnHeaders.add(new TimeIntervalColumnHeader(1)); + columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); + columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); + columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); + return columnHeaders; + } + + private List getShortListOfColumnHeaders() { + List columnHeaders = new ArrayList<>(); + columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -6)); + columnHeaders.add(new TimeIntervalColumnHeader(-5, -1)); + columnHeaders.add(new TimeIntervalColumnHeader(0)); + columnHeaders.add(new TimeIntervalColumnHeader(1, 5)); + columnHeaders.add(new TimeIntervalColumnHeader(6, Integer.MAX_VALUE)); + return columnHeaders; + } + + private String reportToString(WorkbasketLevelReport report) { + return reportToString(report, null); + } + + private String reportToString(WorkbasketLevelReport report, + List reportLineItemDefinitions) { + String formatColumWidth = "| %-7s "; + String formatFirstColumn = "| %-36s %-4s "; + String formatFirstColumnFirstLine = "| %-29s %12s "; + String formatFirstColumnSumLine = "| %-36s %-5s"; + int reportWidth = reportLineItemDefinitions == null ? 46 : reportLineItemDefinitions.size() * 10 + 46; + + StringBuilder builder = new StringBuilder(); + builder.append("\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + builder.append(String.format(formatFirstColumnFirstLine, "Workbasket levels", "Total")); + if (reportLineItemDefinitions != null) { + for (TimeIntervalColumnHeader def : reportLineItemDefinitions) { + if (def.getLowerAgeLimit() == Integer.MIN_VALUE) { + builder.append(String.format(formatColumWidth, "< " + def.getUpperAgeLimit())); + } else if (def.getUpperAgeLimit() == Integer.MAX_VALUE) { + builder.append(String.format(formatColumWidth, "> " + def.getLowerAgeLimit())); + } else if (def.getLowerAgeLimit() == def.getUpperAgeLimit()) { + if (def.getLowerAgeLimit() == 0) { + builder.append(String.format(formatColumWidth, "today")); + } else { + builder.append(String.format(formatColumWidth, def.getLowerAgeLimit())); + } + } else { + builder.append( + String.format(formatColumWidth, def.getLowerAgeLimit() + ".." + def.getUpperAgeLimit())); + } + } + } + builder.append("|\n"); + + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + + for (String rl : report.rowTitles()) { + builder + .append(String.format(formatFirstColumn, rl, report.getRow(rl).getTotalValue())); + if (reportLineItemDefinitions != null) { + for (int cell : report.getRow(rl).getCells()) { + builder.append(String.format(formatColumWidth, cell)); + } + } + builder.append("|\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + } + builder.append(String.format(formatFirstColumnSumLine, "Total", report.getSumRow().getTotalValue())); + for (int cell : report.getSumRow().getCells()) { + builder.append(String.format(formatColumWidth, cell)); + } + builder.append("|\n"); + for (int i = 0; i < reportWidth; i++) { + builder.append("-"); + } + builder.append("\n"); + return builder.toString(); + } + +} diff --git a/lib/taskana-core/src/test/java/pro/taskana/database/TestDataGenerator.java b/lib/taskana-core/src/test/java/pro/taskana/database/TestDataGenerator.java index a7d1d1246..2aa1327cb 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/database/TestDataGenerator.java +++ b/lib/taskana-core/src/test/java/pro/taskana/database/TestDataGenerator.java @@ -1,194 +1,194 @@ -package pro.taskana.database; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.sql.Connection; -import java.sql.SQLException; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Stream; - -import javax.sql.DataSource; - -import org.apache.ibatis.jdbc.ScriptRunner; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.configuration.DbSchemaCreator; -import pro.taskana.impl.TaskanaEngineImpl; - -/** - * Generates the test data for integration and acceptance tests. - */ -public class TestDataGenerator { - - private static final Logger LOGGER = LoggerFactory.getLogger(DbSchemaCreator.class); - private static final String SQL = "/sql"; - private static final String TASK = SQL + "/task.sql"; - private static final String WORKBASKET = SQL + "/workbasket.sql"; - private static final String DISTRIBUTION_TARGETS = SQL + "/distribution-targets.sql"; - private static final String WORKBASKET_ACCESS_LIST = SQL + "/workbasket-access-list.sql"; - private static final String CLASSIFICATION = SQL + "/classification.sql"; - private static final String OBJECT_REFERENCE = SQL + "/object-reference.sql"; - private static final String ATTACHMENT = SQL + "/attachment.sql"; - private static final String MONITOR_SAMPLE_DATA = SQL + "/monitor-sample-data.sql"; - private static SQLReplacer sqlReplacer; - - private StringWriter outWriter = new StringWriter(); - private PrintWriter logWriter; - private StringWriter errorWriter; - private PrintWriter errorLogWriter; - - public TestDataGenerator() { - this.logWriter = new PrintWriter(this.outWriter); - this.errorWriter = new StringWriter(); - this.errorLogWriter = new PrintWriter(this.errorWriter); - } - - public void generateTestData(DataSource dataSource) throws SQLException, IOException { - ScriptRunner runner = null; - try { - Connection connection = dataSource.getConnection(); - LOGGER.debug(connection.getMetaData().toString()); - runner = new ScriptRunner(connection); - runner.setStopOnError(true); - runner.setLogWriter(this.logWriter); - runner.setErrorLogWriter(this.errorLogWriter); - runner.setStopOnError(true); - runner.setLogWriter(this.logWriter); - runner.setErrorLogWriter(this.errorLogWriter); - - if (sqlReplacer == null) { - sqlReplacer = new SQLReplacer(connection.getMetaData().getDatabaseProductName()); - } - - Stream.of(sqlReplacer.classificationSql, sqlReplacer.workbasketSql, sqlReplacer.taskSql, - sqlReplacer.workbasketAccessListSql, sqlReplacer.distributionTargetSql, sqlReplacer.objectReferenceSql, - sqlReplacer.attachmentSql) - .map(s -> s.getBytes(StandardCharsets.UTF_8)) - .map(ByteArrayInputStream::new) - .map(InputStreamReader::new) - .forEach(runner::runScript); - - } finally { - if (runner != null) { - runner.closeConnection(); - } - LOGGER.debug(outWriter.toString()); - if (!errorWriter.toString().trim().isEmpty()) { - LOGGER.error(errorWriter.toString()); - } - } - } - - public void generateMonitoringTestData(DataSource dataSource) throws IOException, SQLException { - ScriptRunner runner = null; - try { - Connection connection = dataSource.getConnection(); - LOGGER.debug(connection.getMetaData().toString()); - runner = new ScriptRunner(connection); - runner.setStopOnError(true); - runner.setLogWriter(this.logWriter); - runner.setErrorLogWriter(this.errorLogWriter); - runner.setStopOnError(true); - runner.setLogWriter(this.logWriter); - runner.setErrorLogWriter(this.errorLogWriter); - - if (sqlReplacer == null) { - sqlReplacer = new SQLReplacer(connection.getMetaData().getDatabaseProductName()); - } - - runner.runScript( - new InputStreamReader( - new ByteArrayInputStream( - sqlReplacer.monitoringTestDataSql.getBytes(StandardCharsets.UTF_8)))); - } finally { - if (runner != null) { - runner.closeConnection(); - } - LOGGER.debug(outWriter.toString()); - if (!errorWriter.toString().trim().isEmpty()) { - LOGGER.error(errorWriter.toString()); - } - } - } - - /** - * This class replaces boolean values with int values if the database is db2. - */ - private static final class SQLReplacer { - - private String classificationSql; - private String workbasketSql; - private String taskSql; - private String workbasketAccessListSql; - private String distributionTargetSql; - private String objectReferenceSql; - private String attachmentSql; - private String monitoringTestDataSql; - - private SQLReplacer(String dbProductName) throws IOException { - boolean isDb2 = TaskanaEngineImpl.isDb2(dbProductName); - classificationSql = parseAndReplace(getClass().getResourceAsStream(CLASSIFICATION), isDb2); - workbasketSql = parseAndReplace(getClass().getResourceAsStream(WORKBASKET), isDb2); - taskSql = parseAndReplace(getClass().getResourceAsStream(TASK), isDb2); - workbasketAccessListSql = parseAndReplace(getClass().getResourceAsStream(WORKBASKET_ACCESS_LIST), isDb2); - distributionTargetSql = parseAndReplace(getClass().getResourceAsStream(DISTRIBUTION_TARGETS), isDb2); - objectReferenceSql = parseAndReplace(getClass().getResourceAsStream(OBJECT_REFERENCE), isDb2); - attachmentSql = parseAndReplace(getClass().getResourceAsStream(ATTACHMENT), isDb2); - monitoringTestDataSql = generateMonitoringSqlData(isDb2); - } - - private String parseAndReplace(InputStream stream, boolean replace) throws IOException { - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream)); - StringBuilder sql = new StringBuilder(); - String line; - if (replace) { - while ((line = bufferedReader.readLine()) != null) { - sql.append(line.replaceAll("true|TRUE", "1").replaceAll("false|FALSE", "0")).append("\n"); - } - } else { - while ((line = bufferedReader.readLine()) != null) { - sql.append(line).append("\n"); - } - } - return sql.toString(); - } - - private String generateMonitoringSqlData(boolean replace) throws IOException { - String rawSql = parseAndReplace(getClass().getResourceAsStream(MONITOR_SAMPLE_DATA), replace); - - BufferedReader bufferedReader = new BufferedReader( - new InputStreamReader(new ByteArrayInputStream(rawSql.getBytes(StandardCharsets.UTF_8)))); - LocalDateTime now = LocalDateTime.now(); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - StringBuilder sql = new StringBuilder(); - String line; - - List ages = Arrays.asList(-70000, -14000, -2800, -1400, -1400, -700, -700, -35, -28, -28, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, 0, 0, 0, 0, 7, 7, 7, 7, - 7, 7, - 7, 14, 14, 14, 14, 21, 210, 210, 28000, 700000); - int i = 0; - while ((line = bufferedReader.readLine()) != null) { - if (line.contains("dueDate")) { - line = line.replace("dueDate", "\'" + now.plusDays(ages.get(i)).format(formatter) + "\' "); - i++; - } - sql.append(line).append("\n"); - } - bufferedReader.close(); - return sql.toString(); - } - - } - -} +package pro.taskana.database; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.charset.StandardCharsets; +import java.sql.Connection; +import java.sql.SQLException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +import javax.sql.DataSource; + +import org.apache.ibatis.jdbc.ScriptRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.configuration.DbSchemaCreator; +import pro.taskana.impl.TaskanaEngineImpl; + +/** + * Generates the test data for integration and acceptance tests. + */ +public class TestDataGenerator { + + private static final Logger LOGGER = LoggerFactory.getLogger(DbSchemaCreator.class); + private static final String SQL = "/sql"; + private static final String TASK = SQL + "/task.sql"; + private static final String WORKBASKET = SQL + "/workbasket.sql"; + private static final String DISTRIBUTION_TARGETS = SQL + "/distribution-targets.sql"; + private static final String WORKBASKET_ACCESS_LIST = SQL + "/workbasket-access-list.sql"; + private static final String CLASSIFICATION = SQL + "/classification.sql"; + private static final String OBJECT_REFERENCE = SQL + "/object-reference.sql"; + private static final String ATTACHMENT = SQL + "/attachment.sql"; + private static final String MONITOR_SAMPLE_DATA = SQL + "/monitor-sample-data.sql"; + private static SQLReplacer sqlReplacer; + + private StringWriter outWriter = new StringWriter(); + private PrintWriter logWriter; + private StringWriter errorWriter; + private PrintWriter errorLogWriter; + + public TestDataGenerator() { + this.logWriter = new PrintWriter(this.outWriter); + this.errorWriter = new StringWriter(); + this.errorLogWriter = new PrintWriter(this.errorWriter); + } + + public void generateTestData(DataSource dataSource) throws SQLException, IOException { + ScriptRunner runner = null; + try { + Connection connection = dataSource.getConnection(); + LOGGER.debug(connection.getMetaData().toString()); + runner = new ScriptRunner(connection); + runner.setStopOnError(true); + runner.setLogWriter(this.logWriter); + runner.setErrorLogWriter(this.errorLogWriter); + runner.setStopOnError(true); + runner.setLogWriter(this.logWriter); + runner.setErrorLogWriter(this.errorLogWriter); + + if (sqlReplacer == null) { + sqlReplacer = new SQLReplacer(connection.getMetaData().getDatabaseProductName()); + } + + Stream.of(sqlReplacer.classificationSql, sqlReplacer.workbasketSql, sqlReplacer.taskSql, + sqlReplacer.workbasketAccessListSql, sqlReplacer.distributionTargetSql, sqlReplacer.objectReferenceSql, + sqlReplacer.attachmentSql) + .map(s -> s.getBytes(StandardCharsets.UTF_8)) + .map(ByteArrayInputStream::new) + .map(InputStreamReader::new) + .forEach(runner::runScript); + + } finally { + if (runner != null) { + runner.closeConnection(); + } + LOGGER.debug(outWriter.toString()); + if (!errorWriter.toString().trim().isEmpty()) { + LOGGER.error(errorWriter.toString()); + } + } + } + + public void generateMonitoringTestData(DataSource dataSource) throws IOException, SQLException { + ScriptRunner runner = null; + try { + Connection connection = dataSource.getConnection(); + LOGGER.debug(connection.getMetaData().toString()); + runner = new ScriptRunner(connection); + runner.setStopOnError(true); + runner.setLogWriter(this.logWriter); + runner.setErrorLogWriter(this.errorLogWriter); + runner.setStopOnError(true); + runner.setLogWriter(this.logWriter); + runner.setErrorLogWriter(this.errorLogWriter); + + if (sqlReplacer == null) { + sqlReplacer = new SQLReplacer(connection.getMetaData().getDatabaseProductName()); + } + + runner.runScript( + new InputStreamReader( + new ByteArrayInputStream( + sqlReplacer.monitoringTestDataSql.getBytes(StandardCharsets.UTF_8)))); + } finally { + if (runner != null) { + runner.closeConnection(); + } + LOGGER.debug(outWriter.toString()); + if (!errorWriter.toString().trim().isEmpty()) { + LOGGER.error(errorWriter.toString()); + } + } + } + + /** + * This class replaces boolean values with int values if the database is db2. + */ + private static final class SQLReplacer { + + private String classificationSql; + private String workbasketSql; + private String taskSql; + private String workbasketAccessListSql; + private String distributionTargetSql; + private String objectReferenceSql; + private String attachmentSql; + private String monitoringTestDataSql; + + private SQLReplacer(String dbProductName) throws IOException { + boolean isDb2 = TaskanaEngineImpl.isDb2(dbProductName); + classificationSql = parseAndReplace(getClass().getResourceAsStream(CLASSIFICATION), isDb2); + workbasketSql = parseAndReplace(getClass().getResourceAsStream(WORKBASKET), isDb2); + taskSql = parseAndReplace(getClass().getResourceAsStream(TASK), isDb2); + workbasketAccessListSql = parseAndReplace(getClass().getResourceAsStream(WORKBASKET_ACCESS_LIST), isDb2); + distributionTargetSql = parseAndReplace(getClass().getResourceAsStream(DISTRIBUTION_TARGETS), isDb2); + objectReferenceSql = parseAndReplace(getClass().getResourceAsStream(OBJECT_REFERENCE), isDb2); + attachmentSql = parseAndReplace(getClass().getResourceAsStream(ATTACHMENT), isDb2); + monitoringTestDataSql = generateMonitoringSqlData(isDb2); + } + + private String parseAndReplace(InputStream stream, boolean replace) throws IOException { + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream)); + StringBuilder sql = new StringBuilder(); + String line; + if (replace) { + while ((line = bufferedReader.readLine()) != null) { + sql.append(line.replaceAll("true|TRUE", "1").replaceAll("false|FALSE", "0")).append("\n"); + } + } else { + while ((line = bufferedReader.readLine()) != null) { + sql.append(line).append("\n"); + } + } + return sql.toString(); + } + + private String generateMonitoringSqlData(boolean replace) throws IOException { + String rawSql = parseAndReplace(getClass().getResourceAsStream(MONITOR_SAMPLE_DATA), replace); + + BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(new ByteArrayInputStream(rawSql.getBytes(StandardCharsets.UTF_8)))); + LocalDateTime now = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + StringBuilder sql = new StringBuilder(); + String line; + + List ages = Arrays.asList(-70000, -14000, -2800, -1400, -1400, -700, -700, -35, -28, -28, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, 0, 0, 0, 0, 7, 7, 7, 7, + 7, 7, + 7, 14, 14, 14, 14, 21, 210, 210, 28000, 700000); + int i = 0; + while ((line = bufferedReader.readLine()) != null) { + if (line.contains("dueDate")) { + line = line.replace("dueDate", "\'" + now.plusDays(ages.get(i)).format(formatter) + "\' "); + i++; + } + sql.append(line).append("\n"); + } + bufferedReader.close(); + return sql.toString(); + } + + } + +} diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/DaysToWorkingDaysConverterTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/DaysToWorkingDaysConverterTest.java index 883501487..3e82cad58 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/DaysToWorkingDaysConverterTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/DaysToWorkingDaysConverterTest.java @@ -1,398 +1,398 @@ -package pro.taskana.impl; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.fail; - -import java.time.Instant; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.junit.BeforeClass; -import org.junit.Test; - -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; - -/** - * Test for the DaysToWorkingDaysConverter. - */ -public class DaysToWorkingDaysConverterTest { - - @BeforeClass - public static void setup() { - DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled(true); - LocalDate dayOfReformation = LocalDate.of(2018, 10, 31); - LocalDate allSaintsDays = LocalDate.of(2018, 11, 1); - DaysToWorkingDaysConverter.setCustomHolidays(Arrays.asList(dayOfReformation, allSaintsDays)); - } - - @Test - public void testInitializeForDifferentReportLineItemDefinitions() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance1 = DaysToWorkingDaysConverter - .initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-03T00:00:00.000Z")); - DaysToWorkingDaysConverter instance2 = DaysToWorkingDaysConverter - .initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-03T00:00:00.000Z")); - DaysToWorkingDaysConverter instance3 = DaysToWorkingDaysConverter - .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-02-03T00:00:00.000Z")); - - assertEquals(instance1, instance2); - assertNotEquals(instance1, instance3); - } - - @Test - public void testConvertWorkingDaysToDaysForTasks() { - List reportItems = Collections.singletonList(new TimeIntervalColumnHeader(0)); - try { - DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(reportItems, Instant.now()); - - Instant thursday0201 = Instant.parse("2018-02-01T07:00:00.000Z"); - long days = converter.convertWorkingDaysToDays(thursday0201, 0); // = thursday - assertEquals(0, days); - days = converter.convertWorkingDaysToDays(thursday0201, 1); // fri - assertEquals(1, days); - days = converter.convertWorkingDaysToDays(thursday0201, 2); // mon - assertEquals(4, days); - days = converter.convertWorkingDaysToDays(thursday0201, 3); // tues - assertEquals(5, days); - days = converter.convertWorkingDaysToDays(thursday0201, 4); // we - assertEquals(6, days); - days = converter.convertWorkingDaysToDays(thursday0201, 5); // thurs - assertEquals(7, days); - days = converter.convertWorkingDaysToDays(thursday0201, 6); // fri - assertEquals(8, days); - days = converter.convertWorkingDaysToDays(thursday0201, 7); // mon - assertEquals(11, days); - days = converter.convertWorkingDaysToDays(thursday0201, 8); // tue - assertEquals(12, days); - days = converter.convertWorkingDaysToDays(thursday0201, 9); // we - assertEquals(13, days); - days = converter.convertWorkingDaysToDays(thursday0201, 10); // thu - assertEquals(14, days); - days = converter.convertWorkingDaysToDays(thursday0201, 11); // fri - assertEquals(15, days); - - Instant gruenDonnerstag2018 = Instant.parse("2018-03-29T01:00:00.000Z"); - days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 0); - assertEquals(0, days); - days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 1); // Karfreitag - assertEquals(5, days); // osterdienstag - days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 2); // Karfreitag - assertEquals(6, days); // ostermittwoch - - Instant freitag0427 = Instant.parse("2018-04-27T19:00:00.000Z"); - days = converter.convertWorkingDaysToDays(freitag0427, 0); - assertEquals(0, days); - days = converter.convertWorkingDaysToDays(freitag0427, 1); - assertEquals(3, days); // 30.4. - days = converter.convertWorkingDaysToDays(freitag0427, 2); - assertEquals(5, days); // 2.5. - - } catch (InvalidArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - fail(""); - } - - } - - @Test - public void testInitializeForDifferentDates() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance1 = DaysToWorkingDaysConverter - .initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-04T00:00:00.000Z")); - DaysToWorkingDaysConverter instance2 = DaysToWorkingDaysConverter - .initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-05T00:00:00.000Z")); - - assertNotEquals(instance1, instance2); - } - - @Test - public void testConvertDaysToWorkingDays() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter - .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-02-06T00:00:00.000Z")); - - assertEquals(-16, instance.convertDaysToWorkingDays(-16)); - assertEquals(-11, instance.convertDaysToWorkingDays(-15)); - - assertEquals(-2, instance.convertDaysToWorkingDays(-4)); - assertEquals(-1, instance.convertDaysToWorkingDays(-3)); - assertEquals(-1, instance.convertDaysToWorkingDays(-2)); - assertEquals(-1, instance.convertDaysToWorkingDays(-1)); - assertEquals(0, instance.convertDaysToWorkingDays(0)); - assertEquals(1, instance.convertDaysToWorkingDays(1)); - assertEquals(2, instance.convertDaysToWorkingDays(2)); - assertEquals(3, instance.convertDaysToWorkingDays(3)); - assertEquals(3, instance.convertDaysToWorkingDays(4)); - assertEquals(3, instance.convertDaysToWorkingDays(5)); - assertEquals(4, instance.convertDaysToWorkingDays(6)); - - assertEquals(11, instance.convertDaysToWorkingDays(15)); - assertEquals(16, instance.convertDaysToWorkingDays(16)); - } - - @Test - public void testConvertWorkingDaysToDays() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter - .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-02-27T00:00:00.000Z")); - - assertEquals(Arrays.asList(-13), instance.convertWorkingDaysToDays(-13)); - assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-12)); - - assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-8)); - assertEquals(Arrays.asList(-11), instance.convertWorkingDaysToDays(-7)); - assertEquals(Arrays.asList(-8, -9, -10), instance.convertWorkingDaysToDays(-6)); - assertEquals(Arrays.asList(-7), instance.convertWorkingDaysToDays(-5)); - assertEquals(Arrays.asList(-6), instance.convertWorkingDaysToDays(-4)); - assertEquals(Arrays.asList(-5), instance.convertWorkingDaysToDays(-3)); - assertEquals(Arrays.asList(-4), instance.convertWorkingDaysToDays(-2)); - assertEquals(Arrays.asList(-1, -2, -3), instance.convertWorkingDaysToDays(-1)); - assertEquals(Arrays.asList(0), instance.convertWorkingDaysToDays(0)); - assertEquals(Arrays.asList(1), instance.convertWorkingDaysToDays(1)); - assertEquals(Arrays.asList(2), instance.convertWorkingDaysToDays(2)); - assertEquals(Arrays.asList(3, 4, 5), instance.convertWorkingDaysToDays(3)); - assertEquals(Arrays.asList(6), instance.convertWorkingDaysToDays(4)); - assertEquals(Arrays.asList(7), instance.convertWorkingDaysToDays(5)); - assertEquals(Arrays.asList(8), instance.convertWorkingDaysToDays(6)); - assertEquals(Arrays.asList(9), instance.convertWorkingDaysToDays(7)); - assertEquals(Arrays.asList(10, 11, 12), instance.convertWorkingDaysToDays(8)); - assertEquals(Arrays.asList(13), instance.convertWorkingDaysToDays(9)); - assertEquals(Arrays.asList(14), instance.convertWorkingDaysToDays(10)); - assertEquals(Arrays.asList(15), instance.convertWorkingDaysToDays(11)); - - assertEquals(Arrays.asList(12), instance.convertWorkingDaysToDays(12)); - assertEquals(Arrays.asList(13), instance.convertWorkingDaysToDays(13)); - } - - @Test - public void testConvertWorkingDaysToDaysAtWeekend() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter - .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-03-10T00:00:00.000Z")); - - assertEquals(Arrays.asList(-13), instance.convertWorkingDaysToDays(-13)); - assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-12)); - - assertEquals(Arrays.asList(-10), instance.convertWorkingDaysToDays(-8)); - assertEquals(Arrays.asList(-9), instance.convertWorkingDaysToDays(-7)); - assertEquals(Arrays.asList(-8), instance.convertWorkingDaysToDays(-6)); - assertEquals(Arrays.asList(-5, -6, -7), instance.convertWorkingDaysToDays(-5)); - assertEquals(Arrays.asList(-4), instance.convertWorkingDaysToDays(-4)); - assertEquals(Arrays.asList(-3), instance.convertWorkingDaysToDays(-3)); - assertEquals(Arrays.asList(-2), instance.convertWorkingDaysToDays(-2)); - assertEquals(Arrays.asList(-1), instance.convertWorkingDaysToDays(-1)); - assertEquals(Arrays.asList(0, 1), instance.convertWorkingDaysToDays(0)); - assertEquals(Arrays.asList(2), instance.convertWorkingDaysToDays(1)); - assertEquals(Arrays.asList(3), instance.convertWorkingDaysToDays(2)); - assertEquals(Arrays.asList(4), instance.convertWorkingDaysToDays(3)); - assertEquals(Arrays.asList(5), instance.convertWorkingDaysToDays(4)); - assertEquals(Arrays.asList(6, 7, 8), instance.convertWorkingDaysToDays(5)); - assertEquals(Arrays.asList(9), instance.convertWorkingDaysToDays(6)); - assertEquals(Arrays.asList(10), instance.convertWorkingDaysToDays(7)); - assertEquals(Arrays.asList(11), instance.convertWorkingDaysToDays(8)); - assertEquals(Arrays.asList(12), instance.convertWorkingDaysToDays(9)); - assertEquals(Arrays.asList(13, 14, 15), instance.convertWorkingDaysToDays(10)); - assertEquals(Arrays.asList(16), instance.convertWorkingDaysToDays(11)); - - assertEquals(Arrays.asList(12), instance.convertWorkingDaysToDays(12)); - assertEquals(Arrays.asList(13), instance.convertWorkingDaysToDays(13)); - } - - @Test - public void testConvertWorkingDaysToDaysOnEasterSunday() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter - .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-04-01T00:00:00.000Z")); - - assertEquals(Arrays.asList(-13), instance.convertWorkingDaysToDays(-13)); - assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-12)); - - assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-8)); - assertEquals(Arrays.asList(-11), instance.convertWorkingDaysToDays(-7)); - assertEquals(Arrays.asList(-10), instance.convertWorkingDaysToDays(-6)); - assertEquals(Arrays.asList(-9), instance.convertWorkingDaysToDays(-5)); - assertEquals(Arrays.asList(-6, -7, -8), instance.convertWorkingDaysToDays(-4)); - assertEquals(Arrays.asList(-5), instance.convertWorkingDaysToDays(-3)); - assertEquals(Arrays.asList(-4), instance.convertWorkingDaysToDays(-2)); - assertEquals(Arrays.asList(-3), instance.convertWorkingDaysToDays(-1)); - assertEquals(Arrays.asList(0, 1, -1, -2), instance.convertWorkingDaysToDays(0)); - assertEquals(Arrays.asList(2), instance.convertWorkingDaysToDays(1)); - assertEquals(Arrays.asList(3), instance.convertWorkingDaysToDays(2)); - assertEquals(Arrays.asList(4), instance.convertWorkingDaysToDays(3)); - assertEquals(Arrays.asList(5, 6, 7), instance.convertWorkingDaysToDays(4)); - assertEquals(Arrays.asList(8), instance.convertWorkingDaysToDays(5)); - assertEquals(Arrays.asList(9), instance.convertWorkingDaysToDays(6)); - assertEquals(Arrays.asList(10), instance.convertWorkingDaysToDays(7)); - assertEquals(Arrays.asList(11), instance.convertWorkingDaysToDays(8)); - assertEquals(Arrays.asList(12, 13, 14), instance.convertWorkingDaysToDays(9)); - assertEquals(Arrays.asList(15), instance.convertWorkingDaysToDays(10)); - assertEquals(Arrays.asList(16), instance.convertWorkingDaysToDays(11)); - - assertEquals(Arrays.asList(12), instance.convertWorkingDaysToDays(12)); - assertEquals(Arrays.asList(13), instance.convertWorkingDaysToDays(13)); - } - - @Test - public void testEasterHolidays() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter - .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-03-28T00:00:00.000Z")); - - assertEquals(0, instance.convertDaysToWorkingDays(0)); - assertEquals(1, instance.convertDaysToWorkingDays(1)); - assertEquals(1, instance.convertDaysToWorkingDays(2)); - assertEquals(1, instance.convertDaysToWorkingDays(3)); - assertEquals(1, instance.convertDaysToWorkingDays(4)); - assertEquals(1, instance.convertDaysToWorkingDays(5)); - assertEquals(2, instance.convertDaysToWorkingDays(6)); - } - - @Test - public void testWhitsunHolidays() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter - .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-05-16T00:00:00.000Z")); - - assertEquals(0, instance.convertDaysToWorkingDays(0)); - assertEquals(1, instance.convertDaysToWorkingDays(1)); - assertEquals(2, instance.convertDaysToWorkingDays(2)); - assertEquals(2, instance.convertDaysToWorkingDays(3)); - assertEquals(2, instance.convertDaysToWorkingDays(4)); - assertEquals(2, instance.convertDaysToWorkingDays(5)); - assertEquals(3, instance.convertDaysToWorkingDays(6)); - } - - @Test - public void testLabourDayHoliday() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter - .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-04-26T00:00:00.000Z")); - - assertEquals(0, instance.convertDaysToWorkingDays(0)); - assertEquals(1, instance.convertDaysToWorkingDays(1)); - assertEquals(1, instance.convertDaysToWorkingDays(2)); - assertEquals(1, instance.convertDaysToWorkingDays(3)); - assertEquals(2, instance.convertDaysToWorkingDays(4)); - assertEquals(2, instance.convertDaysToWorkingDays(5)); - assertEquals(3, instance.convertDaysToWorkingDays(6)); - assertEquals(4, instance.convertDaysToWorkingDays(7)); - } - - @Test - public void testAscensionDayHoliday() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter - .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-05-07T00:00:00.000Z")); - - assertEquals(0, instance.convertDaysToWorkingDays(0)); - assertEquals(1, instance.convertDaysToWorkingDays(1)); - assertEquals(2, instance.convertDaysToWorkingDays(2)); - assertEquals(2, instance.convertDaysToWorkingDays(3)); - assertEquals(3, instance.convertDaysToWorkingDays(4)); - assertEquals(3, instance.convertDaysToWorkingDays(5)); - assertEquals(3, instance.convertDaysToWorkingDays(6)); - assertEquals(4, instance.convertDaysToWorkingDays(7)); - } - - @Test - public void testDayOfGermanUnityHoliday() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter - .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-10-01T00:00:00.000Z")); - - assertEquals(0, instance.convertDaysToWorkingDays(0)); - assertEquals(1, instance.convertDaysToWorkingDays(1)); - assertEquals(1, instance.convertDaysToWorkingDays(2)); - assertEquals(2, instance.convertDaysToWorkingDays(3)); - assertEquals(3, instance.convertDaysToWorkingDays(4)); - assertEquals(3, instance.convertDaysToWorkingDays(5)); - assertEquals(3, instance.convertDaysToWorkingDays(6)); - assertEquals(4, instance.convertDaysToWorkingDays(7)); - } - - @Test - public void testChristmasAndNewYearHolidays() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter - .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-12-20T00:00:00.000Z")); - - assertEquals(0, instance.convertDaysToWorkingDays(0)); - assertEquals(1, instance.convertDaysToWorkingDays(1)); - assertEquals(1, instance.convertDaysToWorkingDays(2)); - assertEquals(1, instance.convertDaysToWorkingDays(3)); - assertEquals(2, instance.convertDaysToWorkingDays(4)); - assertEquals(2, instance.convertDaysToWorkingDays(5)); - assertEquals(2, instance.convertDaysToWorkingDays(6)); - assertEquals(3, instance.convertDaysToWorkingDays(7)); - assertEquals(4, instance.convertDaysToWorkingDays(8)); - assertEquals(4, instance.convertDaysToWorkingDays(9)); - assertEquals(4, instance.convertDaysToWorkingDays(10)); - assertEquals(5, instance.convertDaysToWorkingDays(11)); - assertEquals(5, instance.convertDaysToWorkingDays(12)); - assertEquals(6, instance.convertDaysToWorkingDays(13)); - assertEquals(7, instance.convertDaysToWorkingDays(14)); - } - - @Test - public void testCustomHolidaysWithDayOfReformationAndAllSaintsDay() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter - .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-10-26T00:00:00.000Z")); - - assertEquals(0, instance.convertDaysToWorkingDays(0)); - assertEquals(0, instance.convertDaysToWorkingDays(1)); - assertEquals(0, instance.convertDaysToWorkingDays(2)); - assertEquals(1, instance.convertDaysToWorkingDays(3)); - assertEquals(2, instance.convertDaysToWorkingDays(4)); - assertEquals(2, instance.convertDaysToWorkingDays(5)); - assertEquals(2, instance.convertDaysToWorkingDays(6)); - assertEquals(3, instance.convertDaysToWorkingDays(7)); - - } - - @Test - public void testGetEasterSunday() throws InvalidArgumentException { - DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter - .initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-27T00:00:00.000Z")); - - assertEquals(LocalDate.of(2018, 4, 1), instance.getEasterSunday(2018)); - assertEquals(LocalDate.of(2019, 4, 21), instance.getEasterSunday(2019)); - assertEquals(LocalDate.of(2020, 4, 12), instance.getEasterSunday(2020)); - assertEquals(LocalDate.of(2021, 4, 4), instance.getEasterSunday(2021)); - assertEquals(LocalDate.of(2022, 4, 17), instance.getEasterSunday(2022)); - assertEquals(LocalDate.of(2023, 4, 9), instance.getEasterSunday(2023)); - assertEquals(LocalDate.of(2024, 3, 31), instance.getEasterSunday(2024)); - assertEquals(LocalDate.of(2025, 4, 20), instance.getEasterSunday(2025)); - assertEquals(LocalDate.of(2026, 4, 5), instance.getEasterSunday(2026)); - assertEquals(LocalDate.of(2027, 3, 28), instance.getEasterSunday(2027)); - assertEquals(LocalDate.of(2028, 4, 16), instance.getEasterSunday(2028)); - assertEquals(LocalDate.of(2029, 4, 1), instance.getEasterSunday(2029)); - assertEquals(LocalDate.of(2030, 4, 21), instance.getEasterSunday(2030)); - assertEquals(LocalDate.of(2031, 4, 13), instance.getEasterSunday(2031)); - assertEquals(LocalDate.of(2032, 3, 28), instance.getEasterSunday(2032)); - assertEquals(LocalDate.of(2033, 4, 17), instance.getEasterSunday(2033)); - assertEquals(LocalDate.of(2034, 4, 9), instance.getEasterSunday(2034)); - assertEquals(LocalDate.of(2035, 3, 25), instance.getEasterSunday(2035)); - assertEquals(LocalDate.of(2040, 4, 1), instance.getEasterSunday(2040)); - assertEquals(LocalDate.of(2050, 4, 10), instance.getEasterSunday(2050)); - assertEquals(LocalDate.of(2100, 3, 28), instance.getEasterSunday(2100)); - - } - - private List getShortListOfColumnHeaders() { - List columnHeaders = new ArrayList<>(); - columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -3)); - columnHeaders.add(new TimeIntervalColumnHeader(-1, -2)); - columnHeaders.add(new TimeIntervalColumnHeader(0)); - columnHeaders.add(new TimeIntervalColumnHeader(1, 2)); - columnHeaders.add(new TimeIntervalColumnHeader(3, Integer.MAX_VALUE)); - return columnHeaders; - } - - private List getLargeListOfColumnHeaders() { - List columnHeaders = new ArrayList<>(); - columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); - columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); - columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); - columnHeaders.add(new TimeIntervalColumnHeader(-1)); - columnHeaders.add(new TimeIntervalColumnHeader(0)); - columnHeaders.add(new TimeIntervalColumnHeader(1)); - columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); - columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); - columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); - return columnHeaders; - } -} +package pro.taskana.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.fail; + +import java.time.Instant; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; + +import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; + +/** + * Test for the DaysToWorkingDaysConverter. + */ +public class DaysToWorkingDaysConverterTest { + + @BeforeClass + public static void setup() { + DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled(true); + LocalDate dayOfReformation = LocalDate.of(2018, 10, 31); + LocalDate allSaintsDays = LocalDate.of(2018, 11, 1); + DaysToWorkingDaysConverter.setCustomHolidays(Arrays.asList(dayOfReformation, allSaintsDays)); + } + + @Test + public void testInitializeForDifferentReportLineItemDefinitions() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance1 = DaysToWorkingDaysConverter + .initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-03T00:00:00.000Z")); + DaysToWorkingDaysConverter instance2 = DaysToWorkingDaysConverter + .initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-03T00:00:00.000Z")); + DaysToWorkingDaysConverter instance3 = DaysToWorkingDaysConverter + .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-02-03T00:00:00.000Z")); + + assertEquals(instance1, instance2); + assertNotEquals(instance1, instance3); + } + + @Test + public void testConvertWorkingDaysToDaysForTasks() { + List reportItems = Collections.singletonList(new TimeIntervalColumnHeader(0)); + try { + DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(reportItems, Instant.now()); + + Instant thursday0201 = Instant.parse("2018-02-01T07:00:00.000Z"); + long days = converter.convertWorkingDaysToDays(thursday0201, 0); // = thursday + assertEquals(0, days); + days = converter.convertWorkingDaysToDays(thursday0201, 1); // fri + assertEquals(1, days); + days = converter.convertWorkingDaysToDays(thursday0201, 2); // mon + assertEquals(4, days); + days = converter.convertWorkingDaysToDays(thursday0201, 3); // tues + assertEquals(5, days); + days = converter.convertWorkingDaysToDays(thursday0201, 4); // we + assertEquals(6, days); + days = converter.convertWorkingDaysToDays(thursday0201, 5); // thurs + assertEquals(7, days); + days = converter.convertWorkingDaysToDays(thursday0201, 6); // fri + assertEquals(8, days); + days = converter.convertWorkingDaysToDays(thursday0201, 7); // mon + assertEquals(11, days); + days = converter.convertWorkingDaysToDays(thursday0201, 8); // tue + assertEquals(12, days); + days = converter.convertWorkingDaysToDays(thursday0201, 9); // we + assertEquals(13, days); + days = converter.convertWorkingDaysToDays(thursday0201, 10); // thu + assertEquals(14, days); + days = converter.convertWorkingDaysToDays(thursday0201, 11); // fri + assertEquals(15, days); + + Instant gruenDonnerstag2018 = Instant.parse("2018-03-29T01:00:00.000Z"); + days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 0); + assertEquals(0, days); + days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 1); // Karfreitag + assertEquals(5, days); // osterdienstag + days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 2); // Karfreitag + assertEquals(6, days); // ostermittwoch + + Instant freitag0427 = Instant.parse("2018-04-27T19:00:00.000Z"); + days = converter.convertWorkingDaysToDays(freitag0427, 0); + assertEquals(0, days); + days = converter.convertWorkingDaysToDays(freitag0427, 1); + assertEquals(3, days); // 30.4. + days = converter.convertWorkingDaysToDays(freitag0427, 2); + assertEquals(5, days); // 2.5. + + } catch (InvalidArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + fail(""); + } + + } + + @Test + public void testInitializeForDifferentDates() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance1 = DaysToWorkingDaysConverter + .initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-04T00:00:00.000Z")); + DaysToWorkingDaysConverter instance2 = DaysToWorkingDaysConverter + .initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-05T00:00:00.000Z")); + + assertNotEquals(instance1, instance2); + } + + @Test + public void testConvertDaysToWorkingDays() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter + .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-02-06T00:00:00.000Z")); + + assertEquals(-16, instance.convertDaysToWorkingDays(-16)); + assertEquals(-11, instance.convertDaysToWorkingDays(-15)); + + assertEquals(-2, instance.convertDaysToWorkingDays(-4)); + assertEquals(-1, instance.convertDaysToWorkingDays(-3)); + assertEquals(-1, instance.convertDaysToWorkingDays(-2)); + assertEquals(-1, instance.convertDaysToWorkingDays(-1)); + assertEquals(0, instance.convertDaysToWorkingDays(0)); + assertEquals(1, instance.convertDaysToWorkingDays(1)); + assertEquals(2, instance.convertDaysToWorkingDays(2)); + assertEquals(3, instance.convertDaysToWorkingDays(3)); + assertEquals(3, instance.convertDaysToWorkingDays(4)); + assertEquals(3, instance.convertDaysToWorkingDays(5)); + assertEquals(4, instance.convertDaysToWorkingDays(6)); + + assertEquals(11, instance.convertDaysToWorkingDays(15)); + assertEquals(16, instance.convertDaysToWorkingDays(16)); + } + + @Test + public void testConvertWorkingDaysToDays() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter + .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-02-27T00:00:00.000Z")); + + assertEquals(Arrays.asList(-13), instance.convertWorkingDaysToDays(-13)); + assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-12)); + + assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-8)); + assertEquals(Arrays.asList(-11), instance.convertWorkingDaysToDays(-7)); + assertEquals(Arrays.asList(-8, -9, -10), instance.convertWorkingDaysToDays(-6)); + assertEquals(Arrays.asList(-7), instance.convertWorkingDaysToDays(-5)); + assertEquals(Arrays.asList(-6), instance.convertWorkingDaysToDays(-4)); + assertEquals(Arrays.asList(-5), instance.convertWorkingDaysToDays(-3)); + assertEquals(Arrays.asList(-4), instance.convertWorkingDaysToDays(-2)); + assertEquals(Arrays.asList(-1, -2, -3), instance.convertWorkingDaysToDays(-1)); + assertEquals(Arrays.asList(0), instance.convertWorkingDaysToDays(0)); + assertEquals(Arrays.asList(1), instance.convertWorkingDaysToDays(1)); + assertEquals(Arrays.asList(2), instance.convertWorkingDaysToDays(2)); + assertEquals(Arrays.asList(3, 4, 5), instance.convertWorkingDaysToDays(3)); + assertEquals(Arrays.asList(6), instance.convertWorkingDaysToDays(4)); + assertEquals(Arrays.asList(7), instance.convertWorkingDaysToDays(5)); + assertEquals(Arrays.asList(8), instance.convertWorkingDaysToDays(6)); + assertEquals(Arrays.asList(9), instance.convertWorkingDaysToDays(7)); + assertEquals(Arrays.asList(10, 11, 12), instance.convertWorkingDaysToDays(8)); + assertEquals(Arrays.asList(13), instance.convertWorkingDaysToDays(9)); + assertEquals(Arrays.asList(14), instance.convertWorkingDaysToDays(10)); + assertEquals(Arrays.asList(15), instance.convertWorkingDaysToDays(11)); + + assertEquals(Arrays.asList(12), instance.convertWorkingDaysToDays(12)); + assertEquals(Arrays.asList(13), instance.convertWorkingDaysToDays(13)); + } + + @Test + public void testConvertWorkingDaysToDaysAtWeekend() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter + .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-03-10T00:00:00.000Z")); + + assertEquals(Arrays.asList(-13), instance.convertWorkingDaysToDays(-13)); + assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-12)); + + assertEquals(Arrays.asList(-10), instance.convertWorkingDaysToDays(-8)); + assertEquals(Arrays.asList(-9), instance.convertWorkingDaysToDays(-7)); + assertEquals(Arrays.asList(-8), instance.convertWorkingDaysToDays(-6)); + assertEquals(Arrays.asList(-5, -6, -7), instance.convertWorkingDaysToDays(-5)); + assertEquals(Arrays.asList(-4), instance.convertWorkingDaysToDays(-4)); + assertEquals(Arrays.asList(-3), instance.convertWorkingDaysToDays(-3)); + assertEquals(Arrays.asList(-2), instance.convertWorkingDaysToDays(-2)); + assertEquals(Arrays.asList(-1), instance.convertWorkingDaysToDays(-1)); + assertEquals(Arrays.asList(0, 1), instance.convertWorkingDaysToDays(0)); + assertEquals(Arrays.asList(2), instance.convertWorkingDaysToDays(1)); + assertEquals(Arrays.asList(3), instance.convertWorkingDaysToDays(2)); + assertEquals(Arrays.asList(4), instance.convertWorkingDaysToDays(3)); + assertEquals(Arrays.asList(5), instance.convertWorkingDaysToDays(4)); + assertEquals(Arrays.asList(6, 7, 8), instance.convertWorkingDaysToDays(5)); + assertEquals(Arrays.asList(9), instance.convertWorkingDaysToDays(6)); + assertEquals(Arrays.asList(10), instance.convertWorkingDaysToDays(7)); + assertEquals(Arrays.asList(11), instance.convertWorkingDaysToDays(8)); + assertEquals(Arrays.asList(12), instance.convertWorkingDaysToDays(9)); + assertEquals(Arrays.asList(13, 14, 15), instance.convertWorkingDaysToDays(10)); + assertEquals(Arrays.asList(16), instance.convertWorkingDaysToDays(11)); + + assertEquals(Arrays.asList(12), instance.convertWorkingDaysToDays(12)); + assertEquals(Arrays.asList(13), instance.convertWorkingDaysToDays(13)); + } + + @Test + public void testConvertWorkingDaysToDaysOnEasterSunday() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter + .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-04-01T00:00:00.000Z")); + + assertEquals(Arrays.asList(-13), instance.convertWorkingDaysToDays(-13)); + assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-12)); + + assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-8)); + assertEquals(Arrays.asList(-11), instance.convertWorkingDaysToDays(-7)); + assertEquals(Arrays.asList(-10), instance.convertWorkingDaysToDays(-6)); + assertEquals(Arrays.asList(-9), instance.convertWorkingDaysToDays(-5)); + assertEquals(Arrays.asList(-6, -7, -8), instance.convertWorkingDaysToDays(-4)); + assertEquals(Arrays.asList(-5), instance.convertWorkingDaysToDays(-3)); + assertEquals(Arrays.asList(-4), instance.convertWorkingDaysToDays(-2)); + assertEquals(Arrays.asList(-3), instance.convertWorkingDaysToDays(-1)); + assertEquals(Arrays.asList(0, 1, -1, -2), instance.convertWorkingDaysToDays(0)); + assertEquals(Arrays.asList(2), instance.convertWorkingDaysToDays(1)); + assertEquals(Arrays.asList(3), instance.convertWorkingDaysToDays(2)); + assertEquals(Arrays.asList(4), instance.convertWorkingDaysToDays(3)); + assertEquals(Arrays.asList(5, 6, 7), instance.convertWorkingDaysToDays(4)); + assertEquals(Arrays.asList(8), instance.convertWorkingDaysToDays(5)); + assertEquals(Arrays.asList(9), instance.convertWorkingDaysToDays(6)); + assertEquals(Arrays.asList(10), instance.convertWorkingDaysToDays(7)); + assertEquals(Arrays.asList(11), instance.convertWorkingDaysToDays(8)); + assertEquals(Arrays.asList(12, 13, 14), instance.convertWorkingDaysToDays(9)); + assertEquals(Arrays.asList(15), instance.convertWorkingDaysToDays(10)); + assertEquals(Arrays.asList(16), instance.convertWorkingDaysToDays(11)); + + assertEquals(Arrays.asList(12), instance.convertWorkingDaysToDays(12)); + assertEquals(Arrays.asList(13), instance.convertWorkingDaysToDays(13)); + } + + @Test + public void testEasterHolidays() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter + .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-03-28T00:00:00.000Z")); + + assertEquals(0, instance.convertDaysToWorkingDays(0)); + assertEquals(1, instance.convertDaysToWorkingDays(1)); + assertEquals(1, instance.convertDaysToWorkingDays(2)); + assertEquals(1, instance.convertDaysToWorkingDays(3)); + assertEquals(1, instance.convertDaysToWorkingDays(4)); + assertEquals(1, instance.convertDaysToWorkingDays(5)); + assertEquals(2, instance.convertDaysToWorkingDays(6)); + } + + @Test + public void testWhitsunHolidays() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter + .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-05-16T00:00:00.000Z")); + + assertEquals(0, instance.convertDaysToWorkingDays(0)); + assertEquals(1, instance.convertDaysToWorkingDays(1)); + assertEquals(2, instance.convertDaysToWorkingDays(2)); + assertEquals(2, instance.convertDaysToWorkingDays(3)); + assertEquals(2, instance.convertDaysToWorkingDays(4)); + assertEquals(2, instance.convertDaysToWorkingDays(5)); + assertEquals(3, instance.convertDaysToWorkingDays(6)); + } + + @Test + public void testLabourDayHoliday() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter + .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-04-26T00:00:00.000Z")); + + assertEquals(0, instance.convertDaysToWorkingDays(0)); + assertEquals(1, instance.convertDaysToWorkingDays(1)); + assertEquals(1, instance.convertDaysToWorkingDays(2)); + assertEquals(1, instance.convertDaysToWorkingDays(3)); + assertEquals(2, instance.convertDaysToWorkingDays(4)); + assertEquals(2, instance.convertDaysToWorkingDays(5)); + assertEquals(3, instance.convertDaysToWorkingDays(6)); + assertEquals(4, instance.convertDaysToWorkingDays(7)); + } + + @Test + public void testAscensionDayHoliday() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter + .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-05-07T00:00:00.000Z")); + + assertEquals(0, instance.convertDaysToWorkingDays(0)); + assertEquals(1, instance.convertDaysToWorkingDays(1)); + assertEquals(2, instance.convertDaysToWorkingDays(2)); + assertEquals(2, instance.convertDaysToWorkingDays(3)); + assertEquals(3, instance.convertDaysToWorkingDays(4)); + assertEquals(3, instance.convertDaysToWorkingDays(5)); + assertEquals(3, instance.convertDaysToWorkingDays(6)); + assertEquals(4, instance.convertDaysToWorkingDays(7)); + } + + @Test + public void testDayOfGermanUnityHoliday() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter + .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-10-01T00:00:00.000Z")); + + assertEquals(0, instance.convertDaysToWorkingDays(0)); + assertEquals(1, instance.convertDaysToWorkingDays(1)); + assertEquals(1, instance.convertDaysToWorkingDays(2)); + assertEquals(2, instance.convertDaysToWorkingDays(3)); + assertEquals(3, instance.convertDaysToWorkingDays(4)); + assertEquals(3, instance.convertDaysToWorkingDays(5)); + assertEquals(3, instance.convertDaysToWorkingDays(6)); + assertEquals(4, instance.convertDaysToWorkingDays(7)); + } + + @Test + public void testChristmasAndNewYearHolidays() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter + .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-12-20T00:00:00.000Z")); + + assertEquals(0, instance.convertDaysToWorkingDays(0)); + assertEquals(1, instance.convertDaysToWorkingDays(1)); + assertEquals(1, instance.convertDaysToWorkingDays(2)); + assertEquals(1, instance.convertDaysToWorkingDays(3)); + assertEquals(2, instance.convertDaysToWorkingDays(4)); + assertEquals(2, instance.convertDaysToWorkingDays(5)); + assertEquals(2, instance.convertDaysToWorkingDays(6)); + assertEquals(3, instance.convertDaysToWorkingDays(7)); + assertEquals(4, instance.convertDaysToWorkingDays(8)); + assertEquals(4, instance.convertDaysToWorkingDays(9)); + assertEquals(4, instance.convertDaysToWorkingDays(10)); + assertEquals(5, instance.convertDaysToWorkingDays(11)); + assertEquals(5, instance.convertDaysToWorkingDays(12)); + assertEquals(6, instance.convertDaysToWorkingDays(13)); + assertEquals(7, instance.convertDaysToWorkingDays(14)); + } + + @Test + public void testCustomHolidaysWithDayOfReformationAndAllSaintsDay() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter + .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-10-26T00:00:00.000Z")); + + assertEquals(0, instance.convertDaysToWorkingDays(0)); + assertEquals(0, instance.convertDaysToWorkingDays(1)); + assertEquals(0, instance.convertDaysToWorkingDays(2)); + assertEquals(1, instance.convertDaysToWorkingDays(3)); + assertEquals(2, instance.convertDaysToWorkingDays(4)); + assertEquals(2, instance.convertDaysToWorkingDays(5)); + assertEquals(2, instance.convertDaysToWorkingDays(6)); + assertEquals(3, instance.convertDaysToWorkingDays(7)); + + } + + @Test + public void testGetEasterSunday() throws InvalidArgumentException { + DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter + .initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-27T00:00:00.000Z")); + + assertEquals(LocalDate.of(2018, 4, 1), instance.getEasterSunday(2018)); + assertEquals(LocalDate.of(2019, 4, 21), instance.getEasterSunday(2019)); + assertEquals(LocalDate.of(2020, 4, 12), instance.getEasterSunday(2020)); + assertEquals(LocalDate.of(2021, 4, 4), instance.getEasterSunday(2021)); + assertEquals(LocalDate.of(2022, 4, 17), instance.getEasterSunday(2022)); + assertEquals(LocalDate.of(2023, 4, 9), instance.getEasterSunday(2023)); + assertEquals(LocalDate.of(2024, 3, 31), instance.getEasterSunday(2024)); + assertEquals(LocalDate.of(2025, 4, 20), instance.getEasterSunday(2025)); + assertEquals(LocalDate.of(2026, 4, 5), instance.getEasterSunday(2026)); + assertEquals(LocalDate.of(2027, 3, 28), instance.getEasterSunday(2027)); + assertEquals(LocalDate.of(2028, 4, 16), instance.getEasterSunday(2028)); + assertEquals(LocalDate.of(2029, 4, 1), instance.getEasterSunday(2029)); + assertEquals(LocalDate.of(2030, 4, 21), instance.getEasterSunday(2030)); + assertEquals(LocalDate.of(2031, 4, 13), instance.getEasterSunday(2031)); + assertEquals(LocalDate.of(2032, 3, 28), instance.getEasterSunday(2032)); + assertEquals(LocalDate.of(2033, 4, 17), instance.getEasterSunday(2033)); + assertEquals(LocalDate.of(2034, 4, 9), instance.getEasterSunday(2034)); + assertEquals(LocalDate.of(2035, 3, 25), instance.getEasterSunday(2035)); + assertEquals(LocalDate.of(2040, 4, 1), instance.getEasterSunday(2040)); + assertEquals(LocalDate.of(2050, 4, 10), instance.getEasterSunday(2050)); + assertEquals(LocalDate.of(2100, 3, 28), instance.getEasterSunday(2100)); + + } + + private List getShortListOfColumnHeaders() { + List columnHeaders = new ArrayList<>(); + columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -3)); + columnHeaders.add(new TimeIntervalColumnHeader(-1, -2)); + columnHeaders.add(new TimeIntervalColumnHeader(0)); + columnHeaders.add(new TimeIntervalColumnHeader(1, 2)); + columnHeaders.add(new TimeIntervalColumnHeader(3, Integer.MAX_VALUE)); + return columnHeaders; + } + + private List getLargeListOfColumnHeaders() { + List columnHeaders = new ArrayList<>(); + columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); + columnHeaders.add(new TimeIntervalColumnHeader(-10, -6)); + columnHeaders.add(new TimeIntervalColumnHeader(-5, -2)); + columnHeaders.add(new TimeIntervalColumnHeader(-1)); + columnHeaders.add(new TimeIntervalColumnHeader(0)); + columnHeaders.add(new TimeIntervalColumnHeader(1)); + columnHeaders.add(new TimeIntervalColumnHeader(2, 5)); + columnHeaders.add(new TimeIntervalColumnHeader(6, 10)); + columnHeaders.add(new TimeIntervalColumnHeader(11, Integer.MAX_VALUE)); + return columnHeaders; + } +} diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/TaskMonitorServiceImplTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/TaskMonitorServiceImplTest.java index 8b9581aae..d2d535002 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/TaskMonitorServiceImplTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/TaskMonitorServiceImplTest.java @@ -1,568 +1,568 @@ -package pro.taskana.impl; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InOrder; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.mockito.junit.MockitoJUnitRunner; - -import pro.taskana.CustomField; -import pro.taskana.TaskMonitorService; -import pro.taskana.TaskState; -import pro.taskana.configuration.TaskanaEngineConfiguration; -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.exceptions.NotAuthorizedException; -import pro.taskana.impl.report.impl.CategoryReport; -import pro.taskana.impl.report.impl.ClassificationReport; -import pro.taskana.impl.report.impl.CustomFieldValueReport; -import pro.taskana.impl.report.impl.DetailedClassificationReport; -import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; -import pro.taskana.impl.report.impl.DetailedReportRow; -import pro.taskana.impl.report.impl.MonitorQueryItem; -import pro.taskana.impl.report.impl.TaskQueryItem; -import pro.taskana.impl.report.impl.TaskStatusReport; -import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; -import pro.taskana.impl.report.impl.WorkbasketLevelReport; -import pro.taskana.mappings.TaskMonitorMapper; - -/** - * Unit Test for TaskMonitorServiceImpl. - */ -@RunWith(MockitoJUnitRunner.class) -public class TaskMonitorServiceImplTest { - - @InjectMocks - private TaskMonitorServiceImpl cut; - - @Mock - private TaskanaEngineImpl taskanaEngineImplMock; - - @Mock - private TaskanaEngineConfiguration taskanaEngineConfiguration; - - @Mock - private TaskMonitorMapper taskMonitorMapperMock; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - Mockito.doNothing().when(taskanaEngineImplMock).openConnection(); - Mockito.doNothing().when(taskanaEngineImplMock).returnConnection(); - doReturn(taskanaEngineConfiguration).when(taskanaEngineImplMock).getConfiguration(); - doReturn(true).when(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled(); - doReturn(null).when(taskanaEngineConfiguration).getCustomHolidays(); - } - - @Test - public void testGetTotalNumbersOfWorkbasketLevelReport() throws InvalidArgumentException, NotAuthorizedException { - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); - List categories = Collections.singletonList("EXTERN"); - List domains = Collections.singletonList("DOMAIN_A"); - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - - List expectedResult = new ArrayList<>(); - MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); - monitorQueryItem.setKey("WBI:000000000000000000000000000000000001"); - monitorQueryItem.setNumberOfTasks(1); - expectedResult.add(monitorQueryItem); - doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfWorkbaskets(workbasketIds, states, - categories, domains, customField, customFieldValues); - - WorkbasketLevelReport actualResult = cut.getWorkbasketLevelReport(workbasketIds, states, categories, domains, - customField, customFieldValues); - - verify(taskanaEngineImplMock, times(1)).openConnection(); - verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); - verify(taskanaEngineImplMock, times(2)).getConfiguration(); - verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); - verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); - verify(taskMonitorMapperMock, times(1)).getTaskCountOfWorkbaskets(any(), any(), any(), - any(), any(), any()); - verify(taskanaEngineImplMock, times(1)).returnConnection(); - verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); - - assertNotNull(actualResult); - assertEquals( - actualResult.getRow("WBI:000000000000000000000000000000000001").getTotalValue(), 1); - assertEquals(actualResult.getSumRow().getTotalValue(), 1); - } - - @Test - public void testGetWorkbasketLevelReportWithReportLineItemDefinitions() - throws InvalidArgumentException, NotAuthorizedException { - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); - List categories = Collections.singletonList("EXTERN"); - List domains = Collections.singletonList("DOMAIN_A"); - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - List reportLineItemDefinitions = Collections.singletonList( - new TimeIntervalColumnHeader(0, 0)); - - List expectedResult = new ArrayList<>(); - MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); - monitorQueryItem.setKey("WBI:000000000000000000000000000000000001"); - monitorQueryItem.setAgeInDays(0); - monitorQueryItem.setNumberOfTasks(1); - expectedResult.add(monitorQueryItem); - doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfWorkbaskets(workbasketIds, states, - categories, domains, customField, customFieldValues); - - WorkbasketLevelReport actualResult = cut.getWorkbasketLevelReport(workbasketIds, states, categories, domains, - customField, customFieldValues, reportLineItemDefinitions); - - verify(taskanaEngineImplMock, times(1)).openConnection(); - verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); - verify(taskanaEngineImplMock, times(2)).getConfiguration(); - verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); - verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); - verify(taskMonitorMapperMock, times(1)).getTaskCountOfWorkbaskets(any(), any(), any(), any(), any(), any()); - verify(taskanaEngineImplMock, times(1)).returnConnection(); - verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); - - assertNotNull(actualResult); - assertEquals( - actualResult.getRow("WBI:000000000000000000000000000000000001").getTotalValue(), 1); - assertEquals(actualResult.getRow("WBI:000000000000000000000000000000000001").getCells()[0], 1); - assertEquals(actualResult.getSumRow().getTotalValue(), 1); - } - - @Test - public void testGetTotalNumbersOfCatgoryReport() throws InvalidArgumentException, NotAuthorizedException { - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); - List categories = Collections.singletonList("EXTERN"); - List domains = Collections.singletonList("DOMAIN_A"); - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - - List expectedResult = new ArrayList<>(); - MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); - monitorQueryItem.setKey("EXTERN"); - monitorQueryItem.setNumberOfTasks(1); - expectedResult.add(monitorQueryItem); - doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfCategories(workbasketIds, states, categories, - domains, customField, customFieldValues); - - CategoryReport actualResult = cut.getCategoryReport(workbasketIds, states, categories, domains, - customField, customFieldValues); - - verify(taskanaEngineImplMock, times(1)).openConnection(); - verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); - verify(taskanaEngineImplMock, times(2)).getConfiguration(); - verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); - verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); - verify(taskMonitorMapperMock, times(1)).getTaskCountOfCategories(any(), any(), any(), any(), any(), any()); - verify(taskanaEngineImplMock, times(1)).returnConnection(); - verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); - - assertNotNull(actualResult); - assertEquals(actualResult.getRow("EXTERN").getTotalValue(), 1); - assertEquals(actualResult.getSumRow().getTotalValue(), 1); - } - - @Test - public void testGetCategoryReportWithReportLineItemDefinitions() - throws InvalidArgumentException, NotAuthorizedException { - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); - List categories = Collections.singletonList("EXTERN"); - List domains = Collections.singletonList("DOMAIN_A"); - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - List reportLineItemDefinitions = Collections.singletonList( - new TimeIntervalColumnHeader(0, 0)); - - List expectedResult = new ArrayList<>(); - MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); - monitorQueryItem.setKey("EXTERN"); - monitorQueryItem.setAgeInDays(0); - monitorQueryItem.setNumberOfTasks(1); - expectedResult.add(monitorQueryItem); - doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfCategories(workbasketIds, states, categories, - domains, customField, customFieldValues); - - CategoryReport actualResult = cut.getCategoryReport(workbasketIds, states, categories, domains, - customField, customFieldValues, reportLineItemDefinitions); - - verify(taskanaEngineImplMock, times(1)).openConnection(); - verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); - verify(taskanaEngineImplMock, times(2)).getConfiguration(); - verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); - verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); - verify(taskMonitorMapperMock, times(1)).getTaskCountOfCategories(any(), any(), any(), any(), any(), any()); - verify(taskanaEngineImplMock, times(1)).returnConnection(); - verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); - - assertNotNull(actualResult); - assertEquals(actualResult.getRow("EXTERN").getTotalValue(), 1); - assertEquals(actualResult.getRow("EXTERN").getCells()[0], 1); - assertEquals(actualResult.getSumRow().getTotalValue(), 1); - } - - @Test - public void testGetTotalNumbersOfClassificationReport() throws InvalidArgumentException, NotAuthorizedException { - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); - List categories = Collections.singletonList("EXTERN"); - List domains = Collections.singletonList("DOMAIN_A"); - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - - List expectedResult = new ArrayList<>(); - MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); - monitorQueryItem.setKey("CLI:000000000000000000000000000000000001"); - monitorQueryItem.setNumberOfTasks(1); - expectedResult.add(monitorQueryItem); - doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfClassifications(workbasketIds, states, - categories, domains, customField, customFieldValues); - - ClassificationReport actualResult = cut.getClassificationReport(workbasketIds, states, categories, domains, - customField, customFieldValues); - - verify(taskanaEngineImplMock, times(1)).openConnection(); - verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); - verify(taskanaEngineImplMock, times(2)).getConfiguration(); - verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); - verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); - verify(taskMonitorMapperMock, times(1)).getTaskCountOfClassifications(any(), any(), any(), any(), any(), any()); - verify(taskanaEngineImplMock, times(1)).returnConnection(); - verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); - - assertNotNull(actualResult); - assertEquals( - actualResult.getRow("CLI:000000000000000000000000000000000001").getTotalValue(), 1); - assertEquals(actualResult.getSumRow().getTotalValue(), 1); - } - - @Test - public void testGetClassificationReportWithReportLineItemDefinitions() - throws InvalidArgumentException, NotAuthorizedException { - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); - List categories = Collections.singletonList("EXTERN"); - List domains = Collections.singletonList("DOMAIN_A"); - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - - List reportLineItemDefinitions = Collections.singletonList( - new TimeIntervalColumnHeader(0, 0)); - - List expectedResult = new ArrayList<>(); - MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); - monitorQueryItem.setKey("CLI:000000000000000000000000000000000001"); - monitorQueryItem.setAgeInDays(0); - monitorQueryItem.setNumberOfTasks(1); - expectedResult.add(monitorQueryItem); - doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfClassifications(workbasketIds, states, - categories, domains, customField, customFieldValues); - - ClassificationReport actualResult = cut.getClassificationReport(workbasketIds, states, categories, domains, - customField, customFieldValues, reportLineItemDefinitions); - - verify(taskanaEngineImplMock, times(1)).openConnection(); - verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); - verify(taskanaEngineImplMock, times(2)).getConfiguration(); - verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); - verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); - verify(taskMonitorMapperMock, times(1)).getTaskCountOfClassifications(any(), any(), any(), any(), any(), any()); - verify(taskanaEngineImplMock, times(1)).returnConnection(); - verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); - - assertNotNull(actualResult); - assertEquals( - actualResult.getRow("CLI:000000000000000000000000000000000001").getTotalValue(), 1); - assertEquals(actualResult.getRow("CLI:000000000000000000000000000000000001").getCells()[0], 1); - assertEquals(actualResult.getSumRow().getTotalValue(), 1); - } - - @Test - public void testGetTotalNumbersOfDetailedClassificationReport() - throws InvalidArgumentException, NotAuthorizedException { - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); - List categories = Collections.singletonList("EXTERN"); - List domains = Collections.singletonList("DOMAIN_A"); - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - - List expectedResult = new ArrayList<>(); - DetailedMonitorQueryItem detailedMonitorQueryItem = new DetailedMonitorQueryItem(); - detailedMonitorQueryItem.setKey("CLI:000000000000000000000000000000000001"); - detailedMonitorQueryItem.setAttachmentKey("CLI:000000000000000000000000000000000006"); - detailedMonitorQueryItem.setNumberOfTasks(1); - expectedResult.add(detailedMonitorQueryItem); - doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfDetailedClassifications(workbasketIds, - states, categories, domains, customField, customFieldValues); - - DetailedClassificationReport actualResult = cut.getDetailedClassificationReport(workbasketIds, states, - categories, domains, customField, customFieldValues); - - verify(taskanaEngineImplMock, times(1)).openConnection(); - verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); - verify(taskanaEngineImplMock, times(2)).getConfiguration(); - verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); - verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); - verify(taskMonitorMapperMock, times(1)).getTaskCountOfDetailedClassifications(any(), any(), any(), any(), any(), - any()); - verify(taskanaEngineImplMock, times(1)).returnConnection(); - verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); - - DetailedReportRow line = actualResult.getRow("CLI:000000000000000000000000000000000001"); - assertNotNull(actualResult); - assertEquals(line.getTotalValue(), 1); - assertEquals(line.getDetailRows().get("CLI:000000000000000000000000000000000006").getTotalValue(), 1); - assertEquals(actualResult.getSumRow().getTotalValue(), 1); - } - - @Test - public void testGetDetailedClassificationReportWithReportLineItemDefinitions() - throws InvalidArgumentException, NotAuthorizedException { - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); - List categories = Collections.singletonList("EXTERN"); - List domains = Collections.singletonList("DOMAIN_A"); - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - List reportLineItemDefinitions = Collections.singletonList( - new TimeIntervalColumnHeader(0, 0)); - - List expectedResult = new ArrayList<>(); - DetailedMonitorQueryItem detailedMonitorQueryItem = new DetailedMonitorQueryItem(); - detailedMonitorQueryItem.setKey("CLI:000000000000000000000000000000000001"); - detailedMonitorQueryItem.setAttachmentKey("CLI:000000000000000000000000000000000006"); - detailedMonitorQueryItem.setAgeInDays(0); - detailedMonitorQueryItem.setNumberOfTasks(1); - expectedResult.add(detailedMonitorQueryItem); - doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfDetailedClassifications(workbasketIds, - states, categories, domains, customField, customFieldValues); - - DetailedClassificationReport actualResult = cut.getDetailedClassificationReport(workbasketIds, states, - categories, domains, customField, customFieldValues, reportLineItemDefinitions); - - verify(taskanaEngineImplMock, times(1)).openConnection(); - verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); - verify(taskanaEngineImplMock, times(2)).getConfiguration(); - verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); - verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); - verify(taskMonitorMapperMock, times(1)).getTaskCountOfDetailedClassifications(any(), any(), any(), any(), any(), - any()); - verify(taskanaEngineImplMock, times(1)).returnConnection(); - verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); - - DetailedReportRow line = actualResult.getRow("CLI:000000000000000000000000000000000001"); - assertNotNull(actualResult); - assertEquals(line.getTotalValue(), 1); - assertEquals(line.getDetailRows().get("CLI:000000000000000000000000000000000006").getTotalValue(), 1); - assertEquals(line.getCells()[0], 1); - assertEquals(line.getDetailRows().get("CLI:000000000000000000000000000000000006").getCells()[0], 1); - assertEquals(actualResult.getSumRow().getTotalValue(), 1); - assertEquals(actualResult.getSumRow().getCells()[0], 1); - } - - @Test - public void testGetTotalNumbersOfCustomFieldValueReport() throws InvalidArgumentException, NotAuthorizedException { - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); - List categories = Collections.singletonList("EXTERN"); - List domains = Collections.singletonList("DOMAIN_A"); - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - - List expectedResult = new ArrayList<>(); - MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); - monitorQueryItem.setKey("Geschaeftsstelle A"); - monitorQueryItem.setNumberOfTasks(1); - expectedResult.add(monitorQueryItem); - doReturn(expectedResult).when(taskMonitorMapperMock) - .getTaskCountOfCustomFieldValues(workbasketIds, states, categories, domains, customField, - customFieldValues); - - CustomFieldValueReport actualResult = cut.getCustomFieldValueReport(workbasketIds, states, categories, domains, - customField, customFieldValues); - - verify(taskanaEngineImplMock, times(1)).openConnection(); - verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); - verify(taskanaEngineImplMock, times(2)).getConfiguration(); - verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); - verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); - verify(taskMonitorMapperMock, times(1)).getTaskCountOfCustomFieldValues(any(), any(), any(), any(), any(), - any()); - verify(taskanaEngineImplMock, times(1)).returnConnection(); - verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); - - assertNotNull(actualResult); - assertEquals(actualResult.getRow("Geschaeftsstelle A").getTotalValue(), 1); - assertEquals(actualResult.getSumRow().getTotalValue(), 1); - } - - @Test - public void testGetCustomFieldValueReportWithReportLineItemDefinitions() - throws InvalidArgumentException, NotAuthorizedException { - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); - List categories = Collections.singletonList("EXTERN"); - List domains = Collections.singletonList("DOMAIN_A"); - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - List reportLineItemDefinitions = Collections.singletonList( - new TimeIntervalColumnHeader(0, 0)); - - List expectedResult = new ArrayList<>(); - MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); - monitorQueryItem.setKey("Geschaeftsstelle A"); - monitorQueryItem.setAgeInDays(0); - monitorQueryItem.setNumberOfTasks(1); - expectedResult.add(monitorQueryItem); - doReturn(expectedResult).when(taskMonitorMapperMock) - .getTaskCountOfCustomFieldValues(workbasketIds, states, categories, domains, customField, - customFieldValues); - - CustomFieldValueReport actualResult = cut.getCustomFieldValueReport(workbasketIds, states, categories, domains, - customField, customFieldValues, reportLineItemDefinitions); - - verify(taskanaEngineImplMock, times(1)).openConnection(); - verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); - verify(taskanaEngineImplMock, times(2)).getConfiguration(); - verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); - verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); - verify(taskMonitorMapperMock, times(1)) - .getTaskCountOfCustomFieldValues(any(), any(), any(), any(), any(), any()); - verify(taskanaEngineImplMock, times(1)).returnConnection(); - verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); - - assertNotNull(actualResult); - assertEquals(actualResult.getRow("Geschaeftsstelle A").getTotalValue(), 1); - assertEquals(actualResult.getRow("Geschaeftsstelle A").getCells()[0], 1); - assertEquals(actualResult.getSumRow().getTotalValue(), 1); - } - - @Test - public void testGetTaskIdsForSelectedItems() throws InvalidArgumentException, NotAuthorizedException { - List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); - List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); - List categories = Collections.singletonList("EXTERN"); - List domains = Collections.singletonList("DOMAIN_A"); - List classificationIds = Collections.singletonList("L10000"); - List excludedClassificationIds = Collections.singletonList("L20000"); - CustomField customField = CustomField.CUSTOM_1; - List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); - List reportLineItemDefinitions = Collections.singletonList( - new TimeIntervalColumnHeader(0, 0)); - - SelectedItem selectedItem = new SelectedItem(); - selectedItem.setKey("EXTERN"); - selectedItem.setLowerAgeLimit(1); - selectedItem.setUpperAgeLimit(5); - List selectedItems = Collections.singletonList(selectedItem); - - List expectedResult = Collections.singletonList("TKI:000000000000000000000000000000000001"); - when(taskMonitorMapperMock.getTaskIdsForSelectedItems(workbasketIds, - states, categories, domains, classificationIds, excludedClassificationIds, customField, customFieldValues, - "CLASSIFICATION_CATEGORY", selectedItems, false)).thenReturn(expectedResult); - - List actualResult = cut.getTaskIdsForSelectedItems(workbasketIds, states, categories, domains, - classificationIds, excludedClassificationIds, - customField, customFieldValues, reportLineItemDefinitions, true, selectedItems, - TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); - - verify(taskanaEngineImplMock, times(1)).openConnection(); - verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); - verify(taskanaEngineImplMock, times(2)).getConfiguration(); - verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); - verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); - verify(taskMonitorMapperMock, times(1)) - .getTaskIdsForSelectedItems(any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), - eq(false)); - verify(taskanaEngineImplMock, times(1)).returnConnection(); - verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); - - assertNotNull(actualResult); - assertEquals(expectedResult, actualResult); - } - - @Test - public void testGetTaskStateReportWithoutFilters() throws NotAuthorizedException { - // given - TaskQueryItem queryItem1 = new TaskQueryItem(); - queryItem1.setCount(50); - queryItem1.setState(TaskState.READY); - queryItem1.setDomain("DOMAIN_X"); - TaskQueryItem queryItem2 = new TaskQueryItem(); - queryItem2.setCount(30); - queryItem2.setState(TaskState.COMPLETED); - queryItem2.setDomain("DOMAIN_X"); - List queryItems = Arrays.asList(queryItem1, queryItem2); - when(taskMonitorMapperMock.getTasksCountByState(null, null)).thenReturn(queryItems); - - // when - TaskStatusReport report = cut.getTaskStatusReport(); - - // then - InOrder inOrder = inOrder(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineImplMock); - inOrder.verify(taskanaEngineImplMock).openConnection(); - inOrder.verify(taskMonitorMapperMock).getTasksCountByState(eq(null), eq(null)); - inOrder.verify(taskanaEngineImplMock).returnConnection(); - - 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()); - assertEquals(80, report.getRow("DOMAIN_X").getTotalValue()); - assertEquals(80, report.getSumRow().getTotalValue()); - } - - @Test - public void testGetTotalNumberOfTaskStateReport() throws NotAuthorizedException { - // given - TaskQueryItem queryItem1 = new TaskQueryItem(); - queryItem1.setCount(50); - queryItem1.setState(TaskState.READY); - queryItem1.setDomain("DOMAIN_X"); - TaskQueryItem queryItem2 = new TaskQueryItem(); - queryItem2.setCount(30); - queryItem2.setState(TaskState.COMPLETED); - queryItem2.setDomain("DOMAIN_X"); - List queryItems = Arrays.asList(queryItem1, queryItem2); - when(taskMonitorMapperMock.getTasksCountByState(eq(null), eq(Collections.emptyList()))).thenReturn(queryItems); - - // when - TaskStatusReport report = cut.getTaskStatusReport(null, Collections.emptyList()); - - // then - InOrder inOrder = inOrder(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineImplMock); - inOrder.verify(taskanaEngineImplMock).openConnection(); - inOrder.verify(taskMonitorMapperMock).getTasksCountByState(eq(null), eq(Collections.emptyList())); - inOrder.verify(taskanaEngineImplMock).returnConnection(); - - assertNotNull(report); - assertEquals(1, report.rowSize()); - assertArrayEquals(new int[0], report.getRow("DOMAIN_X").getCells()); - assertArrayEquals(new int[0], report.getSumRow().getCells()); - assertEquals(80, report.getRow("DOMAIN_X").getTotalValue()); - assertEquals(80, report.getSumRow().getTotalValue()); - } -} +package pro.taskana.impl; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InOrder; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; + +import pro.taskana.CustomField; +import pro.taskana.TaskMonitorService; +import pro.taskana.TaskState; +import pro.taskana.configuration.TaskanaEngineConfiguration; +import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.impl.report.impl.CategoryReport; +import pro.taskana.impl.report.impl.ClassificationReport; +import pro.taskana.impl.report.impl.CustomFieldValueReport; +import pro.taskana.impl.report.impl.DetailedClassificationReport; +import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; +import pro.taskana.impl.report.impl.DetailedReportRow; +import pro.taskana.impl.report.impl.MonitorQueryItem; +import pro.taskana.impl.report.impl.TaskQueryItem; +import pro.taskana.impl.report.impl.TaskStatusReport; +import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; +import pro.taskana.impl.report.impl.WorkbasketLevelReport; +import pro.taskana.mappings.TaskMonitorMapper; + +/** + * Unit Test for TaskMonitorServiceImpl. + */ +@RunWith(MockitoJUnitRunner.class) +public class TaskMonitorServiceImplTest { + + @InjectMocks + private TaskMonitorServiceImpl cut; + + @Mock + private TaskanaEngineImpl taskanaEngineImplMock; + + @Mock + private TaskanaEngineConfiguration taskanaEngineConfiguration; + + @Mock + private TaskMonitorMapper taskMonitorMapperMock; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + Mockito.doNothing().when(taskanaEngineImplMock).openConnection(); + Mockito.doNothing().when(taskanaEngineImplMock).returnConnection(); + doReturn(taskanaEngineConfiguration).when(taskanaEngineImplMock).getConfiguration(); + doReturn(true).when(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled(); + doReturn(null).when(taskanaEngineConfiguration).getCustomHolidays(); + } + + @Test + public void testGetTotalNumbersOfWorkbasketLevelReport() throws InvalidArgumentException, NotAuthorizedException { + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); + List categories = Collections.singletonList("EXTERN"); + List domains = Collections.singletonList("DOMAIN_A"); + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + + List expectedResult = new ArrayList<>(); + MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); + monitorQueryItem.setKey("WBI:000000000000000000000000000000000001"); + monitorQueryItem.setNumberOfTasks(1); + expectedResult.add(monitorQueryItem); + doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfWorkbaskets(workbasketIds, states, + categories, domains, customField, customFieldValues); + + WorkbasketLevelReport actualResult = cut.getWorkbasketLevelReport(workbasketIds, states, categories, domains, + customField, customFieldValues); + + verify(taskanaEngineImplMock, times(1)).openConnection(); + verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); + verify(taskanaEngineImplMock, times(2)).getConfiguration(); + verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); + verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); + verify(taskMonitorMapperMock, times(1)).getTaskCountOfWorkbaskets(any(), any(), any(), + any(), any(), any()); + verify(taskanaEngineImplMock, times(1)).returnConnection(); + verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); + + assertNotNull(actualResult); + assertEquals( + actualResult.getRow("WBI:000000000000000000000000000000000001").getTotalValue(), 1); + assertEquals(actualResult.getSumRow().getTotalValue(), 1); + } + + @Test + public void testGetWorkbasketLevelReportWithReportLineItemDefinitions() + throws InvalidArgumentException, NotAuthorizedException { + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); + List categories = Collections.singletonList("EXTERN"); + List domains = Collections.singletonList("DOMAIN_A"); + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + List reportLineItemDefinitions = Collections.singletonList( + new TimeIntervalColumnHeader(0, 0)); + + List expectedResult = new ArrayList<>(); + MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); + monitorQueryItem.setKey("WBI:000000000000000000000000000000000001"); + monitorQueryItem.setAgeInDays(0); + monitorQueryItem.setNumberOfTasks(1); + expectedResult.add(monitorQueryItem); + doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfWorkbaskets(workbasketIds, states, + categories, domains, customField, customFieldValues); + + WorkbasketLevelReport actualResult = cut.getWorkbasketLevelReport(workbasketIds, states, categories, domains, + customField, customFieldValues, reportLineItemDefinitions); + + verify(taskanaEngineImplMock, times(1)).openConnection(); + verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); + verify(taskanaEngineImplMock, times(2)).getConfiguration(); + verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); + verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); + verify(taskMonitorMapperMock, times(1)).getTaskCountOfWorkbaskets(any(), any(), any(), any(), any(), any()); + verify(taskanaEngineImplMock, times(1)).returnConnection(); + verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); + + assertNotNull(actualResult); + assertEquals( + actualResult.getRow("WBI:000000000000000000000000000000000001").getTotalValue(), 1); + assertEquals(actualResult.getRow("WBI:000000000000000000000000000000000001").getCells()[0], 1); + assertEquals(actualResult.getSumRow().getTotalValue(), 1); + } + + @Test + public void testGetTotalNumbersOfCatgoryReport() throws InvalidArgumentException, NotAuthorizedException { + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); + List categories = Collections.singletonList("EXTERN"); + List domains = Collections.singletonList("DOMAIN_A"); + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + + List expectedResult = new ArrayList<>(); + MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); + monitorQueryItem.setKey("EXTERN"); + monitorQueryItem.setNumberOfTasks(1); + expectedResult.add(monitorQueryItem); + doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfCategories(workbasketIds, states, categories, + domains, customField, customFieldValues); + + CategoryReport actualResult = cut.getCategoryReport(workbasketIds, states, categories, domains, + customField, customFieldValues); + + verify(taskanaEngineImplMock, times(1)).openConnection(); + verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); + verify(taskanaEngineImplMock, times(2)).getConfiguration(); + verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); + verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); + verify(taskMonitorMapperMock, times(1)).getTaskCountOfCategories(any(), any(), any(), any(), any(), any()); + verify(taskanaEngineImplMock, times(1)).returnConnection(); + verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); + + assertNotNull(actualResult); + assertEquals(actualResult.getRow("EXTERN").getTotalValue(), 1); + assertEquals(actualResult.getSumRow().getTotalValue(), 1); + } + + @Test + public void testGetCategoryReportWithReportLineItemDefinitions() + throws InvalidArgumentException, NotAuthorizedException { + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); + List categories = Collections.singletonList("EXTERN"); + List domains = Collections.singletonList("DOMAIN_A"); + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + List reportLineItemDefinitions = Collections.singletonList( + new TimeIntervalColumnHeader(0, 0)); + + List expectedResult = new ArrayList<>(); + MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); + monitorQueryItem.setKey("EXTERN"); + monitorQueryItem.setAgeInDays(0); + monitorQueryItem.setNumberOfTasks(1); + expectedResult.add(monitorQueryItem); + doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfCategories(workbasketIds, states, categories, + domains, customField, customFieldValues); + + CategoryReport actualResult = cut.getCategoryReport(workbasketIds, states, categories, domains, + customField, customFieldValues, reportLineItemDefinitions); + + verify(taskanaEngineImplMock, times(1)).openConnection(); + verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); + verify(taskanaEngineImplMock, times(2)).getConfiguration(); + verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); + verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); + verify(taskMonitorMapperMock, times(1)).getTaskCountOfCategories(any(), any(), any(), any(), any(), any()); + verify(taskanaEngineImplMock, times(1)).returnConnection(); + verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); + + assertNotNull(actualResult); + assertEquals(actualResult.getRow("EXTERN").getTotalValue(), 1); + assertEquals(actualResult.getRow("EXTERN").getCells()[0], 1); + assertEquals(actualResult.getSumRow().getTotalValue(), 1); + } + + @Test + public void testGetTotalNumbersOfClassificationReport() throws InvalidArgumentException, NotAuthorizedException { + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); + List categories = Collections.singletonList("EXTERN"); + List domains = Collections.singletonList("DOMAIN_A"); + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + + List expectedResult = new ArrayList<>(); + MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); + monitorQueryItem.setKey("CLI:000000000000000000000000000000000001"); + monitorQueryItem.setNumberOfTasks(1); + expectedResult.add(monitorQueryItem); + doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfClassifications(workbasketIds, states, + categories, domains, customField, customFieldValues); + + ClassificationReport actualResult = cut.getClassificationReport(workbasketIds, states, categories, domains, + customField, customFieldValues); + + verify(taskanaEngineImplMock, times(1)).openConnection(); + verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); + verify(taskanaEngineImplMock, times(2)).getConfiguration(); + verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); + verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); + verify(taskMonitorMapperMock, times(1)).getTaskCountOfClassifications(any(), any(), any(), any(), any(), any()); + verify(taskanaEngineImplMock, times(1)).returnConnection(); + verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); + + assertNotNull(actualResult); + assertEquals( + actualResult.getRow("CLI:000000000000000000000000000000000001").getTotalValue(), 1); + assertEquals(actualResult.getSumRow().getTotalValue(), 1); + } + + @Test + public void testGetClassificationReportWithReportLineItemDefinitions() + throws InvalidArgumentException, NotAuthorizedException { + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); + List categories = Collections.singletonList("EXTERN"); + List domains = Collections.singletonList("DOMAIN_A"); + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + + List reportLineItemDefinitions = Collections.singletonList( + new TimeIntervalColumnHeader(0, 0)); + + List expectedResult = new ArrayList<>(); + MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); + monitorQueryItem.setKey("CLI:000000000000000000000000000000000001"); + monitorQueryItem.setAgeInDays(0); + monitorQueryItem.setNumberOfTasks(1); + expectedResult.add(monitorQueryItem); + doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfClassifications(workbasketIds, states, + categories, domains, customField, customFieldValues); + + ClassificationReport actualResult = cut.getClassificationReport(workbasketIds, states, categories, domains, + customField, customFieldValues, reportLineItemDefinitions); + + verify(taskanaEngineImplMock, times(1)).openConnection(); + verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); + verify(taskanaEngineImplMock, times(2)).getConfiguration(); + verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); + verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); + verify(taskMonitorMapperMock, times(1)).getTaskCountOfClassifications(any(), any(), any(), any(), any(), any()); + verify(taskanaEngineImplMock, times(1)).returnConnection(); + verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); + + assertNotNull(actualResult); + assertEquals( + actualResult.getRow("CLI:000000000000000000000000000000000001").getTotalValue(), 1); + assertEquals(actualResult.getRow("CLI:000000000000000000000000000000000001").getCells()[0], 1); + assertEquals(actualResult.getSumRow().getTotalValue(), 1); + } + + @Test + public void testGetTotalNumbersOfDetailedClassificationReport() + throws InvalidArgumentException, NotAuthorizedException { + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); + List categories = Collections.singletonList("EXTERN"); + List domains = Collections.singletonList("DOMAIN_A"); + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + + List expectedResult = new ArrayList<>(); + DetailedMonitorQueryItem detailedMonitorQueryItem = new DetailedMonitorQueryItem(); + detailedMonitorQueryItem.setKey("CLI:000000000000000000000000000000000001"); + detailedMonitorQueryItem.setAttachmentKey("CLI:000000000000000000000000000000000006"); + detailedMonitorQueryItem.setNumberOfTasks(1); + expectedResult.add(detailedMonitorQueryItem); + doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfDetailedClassifications(workbasketIds, + states, categories, domains, customField, customFieldValues); + + DetailedClassificationReport actualResult = cut.getDetailedClassificationReport(workbasketIds, states, + categories, domains, customField, customFieldValues); + + verify(taskanaEngineImplMock, times(1)).openConnection(); + verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); + verify(taskanaEngineImplMock, times(2)).getConfiguration(); + verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); + verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); + verify(taskMonitorMapperMock, times(1)).getTaskCountOfDetailedClassifications(any(), any(), any(), any(), any(), + any()); + verify(taskanaEngineImplMock, times(1)).returnConnection(); + verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); + + DetailedReportRow line = actualResult.getRow("CLI:000000000000000000000000000000000001"); + assertNotNull(actualResult); + assertEquals(line.getTotalValue(), 1); + assertEquals(line.getDetailRows().get("CLI:000000000000000000000000000000000006").getTotalValue(), 1); + assertEquals(actualResult.getSumRow().getTotalValue(), 1); + } + + @Test + public void testGetDetailedClassificationReportWithReportLineItemDefinitions() + throws InvalidArgumentException, NotAuthorizedException { + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); + List categories = Collections.singletonList("EXTERN"); + List domains = Collections.singletonList("DOMAIN_A"); + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + List reportLineItemDefinitions = Collections.singletonList( + new TimeIntervalColumnHeader(0, 0)); + + List expectedResult = new ArrayList<>(); + DetailedMonitorQueryItem detailedMonitorQueryItem = new DetailedMonitorQueryItem(); + detailedMonitorQueryItem.setKey("CLI:000000000000000000000000000000000001"); + detailedMonitorQueryItem.setAttachmentKey("CLI:000000000000000000000000000000000006"); + detailedMonitorQueryItem.setAgeInDays(0); + detailedMonitorQueryItem.setNumberOfTasks(1); + expectedResult.add(detailedMonitorQueryItem); + doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfDetailedClassifications(workbasketIds, + states, categories, domains, customField, customFieldValues); + + DetailedClassificationReport actualResult = cut.getDetailedClassificationReport(workbasketIds, states, + categories, domains, customField, customFieldValues, reportLineItemDefinitions); + + verify(taskanaEngineImplMock, times(1)).openConnection(); + verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); + verify(taskanaEngineImplMock, times(2)).getConfiguration(); + verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); + verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); + verify(taskMonitorMapperMock, times(1)).getTaskCountOfDetailedClassifications(any(), any(), any(), any(), any(), + any()); + verify(taskanaEngineImplMock, times(1)).returnConnection(); + verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); + + DetailedReportRow line = actualResult.getRow("CLI:000000000000000000000000000000000001"); + assertNotNull(actualResult); + assertEquals(line.getTotalValue(), 1); + assertEquals(line.getDetailRows().get("CLI:000000000000000000000000000000000006").getTotalValue(), 1); + assertEquals(line.getCells()[0], 1); + assertEquals(line.getDetailRows().get("CLI:000000000000000000000000000000000006").getCells()[0], 1); + assertEquals(actualResult.getSumRow().getTotalValue(), 1); + assertEquals(actualResult.getSumRow().getCells()[0], 1); + } + + @Test + public void testGetTotalNumbersOfCustomFieldValueReport() throws InvalidArgumentException, NotAuthorizedException { + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); + List categories = Collections.singletonList("EXTERN"); + List domains = Collections.singletonList("DOMAIN_A"); + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + + List expectedResult = new ArrayList<>(); + MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); + monitorQueryItem.setKey("Geschaeftsstelle A"); + monitorQueryItem.setNumberOfTasks(1); + expectedResult.add(monitorQueryItem); + doReturn(expectedResult).when(taskMonitorMapperMock) + .getTaskCountOfCustomFieldValues(workbasketIds, states, categories, domains, customField, + customFieldValues); + + CustomFieldValueReport actualResult = cut.getCustomFieldValueReport(workbasketIds, states, categories, domains, + customField, customFieldValues); + + verify(taskanaEngineImplMock, times(1)).openConnection(); + verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); + verify(taskanaEngineImplMock, times(2)).getConfiguration(); + verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); + verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); + verify(taskMonitorMapperMock, times(1)).getTaskCountOfCustomFieldValues(any(), any(), any(), any(), any(), + any()); + verify(taskanaEngineImplMock, times(1)).returnConnection(); + verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); + + assertNotNull(actualResult); + assertEquals(actualResult.getRow("Geschaeftsstelle A").getTotalValue(), 1); + assertEquals(actualResult.getSumRow().getTotalValue(), 1); + } + + @Test + public void testGetCustomFieldValueReportWithReportLineItemDefinitions() + throws InvalidArgumentException, NotAuthorizedException { + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); + List categories = Collections.singletonList("EXTERN"); + List domains = Collections.singletonList("DOMAIN_A"); + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + List reportLineItemDefinitions = Collections.singletonList( + new TimeIntervalColumnHeader(0, 0)); + + List expectedResult = new ArrayList<>(); + MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); + monitorQueryItem.setKey("Geschaeftsstelle A"); + monitorQueryItem.setAgeInDays(0); + monitorQueryItem.setNumberOfTasks(1); + expectedResult.add(monitorQueryItem); + doReturn(expectedResult).when(taskMonitorMapperMock) + .getTaskCountOfCustomFieldValues(workbasketIds, states, categories, domains, customField, + customFieldValues); + + CustomFieldValueReport actualResult = cut.getCustomFieldValueReport(workbasketIds, states, categories, domains, + customField, customFieldValues, reportLineItemDefinitions); + + verify(taskanaEngineImplMock, times(1)).openConnection(); + verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); + verify(taskanaEngineImplMock, times(2)).getConfiguration(); + verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); + verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); + verify(taskMonitorMapperMock, times(1)) + .getTaskCountOfCustomFieldValues(any(), any(), any(), any(), any(), any()); + verify(taskanaEngineImplMock, times(1)).returnConnection(); + verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); + + assertNotNull(actualResult); + assertEquals(actualResult.getRow("Geschaeftsstelle A").getTotalValue(), 1); + assertEquals(actualResult.getRow("Geschaeftsstelle A").getCells()[0], 1); + assertEquals(actualResult.getSumRow().getTotalValue(), 1); + } + + @Test + public void testGetTaskIdsForSelectedItems() throws InvalidArgumentException, NotAuthorizedException { + List workbasketIds = Collections.singletonList("WBI:000000000000000000000000000000000001"); + List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); + List categories = Collections.singletonList("EXTERN"); + List domains = Collections.singletonList("DOMAIN_A"); + List classificationIds = Collections.singletonList("L10000"); + List excludedClassificationIds = Collections.singletonList("L20000"); + CustomField customField = CustomField.CUSTOM_1; + List customFieldValues = Collections.singletonList("Geschaeftsstelle A"); + List reportLineItemDefinitions = Collections.singletonList( + new TimeIntervalColumnHeader(0, 0)); + + SelectedItem selectedItem = new SelectedItem(); + selectedItem.setKey("EXTERN"); + selectedItem.setLowerAgeLimit(1); + selectedItem.setUpperAgeLimit(5); + List selectedItems = Collections.singletonList(selectedItem); + + List expectedResult = Collections.singletonList("TKI:000000000000000000000000000000000001"); + when(taskMonitorMapperMock.getTaskIdsForSelectedItems(workbasketIds, + states, categories, domains, classificationIds, excludedClassificationIds, customField, customFieldValues, + "CLASSIFICATION_CATEGORY", selectedItems, false)).thenReturn(expectedResult); + + List actualResult = cut.getTaskIdsForSelectedItems(workbasketIds, states, categories, domains, + classificationIds, excludedClassificationIds, + customField, customFieldValues, reportLineItemDefinitions, true, selectedItems, + TaskMonitorService.DIMENSION_CLASSIFICATION_CATEGORY); + + verify(taskanaEngineImplMock, times(1)).openConnection(); + verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); + verify(taskanaEngineImplMock, times(2)).getConfiguration(); + verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); + verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); + verify(taskMonitorMapperMock, times(1)) + .getTaskIdsForSelectedItems(any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), + eq(false)); + verify(taskanaEngineImplMock, times(1)).returnConnection(); + verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); + + assertNotNull(actualResult); + assertEquals(expectedResult, actualResult); + } + + @Test + public void testGetTaskStateReportWithoutFilters() throws NotAuthorizedException { + // given + TaskQueryItem queryItem1 = new TaskQueryItem(); + queryItem1.setCount(50); + queryItem1.setState(TaskState.READY); + queryItem1.setDomain("DOMAIN_X"); + TaskQueryItem queryItem2 = new TaskQueryItem(); + queryItem2.setCount(30); + queryItem2.setState(TaskState.COMPLETED); + queryItem2.setDomain("DOMAIN_X"); + List queryItems = Arrays.asList(queryItem1, queryItem2); + when(taskMonitorMapperMock.getTasksCountByState(null, null)).thenReturn(queryItems); + + // when + TaskStatusReport report = cut.getTaskStatusReport(); + + // then + InOrder inOrder = inOrder(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineImplMock); + inOrder.verify(taskanaEngineImplMock).openConnection(); + inOrder.verify(taskMonitorMapperMock).getTasksCountByState(eq(null), eq(null)); + inOrder.verify(taskanaEngineImplMock).returnConnection(); + + 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()); + assertEquals(80, report.getRow("DOMAIN_X").getTotalValue()); + assertEquals(80, report.getSumRow().getTotalValue()); + } + + @Test + public void testGetTotalNumberOfTaskStateReport() throws NotAuthorizedException { + // given + TaskQueryItem queryItem1 = new TaskQueryItem(); + queryItem1.setCount(50); + queryItem1.setState(TaskState.READY); + queryItem1.setDomain("DOMAIN_X"); + TaskQueryItem queryItem2 = new TaskQueryItem(); + queryItem2.setCount(30); + queryItem2.setState(TaskState.COMPLETED); + queryItem2.setDomain("DOMAIN_X"); + List queryItems = Arrays.asList(queryItem1, queryItem2); + when(taskMonitorMapperMock.getTasksCountByState(eq(null), eq(Collections.emptyList()))).thenReturn(queryItems); + + // when + TaskStatusReport report = cut.getTaskStatusReport(null, Collections.emptyList()); + + // then + InOrder inOrder = inOrder(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineImplMock); + inOrder.verify(taskanaEngineImplMock).openConnection(); + inOrder.verify(taskMonitorMapperMock).getTasksCountByState(eq(null), eq(Collections.emptyList())); + inOrder.verify(taskanaEngineImplMock).returnConnection(); + + assertNotNull(report); + assertEquals(1, report.rowSize()); + assertArrayEquals(new int[0], report.getRow("DOMAIN_X").getCells()); + assertArrayEquals(new int[0], report.getSumRow().getCells()); + assertEquals(80, report.getRow("DOMAIN_X").getTotalValue()); + assertEquals(80, report.getSumRow().getTotalValue()); + } +} diff --git a/lib/taskana-core/src/test/java/pro/taskana/security/JAASRunner.java b/lib/taskana-core/src/test/java/pro/taskana/security/JAASRunner.java index 41afb93a1..47e41352d 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/security/JAASRunner.java +++ b/lib/taskana-core/src/test/java/pro/taskana/security/JAASRunner.java @@ -1,83 +1,83 @@ -package pro.taskana.security; - -import java.security.Principal; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.ArrayList; -import java.util.List; - -import javax.security.auth.Subject; - -import org.junit.runners.BlockJUnit4ClassRunner; -import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.InitializationError; -import org.junit.runners.model.Statement; - -/** - * Runner for integration tests that enables JAAS subject. - */ -public class JAASRunner extends BlockJUnit4ClassRunner { - - public JAASRunner(Class c) throws InitializationError { - super(c); - } - - @Override - protected Statement methodInvoker(FrameworkMethod method, Object test) { - - Subject subject = new Subject(); - List principalList = new ArrayList<>(); - - if (test != null) { - WithAccessId withAccessId = method.getMethod().getAnnotation(WithAccessId.class); - if (withAccessId != null) { - if (withAccessId.userName() != null) { - principalList.add(new UserPrincipal(withAccessId.userName())); - } - for (String groupName : withAccessId.groupNames()) { - if (groupName != null) { - principalList.add(new GroupPrincipal(groupName)); - } - } - } - subject.getPrincipals().addAll(principalList); - } - - final Statement base = super.methodInvoker(method, test); - return new Statement() { - - @Override - public void evaluate() throws Throwable { - try { - Subject.doAs(subject, new PrivilegedExceptionAction() { - - @Override - public Object run() throws Exception { - - try { - base.evaluate(); - } catch (Throwable e) { - throw new Exception(e); - } - return null; - } - }); - } catch (PrivilegedActionException e) { - Throwable cause = e.getCause(); - Throwable nestedCause = null; - if (cause != null) { - nestedCause = cause.getCause(); - } - if (nestedCause != null) { - throw nestedCause; - } else if (cause != null) { - throw cause; - } else { - throw e; - } - } - } - }; - } - -} +package pro.taskana.security; + +import java.security.Principal; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; +import java.util.List; + +import javax.security.auth.Subject; + +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.InitializationError; +import org.junit.runners.model.Statement; + +/** + * Runner for integration tests that enables JAAS subject. + */ +public class JAASRunner extends BlockJUnit4ClassRunner { + + public JAASRunner(Class c) throws InitializationError { + super(c); + } + + @Override + protected Statement methodInvoker(FrameworkMethod method, Object test) { + + Subject subject = new Subject(); + List principalList = new ArrayList<>(); + + if (test != null) { + WithAccessId withAccessId = method.getMethod().getAnnotation(WithAccessId.class); + if (withAccessId != null) { + if (withAccessId.userName() != null) { + principalList.add(new UserPrincipal(withAccessId.userName())); + } + for (String groupName : withAccessId.groupNames()) { + if (groupName != null) { + principalList.add(new GroupPrincipal(groupName)); + } + } + } + subject.getPrincipals().addAll(principalList); + } + + final Statement base = super.methodInvoker(method, test); + return new Statement() { + + @Override + public void evaluate() throws Throwable { + try { + Subject.doAs(subject, new PrivilegedExceptionAction() { + + @Override + public Object run() throws Exception { + + try { + base.evaluate(); + } catch (Throwable e) { + throw new Exception(e); + } + return null; + } + }); + } catch (PrivilegedActionException e) { + Throwable cause = e.getCause(); + Throwable nestedCause = null; + if (cause != null) { + nestedCause = cause.getCause(); + } + if (nestedCause != null) { + throw nestedCause; + } else if (cause != null) { + throw cause; + } else { + throw e; + } + } + } + }; + } + +} diff --git a/lib/taskana-core/src/test/resources/sql/monitor-sample-data.sql b/lib/taskana-core/src/test/resources/sql/monitor-sample-data.sql index 255b7000b..c0aef9ffe 100644 --- a/lib/taskana-core/src/test/resources/sql/monitor-sample-data.sql +++ b/lib/taskana-core/src/test/resources/sql/monitor-sample-data.sql @@ -1,81 +1,81 @@ --- WORKBASKET TABLE (ID , KEY , CREATED , MODIFIED , NAME , DOMAIN , TYPE , DESCRIPTION , OWNER , CUSTOM_1 , CUSTOM_2 , CUSTOM_3 , CUSTOM_4 , ORG_LEVEL_1 , ORG_LEVEL_2 , ORG_LEVEL_3 , ORG_LEVEL_4 ); -INSERT INTO TASKANA.WORKBASKET VALUES ('WBI:000000000000000000000000000000000001', 'USER_1_1', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'PPK User 1 KSC 1', 'MONITOR_TEST_DOMAIN', 'PERSONAL', 'Monitor Test Postkorb 1', 'John' , '' , '' , '' , '' , '' , '' , '' , '' ); -INSERT INTO TASKANA.WORKBASKET VALUES ('WBI:000000000000000000000000000000000002', 'USER_1_2', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'PPK User 1 KSC 2', 'MONITOR_TEST_DOMAIN', 'PERSONAL', 'Monitor Test Postkorb 2', 'John' , '' , '' , '' , '' , '' , '' , '' , '' ); -INSERT INTO TASKANA.WORKBASKET VALUES ('WBI:000000000000000000000000000000000003', 'USER_1_3', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'PPK User 1 KSC 3', 'MONITOR_TEST_DOMAIN', 'PERSONAL', 'Monitor Test Postkorb 3', 'John' , '' , '' , '' , '' , '' , '' , '' , '' ); -INSERT INTO TASKANA.WORKBASKET VALUES ('WBI:000000000000000000000000000000000004', 'USER_1_4', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'PPK User 1 KSC 4', 'MONITOR_TEST_DOMAIN', 'PERSONAL', 'Monitor Test Postkorb 4', 'John' , '' , '' , '' , '' , '' , '' , '' , '' ); - --- CLASSIFICATION TABLE (ID , KEY , PARENT_ID , CATEGORY , TYPE , DOMAIN , VALID_IN_DOMAIN, CREATED , MODIFIED ,NAME , DESCRIPTION , PRIORITY, SERVICE_LEVEL, APPLICATION_ENTRY_POINT, CUSTOM_1 , CUSTOM_2, CUSTOM_3, CUSTOM_4, CUSTOM_5, CUSTOM_6, CUSTOM_7, CUSTOM_8 ); -INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000001', 'L10000', '' , 'EXTERN' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'OLD-Leistungsfall' , 'OLD-Leistungsfall' , 3 , 'P1D' , '' , 'VNR,RVNR,KOLVNR' , '' , '' , '' , '' , '' , '' , '' ); -INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000002', 'L20000', 'CLI:000000000000000000000000000000000001' , 'EXTERN' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Beratungsprotokoll' , 'Beratungsprotokoll', 1 , 'P1D' , '' , 'VNR,RVNR,KOLVNR, ANR', '' , '' , '' , '' , '' , '' , '' ); -INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000003', 'L30000', 'CLI:000000000000000000000000000000000001' , 'AUTOMATIC', 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Widerruf' , 'Widerruf' , 1 , 'P1D' , '' , 'VNR,RVNR,KOLVNR' , '' , '' , '' , '' , '' , '' , '' ); -INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000004', 'L40000', 'CLI:000000000000000000000000000000000001' , 'MANUAL' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamikaenderung' , 'Dynamikaenderung' , 1 , 'P1D' , '' , 'VNR,RVNR,KOLVNR' , '' , '' , '' , '' , '' , '' , '' ); -INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000005', 'L50000', 'CLI:000000000000000000000000000000000001' , 'EXTERN' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamik-Ablehnung' , 'Dynamik-Ablehnung' , 5 , 'P5D' , '' , 'VNR,RVNR,KOLVNR' , '' , '' , '' , '' , '' , '' , '' ); -INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000006', 'L11000', '' , 'Anhang' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Anhang 1' , 'Anhang 1' , 3 , 'P1D' , '' , 'VNR,RVNR,KOLVNR' , '' , '' , '' , '' , '' , '' , '' ); -INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000007', 'L22000', '' , 'Anhang' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Anhang 2' , 'Anhang 2' , 1 , 'P1D' , '' , 'VNR,RVNR,KOLVNR, ANR', '' , '' , '' , '' , '' , '' , '' ); -INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000008', 'L33000', '' , 'Anhang' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Anhang 3' , 'Anhang 3' , 1 , 'P1D' , '' , 'VNR,RVNR,KOLVNR, ANR', '' , '' , '' , '' , '' , '' , '' ); -INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000009', 'L99000', '' , 'Anhang' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Anhang 9' , 'Anhang 9' , 1 , 'P1D' , '' , 'VNR,RVNR,KOLVNR, ANR', '' , '' , '' , '' , '' , '' , '' ); - --- ATTACHMENT TABLE (ID , TASK_ID , CREATED , MODIFIED , CLASSIFICATION_KEY,CLASSIFICATION_ID , REF_COMPANY, REF_SYSTEM, REF_INSTANCE, REF_TYPE, REF_VALUE, CHANNEL, RECEIVED , CUSTOM_ATTRIBUTES ); -INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000001', 'TKI:000000000000000000000000000000000001', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L11000' ,'CLI:000000000000000000000000000000000006', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); -INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000002', 'TKI:000000000000000000000000000000000013', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L11000' ,'CLI:000000000000000000000000000000000006', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); -INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000003', 'TKI:000000000000000000000000000000000014', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L22000' ,'CLI:000000000000000000000000000000000007', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); -INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000004', 'TKI:000000000000000000000000000000000024', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L22000' ,'CLI:000000000000000000000000000000000007', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); -INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000005', 'TKI:000000000000000000000000000000000025', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L33000' ,'CLI:000000000000000000000000000000000008', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); -INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000006', 'TKI:000000000000000000000000000000000033', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L11000' ,'CLI:000000000000000000000000000000000006', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); -INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000007', 'TKI:000000000000000000000000000000000034', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L22000' ,'CLI:000000000000000000000000000000000007', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); -INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000008', 'TKI:000000000000000000000000000000000035', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L22000' ,'CLI:000000000000000000000000000000000007', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); -INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000009', 'TKI:000000000000000000000000000000000036', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L33000' ,'CLI:000000000000000000000000000000000008', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); -INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000010', 'TKI:000000000000000000000000000000000044', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L33000' ,'CLI:000000000000000000000000000000000008', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); -INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000011', 'TKI:000000000000000000000000000000000045', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L99000' ,'CLI:000000000000000000000000000000000009', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); - --- TASK TABLE (ID , CREATED , CLAIMED , COMPLETED , MODIFIED , PLANNED , DUE , NAME , CREATOR , DESCRIPTION , NOTE , PRIORITY, STATE , CLASSIFICATION_CATEGORY , CLASSIFICATION_KEY, CLASSIFICATION_ID , WORKBASKET_ID , WORKBASKET_KEY, DOMAIN , BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER , POR_COMPANY , POR_SYSTEM , POR_INSTANCE , POR_TYPE , POR_VALUE , IS_READ, IS_TRANSFERRED, CALLBACK_INFO, CUSTOM_ATTRIBUTES, CUSTOM_1 , CUSTOM_2 , CUSTOM_3, CUSTOM_4, CUSTOM_5, CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9 ,CUSTOM_10 ,CUSTOM_11 ,CUSTOM_12 ,CUSTOM_13 ,CUSTOM_14 ,CUSTOM_15 ,CUSTOM_16 ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000001', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task01', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_01' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000002', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task02', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_02' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000003', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task03', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_03' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000004', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task04', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_04' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000005', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task05', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_05' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000006', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task06', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_06' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000007', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task07', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_07' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000008', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task08', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_08' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000009', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task09', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_09' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000010', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task10', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_10' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000011', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task11', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_11' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000012', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task12', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_12' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000013', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task13', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_13' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000014', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task14', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_14' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000015', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task15', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_15' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000016', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task16', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_16' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000017', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task17', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_17' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000018', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task18', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_18' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000019', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task19', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_19' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000020', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task20', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_20' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000021', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task21', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_21' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000022', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task22', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_22' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000023', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task23', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_23' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000024', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task24', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_24' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000025', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task25', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_25' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000026', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task26', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_26' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000027', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task27', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_27' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000028', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task28', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_28' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000029', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task29', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_29' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000030', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task30', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_30' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000031', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task31', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_31' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000032', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task32', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_32' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000033', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task33', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_33' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000034', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task34', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_34' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000035', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task35', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_35' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000036', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task36', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_36' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000037', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task37', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_37' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000038', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task38', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_38' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000039', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task39', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_39' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000040', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task40', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_40' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000041', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task41', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_41' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000042', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task42', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_42' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000043', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task43', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_43' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000044', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task44', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_44' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000045', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task45', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_45' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000046', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task46', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_46' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000047', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task47', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_47' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000048', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task48', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_48' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000049', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task49', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_49' ); -INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000050', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task50', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_50' ); +-- WORKBASKET TABLE (ID , KEY , CREATED , MODIFIED , NAME , DOMAIN , TYPE , DESCRIPTION , OWNER , CUSTOM_1 , CUSTOM_2 , CUSTOM_3 , CUSTOM_4 , ORG_LEVEL_1 , ORG_LEVEL_2 , ORG_LEVEL_3 , ORG_LEVEL_4 ); +INSERT INTO TASKANA.WORKBASKET VALUES ('WBI:000000000000000000000000000000000001', 'USER_1_1', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'PPK User 1 KSC 1', 'MONITOR_TEST_DOMAIN', 'PERSONAL', 'Monitor Test Postkorb 1', 'John' , '' , '' , '' , '' , '' , '' , '' , '' ); +INSERT INTO TASKANA.WORKBASKET VALUES ('WBI:000000000000000000000000000000000002', 'USER_1_2', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'PPK User 1 KSC 2', 'MONITOR_TEST_DOMAIN', 'PERSONAL', 'Monitor Test Postkorb 2', 'John' , '' , '' , '' , '' , '' , '' , '' , '' ); +INSERT INTO TASKANA.WORKBASKET VALUES ('WBI:000000000000000000000000000000000003', 'USER_1_3', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'PPK User 1 KSC 3', 'MONITOR_TEST_DOMAIN', 'PERSONAL', 'Monitor Test Postkorb 3', 'John' , '' , '' , '' , '' , '' , '' , '' , '' ); +INSERT INTO TASKANA.WORKBASKET VALUES ('WBI:000000000000000000000000000000000004', 'USER_1_4', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'PPK User 1 KSC 4', 'MONITOR_TEST_DOMAIN', 'PERSONAL', 'Monitor Test Postkorb 4', 'John' , '' , '' , '' , '' , '' , '' , '' , '' ); + +-- CLASSIFICATION TABLE (ID , KEY , PARENT_ID , CATEGORY , TYPE , DOMAIN , VALID_IN_DOMAIN, CREATED , MODIFIED ,NAME , DESCRIPTION , PRIORITY, SERVICE_LEVEL, APPLICATION_ENTRY_POINT, CUSTOM_1 , CUSTOM_2, CUSTOM_3, CUSTOM_4, CUSTOM_5, CUSTOM_6, CUSTOM_7, CUSTOM_8 ); +INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000001', 'L10000', '' , 'EXTERN' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'OLD-Leistungsfall' , 'OLD-Leistungsfall' , 3 , 'P1D' , '' , 'VNR,RVNR,KOLVNR' , '' , '' , '' , '' , '' , '' , '' ); +INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000002', 'L20000', 'CLI:000000000000000000000000000000000001' , 'EXTERN' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Beratungsprotokoll' , 'Beratungsprotokoll', 1 , 'P1D' , '' , 'VNR,RVNR,KOLVNR, ANR', '' , '' , '' , '' , '' , '' , '' ); +INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000003', 'L30000', 'CLI:000000000000000000000000000000000001' , 'AUTOMATIC', 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Widerruf' , 'Widerruf' , 1 , 'P1D' , '' , 'VNR,RVNR,KOLVNR' , '' , '' , '' , '' , '' , '' , '' ); +INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000004', 'L40000', 'CLI:000000000000000000000000000000000001' , 'MANUAL' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamikaenderung' , 'Dynamikaenderung' , 1 , 'P1D' , '' , 'VNR,RVNR,KOLVNR' , '' , '' , '' , '' , '' , '' , '' ); +INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000005', 'L50000', 'CLI:000000000000000000000000000000000001' , 'EXTERN' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Dynamik-Ablehnung' , 'Dynamik-Ablehnung' , 5 , 'P5D' , '' , 'VNR,RVNR,KOLVNR' , '' , '' , '' , '' , '' , '' , '' ); +INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000006', 'L11000', '' , 'Anhang' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Anhang 1' , 'Anhang 1' , 3 , 'P1D' , '' , 'VNR,RVNR,KOLVNR' , '' , '' , '' , '' , '' , '' , '' ); +INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000007', 'L22000', '' , 'Anhang' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Anhang 2' , 'Anhang 2' , 1 , 'P1D' , '' , 'VNR,RVNR,KOLVNR, ANR', '' , '' , '' , '' , '' , '' , '' ); +INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000008', 'L33000', '' , 'Anhang' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Anhang 3' , 'Anhang 3' , 1 , 'P1D' , '' , 'VNR,RVNR,KOLVNR, ANR', '' , '' , '' , '' , '' , '' , '' ); +INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:000000000000000000000000000000000009', 'L99000', '' , 'Anhang' , 'TASK', 'DOMAIN_A', TRUE , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Anhang 9' , 'Anhang 9' , 1 , 'P1D' , '' , 'VNR,RVNR,KOLVNR, ANR', '' , '' , '' , '' , '' , '' , '' ); + +-- ATTACHMENT TABLE (ID , TASK_ID , CREATED , MODIFIED , CLASSIFICATION_KEY,CLASSIFICATION_ID , REF_COMPANY, REF_SYSTEM, REF_INSTANCE, REF_TYPE, REF_VALUE, CHANNEL, RECEIVED , CUSTOM_ATTRIBUTES ); +INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000001', 'TKI:000000000000000000000000000000000001', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L11000' ,'CLI:000000000000000000000000000000000006', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); +INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000002', 'TKI:000000000000000000000000000000000013', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L11000' ,'CLI:000000000000000000000000000000000006', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); +INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000003', 'TKI:000000000000000000000000000000000014', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L22000' ,'CLI:000000000000000000000000000000000007', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); +INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000004', 'TKI:000000000000000000000000000000000024', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L22000' ,'CLI:000000000000000000000000000000000007', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); +INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000005', 'TKI:000000000000000000000000000000000025', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L33000' ,'CLI:000000000000000000000000000000000008', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); +INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000006', 'TKI:000000000000000000000000000000000033', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L11000' ,'CLI:000000000000000000000000000000000006', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); +INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000007', 'TKI:000000000000000000000000000000000034', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L22000' ,'CLI:000000000000000000000000000000000007', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); +INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000008', 'TKI:000000000000000000000000000000000035', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L22000' ,'CLI:000000000000000000000000000000000007', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); +INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000009', 'TKI:000000000000000000000000000000000036', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L33000' ,'CLI:000000000000000000000000000000000008', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); +INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000010', 'TKI:000000000000000000000000000000000044', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L33000' ,'CLI:000000000000000000000000000000000008', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); +INSERT INTO TASKANA.ATTACHMENT VALUES('ATT:000000000000000000000000000000000011', 'TKI:000000000000000000000000000000000045', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'L99000' ,'CLI:000000000000000000000000000000000009', '' , '' , '' , '' , '' , '' , CURRENT_TIMESTAMP, null ); + +-- TASK TABLE (ID , CREATED , CLAIMED , COMPLETED , MODIFIED , PLANNED , DUE , NAME , CREATOR , DESCRIPTION , NOTE , PRIORITY, STATE , CLASSIFICATION_CATEGORY , CLASSIFICATION_KEY, CLASSIFICATION_ID , WORKBASKET_ID , WORKBASKET_KEY, DOMAIN , BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER , POR_COMPANY , POR_SYSTEM , POR_INSTANCE , POR_TYPE , POR_VALUE , IS_READ, IS_TRANSFERRED, CALLBACK_INFO, CUSTOM_ATTRIBUTES, CUSTOM_1 , CUSTOM_2 , CUSTOM_3, CUSTOM_4, CUSTOM_5, CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9 ,CUSTOM_10 ,CUSTOM_11 ,CUSTOM_12 ,CUSTOM_13 ,CUSTOM_14 ,CUSTOM_15 ,CUSTOM_16 ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000001', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task01', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_01' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000002', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task02', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_02' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000003', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task03', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_03' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000004', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task04', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_04' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000005', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task05', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_05' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000006', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task06', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_06' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000007', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task07', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_07' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000008', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task08', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_08' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000009', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task09', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_09' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000010', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task10', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_10' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000011', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task11', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_11' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000012', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task12', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_12' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000013', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task13', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_13' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000014', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task14', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_14' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000015', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task15', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_15' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000016', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task16', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_16' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000017', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task17', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_17' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000018', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task18', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_18' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000019', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task19', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_19' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000020', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task20', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_20' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000021', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task21', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_21' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000022', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task22', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_22' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000023', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task23', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_23' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000024', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task24', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_24' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000025', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task25', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_25' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000026', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task26', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_26' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000027', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task27', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_27' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000028', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task28', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_28' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000029', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task29', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_29' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000030', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task30', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_30' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000031', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task31', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_31' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000032', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task32', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_32' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000033', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task33', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L10000' , 'CLI:000000000000000000000000000000000001', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_33' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000034', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task34', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_34' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000035', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task35', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L20000' , 'CLI:000000000000000000000000000000000002', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_35' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000036', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task36', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_36' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000037', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task37', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_37' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000038', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task38', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_38' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000039', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task39', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_39' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000040', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task40', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_40' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000041', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task41', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'READY' , 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle B' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_41' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000042', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task42', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_42' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000043', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task43', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'EXTERN' , 'L50000' , 'CLI:000000000000000000000000000000000005', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_43' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000044', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task44', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_44' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000045', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task45', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_45' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000046', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task46', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'AUTOMATIC' , 'L30000' , 'CLI:000000000000000000000000000000000003', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_B', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_46' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000047', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task47', 'teamlead_1', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_47' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000048', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task48', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000001', 'USER_1_1' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_48' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000049', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task49', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000003', 'USER_1_3' , 'DOMAIN_A', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle C' , 'Vollkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_49' ); +INSERT INTO TASKANA.TASK VALUES('TKI:000000000000000000000000000000000050', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task50', 'teamlead_2', 'Some description.', 'Some custom Note', 1 , 'CLAIMED', 'MANUAL' , 'L40000' , 'CLI:000000000000000000000000000000000004', 'WBI:000000000000000000000000000000000002', 'USER_1_2' , 'DOMAIN_C', 'BPI21' , 'PBPI21' , 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true , false , null , null , 'Geschaeftsstelle A' , 'Teilkasko' , null , null , null , null , null , null , null , null , null , null , null , null , null , 'VALUE_50' ); diff --git a/lib/taskana-spring/src/main/java/pro/taskana/configuration/SpringTaskanaEngineConfiguration.java b/lib/taskana-spring/src/main/java/pro/taskana/configuration/SpringTaskanaEngineConfiguration.java index 56bc4305c..6e2d7c163 100644 --- a/lib/taskana-spring/src/main/java/pro/taskana/configuration/SpringTaskanaEngineConfiguration.java +++ b/lib/taskana-spring/src/main/java/pro/taskana/configuration/SpringTaskanaEngineConfiguration.java @@ -1,53 +1,53 @@ -package pro.taskana.configuration; - -import java.sql.SQLException; - -import javax.sql.DataSource; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.SpringTaskanaEngineImpl; -import pro.taskana.TaskanaEngine; - -/** - * This class configures the TaskanaEngineConfiguration for spring - */ -public class SpringTaskanaEngineConfiguration extends TaskanaEngineConfiguration { - - private static final Logger logger = LoggerFactory.getLogger(SpringTaskanaEngineConfiguration.class); - - public SpringTaskanaEngineConfiguration(DataSource dataSource, boolean useManagedTransactions, - boolean securityEnabled) throws SQLException { - super(dataSource, useManagedTransactions, securityEnabled); - } - - public SpringTaskanaEngineConfiguration(DataSource dataSource, boolean useManagedTransactions, - boolean securityEnabled, String propertiesFileName, String propertiesSeparator) throws SQLException { - super(dataSource, useManagedTransactions, securityEnabled, propertiesFileName, propertiesSeparator); - } - - /** - * This method creates the Spring-based TaskanaEngine without an sqlSessionFactory - * - * @return the TaskanaEngine - */ - @Override - public TaskanaEngine buildTaskanaEngine() { - this.useManagedTransactions = true; - - dbScriptRunner = new DbSchemaCreator(this.dataSource); - try { - dbScriptRunner.run(); - } catch (SQLException e) { - logger.error("The taskana schema could not be created: ", e); - } - - return new SpringTaskanaEngineImpl(this); - } - - public void setDataSource(DataSource dataSource) { - this.dataSource = dataSource; - } - -} +package pro.taskana.configuration; + +import java.sql.SQLException; + +import javax.sql.DataSource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.SpringTaskanaEngineImpl; +import pro.taskana.TaskanaEngine; + +/** + * This class configures the TaskanaEngineConfiguration for spring + */ +public class SpringTaskanaEngineConfiguration extends TaskanaEngineConfiguration { + + private static final Logger logger = LoggerFactory.getLogger(SpringTaskanaEngineConfiguration.class); + + public SpringTaskanaEngineConfiguration(DataSource dataSource, boolean useManagedTransactions, + boolean securityEnabled) throws SQLException { + super(dataSource, useManagedTransactions, securityEnabled); + } + + public SpringTaskanaEngineConfiguration(DataSource dataSource, boolean useManagedTransactions, + boolean securityEnabled, String propertiesFileName, String propertiesSeparator) throws SQLException { + super(dataSource, useManagedTransactions, securityEnabled, propertiesFileName, propertiesSeparator); + } + + /** + * This method creates the Spring-based TaskanaEngine without an sqlSessionFactory + * + * @return the TaskanaEngine + */ + @Override + public TaskanaEngine buildTaskanaEngine() { + this.useManagedTransactions = true; + + dbScriptRunner = new DbSchemaCreator(this.dataSource); + try { + dbScriptRunner.run(); + } catch (SQLException e) { + logger.error("The taskana schema could not be created: ", e); + } + + return new SpringTaskanaEngineImpl(this); + } + + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + } + +}