TSK-685: added DailyEntryExitReport and refactored report structure

TSK-685: added tests to report structure + further refactoring
This commit is contained in:
Mustapha Zorgati 2019-01-02 10:37:06 +01:00
parent cc63dbb590
commit 37f48a5667
73 changed files with 1500 additions and 958 deletions

View File

@ -3,6 +3,7 @@ package pro.taskana;
import pro.taskana.report.CategoryReport;
import pro.taskana.report.ClassificationReport;
import pro.taskana.report.CustomFieldValueReport;
import pro.taskana.report.DailyEntryExitReport;
import pro.taskana.report.TaskStatusReport;
import pro.taskana.report.WorkbasketReport;
@ -52,4 +53,12 @@ public interface TaskMonitorService {
* @return a {@link TaskStatusReport.Builder}
*/
TaskStatusReport.Builder createTaskStatusReportBuilder();
/**
* Provides a {@link DailyEntryExitReport.Builder} for creating a {@link DailyEntryExitReport}.
*
* @return a {@link DailyEntryExitReport.Builder}
*/
DailyEntryExitReport.Builder createDailyEntryExitReportBuilder();
}

View File

@ -0,0 +1,8 @@
package pro.taskana;
/**
* This enum contains all statuses of a {@link pro.taskana.Task}.
*/
public enum TaskStatus {
CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE
}

View File

@ -9,9 +9,9 @@ import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaRole;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.DaysToWorkingDaysPreProcessor;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.MonitorQueryItem;
import pro.taskana.impl.report.preprocessor.DaysToWorkingDaysPreProcessor;
import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.CategoryReport;
@ -19,7 +19,7 @@ import pro.taskana.report.CategoryReport;
* The implementation of CategoryReportBuilder.
*/
public class CategoryReportBuilderImpl
extends TimeIntervalReportBuilderImpl<CategoryReport.Builder, TimeIntervalColumnHeader>
extends TimeIntervalReportBuilderImpl<CategoryReport.Builder, MonitorQueryItem, TimeIntervalColumnHeader>
implements CategoryReport.Builder {
private static final Logger LOGGER = LoggerFactory.getLogger(CategoryReport.Builder.class);
@ -34,7 +34,7 @@ public class CategoryReportBuilderImpl
}
@Override
protected String determineDimension() {
protected String determineGroupedBy() {
return "CLASSIFICATION_CATEGORY";
}

View File

@ -9,10 +9,10 @@ import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaRole;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.DaysToWorkingDaysPreProcessor;
import pro.taskana.impl.report.DetailedMonitorQueryItem;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.DetailedMonitorQueryItem;
import pro.taskana.impl.report.item.MonitorQueryItem;
import pro.taskana.impl.report.preprocessor.DaysToWorkingDaysPreProcessor;
import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.ClassificationReport;
import pro.taskana.report.ClassificationReport.DetailedClassificationReport;
@ -21,7 +21,7 @@ import pro.taskana.report.ClassificationReport.DetailedClassificationReport;
* The implementation of ClassificationReportBuilder.
*/
public class ClassificationReportBuilderImpl
extends TimeIntervalReportBuilderImpl<ClassificationReport.Builder, TimeIntervalColumnHeader>
extends TimeIntervalReportBuilderImpl<ClassificationReport.Builder, MonitorQueryItem, TimeIntervalColumnHeader>
implements ClassificationReport.Builder {
private static final Logger LOGGER = LoggerFactory.getLogger(ClassificationReport.Builder.class);
@ -36,7 +36,7 @@ public class ClassificationReportBuilderImpl
}
@Override
protected String determineDimension() {
protected String determineGroupedBy() {
return "CLASSIFICATION_KEY";
}

View File

@ -10,9 +10,9 @@ import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaRole;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.DaysToWorkingDaysPreProcessor;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.MonitorQueryItem;
import pro.taskana.impl.report.preprocessor.DaysToWorkingDaysPreProcessor;
import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.CustomFieldValueReport;
@ -20,7 +20,7 @@ import pro.taskana.report.CustomFieldValueReport;
* The implementation of CustomFieldValueReportBuilder.
*/
public class CustomFieldValueReportBuilderImpl
extends TimeIntervalReportBuilderImpl<CustomFieldValueReport.Builder, TimeIntervalColumnHeader>
extends TimeIntervalReportBuilderImpl<CustomFieldValueReport.Builder, MonitorQueryItem, TimeIntervalColumnHeader>
implements CustomFieldValueReport.Builder {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomFieldValueReportBuilderImpl.class);
@ -39,7 +39,7 @@ public class CustomFieldValueReportBuilderImpl
}
@Override
protected String determineDimension() {
protected String determineGroupedBy() {
return customField.name();
}

View File

@ -0,0 +1,95 @@
package pro.taskana.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pro.taskana.TaskState;
import pro.taskana.TaskStatus;
import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaRole;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.DailyEntryExitQueryItem;
import pro.taskana.impl.report.preprocessor.DaysToWorkingDaysPreProcessor;
import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.DailyEntryExitReport;
/**
* The implementation of {@link DailyEntryExitReport.Builder}.
*/
public class DailyEntryExitReportBuilderImpl extends
TimeIntervalReportBuilderImpl<DailyEntryExitReport.Builder, DailyEntryExitQueryItem, TimeIntervalColumnHeader.Date>
implements DailyEntryExitReport.Builder {
private static final Logger LOGGER = LoggerFactory.getLogger(DailyEntryExitReport.Builder.class);
private List<TaskStatus> status = Arrays.asList(TaskStatus.CREATED, TaskStatus.COMPLETED);
DailyEntryExitReportBuilderImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) {
super(taskanaEngine, taskMonitorMapper);
}
@Override
public DailyEntryExitReport.Builder stateIn(List<TaskState> states) {
throw new UnsupportedOperationException(
"The states have no influence regarding this report. Use statusIn instead");
}
@Override
protected DailyEntryExitReport.Builder _this() {
return this;
}
// since this method is not documented I have no idea what the proper groupedBy should be,
// thus this method is not supported on this builder.
@Override
public List<String> listTaskIdsForSelectedItems(List<SelectedItem> selectedItems) {
throw new UnsupportedOperationException("");
}
@Override
protected String determineGroupedBy() {
throw new UnsupportedOperationException();
}
@Override
public DailyEntryExitReport.Builder statusIn(List<TaskStatus> statuses) {
this.status = new ArrayList<>(statuses);
return _this();
}
@Override
public DailyEntryExitReport buildReport() throws NotAuthorizedException, InvalidArgumentException {
LOGGER.debug("entry to buildDetailedReport(), this = {}", this);
this.taskanaEngine.checkRoleMembership(TaskanaRole.MONITOR, TaskanaRole.ADMIN);
try {
this.taskanaEngine.openConnection();
DailyEntryExitReport report = new DailyEntryExitReport(this.columnHeaders);
List<DailyEntryExitQueryItem> items = status.stream()
// This can also be implemented into a single sql query which combines all statuses with the union
// operator. That would reduce the readability of the sql template. That's why "the loop" is done
// outside of mybatis.
.map(this::getTasksCountForStatusGroupedByOrgLevel)
.flatMap(Collection::stream)
.collect(Collectors.toList());
report.addItems(items,
new DaysToWorkingDaysPreProcessor<>(this.columnHeaders, this.inWorkingDays));
return report;
} finally {
this.taskanaEngine.returnConnection();
LOGGER.debug("exit from buildDetailedReport().");
}
}
private List<DailyEntryExitQueryItem> getTasksCountForStatusGroupedByOrgLevel(TaskStatus s) {
return taskMonitorMapper.getTasksCountForStatusGroupedByOrgLevel(s, categories, classificationIds,
excludedClassificationIds, domains, customAttributeFilter);
}
}

View File

@ -13,7 +13,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.util.LoggerUtils;
/**

View File

@ -2,11 +2,11 @@ package pro.taskana.impl;
import pro.taskana.CustomField;
import pro.taskana.TaskMonitorService;
import pro.taskana.TaskanaEngine;
import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.CategoryReport;
import pro.taskana.report.ClassificationReport;
import pro.taskana.report.CustomFieldValueReport;
import pro.taskana.report.DailyEntryExitReport;
import pro.taskana.report.TaskStatusReport;
import pro.taskana.report.WorkbasketReport;
@ -18,9 +18,9 @@ public class TaskMonitorServiceImpl implements TaskMonitorService {
private TaskanaEngineImpl taskanaEngineImpl;
private TaskMonitorMapper taskMonitorMapper;
TaskMonitorServiceImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) {
TaskMonitorServiceImpl(TaskanaEngineImpl taskanaEngine, TaskMonitorMapper taskMonitorMapper) {
super();
this.taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine;
this.taskanaEngineImpl = taskanaEngine;
this.taskMonitorMapper = taskMonitorMapper;
}
@ -49,4 +49,9 @@ public class TaskMonitorServiceImpl implements TaskMonitorService {
return new TaskStatusReportBuilderImpl(taskanaEngineImpl, taskMonitorMapper);
}
@Override
public DailyEntryExitReport.Builder createDailyEntryExitReportBuilder() {
return new DailyEntryExitReportBuilderImpl(taskanaEngineImpl, taskMonitorMapper);
}
}

View File

@ -50,7 +50,7 @@ import pro.taskana.history.events.task.ClaimedEvent;
import pro.taskana.history.events.task.CompletedEvent;
import pro.taskana.history.events.task.CreatedEvent;
import pro.taskana.history.events.task.TransferredEvent;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.util.IdGenerator;
import pro.taskana.impl.util.LoggerUtils;
import pro.taskana.mappings.AttachmentMapper;

View File

@ -9,7 +9,7 @@ import pro.taskana.TaskState;
import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaRole;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.TaskQueryItem;
import pro.taskana.impl.report.item.TaskQueryItem;
import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.TaskStatusReport;

View File

@ -1,6 +1,8 @@
package pro.taskana.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -13,7 +15,8 @@ import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaRole;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.DateQueryItem;
import pro.taskana.impl.util.LoggerUtils;
import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.ClassificationReport;
@ -22,10 +25,11 @@ import pro.taskana.report.TimeIntervalReportBuilder;
/**
* Implementation of {@link TimeIntervalReportBuilder}.
* @param <B> the true Builder behind this Interface
* @param <I> the true DateQueryItem inside the Report
* @param <H> the column header
*/
abstract class TimeIntervalReportBuilderImpl<B extends TimeIntervalReportBuilder, H extends TimeIntervalColumnHeader>
implements TimeIntervalReportBuilder<B, H> {
abstract class TimeIntervalReportBuilderImpl<B extends TimeIntervalReportBuilder<B, I, H>, I extends DateQueryItem, H extends TimeIntervalColumnHeader>
implements TimeIntervalReportBuilder<B, I, H> {
private static final Logger LOGGER = LoggerFactory.getLogger(TimeIntervalReportBuilder.class);
@ -64,25 +68,25 @@ abstract class TimeIntervalReportBuilderImpl<B extends TimeIntervalReportBuilder
@Override
public B workbasketIdIn(List<String> workbasketIds) {
this.workbasketIds = workbasketIds;
this.workbasketIds = new ArrayList<>(workbasketIds);
return _this();
}
@Override
public B stateIn(List<TaskState> states) {
this.states = states;
this.states = new ArrayList<>(states);
return _this();
}
@Override
public B categoryIn(List<String> categories) {
this.categories = categories;
this.categories = new ArrayList<>(categories);
return _this();
}
@Override
public B classificationIdIn(List<String> classificationIds) {
this.classificationIds = classificationIds;
this.classificationIds = new ArrayList<>(classificationIds);
return _this();
}
@ -94,13 +98,13 @@ abstract class TimeIntervalReportBuilderImpl<B extends TimeIntervalReportBuilder
@Override
public B domainIn(List<String> domains) {
this.domains = domains;
this.domains = new ArrayList<>(domains);
return _this();
}
@Override
public B customAttributeFilterIn(Map<CustomField, String> customAttributeFilter) {
this.customAttributeFilter = customAttributeFilter;
this.customAttributeFilter = new HashMap<>(customAttributeFilter);
return _this();
}
@ -135,27 +139,26 @@ abstract class TimeIntervalReportBuilderImpl<B extends TimeIntervalReportBuilder
if (this.columnHeaders == null) {
throw new InvalidArgumentException("ColumnHeader must not be null.");
}
if (selectedItems == null || selectedItems.size() == 0) {
if (selectedItems == null || selectedItems.isEmpty()) {
throw new InvalidArgumentException("SelectedItems must not be null or empty.");
}
boolean joinWithAttachments = subKeyIsSet(selectedItems);
if (!(this instanceof ClassificationReport.Builder) && joinWithAttachments) {
throw new InvalidArgumentException("SubKeys are supported for ClassificationReport only.");
}
String dimension = determineDimension();
if (this.inWorkingDays) {
selectedItems = convertWorkingDaysToDays(selectedItems, this.columnHeaders);
}
return this.taskMonitorMapper.getTaskIdsForSelectedItems(this.workbasketIds,
this.states, this.categories, this.domains, this.classificationIds, this.excludedClassificationIds,
this.customAttributeFilter, dimension, selectedItems, joinWithAttachments);
this.customAttributeFilter, determineGroupedBy(), selectedItems, joinWithAttachments);
} finally {
this.taskanaEngine.returnConnection();
LOGGER.debug("exit from listTaskIdsForSelectedItems().");
}
}
protected abstract String determineDimension();
protected abstract String determineGroupedBy();
private void configureDaysToWorkingDaysConverter() {
DaysToWorkingDaysConverter.setCustomHolidays(this.taskanaEngine.getConfiguration().getCustomHolidays());

View File

@ -10,9 +10,9 @@ import pro.taskana.TaskanaRole;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.CombinedClassificationFilter;
import pro.taskana.impl.report.DaysToWorkingDaysPreProcessor;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.MonitorQueryItem;
import pro.taskana.impl.report.preprocessor.DaysToWorkingDaysPreProcessor;
import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.WorkbasketReport;
@ -20,7 +20,7 @@ import pro.taskana.report.WorkbasketReport;
* The implementation of WorkbasketReportBuilder.
*/
public class WorkbasketReportBuilderImpl
extends TimeIntervalReportBuilderImpl<WorkbasketReport.Builder, TimeIntervalColumnHeader>
extends TimeIntervalReportBuilderImpl<WorkbasketReport.Builder, MonitorQueryItem, TimeIntervalColumnHeader>
implements WorkbasketReport.Builder {
private static final Logger LOGGER = LoggerFactory.getLogger(WorkbasketReportBuilderImpl.class);
@ -36,7 +36,7 @@ public class WorkbasketReportBuilderImpl
}
@Override
protected String determineDimension() {
protected String determineGroupedBy() {
return "WORKBASKET_KEY";
}

View File

@ -1,31 +0,0 @@
package pro.taskana.impl.report;
import java.util.List;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.impl.DaysToWorkingDaysConverter;
import pro.taskana.report.QueryItemPreprocessor;
/**
* Uses {@link DaysToWorkingDaysConverter} to convert an &lt;Item&gt;s age to working days.
* @param <Item> QueryItem which is being processed
*/
public class DaysToWorkingDaysPreProcessor<Item extends MonitorQueryItem> implements QueryItemPreprocessor<Item> {
private DaysToWorkingDaysConverter instance;
public DaysToWorkingDaysPreProcessor(List<TimeIntervalColumnHeader> columnHeaders, boolean activate)
throws InvalidArgumentException {
if (activate) {
instance = DaysToWorkingDaysConverter.initialize(columnHeaders);
}
}
@Override
public Item apply(Item item) {
if (instance != null) {
item.setAgeInDays(instance.convertDaysToWorkingDays(item.getAgeInDays()));
}
return item;
}
}

View File

@ -1,59 +0,0 @@
package pro.taskana.impl.report;
import java.util.LinkedHashMap;
import java.util.Map;
import pro.taskana.impl.util.LoggerUtils;
import pro.taskana.report.ReportRow;
/**
* The DetailedReportRow extends the {@link ReportRow}.
* In contrast to the ReportRow there is an additional list of ReportRows for the classifications of the
* attachments of the tasks.
*/
public class DetailedReportRow extends ReportRow<DetailedMonitorQueryItem> {
private Map<String, ReportRow<DetailedMonitorQueryItem>> detailRows = new LinkedHashMap<>();
private int columnCount;
public DetailedReportRow(int columnCount) {
super(columnCount);
this.columnCount = columnCount;
}
public Map<String, ReportRow<DetailedMonitorQueryItem>> getDetailRows() {
return detailRows;
}
@Override
public void updateTotalValue(DetailedMonitorQueryItem item) {
super.updateTotalValue(item);
if (item.getAttachmentKey() != null) {
detailRows.computeIfAbsent(item.getAttachmentKey(), (s) -> new ReportRow<>(columnCount))
.updateTotalValue(item);
} else {
detailRows.computeIfAbsent("N/A", (s) -> new ReportRow<>(columnCount))
.updateTotalValue(item);
}
}
@Override
public void addItem(DetailedMonitorQueryItem item, int index) {
super.addItem(item, index);
if (item.getAttachmentKey() != null) {
detailRows.computeIfAbsent(item.getAttachmentKey(), (s) -> new ReportRow<>(columnCount))
.addItem(item, index);
} else {
detailRows.computeIfAbsent("N/A", (s) -> new ReportRow<>(columnCount))
.addItem(item, index);
}
}
@Override
public String toString() {
return "DetailedReportRow [" + "detailRows= " + LoggerUtils.mapToString(this.detailRows)
+ ", columnCount= " + this.columnCount + "]";
}
}

View File

@ -1,50 +0,0 @@
package pro.taskana.impl.report;
import pro.taskana.report.ReportColumnHeader;
/**
* A TimeIntervalColumnHeader has a lower and an upper age limit which subdivide the count of tasks into different
* sections. 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 TimeIntervalColumnHeaders should not
* overlap and should not have gaps. If the TimeIntervalColumnHeader should represent a single day, lowerAgeLimit and
* upperAgeLimit 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.
*/
public class TimeIntervalColumnHeader implements ReportColumnHeader<MonitorQueryItem> {
private final int lowerAgeLimit;
private final int upperAgeLimit;
public TimeIntervalColumnHeader(int ageInDays) {
this.lowerAgeLimit = ageInDays;
this.upperAgeLimit = ageInDays;
}
public TimeIntervalColumnHeader(int lowerAgeLimit, int upperAgeLimit) {
this.lowerAgeLimit = lowerAgeLimit;
this.upperAgeLimit = upperAgeLimit;
}
public int getLowerAgeLimit() {
return lowerAgeLimit;
}
public int getUpperAgeLimit() {
return upperAgeLimit;
}
@Override
public String toString() {
return getDisplayName();
}
@Override
public String getDisplayName() {
return "(" + this.lowerAgeLimit + "," + this.upperAgeLimit + ")";
}
@Override
public boolean fits(MonitorQueryItem item) {
return lowerAgeLimit <= item.getAgeInDays() && upperAgeLimit >= item.getAgeInDays();
}
}

View File

@ -1,12 +1,13 @@
package pro.taskana.impl.report;
package pro.taskana.impl.report.header;
import pro.taskana.TaskState;
import pro.taskana.report.ReportColumnHeader;
import pro.taskana.impl.report.item.TaskQueryItem;
import pro.taskana.report.structure.ColumnHeader;
/**
* The TaskStatusColumnHeader represents a column for each {@link TaskState}.
*/
public class TaskStatusColumnHeader implements ReportColumnHeader<TaskQueryItem> {
public class TaskStatusColumnHeader implements ColumnHeader<TaskQueryItem> {
private TaskState state;

View File

@ -0,0 +1,100 @@
package pro.taskana.impl.report.header;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import pro.taskana.impl.report.item.DateQueryItem;
import pro.taskana.report.structure.ColumnHeader;
/**
* A TimeIntervalColumnHeader has a lower and an upper age limit which subdivide the count of tasks into different
* sections. 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 TimeIntervalColumnHeaders should not
* overlap and should not have gaps. If the TimeIntervalColumnHeader should represent a single day, lowerAgeLimit and
* upperAgeLimit 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.
*/
public class TimeIntervalColumnHeader implements ColumnHeader<DateQueryItem> {
private final int lowerAgeLimit;
private final int upperAgeLimit;
public TimeIntervalColumnHeader(int ageInDays) {
this.lowerAgeLimit = ageInDays;
this.upperAgeLimit = ageInDays;
}
public TimeIntervalColumnHeader(int lowerAgeLimit, int upperAgeLimit) {
this.lowerAgeLimit = lowerAgeLimit;
this.upperAgeLimit = upperAgeLimit;
}
public int getLowerAgeLimit() {
return lowerAgeLimit;
}
public int getUpperAgeLimit() {
return upperAgeLimit;
}
@Override
public String toString() {
return getDisplayName();
}
@Override
public String getDisplayName() {
return "(" + this.lowerAgeLimit + "," + this.upperAgeLimit + ")";
}
@Override
public boolean fits(DateQueryItem item) {
return lowerAgeLimit <= item.getAgeInDays() && upperAgeLimit >= item.getAgeInDays();
}
/**
* for Date representation.
*/
public static class Date extends TimeIntervalColumnHeader {
public Date(int ageInDays) {
super(ageInDays);
}
@Override
public String getDisplayName() {
LocalDateTime ldt = LocalDateTime.now().plusDays(getLowerAgeLimit());
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ENGLISH);
return dateFormat.format(ldt);
}
}
/**
* For representation of Range.
*/
public static class Range extends TimeIntervalColumnHeader {
public Range(int ageInDays) {
super(ageInDays);
}
public Range(int lowerAgeLimit, int upperAgeLimit) {
super(lowerAgeLimit, upperAgeLimit);
}
@Override
public String getDisplayName() {
if (this.getLowerAgeLimit() == Integer.MIN_VALUE) {
return "<" + this.getUpperAgeLimit();
} else if (this.getUpperAgeLimit() == Integer.MAX_VALUE) {
return ">" + this.getLowerAgeLimit();
} else if (this.getLowerAgeLimit() == this.getUpperAgeLimit()) {
return this.getUpperAgeLimit() + "";
} else if (this.getLowerAgeLimit() != this.getUpperAgeLimit()) {
return "[" + this.getLowerAgeLimit() + " ... " + this.getUpperAgeLimit() + "]";
}
return super.getDisplayName();
}
}
}

View File

@ -0,0 +1,54 @@
package pro.taskana.impl.report.item;
import pro.taskana.TaskStatus;
/**
* The DailyEntryExitQueryItem contains the necessary information for the {@link pro.taskana.report.DailyEntryExitReport}.
*/
public class DailyEntryExitQueryItem implements DateQueryItem {
private static final String N_A = "N/A";
private int count;
private TaskStatus status;
private int ageInDays;
private String orgLevel1;
private String orgLevel2;
private String orgLevel3;
private String orgLevel4;
@Override
public String getKey() {
return status.name();
}
@Override
public int getValue() {
return count;
}
@Override
public int getAgeInDays() {
return ageInDays;
}
@Override
public void setAgeInDays(int ageInDays) {
this.ageInDays = ageInDays;
}
public String getOrgLevel1() {
return orgLevel1 == null || orgLevel1.isEmpty() ? N_A : orgLevel1;
}
public String getOrgLevel2() {
return orgLevel2 == null || orgLevel2.isEmpty() ? N_A : orgLevel2;
}
public String getOrgLevel3() {
return orgLevel3 == null || orgLevel3.isEmpty() ? N_A : orgLevel3;
}
public String getOrgLevel4() {
return orgLevel4 == null || orgLevel4.isEmpty() ? N_A : orgLevel4;
}
}

View File

@ -0,0 +1,14 @@
package pro.taskana.impl.report.item;
import pro.taskana.report.structure.QueryItem;
/**
* The MonitorQueryItem entity contains the number of tasks for a key (e.g. workbasketKey) and age in days.
*/
public interface DateQueryItem extends QueryItem {
int getAgeInDays();
void setAgeInDays(int ageInDays);
}

View File

@ -1,4 +1,4 @@
package pro.taskana.impl.report;
package pro.taskana.impl.report.item;
/**
* The DetailedMonitorQueryItem extends the {@link MonitorQueryItem}.

View File

@ -1,16 +1,15 @@
package pro.taskana.impl.report;
import pro.taskana.report.QueryItem;
package pro.taskana.impl.report.item;
/**
* The MonitorQueryItem entity contains the number of tasks for a key (e.g. workbasketKey) and age in days.
*/
public class MonitorQueryItem implements QueryItem {
public class MonitorQueryItem implements DateQueryItem {
private String key;
private int ageInDays;
private int numberOfTasks;
@Override
public String getKey() {
return key;
}
@ -19,14 +18,17 @@ public class MonitorQueryItem implements QueryItem {
this.key = key;
}
@Override
public int getAgeInDays() {
return ageInDays;
}
@Override
public void setAgeInDays(int ageInDays) {
this.ageInDays = ageInDays;
}
@Override
public int getValue() {
return numberOfTasks;
}
@ -37,8 +39,7 @@ public class MonitorQueryItem implements QueryItem {
@Override
public String toString() {
return "MonitorQueryItem [" + "key= " + this.key + ", ageInDays= " + this.ageInDays
+ ", numberOfTasks= " + this.numberOfTasks + "]";
return String.format("MonitorQueryItem [key= %s, ageInDays= %d, numberOfTasks= %d]",
key, ageInDays, numberOfTasks);
}
}

View File

@ -1,7 +1,7 @@
package pro.taskana.impl.report;
package pro.taskana.impl.report.item;
import pro.taskana.TaskState;
import pro.taskana.report.QueryItem;
import pro.taskana.report.structure.QueryItem;
/**
* The TaskQueryItem entity contains the number of tasks for a domain which have a specific state.

View File

@ -0,0 +1,33 @@
package pro.taskana.impl.report.preprocessor;
import java.util.List;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.impl.DaysToWorkingDaysConverter;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.DateQueryItem;
import pro.taskana.report.structure.QueryItemPreprocessor;
/**
* Uses {@link DaysToWorkingDaysConverter} to convert an &lt;I&gt;s age to working days.
* @param <I> QueryItem which is being processed
*/
public class DaysToWorkingDaysPreProcessor<I extends DateQueryItem> implements QueryItemPreprocessor<I> {
private DaysToWorkingDaysConverter instance;
public DaysToWorkingDaysPreProcessor(List<? extends TimeIntervalColumnHeader> columnHeaders, boolean activate)
throws InvalidArgumentException {
if (activate) {
instance = DaysToWorkingDaysConverter.initialize(columnHeaders);
}
}
@Override
public I apply(I item) {
if (instance != null) {
item.setAgeInDays(instance.convertDaysToWorkingDays(item.getAgeInDays()));
}
return item;
}
}

View File

@ -0,0 +1,89 @@
package pro.taskana.impl.report.row;
import pro.taskana.impl.report.item.DailyEntryExitQueryItem;
import pro.taskana.report.structure.Row;
/**
* A single Row inside the {@link pro.taskana.report.DailyEntryExitReport}.
* It contains 4 sub-rows for each org level respectively.
*/
public class DailyEntryExitRow extends FoldableRow<DailyEntryExitQueryItem> {
public DailyEntryExitRow(int columnSize) {
super(columnSize, DailyEntryExitQueryItem::getOrgLevel1);
}
@Override
OrgLevel1Row buildRow(int columnSize) {
return new OrgLevel1Row(columnSize);
}
@Override
public OrgLevel1Row getFoldableRow(String key) {
return (OrgLevel1Row) super.getFoldableRow(key);
}
/**
* Row inside the {@link pro.taskana.report.DailyEntryExitReport} containing
* the information regarding a specific org level 1.
*/
public static final class OrgLevel1Row extends FoldableRow<DailyEntryExitQueryItem> {
private OrgLevel1Row(int columnSize) {
super(columnSize, DailyEntryExitQueryItem::getOrgLevel2);
}
@Override
OrgLevel2Row buildRow(int columnSize) {
return new OrgLevel2Row(columnSize);
}
@Override
public OrgLevel2Row getFoldableRow(String key) {
return (OrgLevel2Row) super.getFoldableRow(key);
}
}
/**
* Row inside the {@link pro.taskana.report.DailyEntryExitReport} containing
* the information regarding a specific org level 2.
*/
public static final class OrgLevel2Row extends FoldableRow<DailyEntryExitQueryItem> {
private OrgLevel2Row(int columnSize) {
super(columnSize, DailyEntryExitQueryItem::getOrgLevel3);
}
@Override
OrgLevel3Row buildRow(int columnSize) {
return new OrgLevel3Row(columnSize);
}
@Override
public OrgLevel3Row getFoldableRow(String key) {
return (OrgLevel3Row) super.getFoldableRow(key);
}
}
/**
* Row inside the {@link pro.taskana.report.DailyEntryExitReport} containing
* the information regarding a specific org level 3.
*/
public static final class OrgLevel3Row extends FoldableRow<DailyEntryExitQueryItem> {
private OrgLevel3Row(int columnSize) {
super(columnSize, DailyEntryExitQueryItem::getOrgLevel4);
}
@Override
Row<DailyEntryExitQueryItem> buildRow(int columnSize) {
return new SingleRow<>(columnSize);
}
@Override
public SingleRow<DailyEntryExitQueryItem> getFoldableRow(String key) {
return (SingleRow<DailyEntryExitQueryItem>) super.getFoldableRow(key);
}
}
}

View File

@ -0,0 +1,25 @@
package pro.taskana.impl.report.row;
import pro.taskana.impl.report.item.DetailedMonitorQueryItem;
import pro.taskana.report.structure.Row;
/**
* Represents a single Row inside {@link pro.taskana.report.ClassificationReport.DetailedClassificationReport}.
* The collapsing criteria is the attachement key of each {@link DetailedMonitorQueryItem}.
*/
public class DetailedClassificationRow extends FoldableRow<DetailedMonitorQueryItem> {
public DetailedClassificationRow(int columnSize) {
super(columnSize, (item) -> item.getAttachmentKey() != null ? item.getAttachmentKey() : "N/A");
}
@Override
Row<DetailedMonitorQueryItem> buildRow(int columnSize) {
return new SingleRow<>(columnSize);
}
@Override
public SingleRow<DetailedMonitorQueryItem> getFoldableRow(String key) {
return (SingleRow<DetailedMonitorQueryItem>) super.getFoldableRow(key);
}
}

View File

@ -0,0 +1,66 @@
package pro.taskana.impl.report.row;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import pro.taskana.impl.util.LoggerUtils;
import pro.taskana.report.structure.QueryItem;
import pro.taskana.report.structure.Row;
/**
* The FoldableRow extends the {@link SingleRow}.
* In contrast to the {@link SingleRow} the FoldableRow contains rows which can be collapsed or expanded.
* The FoldableRow itself displays the sum of all foldable rows.
*
* @param <I> the {@link QueryItem} on which the {@link pro.taskana.report.structure.Report} is based on.
*/
public abstract class FoldableRow<I extends QueryItem> extends SingleRow<I> {
private Map<String, Row<I>> foldableRows = new LinkedHashMap<>();
private Function<? super I, String> calcFoldableRowKey;
private int columnSize;
protected FoldableRow(int columnSize, Function<? super I, String> calcFoldableRowKey) {
super(columnSize);
this.columnSize = columnSize;
this.calcFoldableRowKey = calcFoldableRowKey;
}
public final int getFoldableRowCount() {
return foldableRows.size();
}
public final Set<String> getFoldableRowKeySet() {
return foldableRows.keySet();
}
@Override
public void updateTotalValue(I item) {
super.updateTotalValue(item);
foldableRows
.computeIfAbsent(calcFoldableRowKey.apply(item), (s) -> buildRow(columnSize))
.updateTotalValue(item);
}
@Override
public void addItem(I item, int index) throws IndexOutOfBoundsException {
super.addItem(item, index);
foldableRows
.computeIfAbsent(calcFoldableRowKey.apply(item), (s) -> buildRow(columnSize))
.addItem(item, index);
}
public Row<I> getFoldableRow(String key) {
return foldableRows.get(key);
}
abstract Row<I> buildRow(int columnSize);
@Override
public String toString() {
return String.format("FoldableRow [detailRows= %s, columnSize= %d]",
LoggerUtils.mapToString(this.foldableRows), columnSize);
}
}

View File

@ -0,0 +1,41 @@
package pro.taskana.impl.report.row;
import pro.taskana.report.structure.QueryItem;
import pro.taskana.report.structure.Row;
/**
* A SingleRow represents a single row in a {@link pro.taskana.report.structure.Report}.
* It contains an array of cells whose index corresponds to the {@link pro.taskana.report.structure.ColumnHeader} index in the {@link pro.taskana.report.structure.Report}.
*
* @param <I> {@link QueryItem} on which the {@link pro.taskana.report.structure.Report} is based on.
*/
public class SingleRow<I extends QueryItem> implements Row<I> {
private final int[] cells;
private int total = 0;
public SingleRow(int columnCount) {
cells = new int[columnCount];
}
@Override
public void addItem(I item, int index) throws IndexOutOfBoundsException {
total += item.getValue();
cells[index] += item.getValue();
}
@Override
public void updateTotalValue(I item) {
total += item.getValue();
}
@Override
public final int getTotalValue() {
return total;
}
@Override
public final int[] getCells() {
return cells.clone();
}
}

View File

@ -10,11 +10,13 @@ import org.apache.ibatis.annotations.Select;
import pro.taskana.CustomField;
import pro.taskana.TaskState;
import pro.taskana.TaskStatus;
import pro.taskana.impl.SelectedItem;
import pro.taskana.impl.report.CombinedClassificationFilter;
import pro.taskana.impl.report.DetailedMonitorQueryItem;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TaskQueryItem;
import pro.taskana.impl.report.item.DailyEntryExitQueryItem;
import pro.taskana.impl.report.item.DetailedMonitorQueryItem;
import pro.taskana.impl.report.item.MonitorQueryItem;
import pro.taskana.impl.report.item.TaskQueryItem;
/**
* This class is the mybatis mapping of task monitoring.
@ -379,4 +381,55 @@ public interface TaskMonitorMapper {
@Param("customAttributeFilter") Map<CustomField, String> customAttributeFilter,
@Param("customField") CustomField customField);
@Select("<script>"
+ "SELECT A.AGE_IN_DAYS, A.ORG_LEVEL_1, A.ORG_LEVEL_2, A.ORG_LEVEL_3, A.ORG_LEVEL_4, "
+ "'${status}' AS STATUS, COUNT(A.AGE_IN_DAYS) AS COUNT FROM ("
// This subquery prevents the repetition of the AGE_IN_DAYS column calculation
// (like everywhere else in the Mappers...)in the group by clause.
// DB2 is not able to reuse computed columns in the group by statement. Even if this adds a little
// overhead / complexity. It's worth the trade-off of not computing the AGE_IN_DAYS column twice.
+ "SELECT W.ORG_LEVEL_1, W.ORG_LEVEL_2, W.ORG_LEVEL_3, W.ORG_LEVEL_4, "
+ "<if test=\"_databaseId == 'db2'\">(DAYS(T.${status}) - DAYS(CURRENT_TIMESTAMP))</if>"
+ "<if test=\"_databaseId == 'h2'\">DATEDIFF('DAY', CURRENT_TIMESTAMP, T.${status})</if>"
+ "<if test=\"_databaseId == 'postgres'\">DATE_PART('DAY', T.${status} - CURRENT_TIMESTAMP)</if>"
+ " as AGE_IN_DAYS "
+ "FROM TASK AS T INNER JOIN WORKBASKET AS W ON T.WORKBASKET_KEY=W.KEY "
+ "<where>"
+ "<if test=\"status.name() == 'COMPLETED'\">"
+ "T.COMPLETED IS NOT NULL"
+ "</if>"
+ "<if test='categories != null'>"
+ "AND CLASSIFICATION_CATEGORY IN (<foreach collection='categories' item='category' separator=','>#{category}</foreach>) "
+ "</if>"
+ "<if test='classificationIds != null'>"
+ "AND CLASSIFICATION_ID IN (<foreach collection='classificationIds' item='classificationId' separator=','>#{classificationId}</foreach>) "
+ "</if>"
+ "<if test='excludedClassificationIds != null'>"
+ "AND CLASSIFICATION_ID NOT IN (<foreach collection='excludedClassificationIds' item='excludedClassificationId' separator=','>#{excludedClassificationId}</foreach>) "
+ "</if>"
+ "<if test='domains != null'>"
+ "AND DOMAIN IN (<foreach collection='domains' item='domain' separator=','>#{domain}</foreach>) "
+ "</if>"
+ "<if test='customAttributeFilter != null'>"
+ "AND (<foreach collection='customAttributeFilter.keys' item='key' separator=' AND '>(${key} = '${customAttributeFilter.get(key)}')</foreach>) "
+ "</if>"
+ "</where>"
+ ") AS A "
+ "GROUP BY A.AGE_IN_DAYS, A.ORG_LEVEL_1, A.ORG_LEVEL_2, A.ORG_LEVEL_3, A.ORG_LEVEL_4 "
+ "</script>")
@Results({
@Result(column = "STATUS", property = "status"),
@Result(column = "AGE_IN_DAYS", property = "ageInDays"),
@Result(column = "COUNT", property = "count"),
@Result(column = "ORG_LEVEL_1", property = "orgLevel1"),
@Result(column = "ORG_LEVEL_2", property = "orgLevel2"),
@Result(column = "ORG_LEVEL_3", property = "orgLevel3"),
@Result(column = "ORG_LEVEL_4", property = "orgLevel4")
})
List<DailyEntryExitQueryItem> getTasksCountForStatusGroupedByOrgLevel(@Param("status") TaskStatus status,
@Param("categories") List<String> categories, @Param("classificationIds") List<String> classificationIds,
@Param("excludedClassificationIds") List<String> excludedClassificationIds,
@Param("domains") List<String> domains,
@Param("customAttributeFilter") Map<CustomField, String> customAttributeFilter);
}

View File

@ -4,8 +4,9 @@ import java.util.List;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.MonitorQueryItem;
import pro.taskana.report.structure.Report;
/**
* A CategoryReport contains the total numbers of tasks of the respective category as well as the total number of
@ -24,7 +25,7 @@ public class CategoryReport extends Report<MonitorQueryItem, TimeIntervalColumnH
/**
* Builder for {@link CategoryReport}.
*/
public interface Builder extends TimeIntervalReportBuilder<Builder, TimeIntervalColumnHeader> {
public interface Builder extends TimeIntervalReportBuilder<Builder, MonitorQueryItem, TimeIntervalColumnHeader> {
@Override
CategoryReport buildReport() throws NotAuthorizedException, InvalidArgumentException;

View File

@ -4,13 +4,14 @@ import java.util.List;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.DetailedMonitorQueryItem;
import pro.taskana.impl.report.DetailedReportRow;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.DetailedMonitorQueryItem;
import pro.taskana.impl.report.item.MonitorQueryItem;
import pro.taskana.impl.report.row.DetailedClassificationRow;
import pro.taskana.report.structure.Report;
/**
* The ClassificationReport extends the Report. The {@link ReportRow}s of the ClassificationReport are grouped by
* The ClassificationReport extends the Report. The {@link pro.taskana.report.structure.Row}s of the ClassificationReport are grouped by
* classifications.
*/
public class ClassificationReport extends Report<MonitorQueryItem, TimeIntervalColumnHeader> {
@ -22,7 +23,7 @@ public class ClassificationReport extends Report<MonitorQueryItem, TimeIntervalC
/**
* Builder for {@link ClassificationReport}.
*/
public interface Builder extends TimeIntervalReportBuilder<Builder, TimeIntervalColumnHeader> {
public interface Builder extends TimeIntervalReportBuilder<Builder, MonitorQueryItem, TimeIntervalColumnHeader> {
@Override
ClassificationReport buildReport() throws NotAuthorizedException, InvalidArgumentException;
@ -30,8 +31,8 @@ public class ClassificationReport extends Report<MonitorQueryItem, TimeIntervalC
/**
* Returns a {@link DetailedClassificationReport} containing all tasks after applying the filters. If the column
* headers are set the report is subdivided into clusters. Its
* {@link pro.taskana.impl.report.DetailedReportRow}s contain an additional list of
* {@link ReportRow}s for the classifications of the attachments of the tasks.
* {@link pro.taskana.impl.report.row.FoldableRow}s contain an additional list of
* {@link pro.taskana.report.structure.Row}s for the classifications of the attachments of the tasks.
*
* @throws InvalidArgumentException
* if the column headers are not initialized
@ -44,23 +45,24 @@ public class ClassificationReport extends Report<MonitorQueryItem, TimeIntervalC
/**
* The DetailedClassificationReport is a functional extension of the {@link ClassificationReport}.
* Its {@link DetailedReportRow}s contain an additional list of {@link ReportRow}s
* Its {@link pro.taskana.impl.report.row.FoldableRow}s contain an additional list of {@link pro.taskana.report.structure.Row}s
* for the classifications of the attachments of the tasks.
*/
public static class DetailedClassificationReport extends Report<DetailedMonitorQueryItem, TimeIntervalColumnHeader> {
public static class DetailedClassificationReport
extends Report<DetailedMonitorQueryItem, TimeIntervalColumnHeader> {
public DetailedClassificationReport(List<TimeIntervalColumnHeader> workbasketLevelReportColumnHeaders) {
super(workbasketLevelReportColumnHeaders, "TASK CLASSIFICATION KEYS");
}
@Override
protected DetailedReportRow createReportRow(int columnSize) {
return new DetailedReportRow(columnSize);
protected DetailedClassificationRow createRow(int columnSize) {
return new DetailedClassificationRow(columnSize);
}
@Override
public DetailedReportRow getRow(String key) {
return (DetailedReportRow) super.getRow(key);
public DetailedClassificationRow getRow(String key) {
return (DetailedClassificationRow) super.getRow(key);
}
}

View File

@ -5,8 +5,9 @@ import java.util.List;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.MonitorQueryItem;
import pro.taskana.report.structure.Report;
/**
* A CustomFieldValueReport contains the total numbers of tasks of the respective custom field as well as
@ -24,7 +25,7 @@ public class CustomFieldValueReport extends Report<MonitorQueryItem, TimeInterva
/**
* Builder for {@link CustomFieldValueReport}.
*/
public interface Builder extends TimeIntervalReportBuilder<Builder, TimeIntervalColumnHeader> {
public interface Builder extends TimeIntervalReportBuilder<Builder, MonitorQueryItem, TimeIntervalColumnHeader> {
@Override
CustomFieldValueReport buildReport() throws NotAuthorizedException, InvalidArgumentException;

View File

@ -0,0 +1,43 @@
package pro.taskana.report;
import java.util.List;
import pro.taskana.TaskStatus;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.DailyEntryExitQueryItem;
import pro.taskana.impl.report.row.DailyEntryExitRow;
import pro.taskana.report.structure.Report;
/**
* A {@link DailyEntryExitReport} displays created and competed tasks for a specific dates.
*/
public class DailyEntryExitReport extends Report<DailyEntryExitQueryItem, TimeIntervalColumnHeader.Date> {
public DailyEntryExitReport(List<TimeIntervalColumnHeader.Date> dates) {
super(dates, "STATES");
}
@Override
protected DailyEntryExitRow createRow(int columnSize) {
return new DailyEntryExitRow(columnSize);
}
@Override
public DailyEntryExitRow getRow(String key) {
return (DailyEntryExitRow) super.getRow(key);
}
/**
* Builder for {@link DailyEntryExitReport}.
*/
public interface Builder extends
TimeIntervalReportBuilder<DailyEntryExitReport.Builder, DailyEntryExitQueryItem, TimeIntervalColumnHeader.Date> {
@Override
DailyEntryExitReport buildReport() throws NotAuthorizedException, InvalidArgumentException;
Builder statusIn(List<TaskStatus> statuses);
}
}

View File

@ -1,14 +0,0 @@
package pro.taskana.report;
/**
* A QueryItem is en entity on which a {@link Report} is based on.
* Its value will be added to the existing cell value during the insertion into a report.
* Its key will determine in which {@link ReportRow} the item will be inserted.
*/
public interface QueryItem {
String getKey();
int getValue();
}

View File

@ -1,15 +0,0 @@
package pro.taskana.report;
/**
* A ReportColumnHeader is an element of a {@link Report}.
* It determines weather a given &lt;Item&gt; belongs into the representing column.
*
* @param <Item> {@link QueryItem} on which the {@link Report} is based on.
*/
public interface ReportColumnHeader<Item extends QueryItem> {
String getDisplayName();
boolean fits(Item item);
}

View File

@ -1,34 +0,0 @@
package pro.taskana.report;
/**
* A ReportRow represents a row in a {@link Report}.
* It contains an array of cells whose index corresponds to the {@link ReportColumnHeader} index in the {@link Report}.
*
* @param <Item> {@link QueryItem} on which the {@link Report} is based on.
*/
public class ReportRow<Item extends QueryItem> {
private final int[] cells;
private int totalValue = 0;
public ReportRow(int columnCount) {
cells = new int[columnCount];
}
public int[] getCells() {
return cells;
}
public int getTotalValue() {
return totalValue;
}
public void updateTotalValue(Item item) {
totalValue += item.getValue();
}
public void addItem(Item item, int index) throws IndexOutOfBoundsException {
totalValue += item.getValue();
cells[index] += item.getValue();
}
}

View File

@ -7,8 +7,9 @@ import java.util.stream.Stream;
import pro.taskana.TaskState;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.TaskQueryItem;
import pro.taskana.impl.report.TaskStatusColumnHeader;
import pro.taskana.impl.report.item.TaskQueryItem;
import pro.taskana.impl.report.header.TaskStatusColumnHeader;
import pro.taskana.report.structure.Report;
/**
* A TaskStatusReport contains the total number of tasks, clustered in their task status.

View File

@ -8,16 +8,18 @@ import pro.taskana.TaskState;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.SelectedItem;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.DateQueryItem;
import pro.taskana.report.structure.Report;
/**
* "Super" Interface for all TimeIntervalReportBuilders.
* @param <B> the true Builder behind this Interface.
* @param <I> the DateQueryItem which will be inserted into the Report.
* @param <H> the column Header
*/
public interface TimeIntervalReportBuilder<B extends TimeIntervalReportBuilder, H extends TimeIntervalColumnHeader>
extends Report.Builder<MonitorQueryItem, H> {
public interface TimeIntervalReportBuilder<B extends TimeIntervalReportBuilder<B, I, H>, I extends DateQueryItem, H extends TimeIntervalColumnHeader>
extends Report.Builder<I, H> {
/**
* Adds a list {@link TimeIntervalColumnHeader}s to the builder to subdivide the report into clusters.

View File

@ -5,8 +5,9 @@ import java.util.List;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.CombinedClassificationFilter;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.MonitorQueryItem;
import pro.taskana.report.structure.Report;
/**
* A WorkbasketReport contains the total numbers of tasks of the respective workbasket as well as the
@ -27,7 +28,7 @@ public class WorkbasketReport extends Report<MonitorQueryItem, TimeIntervalColum
/**
* Builder for {@link WorkbasketReport}.
*/
public interface Builder extends TimeIntervalReportBuilder<Builder, TimeIntervalColumnHeader> {
public interface Builder extends TimeIntervalReportBuilder<Builder, MonitorQueryItem, TimeIntervalColumnHeader> {
@Override
WorkbasketReport buildReport() throws NotAuthorizedException, InvalidArgumentException;

View File

@ -0,0 +1,27 @@
package pro.taskana.report.structure;
/**
* A ColumnHeader is an element of a {@link Report}.
* It determines weather a given &lt;Item&gt; belongs into the representing column.
*
* @param <I> {@link QueryItem} on which the {@link Report} is based on.
*/
public interface ColumnHeader<I extends QueryItem> {
/**
* The display name is the string representation of this column.
* Used to give this column a name during presentation.
* @return String representation of this column.
*/
String getDisplayName();
/**
* Determines if a specific item is meant part of this column.
*
* @param item the given item to check.
*
* @return True, if the item is supposed to be part of this column. Otherwise false.
*/
boolean fits(I item);
}

View File

@ -0,0 +1,18 @@
package pro.taskana.report.structure;
/**
* A QueryItem is en entity on which a {@link Report} is based on.
* Its value will be added to the existing cell value during the insertion into a report.
* Its key will determine in which {@link Row} the item will be inserted.
*/
public interface QueryItem {
/**
* The key of a QueryItem determines its row within a {@link Report}.
* @return the key of this query item.
*/
String getKey();
int getValue();
}

View File

@ -1,13 +1,13 @@
package pro.taskana.report;
package pro.taskana.report.structure;
/**
* The QueryItemPreprocessor is used when adding {@link QueryItem}s into a {@link Report}. It defines a processing
* step which is executed on each {@link QueryItem} before inserting it into the {@link Report}.
* @param <Item> Item class which is being pre processed.
* @param <I> Item class which is being pre processed.
*/
@FunctionalInterface
public interface QueryItemPreprocessor<Item extends QueryItem> {
public interface QueryItemPreprocessor<I extends QueryItem> {
Item apply(Item item);
I apply(I item);
}

View File

@ -1,4 +1,4 @@
package pro.taskana.report;
package pro.taskana.report.structure;
import java.util.ArrayList;
import java.util.LinkedHashMap;
@ -8,38 +8,39 @@ import java.util.Set;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.row.SingleRow;
/**
* A Report represents a an abstract table that consists of {@link ReportRow}s and a list of &lt;ColumnHeader&gt;s.
* A Report represents a an abstract table that consists of {@link Row}s and a list of &lt;ColumnHeader&gt;s.
* Since a report does not specify &lt;Item&gt; and &lt;ColumnHeader&gt; it does not contain functional logic.
* Due to readability implicit definition of functional logic is prevented and thus prevent
* initialization of an abstract Report. In order to create a specific Report a subclass has to be created.
*
* @param <Item> {@link QueryItem} whose value is relevant for this report.
* @param <ColumnHeader> {@link ReportColumnHeader} which can determine if an &lt;Item&gt; belongs into that column or not.
* @param <I> {@link QueryItem} whose value is relevant for this report.
* @param <H> {@link ColumnHeader} which can determine if an &lt;Item&gt; belongs into that column or not.
*/
public abstract class Report<Item extends QueryItem, ColumnHeader extends ReportColumnHeader<? super Item>> {
public abstract class Report<I extends QueryItem, H extends ColumnHeader<? super I>> {
protected List<ColumnHeader> columnHeaders = new ArrayList<>();
private Map<String, ReportRow<Item>> reportRows = new LinkedHashMap<>();
private ReportRow<Item> sumRow;
protected List<H> columnHeaders = new ArrayList<>();
private Map<String, Row<I>> reportRows = new LinkedHashMap<>();
private Row<I> sumRow;
private String rowDesc;
protected Report(List<ColumnHeader> columnHeaders, String rowDesc) {
protected Report(List<H> columnHeaders, String rowDesc) {
this.rowDesc = rowDesc;
sumRow = new ReportRow<>(columnHeaders.size());
sumRow = new SingleRow<>(columnHeaders.size());
this.columnHeaders.addAll(columnHeaders);
}
public final Map<String, ReportRow<Item>> getReportRows() {
public final Map<String, Row<I>> getRows() {
return reportRows;
}
public final ReportRow<Item> getSumRow() {
public final Row<I> getSumRow() {
return sumRow;
}
public final List<ColumnHeader> getColumnHeaders() {
public final List<H> getColumnHeaders() {
return columnHeaders;
}
@ -47,7 +48,7 @@ public abstract class Report<Item extends QueryItem, ColumnHeader extends Report
return rowDesc;
}
public ReportRow<Item> getRow(String key) {
public Row<I> getRow(String key) {
return reportRows.get(key);
}
@ -59,14 +60,18 @@ public abstract class Report<Item extends QueryItem, ColumnHeader extends Report
return reportRows.size();
}
public final void addItem(Item item) {
ReportRow<Item> row = reportRows.computeIfAbsent(item.getKey(), (s) -> createReportRow(columnHeaders.size()));
public final void addItem(I item) {
Row<I> row = null;
if (columnHeaders.isEmpty()) {
row = reportRows.computeIfAbsent(item.getKey(), (s) -> createRow(columnHeaders.size()));
row.updateTotalValue(item);
sumRow.updateTotalValue(item);
} else {
for (int i = 0; i < columnHeaders.size(); i++) {
if (columnHeaders.get(i).fits(item)) {
if (row == null) {
row = reportRows.computeIfAbsent(item.getKey(), (s) -> createRow(columnHeaders.size()));
}
row.addItem(item, i);
sumRow.addItem(item, i);
}
@ -74,26 +79,30 @@ public abstract class Report<Item extends QueryItem, ColumnHeader extends Report
}
}
public final void addItems(List<Item> items, QueryItemPreprocessor<Item> preprocessor) {
public final void addItem(I item, QueryItemPreprocessor<I> preprocessor) {
addItem(preprocessor.apply(item));
}
public final void addItems(List<? extends I> items, QueryItemPreprocessor<I> preprocessor) {
items.stream()
.map(preprocessor::apply)
.forEach(this::addItem);
}
public final void addItems(List<Item> items) {
public final void addItems(List<I> items) {
items.forEach(this::addItem);
}
protected ReportRow<Item> createReportRow(int columnSize) {
return new ReportRow<>(columnSize);
protected Row<I> createRow(int columnSize) {
return new SingleRow<>(columnSize);
}
/**
* Builder for {@link Report}.
* @param <I> {@link QueryItem} whose value is relevant for this report.
* @param <H> {@link ReportColumnHeader} which can determine if an &lt;Item&gt; belongs into that column or not.
* @param <H> {@link ColumnHeader} which can determine if an &lt;Item&gt; belongs into that column or not.
*/
public interface Builder<I extends QueryItem, H extends ReportColumnHeader<? super I>> {
public interface Builder<I extends QueryItem, H extends ColumnHeader<? super I>> {
Report<I, H> buildReport() throws NotAuthorizedException, InvalidArgumentException;
}

View File

@ -0,0 +1,29 @@
package pro.taskana.report.structure;
/**
* Representation of a row in a {@link Report}.
* It contains an array of cells whose index corresponds to the {@link ColumnHeader} index in the {@link Report}.
*
* @param <I> {@link QueryItem} on which the {@link Report} is based on.
*/
public interface Row<I extends QueryItem> {
/**
* Appends a specific item value at a specific index.
* @param item the item which will be appended
* @param index the index at which the item will be appended at.
* @throws IndexOutOfBoundsException if the given index is invalid.
*/
void addItem(I item, int index) throws IndexOutOfBoundsException;
/**
* updates the total value of the row without changing any cell value.
* @param item the item whose value will be added to the total value of this row.
*/
void updateTotalValue(I item);
int getTotalValue();
int[] getCells();
}

View File

@ -31,7 +31,7 @@ import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.impl.DaysToWorkingDaysConverter;
import pro.taskana.impl.TaskImpl;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.jobs.JobRunner;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;

View File

@ -0,0 +1,47 @@
package acceptance.report;
import java.io.IOException;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.BeforeClass;
import pro.taskana.TaskanaEngine;
import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.database.TestDataGenerator;
import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
/**
* Abstract test class for all report building tests.
*/
public class AbstractReportAccTest {
protected static TaskanaEngineConfiguration taskanaEngineConfiguration;
protected static TaskanaEngine taskanaEngine;
// checkstyle needs this constructor, since this is only a "utility" class
protected AbstractReportAccTest() {
}
@BeforeClass
public static void setupTest() throws Exception {
resetDb();
}
private 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,
TaskanaEngineConfigurationTest.getSchemaName());
taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskanaEngine.setConnectionManagementMode(TaskanaEngine.ConnectionManagementMode.AUTOCOMMIT);
cleaner.clearDb(dataSource, false);
TestDataGenerator testDataGenerator = new TestDataGenerator();
testDataGenerator.generateMonitoringTestData(dataSource);
}
}

View File

@ -1,32 +1,21 @@
package acceptance.monitoring;
package acceptance.report;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.TaskanaEngine;
import pro.taskana.TaskanaEngine.ConnectionManagementMode;
import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.database.TestDataGenerator;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
@ -34,30 +23,7 @@ import pro.taskana.security.WithAccessId;
* Acceptance test for all "classification report" scenarios.
*/
@RunWith(JAASRunner.class)
public class GetCustomAttributeValuesForReportAcctest {
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,
TaskanaEngineConfigurationTest.getSchemaName());
taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
cleaner.clearDb(dataSource, false);
TestDataGenerator testDataGenerator = new TestDataGenerator();
testDataGenerator.generateMonitoringTestData(dataSource);
}
public class GetCustomAttributeValuesForReportAccTest extends AbstractReportAccTest {
@Test(expected = NotAuthorizedException.class)
public void testRoleCheck() throws NotAuthorizedException {

View File

@ -0,0 +1,202 @@
package acceptance.report;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.Test;
import org.junit.runner.RunWith;
import pro.taskana.TaskMonitorService;
import pro.taskana.TaskanaEngine;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.DailyEntryExitQueryItem;
import pro.taskana.impl.report.row.DailyEntryExitRow;
import pro.taskana.impl.report.row.SingleRow;
import pro.taskana.report.DailyEntryExitReport;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
/**
* Test class for {@link pro.taskana.report.DailyEntryExitReport}.
*/
@RunWith(JAASRunner.class)
public class GetDailyEntryExitReportAccTest extends AbstractReportAccTest {
/**
* This test covers every insert operation of the DailyEntryExitReport.
* We have two definitions for org level 1: 'org1' and 'N/A'.
* All other org levels only contain 'N/A'. Thus this test only tests the separation for org level1.
* Since every OrgLevelRow is a FoldableRow this is sufficient
* to prove that the separation/grouping by detail mechanism works.
*
* @throws Exception if any error occurs during the test.
*/
@WithAccessId(userName = "monitor")
@Test
public void testProperInsertionOfQueryItems() throws Exception {
taskanaEngine.setConnectionManagementMode(TaskanaEngine.ConnectionManagementMode.AUTOCOMMIT);
TaskMonitorService mapper = taskanaEngine.getTaskMonitorService();
//last 14 days. Today excluded.
List<TimeIntervalColumnHeader.Date> collect = IntStream.range(-14, 0)
.mapToObj(TimeIntervalColumnHeader.Date::new)
.collect(Collectors.toList());
DailyEntryExitReport dailyEntryExitReport = mapper.createDailyEntryExitReportBuilder()
.withColumnHeaders(collect)
.buildReport();
final HashSet<String> org1Set = new HashSet<>(Arrays.asList("N/A", "org1"));
final HashSet<String> allOtherOrgLevelSet = new HashSet<>(Collections.singletonList("N/A"));
assertEquals(2, dailyEntryExitReport.getRows().size());
assertEquals(new HashSet<>(Arrays.asList("CREATED", "COMPLETED")),
dailyEntryExitReport.getRows().keySet());
// * * * * * * * * * * * * * * * * * * * * * TEST THE CREATED ROW * * * * * * * * * * * * * * * * * * * * *
DailyEntryExitRow statusRow = dailyEntryExitReport.getRow("CREATED");
assertEquals(2, statusRow.getFoldableRowCount());
assertEquals(org1Set, statusRow.getFoldableRowKeySet());
// 2 Entries with -8 days and one with -9 days.
assertArrayEquals(new int[] {0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0}, statusRow.getCells());
assertEquals(3, statusRow.getTotalValue());
// 'CREATED' -> 'org1'
DailyEntryExitRow.OrgLevel1Row org1Row = statusRow.getFoldableRow("org1");
assertEquals(1, org1Row.getFoldableRowCount());
assertEquals(allOtherOrgLevelSet, org1Row.getFoldableRowKeySet());
// only task TKI:000000000000000000000000000000000029 in 'org1'.
assertArrayEquals(new int[] {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, org1Row.getCells());
assertEquals(1, org1Row.getTotalValue());
// 'CREATED' -> 'org1'/'N/A'
DailyEntryExitRow.OrgLevel2Row org2Row = org1Row.getFoldableRow("N/A");
assertEquals(1, org2Row.getFoldableRowCount());
assertEquals(allOtherOrgLevelSet, org2Row.getFoldableRowKeySet());
// Since no further separation (in org level) they should be the same.
assertArrayEquals(org1Row.getCells(), org2Row.getCells());
assertEquals(org1Row.getTotalValue(), org2Row.getTotalValue());
// 'CREATED' -> 'org1'/'N/A'/'N/A'
DailyEntryExitRow.OrgLevel3Row org3Row = org2Row.getFoldableRow("N/A");
assertEquals(1, org2Row.getFoldableRowCount());
assertEquals(allOtherOrgLevelSet, org3Row.getFoldableRowKeySet());
// Since no further separation (in org level) they should be the same.
assertArrayEquals(org2Row.getCells(), org3Row.getCells());
assertEquals(org2Row.getTotalValue(), org3Row.getTotalValue());
// 'CREATED' -> 'org1'/'N/A'/'N/A'/'N/A'
SingleRow<DailyEntryExitQueryItem> org4Row = org3Row.getFoldableRow("N/A");
// Since no further separation (in org level) they should be the same.
assertArrayEquals(org3Row.getCells(), org4Row.getCells());
assertEquals(org3Row.getTotalValue(), org4Row.getTotalValue());
// 'CREATED' -> 'N/A'
org1Row = statusRow.getFoldableRow("N/A");
assertEquals(1, org1Row.getFoldableRowCount());
assertEquals(allOtherOrgLevelSet, org1Row.getFoldableRowKeySet());
// task TKI:000000000000000000000000000000000030,
// and TKI:000000000000000000000000000000000036 in 'N/A'.
assertArrayEquals(new int[] {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}, org1Row.getCells());
assertEquals(2, org1Row.getTotalValue());
// 'CREATED' -> 'N/A'/'N/A'
org2Row = org1Row.getFoldableRow("N/A");
assertEquals(1, org2Row.getFoldableRowCount());
assertEquals(allOtherOrgLevelSet, org2Row.getFoldableRowKeySet());
// Since no further separation (in org level) they should be the same.
assertArrayEquals(org1Row.getCells(), org2Row.getCells());
assertEquals(org1Row.getTotalValue(), org2Row.getTotalValue());
// 'CREATED' -> 'N/A'/'N/A'/'N/A'
org3Row = org2Row.getFoldableRow("N/A");
assertEquals(1, org2Row.getFoldableRowCount());
assertEquals(allOtherOrgLevelSet, org3Row.getFoldableRowKeySet());
// Since no further separation (in org level) they should be the same.
assertArrayEquals(org2Row.getCells(), org3Row.getCells());
assertEquals(org2Row.getTotalValue(), org3Row.getTotalValue());
// 'CREATED' -> 'N/A'/'N/A'/'N/A'/'N/A'
org4Row = org3Row.getFoldableRow("N/A");
// Since no further separation (in org level) they should be the same.
assertArrayEquals(org3Row.getCells(), org4Row.getCells());
assertEquals(org3Row.getTotalValue(), org4Row.getTotalValue());
// * * * * * * * * * * * * * * * * * * * * * TEST THE COMPLETED ROW * * * * * * * * * * * * * * * * * * * * *
statusRow = dailyEntryExitReport.getRow("COMPLETED");
assertEquals(2, statusRow.getFoldableRowCount());
assertEquals(org1Set, statusRow.getFoldableRowKeySet());
// 2 Entries with -1 days, one with -2 days and one with -7 days.
assertArrayEquals(new int[] {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 2}, statusRow.getCells());
assertEquals(4, statusRow.getTotalValue());
// 'COMPLETED' -> 'org1'
org1Row = statusRow.getFoldableRow("org1");
assertEquals(1, org1Row.getFoldableRowCount());
assertEquals(allOtherOrgLevelSet, org1Row.getFoldableRowKeySet());
// only task TKI:000000000000000000000000000000000029 in 'org1'.
assertArrayEquals(new int[] {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, org1Row.getCells());
assertEquals(1, org1Row.getTotalValue());
// 'COMPLETED' -> 'org1'/'N/A'
org2Row = org1Row.getFoldableRow("N/A");
assertEquals(1, org2Row.getFoldableRowCount());
assertEquals(allOtherOrgLevelSet, org2Row.getFoldableRowKeySet());
// Since no further separation (in org level) they should be the same.
assertArrayEquals(org1Row.getCells(), org2Row.getCells());
assertEquals(org1Row.getTotalValue(), org2Row.getTotalValue());
// 'COMPLETED' -> 'org1'/'N/A'/'N/A'
org3Row = org2Row.getFoldableRow("N/A");
assertEquals(1, org2Row.getFoldableRowCount());
assertEquals(allOtherOrgLevelSet, org3Row.getFoldableRowKeySet());
// Since no further separation (in org level) they should be the same.
assertArrayEquals(org2Row.getCells(), org3Row.getCells());
assertEquals(org2Row.getTotalValue(), org3Row.getTotalValue());
// 'COMPLETED' -> 'org1'/'N/A'/'N/A'/'N/A'
org4Row = org3Row.getFoldableRow("N/A");
// Since no further separation (in org level) they should be the same.
assertArrayEquals(org3Row.getCells(), org4Row.getCells());
assertEquals(org3Row.getTotalValue(), org4Row.getTotalValue());
// 'COMPLETED' -> 'N/A'
org1Row = statusRow.getFoldableRow("N/A");
assertEquals(1, org1Row.getFoldableRowCount());
assertEquals(allOtherOrgLevelSet, org1Row.getFoldableRowKeySet());
// task TKI:000000000000000000000000000000000032,
// TKI:000000000000000000000000000000000034,
// and TKI:000000000000000000000000000000000037 in 'N/A'.
assertArrayEquals(new int[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2}, org1Row.getCells());
assertEquals(3, org1Row.getTotalValue());
// 'COMPLETED' -> 'N/A'/'N/A'
org2Row = org1Row.getFoldableRow("N/A");
assertEquals(1, org2Row.getFoldableRowCount());
assertEquals(allOtherOrgLevelSet, org2Row.getFoldableRowKeySet());
// Since no further separation (in org level) they should be the same.
assertArrayEquals(org1Row.getCells(), org2Row.getCells());
assertEquals(org1Row.getTotalValue(), org2Row.getTotalValue());
// 'COMPLETED' -> 'N/A'/'N/A'/'N/A'
org3Row = org2Row.getFoldableRow("N/A");
assertEquals(1, org2Row.getFoldableRowCount());
assertEquals(allOtherOrgLevelSet, org3Row.getFoldableRowKeySet());
// Since no further separation (in org level) they should be the same.
assertArrayEquals(org2Row.getCells(), org3Row.getCells());
assertEquals(org2Row.getTotalValue(), org3Row.getTotalValue());
// 'COMPLETED' -> 'N/A'/'N/A'/'N/A'/'N/A'
org4Row = org3Row.getFoldableRow("N/A");
// Since no further separation (in org level) they should be the same.
assertArrayEquals(org3Row.getCells(), org4Row.getCells());
assertEquals(org3Row.getTotalValue(), org4Row.getTotalValue());
}
}

View File

@ -1,10 +1,8 @@
package acceptance.monitoring;
package acceptance.report;
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;
@ -12,26 +10,16 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
@ -39,30 +27,7 @@ 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,
TaskanaEngineConfigurationTest.getSchemaName());
taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
cleaner.clearDb(dataSource, false);
TestDataGenerator testDataGenerator = new TestDataGenerator();
testDataGenerator.generateMonitoringTestData(dataSource);
}
public class GetTaskIdsOfCategoryReportAccTest extends AbstractReportAccTest {
@Test(expected = NotAuthorizedException.class)
public void testRoleCheck() throws InvalidArgumentException, NotAuthorizedException {

View File

@ -1,31 +1,19 @@
package acceptance.monitoring;
package acceptance.report;
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.List;
import javax.sql.DataSource;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import pro.taskana.TaskMonitorService;
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.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
@ -33,30 +21,7 @@ import pro.taskana.security.WithAccessId;
* Acceptance test for all "get task ids of classification report" scenarios.
*/
@RunWith(JAASRunner.class)
public class GetTaskIdsOfClassificationReportAccTest {
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,
TaskanaEngineConfigurationTest.getSchemaName());
taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
cleaner.clearDb(dataSource, false);
TestDataGenerator testDataGenerator = new TestDataGenerator();
testDataGenerator.generateMonitoringTestData(dataSource);
}
public class GetTaskIdsOfClassificationReportAccTest extends AbstractReportAccTest {
@Test(expected = NotAuthorizedException.class)
public void testRoleCheck() throws InvalidArgumentException, NotAuthorizedException {

View File

@ -1,10 +1,8 @@
package acceptance.monitoring;
package acceptance.report;
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;
@ -12,26 +10,16 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
@ -39,30 +27,7 @@ import pro.taskana.security.WithAccessId;
* Acceptance test for all "get task ids of category report" scenarios.
*/
@RunWith(JAASRunner.class)
public class GetTaskIdsOfCustomFieldValueReportAccTest {
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,
TaskanaEngineConfigurationTest.getSchemaName());
taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
cleaner.clearDb(dataSource, false);
TestDataGenerator testDataGenerator = new TestDataGenerator();
testDataGenerator.generateMonitoringTestData(dataSource);
}
public class GetTaskIdsOfCustomFieldValueReportAccTest extends AbstractReportAccTest {
@Test(expected = NotAuthorizedException.class)
public void testRoleCheck() throws InvalidArgumentException, NotAuthorizedException {

View File

@ -1,32 +1,20 @@
package acceptance.monitoring;
package acceptance.report;
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.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.TaskMonitorService;
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.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
@ -34,30 +22,7 @@ import pro.taskana.security.WithAccessId;
* Acceptance test for all "get task ids of workbasket report" scenarios.
*/
@RunWith(JAASRunner.class)
public class GetTaskIdsOfWorkbasketReportAccTest {
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,
TaskanaEngineConfigurationTest.getSchemaName());
taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
cleaner.clearDb(dataSource, false);
TestDataGenerator testDataGenerator = new TestDataGenerator();
testDataGenerator.generateMonitoringTestData(dataSource);
}
public class GetTaskIdsOfWorkbasketReportAccTest extends AbstractReportAccTest {
@Test(expected = NotAuthorizedException.class)
public void testRoleCheck() throws InvalidArgumentException, NotAuthorizedException {

View File

@ -1,11 +1,9 @@
package acceptance.monitoring;
package acceptance.report;
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;
@ -14,9 +12,6 @@ import java.util.List;
import java.util.Map;
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;
@ -25,16 +20,9 @@ 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.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.report.CategoryReport;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
@ -43,31 +31,9 @@ import pro.taskana.security.WithAccessId;
* Acceptance test for all "category report" scenarios.
*/
@RunWith(JAASRunner.class)
public class ProvideCategoryReportAccTest {
public class ProvideCategoryReportAccTest extends AbstractReportAccTest {
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,
TaskanaEngineConfigurationTest.getSchemaName());
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 {

View File

@ -1,11 +1,9 @@
package acceptance.monitoring;
package acceptance.report;
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;
@ -14,9 +12,6 @@ import java.util.List;
import java.util.Map;
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;
@ -25,16 +20,9 @@ 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.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.report.ClassificationReport;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
@ -43,31 +31,9 @@ import pro.taskana.security.WithAccessId;
* Acceptance test for all "classification report" scenarios.
*/
@RunWith(JAASRunner.class)
public class ProvideClassificationReportAccTest {
public class ProvideClassificationReportAccTest extends AbstractReportAccTest {
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,
TaskanaEngineConfigurationTest.getSchemaName());
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()

View File

@ -1,11 +1,9 @@
package acceptance.monitoring;
package acceptance.report;
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;
@ -13,9 +11,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
@ -24,15 +19,9 @@ 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.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.report.CustomFieldValueReport;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
@ -41,31 +30,9 @@ import pro.taskana.security.WithAccessId;
* Acceptance test for all "classification report" scenarios.
*/
@RunWith(JAASRunner.class)
public class ProvideCustomFieldValueReportAccTest {
public class ProvideCustomFieldValueReportAccTest extends AbstractReportAccTest {
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,
TaskanaEngineConfigurationTest.getSchemaName());
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()

View File

@ -1,11 +1,9 @@
package acceptance.monitoring;
package acceptance.report;
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;
@ -13,9 +11,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
@ -24,20 +19,13 @@ 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.DetailedMonitorQueryItem;
import pro.taskana.impl.report.DetailedReportRow;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.DetailedMonitorQueryItem;
import pro.taskana.impl.report.row.FoldableRow;
import pro.taskana.report.ClassificationReport.DetailedClassificationReport;
import pro.taskana.report.ReportRow;
import pro.taskana.report.structure.Row;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
@ -45,31 +33,9 @@ import pro.taskana.security.WithAccessId;
* Acceptance test for all "detailed classification report" scenarios.
*/
@RunWith(JAASRunner.class)
public class ProvideDetailedClassificationReportAccTest {
public class ProvideDetailedClassificationReportAccTest extends AbstractReportAccTest {
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,
TaskanaEngineConfigurationTest.getSchemaName());
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()
@ -96,39 +62,39 @@ public class ProvideDetailedClassificationReportAccTest {
assertNotNull(report);
assertEquals(5, report.rowSize());
DetailedReportRow row1 = report.getRow("L10000");
FoldableRow<DetailedMonitorQueryItem> row1 = report.getRow("L10000");
assertEquals(10, row1.getTotalValue());
assertEquals(3, row1.getDetailRows().get("L11000").getTotalValue());
assertEquals(7, row1.getDetailRows().get("N/A").getTotalValue());
assertEquals(3, row1.getFoldableRow("L11000").getTotalValue());
assertEquals(7, row1.getFoldableRow("N/A").getTotalValue());
assertEquals(0, row1.getCells().length);
assertEquals(2, row1.getDetailRows().size());
assertEquals(2, row1.getFoldableRowCount());
DetailedReportRow row2 = report.getRow("L20000");
FoldableRow<DetailedMonitorQueryItem> row2 = report.getRow("L20000");
assertEquals(10, row2.getTotalValue());
assertEquals(4, row2.getDetailRows().get("L22000").getTotalValue());
assertEquals(6, row2.getDetailRows().get("N/A").getTotalValue());
assertEquals(4, row2.getFoldableRow("L22000").getTotalValue());
assertEquals(6, row2.getFoldableRow("N/A").getTotalValue());
assertEquals(0, row2.getCells().length);
assertEquals(2, row2.getDetailRows().size());
assertEquals(2, row2.getFoldableRowCount());
DetailedReportRow row3 = report.getRow("L30000");
FoldableRow<DetailedMonitorQueryItem> 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(3, row3.getFoldableRow("L33000").getTotalValue());
assertEquals(1, row3.getFoldableRow("L99000").getTotalValue());
assertEquals(3, row3.getFoldableRow("N/A").getTotalValue());
assertEquals(0, row3.getCells().length);
assertEquals(3, row3.getDetailRows().size());
assertEquals(3, row3.getFoldableRowCount());
DetailedReportRow row4 = report.getRow("L40000");
FoldableRow<DetailedMonitorQueryItem> row4 = report.getRow("L40000");
assertEquals(10, row4.getTotalValue());
assertEquals(10, row4.getDetailRows().get("N/A").getTotalValue());
assertEquals(10, row4.getFoldableRow("N/A").getTotalValue());
assertEquals(0, row4.getCells().length);
assertEquals(1, row4.getDetailRows().size());
assertEquals(1, row4.getFoldableRowCount());
DetailedReportRow row5 = report.getRow("L50000");
FoldableRow<DetailedMonitorQueryItem> row5 = report.getRow("L50000");
assertEquals(13, row5.getTotalValue());
assertEquals(13, row5.getDetailRows().get("N/A").getTotalValue());
assertEquals(13, row5.getFoldableRow("N/A").getTotalValue());
assertEquals(0, row5.getCells().length);
assertEquals(1, row5.getDetailRows().size());
assertEquals(1, row5.getFoldableRowCount());
assertEquals(50, report.getSumRow().getTotalValue());
}
@ -185,46 +151,46 @@ public class ProvideDetailedClassificationReportAccTest {
assertNotNull(report);
assertEquals(5, report.rowSize());
DetailedReportRow line1 = report.getRow("L10000");
FoldableRow<DetailedMonitorQueryItem> line1 = report.getRow("L10000");
assertArrayEquals(new int[] {7, 2, 1, 0, 0}, line1.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine1 = line1.getDetailRows().get("L11000");
Row<DetailedMonitorQueryItem> detailedLine1 = line1.getFoldableRow("L11000");
assertArrayEquals(new int[] {2, 0, 1, 0, 0}, detailedLine1.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment1 = line1.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment1 = line1.getFoldableRow("N/A");
assertArrayEquals(new int[] {5, 2, 0, 0, 0}, detailedLineNoAttachment1.getCells());
DetailedReportRow line2 = report.getRow("L20000");
FoldableRow<DetailedMonitorQueryItem> line2 = report.getRow("L20000");
assertArrayEquals(new int[] {5, 3, 1, 1, 0}, line2.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine2 = line2.getDetailRows().get("L22000");
Row<DetailedMonitorQueryItem> detailedLine2 = line2.getFoldableRow("L22000");
assertArrayEquals(new int[] {1, 1, 1, 1, 0}, detailedLine2.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment2 = line2.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment2 = line2.getFoldableRow("N/A");
assertArrayEquals(new int[] {4, 2, 0, 0, 0}, detailedLineNoAttachment2.getCells());
DetailedReportRow line3 = report.getRow("L30000");
FoldableRow<DetailedMonitorQueryItem> line3 = report.getRow("L30000");
assertArrayEquals(new int[] {2, 1, 0, 1, 3}, line3.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine3a = line3.getDetailRows().get("L33000");
Row<DetailedMonitorQueryItem> detailedLine3a = line3.getFoldableRow("L33000");
assertArrayEquals(new int[] {0, 1, 0, 1, 1}, detailedLine3a.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine3b = line3.getDetailRows().get("L99000");
Row<DetailedMonitorQueryItem> detailedLine3b = line3.getFoldableRow("L99000");
assertArrayEquals(new int[] {0, 0, 0, 0, 1}, detailedLine3b.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment3 = line3.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment3 = line3.getFoldableRow("N/A");
assertArrayEquals(new int[] {2, 0, 0, 0, 1}, detailedLineNoAttachment3.getCells());
DetailedReportRow line4 = report.getRow("L40000");
FoldableRow<DetailedMonitorQueryItem> line4 = report.getRow("L40000");
assertArrayEquals(new int[] {2, 2, 2, 0, 4}, line4.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment4 = line4.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment4 = line4.getFoldableRow("N/A");
assertArrayEquals(new int[] {2, 2, 2, 0, 4}, detailedLineNoAttachment4.getCells());
DetailedReportRow line5 = report.getRow("L50000");
FoldableRow<DetailedMonitorQueryItem> line5 = report.getRow("L50000");
assertArrayEquals(new int[] {3, 3, 0, 5, 2}, line5.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment5 = line5.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment5 = line5.getFoldableRow("N/A");
assertArrayEquals(new int[] {3, 3, 0, 5, 2}, detailedLineNoAttachment5.getCells());
}
@ -251,43 +217,43 @@ public class ProvideDetailedClassificationReportAccTest {
assertNotNull(report);
assertEquals(5, report.rowSize());
DetailedReportRow line1 = report.getRow("L10000");
FoldableRow<DetailedMonitorQueryItem> line1 = report.getRow("L10000");
assertArrayEquals(new int[] {6, 0, 0, 0, 0}, line1.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine1 = line1.getDetailRows().get("L11000");
Row<DetailedMonitorQueryItem> detailedLine1 = line1.getFoldableRow("L11000");
assertArrayEquals(new int[] {2, 0, 0, 0, 0}, detailedLine1.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment1 = line1.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment1 = line1.getFoldableRow("N/A");
assertArrayEquals(new int[] {4, 0, 0, 0, 0}, detailedLineNoAttachment1.getCells());
DetailedReportRow line2 = report.getRow("L20000");
FoldableRow<DetailedMonitorQueryItem> line2 = report.getRow("L20000");
assertArrayEquals(new int[] {2, 0, 0, 0, 0}, line2.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine2 = line2.getDetailRows().get("L22000");
Row<DetailedMonitorQueryItem> detailedLine2 = line2.getFoldableRow("L22000");
assertArrayEquals(new int[] {1, 0, 0, 0, 0}, detailedLine2.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment2 = line2.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment2 = line2.getFoldableRow("N/A");
assertArrayEquals(new int[] {1, 0, 0, 0, 0}, detailedLineNoAttachment2.getCells());
DetailedReportRow line3 = report.getRow("L30000");
FoldableRow<DetailedMonitorQueryItem> line3 = report.getRow("L30000");
assertArrayEquals(new int[] {2, 1, 0, 1, 1}, line3.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine3a = line3.getDetailRows().get("L33000");
Row<DetailedMonitorQueryItem> detailedLine3a = line3.getFoldableRow("L33000");
assertArrayEquals(new int[] {0, 1, 0, 1, 1}, detailedLine3a.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment3 = line3.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment3 = line3.getFoldableRow("N/A");
assertArrayEquals(new int[] {2, 0, 0, 0, 0}, detailedLineNoAttachment3.getCells());
DetailedReportRow line4 = report.getRow("L40000");
FoldableRow<DetailedMonitorQueryItem> line4 = report.getRow("L40000");
assertArrayEquals(new int[] {1, 0, 1, 0, 1}, line4.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment4 = line4.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment4 = line4.getFoldableRow("N/A");
assertArrayEquals(new int[] {1, 0, 1, 0, 1}, detailedLineNoAttachment4.getCells());
DetailedReportRow line5 = report.getRow("L50000");
FoldableRow<DetailedMonitorQueryItem> line5 = report.getRow("L50000");
assertArrayEquals(new int[] {2, 2, 0, 0, 0}, line5.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment5 = line5.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment5 = line5.getFoldableRow("N/A");
assertArrayEquals(new int[] {2, 2, 0, 0, 0}, detailedLineNoAttachment5.getCells());
}
@ -314,43 +280,43 @@ public class ProvideDetailedClassificationReportAccTest {
assertNotNull(report);
assertEquals(5, report.rowSize());
DetailedReportRow line1 = report.getRow("L10000");
FoldableRow<DetailedMonitorQueryItem> line1 = report.getRow("L10000");
assertArrayEquals(new int[] {7, 2, 1, 0, 0}, line1.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine1 = line1.getDetailRows().get("L11000");
Row<DetailedMonitorQueryItem> detailedLine1 = line1.getFoldableRow("L11000");
assertArrayEquals(new int[] {2, 0, 1, 0, 0}, detailedLine1.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment1 = line1.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment1 = line1.getFoldableRow("N/A");
assertArrayEquals(new int[] {5, 2, 0, 0, 0}, detailedLineNoAttachment1.getCells());
DetailedReportRow line2 = report.getRow("L20000");
FoldableRow<DetailedMonitorQueryItem> line2 = report.getRow("L20000");
assertArrayEquals(new int[] {5, 3, 1, 1, 0}, line2.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine2 = line2.getDetailRows().get("L22000");
Row<DetailedMonitorQueryItem> detailedLine2 = line2.getFoldableRow("L22000");
assertArrayEquals(new int[] {1, 1, 1, 1, 0}, detailedLine2.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment2 = line2.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment2 = line2.getFoldableRow("N/A");
assertArrayEquals(new int[] {4, 2, 0, 0, 0}, detailedLineNoAttachment2.getCells());
DetailedReportRow line3 = report.getRow("L30000");
FoldableRow<DetailedMonitorQueryItem> line3 = report.getRow("L30000");
assertArrayEquals(new int[] {2, 1, 0, 1, 0}, line3.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine3a = line3.getDetailRows().get("L33000");
Row<DetailedMonitorQueryItem> detailedLine3a = line3.getFoldableRow("L33000");
assertArrayEquals(new int[] {0, 1, 0, 1, 0}, detailedLine3a.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment3 = line3.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment3 = line3.getFoldableRow("N/A");
assertArrayEquals(new int[] {2, 0, 0, 0, 0}, detailedLineNoAttachment3.getCells());
DetailedReportRow line4 = report.getRow("L40000");
FoldableRow<DetailedMonitorQueryItem> line4 = report.getRow("L40000");
assertArrayEquals(new int[] {2, 2, 2, 0, 0}, line4.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment4 = line4.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment4 = line4.getFoldableRow("N/A");
assertArrayEquals(new int[] {2, 2, 2, 0, 0}, detailedLineNoAttachment4.getCells());
DetailedReportRow line5 = report.getRow("L50000");
FoldableRow<DetailedMonitorQueryItem> line5 = report.getRow("L50000");
assertArrayEquals(new int[] {3, 3, 0, 5, 0}, line5.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment5 = line5.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment5 = line5.getFoldableRow("N/A");
assertArrayEquals(new int[] {3, 3, 0, 5, 0}, detailedLineNoAttachment5.getCells());
}
@ -374,46 +340,46 @@ public class ProvideDetailedClassificationReportAccTest {
assertNotNull(report);
assertEquals(5, report.rowSize());
DetailedReportRow line1 = report.getRow("L10000");
FoldableRow<DetailedMonitorQueryItem> line1 = report.getRow("L10000");
assertArrayEquals(new int[] {9, 0, 1, 0, 0}, line1.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine1 = line1.getDetailRows().get("L11000");
Row<DetailedMonitorQueryItem> detailedLine1 = line1.getFoldableRow("L11000");
assertArrayEquals(new int[] {2, 0, 1, 0, 0}, detailedLine1.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment1 = line1.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment1 = line1.getFoldableRow("N/A");
assertArrayEquals(new int[] {7, 0, 0, 0, 0}, detailedLineNoAttachment1.getCells());
DetailedReportRow line2 = report.getRow("L20000");
FoldableRow<DetailedMonitorQueryItem> line2 = report.getRow("L20000");
assertArrayEquals(new int[] {8, 0, 1, 0, 1}, line2.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine2 = line2.getDetailRows().get("L22000");
Row<DetailedMonitorQueryItem> detailedLine2 = line2.getFoldableRow("L22000");
assertArrayEquals(new int[] {2, 0, 1, 0, 1}, detailedLine2.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment2 = line2.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment2 = line2.getFoldableRow("N/A");
assertArrayEquals(new int[] {6, 0, 0, 0, 0}, detailedLineNoAttachment2.getCells());
DetailedReportRow line3 = report.getRow("L30000");
FoldableRow<DetailedMonitorQueryItem> line3 = report.getRow("L30000");
assertArrayEquals(new int[] {3, 0, 0, 0, 4}, line3.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine3a = line3.getDetailRows().get("L33000");
Row<DetailedMonitorQueryItem> detailedLine3a = line3.getFoldableRow("L33000");
assertArrayEquals(new int[] {1, 0, 0, 0, 2}, detailedLine3a.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine3b = line3.getDetailRows().get("L99000");
Row<DetailedMonitorQueryItem> detailedLine3b = line3.getFoldableRow("L99000");
assertArrayEquals(new int[] {0, 0, 0, 0, 1}, detailedLine3b.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment3 = line3.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment3 = line3.getFoldableRow("N/A");
assertArrayEquals(new int[] {2, 0, 0, 0, 1}, detailedLineNoAttachment3.getCells());
DetailedReportRow line4 = report.getRow("L40000");
FoldableRow<DetailedMonitorQueryItem> line4 = report.getRow("L40000");
assertArrayEquals(new int[] {4, 0, 2, 0, 4}, line4.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment4 = line4.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment4 = line4.getFoldableRow("N/A");
assertArrayEquals(new int[] {4, 0, 2, 0, 4}, detailedLineNoAttachment4.getCells());
DetailedReportRow line5 = report.getRow("L50000");
FoldableRow<DetailedMonitorQueryItem> line5 = report.getRow("L50000");
assertArrayEquals(new int[] {6, 0, 0, 0, 7}, line5.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment5 = line5.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment5 = line5.getFoldableRow("N/A");
assertArrayEquals(new int[] {6, 0, 0, 0, 7}, detailedLineNoAttachment5.getCells());
}
@ -440,22 +406,22 @@ public class ProvideDetailedClassificationReportAccTest {
assertNotNull(report);
assertEquals(2, report.rowSize());
DetailedReportRow line1 = report.getRow("L30000");
FoldableRow<DetailedMonitorQueryItem> line1 = report.getRow("L30000");
assertArrayEquals(new int[] {2, 1, 0, 1, 3}, line1.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine1a = line1.getDetailRows().get("L33000");
Row<DetailedMonitorQueryItem> detailedLine1a = line1.getFoldableRow("L33000");
assertArrayEquals(new int[] {0, 1, 0, 1, 1}, detailedLine1a.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine1b = line1.getDetailRows().get("L99000");
Row<DetailedMonitorQueryItem> detailedLine1b = line1.getFoldableRow("L99000");
assertArrayEquals(new int[] {0, 0, 0, 0, 1}, detailedLine1b.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine1WithoutAttachment = line1.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLine1WithoutAttachment = line1.getFoldableRow("N/A");
assertArrayEquals(new int[] {2, 0, 0, 0, 1}, detailedLine1WithoutAttachment.getCells());
DetailedReportRow line2 = report.getRow("L40000");
FoldableRow<DetailedMonitorQueryItem> line2 = report.getRow("L40000");
assertArrayEquals(new int[] {2, 2, 2, 0, 4}, line2.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine2WithoutAttachment = line2.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLine2WithoutAttachment = line2.getFoldableRow("N/A");
assertArrayEquals(new int[] {2, 2, 2, 0, 4}, detailedLine2WithoutAttachment.getCells());
}
@ -483,43 +449,43 @@ public class ProvideDetailedClassificationReportAccTest {
assertNotNull(report);
assertEquals(5, report.rowSize());
DetailedReportRow line1 = report.getRow("L10000");
FoldableRow<DetailedMonitorQueryItem> line1 = report.getRow("L10000");
assertArrayEquals(new int[] {5, 2, 1, 0, 0}, line1.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine1 = line1.getDetailRows().get("L11000");
Row<DetailedMonitorQueryItem> detailedLine1 = line1.getFoldableRow("L11000");
assertArrayEquals(new int[] {1, 0, 1, 0, 0}, detailedLine1.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment1 = line1.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment1 = line1.getFoldableRow("N/A");
assertArrayEquals(new int[] {4, 2, 0, 0, 0}, detailedLineNoAttachment1.getCells());
DetailedReportRow line2 = report.getRow("L20000");
FoldableRow<DetailedMonitorQueryItem> line2 = report.getRow("L20000");
assertArrayEquals(new int[] {3, 1, 1, 1, 0}, line2.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine2 = line2.getDetailRows().get("L22000");
Row<DetailedMonitorQueryItem> detailedLine2 = line2.getFoldableRow("L22000");
assertArrayEquals(new int[] {1, 0, 1, 1, 0}, detailedLine2.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment2 = line2.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment2 = line2.getFoldableRow("N/A");
assertArrayEquals(new int[] {2, 1, 0, 0, 0}, detailedLineNoAttachment2.getCells());
DetailedReportRow line3 = report.getRow("L30000");
FoldableRow<DetailedMonitorQueryItem> line3 = report.getRow("L30000");
assertArrayEquals(new int[] {1, 0, 0, 1, 1}, line3.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine3 = line3.getDetailRows().get("L33000");
Row<DetailedMonitorQueryItem> detailedLine3 = line3.getFoldableRow("L33000");
assertArrayEquals(new int[] {0, 0, 0, 1, 1}, detailedLine3.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment3 = line3.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment3 = line3.getFoldableRow("N/A");
assertArrayEquals(new int[] {1, 0, 0, 0, 0}, detailedLineNoAttachment3.getCells());
DetailedReportRow line4 = report.getRow("L40000");
FoldableRow<DetailedMonitorQueryItem> line4 = report.getRow("L40000");
assertArrayEquals(new int[] {2, 0, 0, 0, 3}, line4.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment4 = line4.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment4 = line4.getFoldableRow("N/A");
assertArrayEquals(new int[] {2, 0, 0, 0, 3}, detailedLineNoAttachment4.getCells());
DetailedReportRow line5 = report.getRow("L50000");
FoldableRow<DetailedMonitorQueryItem> line5 = report.getRow("L50000");
assertArrayEquals(new int[] {0, 1, 0, 3, 0}, line5.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment5 = line5.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment5 = line5.getFoldableRow("N/A");
assertArrayEquals(new int[] {0, 1, 0, 3, 0}, detailedLineNoAttachment5.getCells());
}
@ -547,43 +513,43 @@ public class ProvideDetailedClassificationReportAccTest {
assertNotNull(report);
assertEquals(5, report.rowSize());
DetailedReportRow line1 = report.getRow("L10000");
FoldableRow<DetailedMonitorQueryItem> line1 = report.getRow("L10000");
assertArrayEquals(new int[] {4, 0, 0, 0, 0}, line1.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine1 = line1.getDetailRows().get("L11000");
Row<DetailedMonitorQueryItem> detailedLine1 = line1.getFoldableRow("L11000");
assertArrayEquals(new int[] {1, 0, 0, 0, 0}, detailedLine1.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment1 = line1.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment1 = line1.getFoldableRow("N/A");
assertArrayEquals(new int[] {3, 0, 0, 0, 0}, detailedLineNoAttachment1.getCells());
DetailedReportRow line2 = report.getRow("L20000");
FoldableRow<DetailedMonitorQueryItem> line2 = report.getRow("L20000");
assertArrayEquals(new int[] {4, 1, 1, 1, 0}, line2.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine2 = line2.getDetailRows().get("L22000");
Row<DetailedMonitorQueryItem> detailedLine2 = line2.getFoldableRow("L22000");
assertArrayEquals(new int[] {1, 1, 1, 1, 0}, detailedLine2.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment2 = line2.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment2 = line2.getFoldableRow("N/A");
assertArrayEquals(new int[] {3, 0, 0, 0, 0}, detailedLineNoAttachment2.getCells());
DetailedReportRow line3 = report.getRow("L30000");
FoldableRow<DetailedMonitorQueryItem> line3 = report.getRow("L30000");
assertArrayEquals(new int[] {1, 0, 0, 1, 1}, line3.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLine3a = line3.getDetailRows().get("L33000");
Row<DetailedMonitorQueryItem> detailedLine3a = line3.getFoldableRow("L33000");
assertArrayEquals(new int[] {0, 0, 0, 1, 0}, detailedLine3a.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment3 = line3.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment3 = line3.getFoldableRow("N/A");
assertArrayEquals(new int[] {1, 0, 0, 0, 1}, detailedLineNoAttachment3.getCells());
DetailedReportRow line4 = report.getRow("L40000");
FoldableRow<DetailedMonitorQueryItem> line4 = report.getRow("L40000");
assertArrayEquals(new int[] {1, 1, 2, 0, 2}, line4.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment4 = line4.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment4 = line4.getFoldableRow("N/A");
assertArrayEquals(new int[] {1, 1, 2, 0, 2}, detailedLineNoAttachment4.getCells());
DetailedReportRow line5 = report.getRow("L50000");
FoldableRow<DetailedMonitorQueryItem> line5 = report.getRow("L50000");
assertArrayEquals(new int[] {1, 2, 0, 2, 0}, line5.getCells());
ReportRow<DetailedMonitorQueryItem> detailedLineNoAttachment5 = line5.getDetailRows().get("N/A");
Row<DetailedMonitorQueryItem> detailedLineNoAttachment5 = line5.getFoldableRow("N/A");
assertArrayEquals(new int[] {1, 2, 0, 2, 0}, detailedLineNoAttachment5.getCells());
}
@ -663,8 +629,8 @@ public class ProvideDetailedClassificationReportAccTest {
}
}
builder.append("|\n");
for (String detaileLine : report.getRow(rl).getDetailRows().keySet()) {
ReportRow<DetailedMonitorQueryItem> reportLine = report.getRow(rl).getDetailRows().get(detaileLine);
for (String detaileLine : report.getRow(rl).getFoldableRowKeySet()) {
Row<DetailedMonitorQueryItem> reportLine = report.getRow(rl).getFoldableRow(detaileLine);
builder.append(
String.format(formatFirstColumnDetailLines, detaileLine, reportLine.getTotalValue()));
for (int cell : reportLine.getCells()) {

View File

@ -1,18 +1,13 @@
package acceptance.monitoring;
package acceptance.report;
import static java.util.Arrays.asList;
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.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;
@ -20,16 +15,11 @@ import org.slf4j.LoggerFactory;
import pro.taskana.TaskMonitorService;
import pro.taskana.TaskState;
import pro.taskana.TaskanaEngine;
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.TaskQueryItem;
import pro.taskana.impl.report.TaskStatusColumnHeader;
import pro.taskana.report.ReportRow;
import pro.taskana.impl.report.header.TaskStatusColumnHeader;
import pro.taskana.impl.report.item.TaskQueryItem;
import pro.taskana.report.structure.Row;
import pro.taskana.report.TaskStatusReport;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
@ -38,31 +28,9 @@ import pro.taskana.security.WithAccessId;
* Acceptance test for all "task status report" scenarios.
*/
@RunWith(JAASRunner.class)
public class ProvideTaskStatusReportAccTest {
public class ProvideTaskStatusReportAccTest extends AbstractReportAccTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ProvideWorkbasketReportAccTest.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,
TaskanaEngineConfigurationTest.getSchemaName());
taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskanaEngine.setConnectionManagementMode(TaskanaEngine.ConnectionManagementMode.AUTOCOMMIT);
cleaner.clearDb(dataSource, false);
TestDataGenerator testDataGenerator = new TestDataGenerator();
testDataGenerator.generateMonitoringTestData(dataSource);
}
@Test(expected = NotAuthorizedException.class)
public void testRoleCheck() throws NotAuthorizedException, InvalidArgumentException {
@ -85,19 +53,19 @@ public class ProvideTaskStatusReportAccTest {
assertNotNull(report);
assertEquals(3, report.rowSize());
ReportRow<TaskQueryItem> row1 = report.getRow("DOMAIN_A");
Row<TaskQueryItem> row1 = report.getRow("DOMAIN_A");
assertArrayEquals(new int[] {22, 4, 0}, row1.getCells());
assertEquals(26, row1.getTotalValue());
ReportRow<TaskQueryItem> row2 = report.getRow("DOMAIN_B");
Row<TaskQueryItem> row2 = report.getRow("DOMAIN_B");
assertArrayEquals(new int[] {9, 3, 0}, row2.getCells());
assertEquals(12, row2.getTotalValue());
ReportRow<TaskQueryItem> row3 = report.getRow("DOMAIN_C");
Row<TaskQueryItem> row3 = report.getRow("DOMAIN_C");
assertArrayEquals(new int[] {10, 2, 0}, row3.getCells());
assertEquals(12, row3.getTotalValue());
ReportRow<TaskQueryItem> sumRow = report.getSumRow();
Row<TaskQueryItem> sumRow = report.getSumRow();
assertArrayEquals(new int[] {41, 9, 0}, sumRow.getCells());
assertEquals(50, sumRow.getTotalValue());
}
@ -128,15 +96,15 @@ public class ProvideTaskStatusReportAccTest {
assertNotNull(report);
assertEquals(2, report.rowSize());
ReportRow<TaskQueryItem> row1 = report.getRow("DOMAIN_A");
Row<TaskQueryItem> row1 = report.getRow("DOMAIN_A");
assertArrayEquals(new int[] {22, 4, 0}, row1.getCells());
assertEquals(26, row1.getTotalValue());
ReportRow<TaskQueryItem> row2 = report.getRow("DOMAIN_C");
Row<TaskQueryItem> row2 = report.getRow("DOMAIN_C");
assertArrayEquals(new int[] {10, 2, 0}, row2.getCells());
assertEquals(12, row2.getTotalValue());
ReportRow<TaskQueryItem> sumRow = report.getSumRow();
Row<TaskQueryItem> sumRow = report.getSumRow();
assertArrayEquals(new int[] {32, 6, 0}, sumRow.getCells());
assertEquals(38, sumRow.getTotalValue());
}
@ -159,19 +127,19 @@ public class ProvideTaskStatusReportAccTest {
assertNotNull(report);
assertEquals(3, report.rowSize());
ReportRow<TaskQueryItem> row1 = report.getRow("DOMAIN_A");
Row<TaskQueryItem> row1 = report.getRow("DOMAIN_A");
assertArrayEquals(new int[] {22}, row1.getCells());
assertEquals(22, row1.getTotalValue());
ReportRow<TaskQueryItem> row2 = report.getRow("DOMAIN_B");
Row<TaskQueryItem> row2 = report.getRow("DOMAIN_B");
assertArrayEquals(new int[] {9}, row2.getCells());
assertEquals(9, row2.getTotalValue());
ReportRow<TaskQueryItem> row3 = report.getRow("DOMAIN_C");
Row<TaskQueryItem> row3 = report.getRow("DOMAIN_C");
assertArrayEquals(new int[] {10}, row3.getCells());
assertEquals(10, row3.getTotalValue());
ReportRow<TaskQueryItem> sumRow = report.getSumRow();
Row<TaskQueryItem> sumRow = report.getSumRow();
assertArrayEquals(new int[] {41}, sumRow.getCells());
assertEquals(41, sumRow.getTotalValue());
}

View File

@ -1,11 +1,9 @@
package acceptance.monitoring;
package acceptance.report;
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;
@ -14,9 +12,6 @@ import java.util.List;
import java.util.Map;
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;
@ -25,16 +20,10 @@ 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.CombinedClassificationFilter;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.report.WorkbasketReport;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
@ -43,31 +32,9 @@ import pro.taskana.security.WithAccessId;
* Acceptance test for all "workbasket level report" scenarios.
*/
@RunWith(JAASRunner.class)
public class ProvideWorkbasketReportAccTest {
public class ProvideWorkbasketReportAccTest extends AbstractReportAccTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ProvideWorkbasketReportAccTest.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,
TaskanaEngineConfigurationTest.getSchemaName());
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()

View File

@ -33,7 +33,7 @@ import pro.taskana.exceptions.WorkbasketNotFoundException;
import pro.taskana.impl.DaysToWorkingDaysConverter;
import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.TaskanaEngineProxyForTest;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.mappings.AttachmentMapper;
import pro.taskana.mappings.TaskTestMapper;
import pro.taskana.security.CurrentUserContext;

View File

@ -34,7 +34,7 @@ import pro.taskana.exceptions.WorkbasketNotFoundException;
import pro.taskana.impl.AttachmentImpl;
import pro.taskana.impl.DaysToWorkingDaysConverter;
import pro.taskana.impl.TaskImpl;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.security.CurrentUserContext;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;

View File

@ -31,8 +31,8 @@ import pro.taskana.TaskState;
import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.MonitorQueryItem;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.CategoryReport;

View File

@ -31,10 +31,10 @@ import pro.taskana.TaskState;
import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.DetailedMonitorQueryItem;
import pro.taskana.impl.report.DetailedReportRow;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.DetailedMonitorQueryItem;
import pro.taskana.impl.report.item.MonitorQueryItem;
import pro.taskana.impl.report.row.FoldableRow;
import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.ClassificationReport;
import pro.taskana.report.ClassificationReport.DetailedClassificationReport;
@ -206,10 +206,10 @@ public class ClassificationReportBuilderImplTest {
verify(taskanaEngineImplMock, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration);
DetailedReportRow line = actualResult.getRow("CLI:000000000000000000000000000000000001");
FoldableRow<DetailedMonitorQueryItem> line = actualResult.getRow("CLI:000000000000000000000000000000000001");
assertNotNull(actualResult);
assertEquals(line.getTotalValue(), 1);
assertEquals(line.getDetailRows().get("CLI:000000000000000000000000000000000006").getTotalValue(), 1);
assertEquals(line.getFoldableRow("CLI:000000000000000000000000000000000006").getTotalValue(), 1);
assertEquals(actualResult.getSumRow().getTotalValue(), 1);
}
@ -259,12 +259,12 @@ public class ClassificationReportBuilderImplTest {
verify(taskanaEngineImplMock, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineImplMock, taskMonitorMapperMock, taskanaEngineConfiguration);
DetailedReportRow line = actualResult.getRow("CLI:000000000000000000000000000000000001");
FoldableRow<DetailedMonitorQueryItem> line = actualResult.getRow("CLI:000000000000000000000000000000000001");
assertNotNull(actualResult);
assertEquals(line.getTotalValue(), 1);
assertEquals(line.getDetailRows().get("CLI:000000000000000000000000000000000006").getTotalValue(), 1);
assertEquals(line.getFoldableRow("CLI:000000000000000000000000000000000006").getTotalValue(), 1);
assertEquals(line.getCells()[0], 1);
assertEquals(line.getDetailRows().get("CLI:000000000000000000000000000000000006").getCells()[0], 1);
assertEquals(line.getFoldableRow("CLI:000000000000000000000000000000000006").getCells()[0], 1);
assertEquals(actualResult.getSumRow().getTotalValue(), 1);
assertEquals(actualResult.getSumRow().getCells()[0], 1);
}

View File

@ -6,7 +6,7 @@ import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import java.time.LocalDate;
import java.time.Instant;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
@ -36,24 +36,22 @@ import pro.taskana.mappings.JobMapper;
@RunWith(MockitoJUnitRunner.class)
public class ClassificationServiceImplTest {
private final String todaysDate = LocalDate.now().toString().substring(0, 10);
// This is important. Since ClassificationService.createClassification() uses an Instant for the time
// and thus the UTC time zone. e.g. LocalDate uses the system timezone. This may lead to issues when the day differs
// between those timezones.
private final String todaysDate = Instant.now().toString().substring(0, 10);
@Spy
@InjectMocks
private ClassificationServiceImpl cutSpy;
@Mock
private ClassificationMapper classificationMapperMock;
@Mock
private TaskanaEngineImpl taskanaEngineImplMock;
@Mock
private ClassificationQueryImpl classificationQueryImplMock;
@Mock
private SqlSession sqlSessionMock;
@Mock
private JobService jobServiceMock;

View File

@ -30,8 +30,8 @@ import pro.taskana.TaskState;
import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.MonitorQueryItem;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.CustomFieldValueReport;

View File

@ -15,7 +15,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
/**
* Test for the DaysToWorkingDaysConverter.

View File

@ -25,7 +25,7 @@ import pro.taskana.TaskState;
import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.TaskQueryItem;
import pro.taskana.impl.report.item.TaskQueryItem;
import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.TaskStatusReport;

View File

@ -32,8 +32,8 @@ import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.CombinedClassificationFilter;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.MonitorQueryItem;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.WorkbasketReport;

View File

@ -0,0 +1,198 @@
package pro.taskana.report.structure;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.Before;
import org.junit.Test;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.impl.report.item.MonitorQueryItem;
/**
* Tests for {@link Report}.
*/
public class ReportTest {
private static final List<TimeIntervalColumnHeader> HEADERS = IntStream.range(0, 4)
.mapToObj(TimeIntervalColumnHeader::new)
.collect(Collectors.toList());
private Report<MonitorQueryItem, TimeIntervalColumnHeader> report;
private MonitorQueryItem item;
@Before
public void before() {
this.report = new Report<MonitorQueryItem, TimeIntervalColumnHeader>(HEADERS, "rowDesc") {
};
item = new MonitorQueryItem();
item.setKey("key");
item.setAgeInDays(0);
item.setNumberOfTasks(3);
}
@Test
public void testEmptyReport() {
//then
assertEquals(0, report.getRows().size());
Row<MonitorQueryItem> sumRow = report.getSumRow();
assertArrayEquals(new int[] {0, 0, 0, 0}, sumRow.getCells());
assertEquals(0, sumRow.getTotalValue());
}
@Test
public void testInsertSingleItem() {
//when
report.addItem(item);
//then
assertEquals(1, report.getRows().size());
Row<MonitorQueryItem> row = report.getRow("key");
assertArrayEquals(new int[] {item.getValue(), 0, 0, 0}, row.getCells());
assertEquals(item.getValue(), row.getTotalValue());
}
@Test
public void testInsertSameItemMultipleTimes() {
//when
report.addItem(item);
report.addItem(item);
//then
assertEquals(1, report.getRows().size());
Row<MonitorQueryItem> row = report.getRow("key");
assertArrayEquals(new int[] {2 * item.getValue(), 0, 0, 0}, row.getCells());
assertEquals(2 * item.getValue(), row.getTotalValue());
}
@Test
public void testInsertSameItemMultipleTimes2() {
//given
MonitorQueryItem item = new MonitorQueryItem();
item.setKey("key");
item.setAgeInDays(0);
item.setNumberOfTasks(3);
//when
report.addItems(Arrays.asList(item, item));
//then
assertEquals(1, report.getRows().size());
Row<MonitorQueryItem> row = report.getRow("key");
assertArrayEquals(new int[] {2 * item.getValue(), 0, 0, 0}, row.getCells());
assertEquals(2 * item.getValue(), row.getTotalValue());
}
@Test
public void testInsertSameItemMultipleTimesWithPreProcessor() {
//given
int overrideValue = 5;
QueryItemPreprocessor<MonitorQueryItem> preprocessor = (item) -> {
item.setNumberOfTasks(overrideValue);
return item;
};
//when
report.addItems(Arrays.asList(item, item), preprocessor);
//then
assertEquals(1, report.getRows().size());
Row<MonitorQueryItem> row = report.getRow("key");
assertArrayEquals(new int[] {2 * overrideValue, 0, 0, 0}, row.getCells());
assertEquals(2 * overrideValue, row.getTotalValue());
}
@Test
public void testInsertItemWithNoColumnHeaders() {
//given
report = new Report<MonitorQueryItem, TimeIntervalColumnHeader>(Collections.emptyList(), "rowDesc") {
};
//when
report.addItem(item);
//then
assertEquals(1, report.getRows().size());
assertArrayEquals(new int[0], report.getRow("key").getCells());
assertEquals(item.getValue(), report.getRow("key").getTotalValue());
}
@Test
public void testInsertItemWhichIsNotInHeaderScopes() {
//given
item.setAgeInDays(-2);
//when
report.addItem(item);
//then
assertEquals(0, report.getRows().size());
Row<MonitorQueryItem> sumRow = report.getSumRow();
assertArrayEquals(new int[] {0, 0, 0, 0}, sumRow.getCells());
assertEquals(0, sumRow.getTotalValue());
}
@Test
public void testInsertItemWhichIsInMultipleHeaderScopes() {
//given
List<TimeIntervalColumnHeader> headers = new ArrayList<>(HEADERS);
headers.add(new TimeIntervalColumnHeader(0, 3));
report = new Report<MonitorQueryItem, TimeIntervalColumnHeader>(headers, "rowDesc") {
};
item.setAgeInDays(2);
//when
report.addItem(item);
//then
assertEquals(1, report.getRows().size());
Row<MonitorQueryItem> row = report.getRow("key");
assertArrayEquals(new int[] {0, 0, item.getValue(), 0, item.getValue()}, row.getCells());
assertEquals(2 * item.getValue(), row.getTotalValue());
Row<MonitorQueryItem> sumRow = report.getSumRow();
assertArrayEquals(new int[] {0, 0, item.getValue(), 0, item.getValue()}, sumRow.getCells());
assertEquals(2 * item.getValue(), sumRow.getTotalValue());
}
@Test
public void testInsertItemWithPreProcessor() {
//given
int overrideValue = 5;
QueryItemPreprocessor<MonitorQueryItem> preprocessor = item -> {
item.setNumberOfTasks(overrideValue);
return item;
};
item.setAgeInDays(1);
//when
report.addItem(item, preprocessor);
//then
assertEquals(1, report.getRows().size());
Row<MonitorQueryItem> row = report.getRow(item.getKey());
assertArrayEquals(new int[] {0, overrideValue, 0, 0}, row.getCells());
assertEquals(overrideValue, row.getTotalValue());
Row<MonitorQueryItem> sumRow = report.getSumRow();
assertArrayEquals(new int[] {0, overrideValue, 0, 0}, sumRow.getCells());
assertEquals(overrideValue, sumRow.getTotalValue());
}
}

View File

@ -1,7 +1,7 @@
-- 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 , MARKED_FOR_DELETION );
INSERT INTO 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' , '' , '' , '' , '' , '' , '' , '' , '' , FALSE );
INSERT INTO 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' , '' , '' , '' , '' , 'org1' , '' , '' , '' , FALSE );
INSERT INTO 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' , '' , '' , '' , '' , '' , '' , '' , '' , FALSE );
INSERT INTO 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' , '' , '' , '' , '' , '' , '' , '' , '' , FALSE );
INSERT INTO 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' , '' , '' , '' , '' , 'org1' , '' , '' , '' , FALSE );
INSERT INTO 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' , '' , '' , '' , '' , '' , '' , '' , '' , FALSE );
-- CLASSIFICATION TABLE (ID , KEY , PARENT_ID , PARENT_KEY, 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 );
@ -57,15 +57,15 @@ INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000025', 'ETI:0000000
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000026', 'ETI:000000000000000000000000000000000026', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(-7) , '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 TASK VALUES('TKI:000000000000000000000000000000000027', 'ETI:000000000000000000000000000000000027', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(-7) , '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 TASK VALUES('TKI:000000000000000000000000000000000028', 'ETI:000000000000000000000000000000000028', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(-7) , '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 TASK VALUES('TKI:000000000000000000000000000000000029', 'ETI:000000000000000000000000000000000029', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(-7) , '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 TASK VALUES('TKI:000000000000000000000000000000000030', 'ETI:000000000000000000000000000000000030', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(-7) , '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 TASK VALUES('TKI:000000000000000000000000000000000029', 'ETI:000000000000000000000000000000000029', RELATIVE_DATE(-8), CURRENT_TIMESTAMP, RELATIVE_DATE(-7), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(-7) , '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 TASK VALUES('TKI:000000000000000000000000000000000030', 'ETI:000000000000000000000000000000000030', RELATIVE_DATE(-9), CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(-7) , '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 TASK VALUES('TKI:000000000000000000000000000000000031', 'ETI:000000000000000000000000000000000031', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(0) , '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 TASK VALUES('TKI:000000000000000000000000000000000032', 'ETI:000000000000000000000000000000000032', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(0) , '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 TASK VALUES('TKI:000000000000000000000000000000000032', 'ETI:000000000000000000000000000000000032', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(-1), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(0) , '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 TASK VALUES('TKI:000000000000000000000000000000000033', 'ETI:000000000000000000000000000000000033', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(0) , '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 TASK VALUES('TKI:000000000000000000000000000000000034', 'ETI:000000000000000000000000000000000034', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(0) , '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 TASK VALUES('TKI:000000000000000000000000000000000034', 'ETI:000000000000000000000000000000000034', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(-1), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(0) , '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 TASK VALUES('TKI:000000000000000000000000000000000035', 'ETI:000000000000000000000000000000000035', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(7) , '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 TASK VALUES('TKI:000000000000000000000000000000000036', 'ETI:000000000000000000000000000000000036', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(7) , '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 TASK VALUES('TKI:000000000000000000000000000000000037', 'ETI:000000000000000000000000000000000037', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(7) , '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 TASK VALUES('TKI:000000000000000000000000000000000037', 'ETI:000000000000000000000000000000000037', RELATIVE_DATE(-8), CURRENT_TIMESTAMP, RELATIVE_DATE(-2), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(7) , '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 TASK VALUES('TKI:000000000000000000000000000000000038', 'ETI:000000000000000000000000000000000038', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(7) , '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 TASK VALUES('TKI:000000000000000000000000000000000039', 'ETI:000000000000000000000000000000000039', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(7) , '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 TASK VALUES('TKI:000000000000000000000000000000000040', 'ETI:000000000000000000000000000000000040', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, RELATIVE_DATE(7) , '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' );

View File

@ -1,33 +0,0 @@
package pro.taskana.monitor;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
/**
* Class for Classification time Interval Column Header, overrides displayName.
*
* @author mmr
*/
public class ClassificationTimeIntervalColumnHeader extends TimeIntervalColumnHeader {
public ClassificationTimeIntervalColumnHeader(int ageInDays) {
super(ageInDays);
}
public ClassificationTimeIntervalColumnHeader(int lowerAgeLimit, int upperAgeLimit) {
super(lowerAgeLimit, upperAgeLimit);
}
@Override
public String getDisplayName() {
if (this.getLowerAgeLimit() == Integer.MIN_VALUE) {
return "<" + this.getUpperAgeLimit();
} else if (this.getUpperAgeLimit() == Integer.MAX_VALUE) {
return ">" + this.getLowerAgeLimit();
} else if (this.getLowerAgeLimit() == this.getUpperAgeLimit()) {
return this.getUpperAgeLimit() + "";
} else if (this.getLowerAgeLimit() != this.getUpperAgeLimit()) {
return "[" + this.getLowerAgeLimit() + " ... " + this.getUpperAgeLimit() + "]";
}
return super.getDisplayName();
}
}

View File

@ -1,26 +0,0 @@
package pro.taskana.monitor;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
/**
* Class for Workbasket Time Interval Column Header, overrides displayName.
*
* @author mmr
*/
public class WorkbasketTimeIntervalColumnHeader extends TimeIntervalColumnHeader {
public WorkbasketTimeIntervalColumnHeader(int ageInDays) {
super(ageInDays);
}
@Override
public String getDisplayName() {
LocalDateTime ldt = LocalDateTime.now().plusDays(getLowerAgeLimit());
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ENGLISH);
return dateFormat.format(ldt);
}
}

View File

@ -20,9 +20,8 @@ import pro.taskana.TaskMonitorService;
import pro.taskana.TaskState;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.monitor.ClassificationTimeIntervalColumnHeader;
import pro.taskana.monitor.WorkbasketTimeIntervalColumnHeader;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
import pro.taskana.rest.resource.ReportResource;
import pro.taskana.rest.resource.ReportAssembler;
import pro.taskana.rest.resource.ReportResource;
@ -94,14 +93,14 @@ public class MonitorController {
private List<TimeIntervalColumnHeader> getTaskClassificationTimeInterval() {
return Stream.concat(Stream.concat(
Stream.of(new ClassificationTimeIntervalColumnHeader(Integer.MIN_VALUE, -10),
new ClassificationTimeIntervalColumnHeader(-10, -5)
Stream.of(new TimeIntervalColumnHeader.Range(Integer.MIN_VALUE, -10),
new TimeIntervalColumnHeader.Range(-10, -5)
),
Stream.of(-4, -3, -2, -1, 0, 1, 2, 3, 4)
.map(ClassificationTimeIntervalColumnHeader::new)
.map(TimeIntervalColumnHeader.Range::new)
),
Stream.of(new ClassificationTimeIntervalColumnHeader(5, 10),
new ClassificationTimeIntervalColumnHeader(10, Integer.MAX_VALUE)
Stream.of(new TimeIntervalColumnHeader.Range(5, 10),
new TimeIntervalColumnHeader.Range(10, Integer.MAX_VALUE)
))
.collect(Collectors.toList());
}
@ -110,7 +109,7 @@ public class MonitorController {
List<TimeIntervalColumnHeader> columnHeaders = new ArrayList<>();
for (int i = 0; i <= daysInPast; i++) {
columnHeaders.add(new WorkbasketTimeIntervalColumnHeader(i - daysInPast));
columnHeaders.add(new TimeIntervalColumnHeader.Date(i - daysInPast));
}
return columnHeaders;
}

View File

@ -14,14 +14,14 @@ import org.springframework.stereotype.Component;
import pro.taskana.TaskState;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.report.QueryItem;
import pro.taskana.report.Report;
import pro.taskana.report.ReportColumnHeader;
import pro.taskana.report.ReportRow;
import pro.taskana.report.TaskStatusReport;
import pro.taskana.report.ClassificationReport;
import pro.taskana.report.structure.ColumnHeader;
import pro.taskana.report.DailyEntryExitReport;
import pro.taskana.report.structure.QueryItem;
import pro.taskana.report.structure.Report;
import pro.taskana.report.structure.Row;
import pro.taskana.report.TaskStatusReport;
import pro.taskana.report.WorkbasketReport;
import pro.taskana.rest.MonitorController;
/**
@ -57,11 +57,11 @@ public class ReportAssembler {
return resource;
}
private <I extends QueryItem, H extends ReportColumnHeader<? super I>> ReportResource toReportResource(
private <I extends QueryItem, H extends ColumnHeader<? super I>> ReportResource toReportResource(
Report<I, H> report) {
String[] header = report.getColumnHeaders()
.stream()
.map(ReportColumnHeader::getDisplayName)
.map(ColumnHeader::getDisplayName)
.toArray(String[]::new);
ReportResource.MetaInformation meta = new ReportResource.MetaInformation(
report.getClass().getSimpleName(),
@ -69,8 +69,8 @@ public class ReportAssembler {
header,
report.getRowDesc());
// iterate over each ReportRow and transform it to a RowResource while keeping the domain key.
Map<String, ReportResource.RowResource> rows = report.getReportRows()
// iterate over each Row and transform it to a RowResource while keeping the domain key.
Map<String, ReportResource.RowResource> rows = report.getRows()
.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, i -> transformRow(i.getValue(), header)));
@ -80,7 +80,8 @@ public class ReportAssembler {
return new ReportResource(meta, rows, sumRow);
}
private <I extends QueryItem> ReportResource.RowResource transformRow(ReportRow<I> row, String[] header) {
private <I extends QueryItem> ReportResource.RowResource transformRow(Row<I> row,
String[] header) {
Map<String, Integer> result = new HashMap<>();
int[] cells = row.getCells();
for (int i = 0; i < cells.length; i++) {

View File

@ -5,9 +5,11 @@ import java.util.Map;
import org.springframework.hateoas.ResourceSupport;
import pro.taskana.impl.util.LoggerUtils;
import pro.taskana.report.structure.Report;
import pro.taskana.report.structure.Row;
/**
* Resource class for {@link pro.taskana.report.Report}.
* Resource class for {@link Report}.
*/
public class ReportResource extends ResourceSupport {
@ -86,7 +88,7 @@ public class ReportResource extends ResourceSupport {
}
/**
* Resource class for {@link pro.taskana.report.ReportRow}.
* Resource class for {@link Row}.
*/
public static class RowResource {