TSK-367: Provide a workbasket level report for specific classifications

This commit is contained in:
Konstantin Kläger 2018-06-11 08:08:36 +02:00 committed by Holger Hagen
parent 169ad0d718
commit 71a42b58fd
6 changed files with 179 additions and 54 deletions

View File

@ -8,6 +8,7 @@ import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.SelectedItem; import pro.taskana.impl.SelectedItem;
import pro.taskana.impl.report.impl.CategoryReport; import pro.taskana.impl.report.impl.CategoryReport;
import pro.taskana.impl.report.impl.ClassificationReport; import pro.taskana.impl.report.impl.ClassificationReport;
import pro.taskana.impl.report.impl.CombinedClassificationFilter;
import pro.taskana.impl.report.impl.CustomFieldValueReport; import pro.taskana.impl.report.impl.CustomFieldValueReport;
import pro.taskana.impl.report.impl.DetailedClassificationReport; import pro.taskana.impl.report.impl.DetailedClassificationReport;
import pro.taskana.impl.report.impl.TaskStatusReport; import pro.taskana.impl.report.impl.TaskStatusReport;
@ -43,6 +44,11 @@ public interface TaskMonitorService {
* @param customFieldValues * @param customFieldValues
* a list of custom field values to filter by the values of the custom field. To omit this filter, use * a list of custom field values to filter by the values of the custom field. To omit this filter, use
* null for this parameter * null for this parameter
* @param combinedClassificationFilter
* a list of pairs of a classificationId for a task and a classificationId for the corresponding
* attachment that is used to filter by the classification of the attachment. To filter by the
* classification of the task, the classificationId of the attachment should be null. To omit this
* filter, use null for this parameter
* @return the report * @return the report
* @throws InvalidArgumentException * @throws InvalidArgumentException
* thrown if DaysToWorkingDaysConverter is initialized with null * thrown if DaysToWorkingDaysConverter is initialized with null
@ -50,7 +56,8 @@ public interface TaskMonitorService {
* if the current user is not member of role MONITOR * if the current user is not member of role MONITOR
*/ */
WorkbasketLevelReport getWorkbasketLevelReport(List<String> workbasketIds, List<TaskState> states, WorkbasketLevelReport getWorkbasketLevelReport(List<String> workbasketIds, List<TaskState> states,
List<String> categories, List<String> domains, CustomField customField, List<String> customFieldValues) List<String> categories, List<String> domains, CustomField customField, List<String> customFieldValues,
List<CombinedClassificationFilter> combinedClassificationFilter)
throws InvalidArgumentException, NotAuthorizedException; throws InvalidArgumentException, NotAuthorizedException;
/** /**
@ -77,6 +84,11 @@ public interface TaskMonitorService {
* @param customFieldValues * @param customFieldValues
* a list of custom field values to filter by the values of the custom field. To omit this filter, use * a list of custom field values to filter by the values of the custom field. To omit this filter, use
* null for this parameter * null for this parameter
* @param combinedClassificationFilter
* a list of pairs of a classificationId for a task and a classificationId for the corresponding
* attachment that is used to filter by the classification of the attachment. To filter by the
* classification of the task, the classificationId of the attachment should be null. To omit this
* filter, use null for this parameter
* @param columnHeaders * @param columnHeaders
* a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past * 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 * are represented as negative values and days in the future are represented as positive values. To avoid
@ -92,16 +104,17 @@ public interface TaskMonitorService {
*/ */
WorkbasketLevelReport getWorkbasketLevelReport(List<String> workbasketIds, List<TaskState> states, WorkbasketLevelReport getWorkbasketLevelReport(List<String> workbasketIds, List<TaskState> states,
List<String> categories, List<String> domains, CustomField customField, List<String> customFieldValues, List<String> categories, List<String> domains, CustomField customField, List<String> customFieldValues,
List<TimeIntervalColumnHeader> columnHeaders) throws InvalidArgumentException, NotAuthorizedException; List<CombinedClassificationFilter> combinedClassificationFilter, List<TimeIntervalColumnHeader> columnHeaders)
throws InvalidArgumentException, NotAuthorizedException;
/** /**
* Returns a {@link WorkbasketLevelReport} grouped by workbaskets. For each workbasket the report contains the total * Returns a {@link WorkbasketLevelReport} for specific classifications grouped by workbaskets. For each workbasket
* number of tasks and the number of tasks of the respective cluster that are specified by the * the report contains the total number of tasks and the number of tasks of the respective cluster that are
* {@link TimeIntervalColumnHeader}s. It can be specified whether the age of the tasks is counted in days or in * specified by the {@link TimeIntervalColumnHeader}s. It can be specified whether the age of the tasks is counted
* working days. Furthermore the report contains a sum line that contains the total numbers of the different * in days or in working days. Furthermore the report contains a sum line that contains the total numbers of the
* clusters and the total number of all tasks. The tasks of the report are filtered by workbaskets, states, * different clusters and the total number of all tasks. The tasks of the report are filtered by workbaskets,
* categories, domains and values of a custom field. If no filter is required, the respective parameter should be * states, categories, domains and values of a custom field. If no filter is required, the respective parameter
* null. Tasks with Timestamp DUE = null are not considered. * should be null. Tasks with Timestamp DUE = null are not considered.
* *
* @param workbasketIds * @param workbasketIds
* a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this * a list of workbasket ids objects to filter by workbaskets. To omit this filter, use null for this
@ -118,6 +131,11 @@ public interface TaskMonitorService {
* @param customFieldValues * @param customFieldValues
* a list of custom field values to filter by the values of the custom field. To omit this filter, use * a list of custom field values to filter by the values of the custom field. To omit this filter, use
* null for this parameter * null for this parameter
* @param combinedClassificationFilter
* a list of pairs of a classificationId for a task and a classificationId for the corresponding
* attachment that is used to filter by the classification of the attachment. To filter by the
* classification of the task, the classificationId of the attachment should be null. To omit this
* filter, use null for this parameter
* @param columnHeaders * @param columnHeaders
* a list of columnHeaders that specify the subdivision into different cluster of due dates. Days in past * 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 * are represented as negative values and days in the future are represented as positive values. To avoid
@ -136,8 +154,8 @@ public interface TaskMonitorService {
*/ */
WorkbasketLevelReport getWorkbasketLevelReport(List<String> workbasketIds, List<TaskState> states, WorkbasketLevelReport getWorkbasketLevelReport(List<String> workbasketIds, List<TaskState> states,
List<String> categories, List<String> domains, CustomField customField, List<String> customFieldValues, List<String> categories, List<String> domains, CustomField customField, List<String> customFieldValues,
List<TimeIntervalColumnHeader> columnHeaders, boolean inWorkingDays) List<CombinedClassificationFilter> combinedClassificationFilter, List<TimeIntervalColumnHeader> columnHeaders,
throws InvalidArgumentException, NotAuthorizedException; boolean inWorkingDays) throws InvalidArgumentException, NotAuthorizedException;
/** /**
* Returns a {@link CategoryReport} grouped by categories. The report contains the total numbers of tasks of the * Returns a {@link CategoryReport} grouped by categories. The report contains the total numbers of tasks of the

View File

@ -16,6 +16,7 @@ import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.impl.CategoryReport; import pro.taskana.impl.report.impl.CategoryReport;
import pro.taskana.impl.report.impl.ClassificationReport; import pro.taskana.impl.report.impl.ClassificationReport;
import pro.taskana.impl.report.impl.CombinedClassificationFilter;
import pro.taskana.impl.report.impl.CustomFieldValueReport; import pro.taskana.impl.report.impl.CustomFieldValueReport;
import pro.taskana.impl.report.impl.DaysToWorkingDaysPreProcessor; import pro.taskana.impl.report.impl.DaysToWorkingDaysPreProcessor;
import pro.taskana.impl.report.impl.DetailedClassificationReport; import pro.taskana.impl.report.impl.DetailedClassificationReport;
@ -45,31 +46,34 @@ public class TaskMonitorServiceImpl implements TaskMonitorService {
@Override @Override
public WorkbasketLevelReport getWorkbasketLevelReport(List<String> workbasketIds, List<TaskState> states, public WorkbasketLevelReport getWorkbasketLevelReport(List<String> workbasketIds, List<TaskState> states,
List<String> categories, List<String> domains, CustomField customField, List<String> customFieldValues) List<String> categories, List<String> domains, CustomField customField, List<String> customFieldValues,
List<CombinedClassificationFilter> combinedClassificationFilter)
throws InvalidArgumentException, NotAuthorizedException { throws InvalidArgumentException, NotAuthorizedException {
return getWorkbasketLevelReport(workbasketIds, states, categories, domains, customField, customFieldValues, return getWorkbasketLevelReport(workbasketIds, states, categories, domains, customField, customFieldValues,
Collections.emptyList(), false); combinedClassificationFilter, Collections.emptyList(), false);
} }
@Override @Override
public WorkbasketLevelReport getWorkbasketLevelReport(List<String> workbasketIds, List<TaskState> states, public WorkbasketLevelReport getWorkbasketLevelReport(List<String> workbasketIds, List<TaskState> states,
List<String> categories, List<String> domains, CustomField customField, List<String> customFieldValues, List<String> categories, List<String> domains, CustomField customField, List<String> customFieldValues,
List<TimeIntervalColumnHeader> columnHeaders) throws InvalidArgumentException, NotAuthorizedException { List<CombinedClassificationFilter> combinedClassificationFilter, List<TimeIntervalColumnHeader> columnHeaders)
throws InvalidArgumentException, NotAuthorizedException {
return getWorkbasketLevelReport(workbasketIds, states, categories, domains, customField, customFieldValues, return getWorkbasketLevelReport(workbasketIds, states, categories, domains, customField, customFieldValues,
columnHeaders, true); combinedClassificationFilter, columnHeaders, true);
} }
@Override @Override
public WorkbasketLevelReport getWorkbasketLevelReport(List<String> workbasketIds, List<TaskState> states, public WorkbasketLevelReport getWorkbasketLevelReport(List<String> workbasketIds, List<TaskState> states,
List<String> categories, List<String> domains, CustomField customField, List<String> customFieldValues, List<String> categories, List<String> domains, CustomField customField, List<String> customFieldValues,
List<TimeIntervalColumnHeader> columnHeaders, boolean inWorkingDays) List<CombinedClassificationFilter> combinedClassificationFilter, List<TimeIntervalColumnHeader> columnHeaders,
throws InvalidArgumentException, NotAuthorizedException { boolean inWorkingDays) throws InvalidArgumentException, NotAuthorizedException {
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("entry to getWorkbasketLevelReport(workbasketIds = {}, states = {}, categories = {}, " LOGGER.debug("entry to getWorkbasketLevelReport(workbasketIds = {}, states = {}, categories = {}, "
+ "domains = {}, customField = {}, customFieldValues = {}, columnHeaders = {}, " + "domains = {}, customField = {}, customFieldValues = {}, combinedClassificationFilter = {}, "
+ "inWorkingDays = {})", LoggerUtils.listToString(workbasketIds), LoggerUtils.listToString(states), + "columnHeaders = {}, inWorkingDays = {})", LoggerUtils.listToString(workbasketIds),
LoggerUtils.listToString(categories), LoggerUtils.listToString(domains), customField, LoggerUtils.listToString(states), LoggerUtils.listToString(categories),
LoggerUtils.listToString(customFieldValues), LoggerUtils.listToString(columnHeaders), LoggerUtils.listToString(domains), customField, LoggerUtils.listToString(customFieldValues),
LoggerUtils.listToString(combinedClassificationFilter), LoggerUtils.listToString(columnHeaders),
inWorkingDays); inWorkingDays);
} }
taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR); taskanaEngineImpl.checkRoleMembership(TaskanaRole.MONITOR);
@ -80,7 +84,8 @@ public class TaskMonitorServiceImpl implements TaskMonitorService {
WorkbasketLevelReport report = new WorkbasketLevelReport(columnHeaders); WorkbasketLevelReport report = new WorkbasketLevelReport(columnHeaders);
List<MonitorQueryItem> monitorQueryItems = taskMonitorMapper.getTaskCountOfWorkbaskets( List<MonitorQueryItem> monitorQueryItems = taskMonitorMapper.getTaskCountOfWorkbaskets(
workbasketIds, states, categories, domains, customField, customFieldValues); workbasketIds, states, categories, domains, customField, customFieldValues,
combinedClassificationFilter);
report.addItems(monitorQueryItems, new DaysToWorkingDaysPreProcessor<>(columnHeaders, inWorkingDays)); report.addItems(monitorQueryItems, new DaysToWorkingDaysPreProcessor<>(columnHeaders, inWorkingDays));

View File

@ -0,0 +1,43 @@
package pro.taskana.impl.report.impl;
/**
* The CombinedClassificationFilter is a pair of a classificationId for a task and a classificationId for the
* corresponding attachment that is used to filter the {@link WorkbasketLevelReport} by the classification of the
* attachment. To filter by the classification of the task, the classificationId of the attachment should be null.
*/
public class CombinedClassificationFilter {
private String taskClassificationId;
private String attachmentClassificationId;
public CombinedClassificationFilter(String taskClassificationId) {
this.taskClassificationId = taskClassificationId;
}
public CombinedClassificationFilter(String taskClassificationId, String attachmentClassificationId) {
this.taskClassificationId = taskClassificationId;
this.attachmentClassificationId = attachmentClassificationId;
}
public String getTaskClassificationId() {
return this.taskClassificationId;
}
public void setTaskClassificationId(String taskClassificationId) {
this.taskClassificationId = taskClassificationId;
}
public String getAttachmentClassificationId() {
return this.attachmentClassificationId;
}
public void setAttachmentClassificationId(String attachmentClassificationId) {
this.attachmentClassificationId = attachmentClassificationId;
}
@Override
public String toString() {
return "(" + this.taskClassificationId + "," + this.attachmentClassificationId + ")";
}
}

View File

@ -11,6 +11,7 @@ import org.apache.ibatis.annotations.Select;
import pro.taskana.CustomField; import pro.taskana.CustomField;
import pro.taskana.TaskState; import pro.taskana.TaskState;
import pro.taskana.impl.SelectedItem; import pro.taskana.impl.SelectedItem;
import pro.taskana.impl.report.impl.CombinedClassificationFilter;
import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; import pro.taskana.impl.report.impl.DetailedMonitorQueryItem;
import pro.taskana.impl.report.impl.MonitorQueryItem; import pro.taskana.impl.report.impl.MonitorQueryItem;
import pro.taskana.impl.report.impl.TaskQueryItem; import pro.taskana.impl.report.impl.TaskQueryItem;
@ -21,31 +22,39 @@ import pro.taskana.impl.report.impl.TaskQueryItem;
public interface TaskMonitorMapper { public interface TaskMonitorMapper {
@Select("<script>" @Select("<script>"
+ "<if test=\"_databaseId == 'db2'\">SELECT WORKBASKET_KEY, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP)) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> " + "<if test=\"_databaseId == 'db2'\">SELECT T.WORKBASKET_KEY, (DAYS(T.DUE) - DAYS(CURRENT_TIMESTAMP)) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "<if test=\"_databaseId == 'h2'\">SELECT WORKBASKET_KEY, DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> " + "<if test=\"_databaseId == 'h2'\">SELECT T.WORKBASKET_KEY, DATEDIFF('DAY', CURRENT_TIMESTAMP, T.DUE) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "<if test=\"_databaseId == 'postgres'\">SELECT WORKBASKET_KEY, DATE_PART('DAY', DUE - CURRENT_TIMESTAMP) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> " + "<if test=\"_databaseId == 'postgres'\">SELECT T.WORKBASKET_KEY, DATE_PART('DAY', T.DUE - CURRENT_TIMESTAMP) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "FROM TASKANA.TASK " + "FROM TASKANA.TASK AS T LEFT JOIN TASKANA.ATTACHMENT AS A ON T.ID = A.TASK_ID "
+ "<where>" + "<where>"
+ "<if test=\"workbasketIds != null\">" + "<if test=\"workbasketIds != null\">"
+ "WORKBASKET_ID IN (<foreach collection='workbasketIds' item='workbasketId' separator=','>#{workbasketId}</foreach>) " + "T.WORKBASKET_ID IN (<foreach collection='workbasketIds' item='workbasketId' separator=','>#{workbasketId}</foreach>) "
+ "</if>" + "</if>"
+ "<if test=\"states != null\">" + "<if test=\"states != null\">"
+ "AND STATE IN (<foreach collection='states' item='state' separator=','>#{state}</foreach>) " + "AND T.STATE IN (<foreach collection='states' item='state' separator=','>#{state}</foreach>) "
+ "</if>" + "</if>"
+ "<if test=\"categories != null\">" + "<if test=\"categories != null\">"
+ "AND CLASSIFICATION_CATEGORY IN (<foreach collection='categories' item='category' separator=','>#{category}</foreach>) " + "AND T.CLASSIFICATION_CATEGORY IN (<foreach collection='categories' item='category' separator=','>#{category}</foreach>) "
+ "</if>" + "</if>"
+ "<if test=\"domains != null\">" + "<if test=\"domains != null\">"
+ "AND DOMAIN IN (<foreach collection='domains' item='domain' separator=','>#{domain}</foreach>) " + "AND T.DOMAIN IN (<foreach collection='domains' item='domain' separator=','>#{domain}</foreach>) "
+ "</if>" + "</if>"
+ "<if test=\"customField != null and customFieldValues != null\">" + "<if test=\"customField != null and customFieldValues != null\">"
+ "AND ${customField} IN (<foreach collection='customFieldValues' item='customFieldValue' separator=','>#{customFieldValue}</foreach>) " + "AND ${customField} IN (<foreach collection='customFieldValues' item='customFieldValue' separator=','>#{customFieldValue}</foreach>) "
+ "</if>" + "</if>"
+ "AND DUE IS NOT NULL " + "<if test=\"combinedClassificationFilter != null\">"
+ "AND <foreach collection='combinedClassificationFilter' item='item' separator='OR'> "
+ "T.CLASSIFICATION_ID = #{item.taskClassificationId}"
+ "<if test=\"item.attachmentClassificationId != null\">"
+ "AND A.CLASSIFICATION_ID = #{item.attachmentClassificationId}"
+ "</if>"
+ "</foreach>"
+ "</if>"
+ "AND T.DUE IS NOT NULL "
+ "</where>" + "</where>"
+ "<if test=\"_databaseId == 'db2'\">GROUP BY WORKBASKET_KEY, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP))</if> " + "<if test=\"_databaseId == 'db2'\">GROUP BY T.WORKBASKET_KEY, (DAYS(T.DUE) - DAYS(CURRENT_TIMESTAMP))</if> "
+ "<if test=\"_databaseId == 'h2'\">GROUP BY WORKBASKET_KEY, DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE)</if> " + "<if test=\"_databaseId == 'h2'\">GROUP BY T.WORKBASKET_KEY, DATEDIFF('DAY', CURRENT_TIMESTAMP, T.DUE)</if> "
+ "<if test=\"_databaseId == 'postgres'\">GROUP BY WORKBASKET_KEY, DATE_PART('DAY', DUE - CURRENT_TIMESTAMP)</if> " + "<if test=\"_databaseId == 'postgres'\">GROUP BY T.WORKBASKET_KEY, DATE_PART('DAY', T.DUE - CURRENT_TIMESTAMP)</if> "
+ "<if test=\"_databaseId == 'db2'\">with UR </if> " + "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ "</script>") + "</script>")
@Results({ @Results({
@ -57,7 +66,8 @@ public interface TaskMonitorMapper {
@Param("categories") List<String> categories, @Param("categories") List<String> categories,
@Param("domains") List<String> domains, @Param("domains") List<String> domains,
@Param("customField") CustomField customField, @Param("customField") CustomField customField,
@Param("customFieldValues") List<String> customFieldValues); @Param("customFieldValues") List<String> customFieldValues,
@Param("combinedClassificationFilter") List<CombinedClassificationFilter> combinedClassificationFilter);
@Select("<script>" @Select("<script>"
+ "<if test=\"_databaseId == 'db2'\">SELECT CLASSIFICATION_CATEGORY, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP)) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> " + "<if test=\"_databaseId == 'db2'\">SELECT CLASSIFICATION_CATEGORY, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP)) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "

View File

@ -31,6 +31,7 @@ import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.configuration.DBCleaner; import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.report.impl.CombinedClassificationFilter;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.impl.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.WorkbasketLevelReport; import pro.taskana.impl.report.impl.WorkbasketLevelReport;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
@ -70,7 +71,8 @@ public class ProvideWorkbasketLevelReportAccTest {
throws InvalidArgumentException, NotAuthorizedException { throws InvalidArgumentException, NotAuthorizedException {
TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService();
taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null); taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null,
null);
} }
@WithAccessId( @WithAccessId(
@ -80,7 +82,8 @@ public class ProvideWorkbasketLevelReportAccTest {
throws InvalidArgumentException, NotAuthorizedException { throws InvalidArgumentException, NotAuthorizedException {
TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService();
WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null); WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null,
null);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(reportToString(report)); LOGGER.debug(reportToString(report));
@ -106,7 +109,7 @@ public class ProvideWorkbasketLevelReportAccTest {
List<TimeIntervalColumnHeader> columnHeaders = getListOfColumnHeaders(); List<TimeIntervalColumnHeader> columnHeaders = getListOfColumnHeaders();
WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null, WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null,
columnHeaders); null, columnHeaders);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(reportToString(report, columnHeaders)); LOGGER.debug(reportToString(report, columnHeaders));
@ -137,7 +140,7 @@ public class ProvideWorkbasketLevelReportAccTest {
List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders(); List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders();
WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null, WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null,
columnHeaders); null, columnHeaders);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(reportToString(report, columnHeaders)); LOGGER.debug(reportToString(report, columnHeaders));
@ -166,7 +169,7 @@ public class ProvideWorkbasketLevelReportAccTest {
List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders(); List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders();
WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null, WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null, null,
columnHeaders, false); null, columnHeaders, false);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(reportToString(report, columnHeaders)); LOGGER.debug(reportToString(report, columnHeaders));
@ -196,8 +199,7 @@ public class ProvideWorkbasketLevelReportAccTest {
List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders(); List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders();
WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(workbasketIds, null, null, null, WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(workbasketIds, null, null, null,
null, null, null, null, null, columnHeaders);
columnHeaders);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(reportToString(report, columnHeaders)); LOGGER.debug(reportToString(report, columnHeaders));
@ -222,7 +224,7 @@ public class ProvideWorkbasketLevelReportAccTest {
List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders(); List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders();
WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, states, null, null, null, null, WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, states, null, null, null, null,
columnHeaders); null, columnHeaders);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(reportToString(report, columnHeaders)); LOGGER.debug(reportToString(report, columnHeaders));
@ -252,8 +254,7 @@ public class ProvideWorkbasketLevelReportAccTest {
List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders(); List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders();
WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, categories, null, null, WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, categories, null, null,
null, null, null, columnHeaders);
columnHeaders);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(reportToString(report, columnHeaders)); LOGGER.debug(reportToString(report, columnHeaders));
@ -284,8 +285,7 @@ public class ProvideWorkbasketLevelReportAccTest {
List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders(); List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders();
WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, domains, null, WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, domains, null,
null, null, null, columnHeaders);
columnHeaders);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(reportToString(report, columnHeaders)); LOGGER.debug(reportToString(report, columnHeaders));
@ -316,7 +316,7 @@ public class ProvideWorkbasketLevelReportAccTest {
List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders(); List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders();
WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null,
customField, customFieldValues, columnHeaders); customField, customFieldValues, null, columnHeaders);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(reportToString(report, columnHeaders)); LOGGER.debug(reportToString(report, columnHeaders));
@ -335,6 +335,47 @@ public class ProvideWorkbasketLevelReportAccTest {
assertArrayEquals(new int[] {2, 1, 0, 0, 1}, row3); assertArrayEquals(new int[] {2, 1, 0, 0, 1}, row3);
} }
@WithAccessId(
userName = "monitor")
@Test
public void testEachItemOfWorkbasketLevelReportForSelectedClassifications()
throws InvalidArgumentException, NotAuthorizedException {
TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService();
List<TimeIntervalColumnHeader> columnHeaders = getShortListOfColumnHeaders();
List<CombinedClassificationFilter> combinedClassificationFilter = new ArrayList<>();
combinedClassificationFilter
.add(new CombinedClassificationFilter("CLI:000000000000000000000000000000000003",
"CLI:000000000000000000000000000000000008"));
combinedClassificationFilter
.add(new CombinedClassificationFilter("CLI:000000000000000000000000000000000003",
"CLI:000000000000000000000000000000000009"));
combinedClassificationFilter
.add(new CombinedClassificationFilter("CLI:000000000000000000000000000000000002",
"CLI:000000000000000000000000000000000007"));
combinedClassificationFilter
.add(new CombinedClassificationFilter("CLI:000000000000000000000000000000000005"));
WorkbasketLevelReport report = taskMonitorService.getWorkbasketLevelReport(null, null, null, null, null,
null, combinedClassificationFilter, columnHeaders, true);
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, 3, 0, 1, 1}, row1);
int[] row2 = report.getRow("USER_1_2").getCells();
assertArrayEquals(new int[] {0, 2, 1, 6, 0}, row2);
int[] row3 = report.getRow("USER_1_3").getCells();
assertArrayEquals(new int[] {1, 0, 0, 0, 3}, row3);
}
private List<TimeIntervalColumnHeader> getListOfColumnHeaders() { private List<TimeIntervalColumnHeader> getListOfColumnHeaders() {
List<TimeIntervalColumnHeader> columnHeaders = new ArrayList<>(); List<TimeIntervalColumnHeader> columnHeaders = new ArrayList<>();
columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11)); columnHeaders.add(new TimeIntervalColumnHeader(Integer.MIN_VALUE, -11));

View File

@ -35,6 +35,7 @@ import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.impl.CategoryReport; import pro.taskana.impl.report.impl.CategoryReport;
import pro.taskana.impl.report.impl.ClassificationReport; import pro.taskana.impl.report.impl.ClassificationReport;
import pro.taskana.impl.report.impl.CombinedClassificationFilter;
import pro.taskana.impl.report.impl.CustomFieldValueReport; import pro.taskana.impl.report.impl.CustomFieldValueReport;
import pro.taskana.impl.report.impl.DetailedClassificationReport; import pro.taskana.impl.report.impl.DetailedClassificationReport;
import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; import pro.taskana.impl.report.impl.DetailedMonitorQueryItem;
@ -82,6 +83,9 @@ public class TaskMonitorServiceImplTest {
List<String> domains = Collections.singletonList("DOMAIN_A"); List<String> domains = Collections.singletonList("DOMAIN_A");
CustomField customField = CustomField.CUSTOM_1; CustomField customField = CustomField.CUSTOM_1;
List<String> customFieldValues = Collections.singletonList("Geschaeftsstelle A"); List<String> customFieldValues = Collections.singletonList("Geschaeftsstelle A");
List<CombinedClassificationFilter> combinedClassificationFilter = Arrays
.asList(new CombinedClassificationFilter("CLI:000000000000000000000000000000000003",
"CLI:000000000000000000000000000000000008"));
List<MonitorQueryItem> expectedResult = new ArrayList<>(); List<MonitorQueryItem> expectedResult = new ArrayList<>();
MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); MonitorQueryItem monitorQueryItem = new MonitorQueryItem();
@ -89,17 +93,17 @@ public class TaskMonitorServiceImplTest {
monitorQueryItem.setNumberOfTasks(1); monitorQueryItem.setNumberOfTasks(1);
expectedResult.add(monitorQueryItem); expectedResult.add(monitorQueryItem);
doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfWorkbaskets(workbasketIds, states, doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfWorkbaskets(workbasketIds, states,
categories, domains, customField, customFieldValues); categories, domains, customField, customFieldValues, combinedClassificationFilter);
WorkbasketLevelReport actualResult = cut.getWorkbasketLevelReport(workbasketIds, states, categories, domains, WorkbasketLevelReport actualResult = cut.getWorkbasketLevelReport(workbasketIds, states, categories, domains,
customField, customFieldValues); customField, customFieldValues, combinedClassificationFilter);
verify(taskanaEngineImplMock, times(1)).openConnection(); verify(taskanaEngineImplMock, times(1)).openConnection();
verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any());
verify(taskanaEngineImplMock, times(2)).getConfiguration(); verify(taskanaEngineImplMock, times(2)).getConfiguration();
verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); verify(taskanaEngineConfiguration, times(1)).getCustomHolidays();
verify(taskMonitorMapperMock, times(1)).getTaskCountOfWorkbaskets(any(), any(), any(), verify(taskMonitorMapperMock, times(1)).getTaskCountOfWorkbaskets(any(), any(), any(), any(),
any(), any(), any()); any(), any(), any());
verify(taskanaEngineImplMock, times(1)).returnConnection(); verify(taskanaEngineImplMock, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration);
@ -119,6 +123,9 @@ public class TaskMonitorServiceImplTest {
List<String> domains = Collections.singletonList("DOMAIN_A"); List<String> domains = Collections.singletonList("DOMAIN_A");
CustomField customField = CustomField.CUSTOM_1; CustomField customField = CustomField.CUSTOM_1;
List<String> customFieldValues = Collections.singletonList("Geschaeftsstelle A"); List<String> customFieldValues = Collections.singletonList("Geschaeftsstelle A");
List<CombinedClassificationFilter> combinedClassificationFilter = Arrays
.asList(new CombinedClassificationFilter("CLI:000000000000000000000000000000000003",
"CLI:000000000000000000000000000000000008"));
List<TimeIntervalColumnHeader> reportLineItemDefinitions = Collections.singletonList( List<TimeIntervalColumnHeader> reportLineItemDefinitions = Collections.singletonList(
new TimeIntervalColumnHeader(0, 0)); new TimeIntervalColumnHeader(0, 0));
@ -129,17 +136,18 @@ public class TaskMonitorServiceImplTest {
monitorQueryItem.setNumberOfTasks(1); monitorQueryItem.setNumberOfTasks(1);
expectedResult.add(monitorQueryItem); expectedResult.add(monitorQueryItem);
doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfWorkbaskets(workbasketIds, states, doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountOfWorkbaskets(workbasketIds, states,
categories, domains, customField, customFieldValues); categories, domains, customField, customFieldValues, combinedClassificationFilter);
WorkbasketLevelReport actualResult = cut.getWorkbasketLevelReport(workbasketIds, states, categories, domains, WorkbasketLevelReport actualResult = cut.getWorkbasketLevelReport(workbasketIds, states, categories, domains,
customField, customFieldValues, reportLineItemDefinitions); customField, customFieldValues, combinedClassificationFilter, reportLineItemDefinitions);
verify(taskanaEngineImplMock, times(1)).openConnection(); verify(taskanaEngineImplMock, times(1)).openConnection();
verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any()); verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any());
verify(taskanaEngineImplMock, times(2)).getConfiguration(); verify(taskanaEngineImplMock, times(2)).getConfiguration();
verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled(); verify(taskanaEngineConfiguration, times(1)).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration, times(1)).getCustomHolidays(); verify(taskanaEngineConfiguration, times(1)).getCustomHolidays();
verify(taskMonitorMapperMock, times(1)).getTaskCountOfWorkbaskets(any(), any(), any(), any(), any(), any()); verify(taskMonitorMapperMock, times(1)).getTaskCountOfWorkbaskets(any(), any(), any(), any(), any(), any(),
any());
verify(taskanaEngineImplMock, times(1)).returnConnection(); verify(taskanaEngineImplMock, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration); verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration);