From dc5efe527bafa0fb4c0fa128d5b7cd70806e20d9 Mon Sep 17 00:00:00 2001
From: ryzheboka <25465835+ryzheboka@users.noreply.github.com>
Date: Wed, 31 Aug 2022 15:46:36 +0200
Subject: [PATCH] TSK-1951: Extend WorkbasketPriorityReport for customInt
---
.../reports/TimeIntervalReportBuilder.java | 62 ++++++
.../api/reports/WorkbasketPriorityReport.java | 97 +++++++--
.../internal/MonitorMapperSqlProvider.java | 17 ++
.../TimeIntervalReportBuilderImpl.java | 191 ++++++++++++++++++
.../WorkbasketPriorityReportBuilderImpl.java | 191 ++++++++++++++++++
...rovideWorkbasketPriorityReportAccTest.java | 178 +++++++++++++++-
6 files changed, 720 insertions(+), 16 deletions(-)
diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TimeIntervalReportBuilder.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TimeIntervalReportBuilder.java
index 22dd3b6e1..2c70b765f 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TimeIntervalReportBuilder.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TimeIntervalReportBuilder.java
@@ -2,6 +2,7 @@ package pro.taskana.monitor.api.reports;
import java.util.List;
+import pro.taskana.common.api.IntInterval;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.monitor.api.SelectedItem;
@@ -9,6 +10,7 @@ import pro.taskana.monitor.api.TaskTimestamp;
import pro.taskana.monitor.api.reports.header.TimeIntervalColumnHeader;
import pro.taskana.monitor.api.reports.item.AgeQueryItem;
import pro.taskana.task.api.TaskCustomField;
+import pro.taskana.task.api.TaskCustomIntField;
import pro.taskana.task.api.TaskState;
import pro.taskana.task.api.models.Task;
@@ -127,6 +129,66 @@ public interface TimeIntervalReportBuilder<
B customAttributeNotIn(TaskCustomField customField, String... strings)
throws InvalidArgumentException;
+ /**
+ * Adds the values of a certain {@linkplain TaskCustomIntField} for exact matching to the builder.
+ *
+ *
The created {@linkplain Report} contains only {@linkplain Task Tasks} with a {@linkplain
+ * Task#getCustomIntField(TaskCustomIntField) custom attribute} value exactly matching one of the
+ * items in the List.
+ *
+ * @param customIntField the specified {@linkplain TaskCustomIntField}
+ * @param values the values the specified {@linkplain Task#getCustomIntField(TaskCustomIntField)
+ * customIntField } should match
+ * @return the modified {@linkplain TimeIntervalReportBuilder}
+ * @throws InvalidArgumentException if filter values are not given
+ */
+ B customIntAttributeIn(TaskCustomIntField customIntField, Integer... values)
+ throws InvalidArgumentException;
+
+ /**
+ * Excludes the values of a certain {@linkplain TaskCustomIntField} to the builder.
+ *
+ *
The created {@linkplain Report} contains only {@linkplain Task Tasks} with a {@linkplain
+ * Task#getCustomIntField(TaskCustomIntField) custom attribute} value not matching one of the
+ * items in the List.
+ *
+ * @param customIntField the specified {@linkplain TaskCustomIntField}
+ * @param values the values the specified {@linkplain Task#getCustomIntField(TaskCustomIntField)
+ * customIntFields} should not match
+ * @return the modified TimeIntervalReportBuilder
+ * @throws InvalidArgumentException if filter values are not given
+ */
+ B customIntAttributeNotIn(TaskCustomIntField customIntField, Integer... values)
+ throws InvalidArgumentException;
+
+ /**
+ * Adds ranges of {@linkplain TaskCustomIntField} for matching to the TimeIntervalReportBuilder.
+ *
+ *
The created {@linkplain Report} contains only {@linkplain Task Tasks} with a {@linkplain
+ * Task#getCustomIntField(TaskCustomIntField) customIntField} value being inside the range of one
+ * of the items in the list.
+ *
+ * @param customIntField the specified {@linkplain TaskCustomIntField}
+ * @param values the values the specified {@linkplain Task#getCustomIntField(TaskCustomIntField)
+ * customIntField} should match
+ * @return the modified {@linkplain TimeIntervalReportBuilder}
+ */
+ B customIntAttributeWithin(TaskCustomIntField customIntField, IntInterval... values);
+
+ /**
+ * Exclude ranges of {@linkplain TaskCustomIntField} for matching to the builder.
+ *
+ *
The created report contains only {@linkplain Task Tasks} with a {@linkplain
+ * Task#getCustomIntField(TaskCustomIntField) customIntField} value being not inside the range of
+ * one of the items in the list.
+ *
+ * @param customIntField the specified {@linkplain TaskCustomIntField}
+ * @param values the values the specified {@linkplain Task#getCustomIntField(TaskCustomIntField)
+ * customIntField} should match
+ * @return the modified {@linkplain TimeIntervalReportBuilder}
+ */
+ B customIntAttributeNotWithin(TaskCustomIntField customIntField, IntInterval... values);
+
/**
* Adds the values of a certain {@linkplain TaskCustomField} for pattern matching to the builder.
*
diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/WorkbasketPriorityReport.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/WorkbasketPriorityReport.java
index 5e18515ec..d91864b37 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/WorkbasketPriorityReport.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/WorkbasketPriorityReport.java
@@ -2,6 +2,7 @@ package pro.taskana.monitor.api.reports;
import java.util.List;
+import pro.taskana.common.api.IntInterval;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.monitor.api.reports.header.ColumnHeader;
@@ -9,6 +10,7 @@ import pro.taskana.monitor.api.reports.header.PriorityColumnHeader;
import pro.taskana.monitor.api.reports.item.PriorityQueryItem;
import pro.taskana.monitor.api.reports.row.Row;
import pro.taskana.task.api.TaskCustomField;
+import pro.taskana.task.api.TaskCustomIntField;
import pro.taskana.task.api.TaskState;
import pro.taskana.task.api.models.Task;
import pro.taskana.workbasket.api.WorkbasketType;
@@ -35,10 +37,10 @@ public class WorkbasketPriorityReport extends Report workbasketIds);
@@ -56,7 +58,7 @@ public class WorkbasketPriorityReport extends Report states);
@@ -65,7 +67,7 @@ public class WorkbasketPriorityReport extends Report classificationCategory);
@@ -74,7 +76,7 @@ public class WorkbasketPriorityReport extends Report classificationIds);
@@ -83,7 +85,7 @@ public class WorkbasketPriorityReport extends Report excludedClassificationIds);
@@ -92,7 +94,7 @@ public class WorkbasketPriorityReport extends Report domains);
@@ -106,7 +108,7 @@ public class WorkbasketPriorityReport extends ReportThe created {@linkplain Report} contains only {@linkplain Task Tasks} with a {@linkplain
+ * Task#getCustomIntField(TaskCustomIntField) customIntField} value exactly matching one of the
+ * items in the list.
+ *
+ * @param customIntField the specified {@linkplain TaskCustomIntField}
+ * @param values the values the specified {@linkplain Task#getCustomIntField(TaskCustomIntField)
+ * customIntField} should match
+ * @return the modified {@linkplain Builder}
+ * @throws InvalidArgumentException if filter values are not given
+ */
+ Builder customIntAttributeIn(TaskCustomIntField customIntField, Integer... values)
+ throws InvalidArgumentException;
+
+ /**
+ * Excludes the values of a certain {@linkplain TaskCustomIntField} to the builder.
+ *
+ * The created {@linkplain Report} contains only {@linkplain Task Tasks} with a {@linkplain
+ * Task#getCustomIntField(TaskCustomIntField) customIntField} value not matching one of the
+ * items in the list.
+ *
+ * @param customIntField the specified {@linkplain TaskCustomIntField}
+ * @param values the values the specified {@linkplain Task#getCustomIntField(TaskCustomIntField)
+ * customIntField} should not match
+ * @return the modified {@linkplain Builder}
+ * @throws InvalidArgumentException if filter values are not given
+ */
+ Builder customIntAttributeNotIn(TaskCustomIntField customIntField, Integer... values)
+ throws InvalidArgumentException;
+
+ /**
+ * Adds ranges of {@linkplain TaskCustomIntField} for matching to the builder.
+ *
+ *
The created report contains only {@linkplain Task Tasks} with a {@linkplain
+ * Task#getCustomIntField(TaskCustomIntField) customIntField} value being inside the range of
+ * one of the items in the list.
+ *
+ * @param customIntField the specified {@linkplain TaskCustomIntField}
+ * @param values the values the specified {@linkplain Task#getCustomIntField(TaskCustomIntField)
+ * customIntField} should match
+ * @return the modified {@linkplain Builder}
+ * @throws InvalidArgumentException if filter values are not given
+ */
+ Builder customIntAttributeWithin(TaskCustomIntField customIntField, IntInterval... values)
+ throws InvalidArgumentException;
+
+ /**
+ * Exclude ranges of {@linkplain TaskCustomIntField} for matching to the builder.
+ *
+ *
The created report contains only {@linkplain Task Tasks} with a {@linkplain
+ * Task#getCustomIntField(TaskCustomIntField) customIntField} value being not inside the range
+ * of one of the items in the list.
+ *
+ * @param customIntField the specified {@linkplain TaskCustomIntField}
+ * @param values the values the specified {@linkplain Task#getCustomIntField(TaskCustomIntField)
+ * customIntField} should match
+ * @return the modified {@linkplain Builder}
+ * @throws InvalidArgumentException if filter values are not given
+ */
+ Builder customIntAttributeNotWithin(TaskCustomIntField customIntField, IntInterval... values)
+ throws InvalidArgumentException;
+
+ /**
+ * Adds a list of {@linkplain PriorityColumnHeader PriorityColumnHeaders} to the builder to
+ * subdivide the report into clusters.
*
* @param columnHeaders the column headers the report should consist of.
- * @return the builder
+ * @return the {@linkplain Builder}
*/
Builder withColumnHeaders(List columnHeaders);
/**
* If this filter is used, the days of the report are counted in working days.
*
- * @return the TimeIntervalReportBuilder
+ * @return the {@linkplain Builder}
*/
Builder inWorkingDays();
}
diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/MonitorMapperSqlProvider.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/MonitorMapperSqlProvider.java
index 469ce4095..468ec2c1e 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/MonitorMapperSqlProvider.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/MonitorMapperSqlProvider.java
@@ -5,8 +5,10 @@ import static pro.taskana.common.internal.util.SqlProviderUtil.CLOSING_WHERE_TAG
import static pro.taskana.common.internal.util.SqlProviderUtil.OPENING_SCRIPT_TAG;
import static pro.taskana.common.internal.util.SqlProviderUtil.OPENING_WHERE_TAG;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereIn;
+import static pro.taskana.common.internal.util.SqlProviderUtil.whereInInterval;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereLike;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereNotIn;
+import static pro.taskana.common.internal.util.SqlProviderUtil.whereNotInInterval;
import java.util.stream.IntStream;
@@ -293,6 +295,20 @@ public class MonitorMapperSqlProvider {
return sb;
}
+ private static StringBuilder whereCustomIntStatements(
+ String baseCollection, String baseColumn, int customBound, StringBuilder sb) {
+ IntStream.rangeClosed(1, customBound)
+ .forEach(
+ x -> {
+ String column = baseColumn + "_" + x;
+ whereIn(baseCollection + x + "In", column, sb);
+ whereNotIn(baseCollection + x + "NotIn", column, sb);
+ whereInInterval(baseCollection + x + "Within", column, sb);
+ whereNotInInterval(baseCollection + x + "NotWithin", column, sb);
+ });
+ return sb;
+ }
+
private static StringBuilder taskWhereStatements() {
StringBuilder sb = new StringBuilder();
SqlProviderUtil.whereIn("report.workbasketIds", "T.WORKBASKET_ID", sb);
@@ -302,6 +318,7 @@ public class MonitorMapperSqlProvider {
SqlProviderUtil.whereIn("report.classificationIds", "T.CLASSIFICATION_ID", sb);
SqlProviderUtil.whereNotIn("report.excludedClassificationIds", "T.CLASSIFICATION_ID", sb);
whereCustomStatements("report.custom", "T.CUSTOM", 16, sb);
+ whereCustomIntStatements("report.customInt", "T.CUSTOM_INT", 8, sb);
return sb;
}
diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TimeIntervalReportBuilderImpl.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TimeIntervalReportBuilderImpl.java
index 01d7cc6ca..9185ab7dd 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TimeIntervalReportBuilderImpl.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TimeIntervalReportBuilderImpl.java
@@ -5,6 +5,7 @@ import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
+import pro.taskana.common.api.IntInterval;
import pro.taskana.common.api.TaskanaRole;
import pro.taskana.common.api.WorkingDaysToDaysConverter;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
@@ -21,6 +22,7 @@ import pro.taskana.monitor.api.reports.item.AgeQueryItem;
import pro.taskana.monitor.internal.MonitorMapper;
import pro.taskana.monitor.internal.preprocessor.WorkingDaysToDaysReportConverter;
import pro.taskana.task.api.TaskCustomField;
+import pro.taskana.task.api.TaskCustomIntField;
import pro.taskana.task.api.TaskState;
/**
@@ -95,6 +97,39 @@ abstract class TimeIntervalReportBuilderImpl<
private String[] custom16In;
private String[] custom16NotIn;
private String[] custom16Like;
+ private Integer[] customInt1In;
+ private Integer[] customInt1NotIn;
+ private Integer[] customInt2In;
+ private Integer[] customInt2NotIn;
+ private Integer[] customInt3In;
+ private Integer[] customInt3NotIn;
+ private Integer[] customInt4In;
+ private Integer[] customInt4NotIn;
+ private Integer[] customInt5In;
+ private Integer[] customInt5NotIn;
+ private Integer[] customInt6In;
+ private Integer[] customInt6NotIn;
+ private Integer[] customInt7In;
+ private Integer[] customInt7NotIn;
+ private Integer[] customInt8In;
+ private Integer[] customInt8NotIn;
+
+ private IntInterval[] customInt1Within;
+ private IntInterval[] customInt1NotWithin;
+ private IntInterval[] customInt2Within;
+ private IntInterval[] customInt2NotWithin;
+ private IntInterval[] customInt3Within;
+ private IntInterval[] customInt3NotWithin;
+ private IntInterval[] customInt4Within;
+ private IntInterval[] customInt4NotWithin;
+ private IntInterval[] customInt5Within;
+ private IntInterval[] customInt5NotWithin;
+ private IntInterval[] customInt6Within;
+ private IntInterval[] customInt6NotWithin;
+ private IntInterval[] customInt7Within;
+ private IntInterval[] customInt7NotWithin;
+ private IntInterval[] customInt8Within;
+ private IntInterval[] customInt8NotWithin;
TimeIntervalReportBuilderImpl(InternalTaskanaEngine taskanaEngine, MonitorMapper monitorMapper) {
this.taskanaEngine = taskanaEngine;
@@ -289,6 +324,162 @@ abstract class TimeIntervalReportBuilderImpl<
return _this();
}
+ @Override
+ public B customIntAttributeIn(TaskCustomIntField customIntField, Integer... values)
+ throws InvalidArgumentException {
+ if (values.length == 0) {
+ throw new InvalidArgumentException(
+ "At least one Integer has to be provided as a search parameter");
+ }
+ switch (customIntField) {
+ case CUSTOM_INT_1:
+ this.customInt1In = values;
+ break;
+ case CUSTOM_INT_2:
+ this.customInt2In = values;
+ break;
+ case CUSTOM_INT_3:
+ this.customInt3In = values;
+ break;
+ case CUSTOM_INT_4:
+ this.customInt4In = values;
+ break;
+ case CUSTOM_INT_5:
+ this.customInt5In = values;
+ break;
+ case CUSTOM_INT_6:
+ this.customInt6In = values;
+ break;
+ case CUSTOM_INT_7:
+ this.customInt7In = values;
+ break;
+ case CUSTOM_INT_8:
+ this.customInt8In = values;
+ break;
+ default:
+ throw new SystemException("Unknown custom int attribute '" + customIntField + "'");
+ }
+
+ return _this();
+ }
+
+ @Override
+ public B customIntAttributeNotIn(TaskCustomIntField customIntField, Integer... values)
+ throws InvalidArgumentException {
+ if (values.length == 0) {
+ throw new InvalidArgumentException(
+ "At least one Integer has to be provided as a search parameter");
+ }
+ switch (customIntField) {
+ case CUSTOM_INT_1:
+ this.customInt1NotIn = values;
+ break;
+ case CUSTOM_INT_2:
+ this.customInt2NotIn = values;
+ break;
+ case CUSTOM_INT_3:
+ this.customInt3NotIn = values;
+ break;
+ case CUSTOM_INT_4:
+ this.customInt4NotIn = values;
+ break;
+ case CUSTOM_INT_5:
+ this.customInt5NotIn = values;
+ break;
+ case CUSTOM_INT_6:
+ this.customInt6NotIn = values;
+ break;
+ case CUSTOM_INT_7:
+ this.customInt7NotIn = values;
+ break;
+ case CUSTOM_INT_8:
+ this.customInt8NotIn = values;
+ break;
+ default:
+ throw new SystemException("Unknown custom int attribute '" + customIntField + "'");
+ }
+
+ return _this();
+ }
+
+ @Override
+ public B customIntAttributeWithin(TaskCustomIntField customIntField, IntInterval... values)
+ throws IllegalArgumentException {
+ for (IntInterval i : values) {
+ if (!i.isValid()) {
+ throw new IllegalArgumentException("IntInterval " + i + " is invalid.");
+ }
+ }
+ switch (customIntField) {
+ case CUSTOM_INT_1:
+ this.customInt1Within = values;
+ break;
+ case CUSTOM_INT_2:
+ this.customInt2Within = values;
+ break;
+ case CUSTOM_INT_3:
+ this.customInt3Within = values;
+ break;
+ case CUSTOM_INT_4:
+ this.customInt4Within = values;
+ break;
+ case CUSTOM_INT_5:
+ this.customInt5Within = values;
+ break;
+ case CUSTOM_INT_6:
+ this.customInt6Within = values;
+ break;
+ case CUSTOM_INT_7:
+ this.customInt7Within = values;
+ break;
+ case CUSTOM_INT_8:
+ this.customInt8Within = values;
+ break;
+ default:
+ throw new SystemException("Unknown custom int attribute '" + customIntField + "'");
+ }
+ return _this();
+ }
+
+ @Override
+ public B customIntAttributeNotWithin(TaskCustomIntField customIntField, IntInterval... values)
+ throws IllegalArgumentException {
+ for (IntInterval i : values) {
+ if (!i.isValid()) {
+ throw new IllegalArgumentException("IntInterval " + i + " is invalid.");
+ }
+ }
+ switch (customIntField) {
+ case CUSTOM_INT_1:
+ this.customInt1NotWithin = values;
+ break;
+ case CUSTOM_INT_2:
+ this.customInt2NotWithin = values;
+ break;
+ case CUSTOM_INT_3:
+ this.customInt3NotWithin = values;
+ break;
+ case CUSTOM_INT_4:
+ this.customInt4NotWithin = values;
+ break;
+ case CUSTOM_INT_5:
+ this.customInt5NotWithin = values;
+ break;
+ case CUSTOM_INT_6:
+ this.customInt6NotWithin = values;
+ break;
+ case CUSTOM_INT_7:
+ this.customInt7NotWithin = values;
+ break;
+ case CUSTOM_INT_8:
+ this.customInt8NotWithin = values;
+ break;
+ default:
+ throw new SystemException("Unknown custom int attribute '" + customIntField + "'");
+ }
+ return _this();
+ }
+
@Override
public B customAttributeLike(TaskCustomField customField, String... strings)
throws InvalidArgumentException {
diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/WorkbasketPriorityReportBuilderImpl.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/WorkbasketPriorityReportBuilderImpl.java
index 0215989b3..90e3315b4 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/WorkbasketPriorityReportBuilderImpl.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/WorkbasketPriorityReportBuilderImpl.java
@@ -3,6 +3,7 @@ package pro.taskana.monitor.internal.reports;
import java.util.Collections;
import java.util.List;
+import pro.taskana.common.api.IntInterval;
import pro.taskana.common.api.TaskanaRole;
import pro.taskana.common.api.WorkingDaysToDaysConverter;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
@@ -15,6 +16,7 @@ import pro.taskana.monitor.api.reports.header.PriorityColumnHeader;
import pro.taskana.monitor.api.reports.item.PriorityQueryItem;
import pro.taskana.monitor.internal.MonitorMapper;
import pro.taskana.task.api.TaskCustomField;
+import pro.taskana.task.api.TaskCustomIntField;
import pro.taskana.task.api.TaskState;
import pro.taskana.workbasket.api.WorkbasketType;
@@ -80,6 +82,39 @@ public class WorkbasketPriorityReportBuilderImpl implements WorkbasketPriorityRe
private String[] custom16In;
private String[] custom16NotIn;
private String[] custom16Like;
+ private Integer[] customInt1In;
+ private Integer[] customInt1NotIn;
+ private Integer[] customInt2In;
+ private Integer[] customInt2NotIn;
+ private Integer[] customInt3In;
+ private Integer[] customInt3NotIn;
+ private Integer[] customInt4In;
+ private Integer[] customInt4NotIn;
+ private Integer[] customInt5In;
+ private Integer[] customInt5NotIn;
+ private Integer[] customInt6In;
+ private Integer[] customInt6NotIn;
+ private Integer[] customInt7In;
+ private Integer[] customInt7NotIn;
+ private Integer[] customInt8In;
+ private Integer[] customInt8NotIn;
+
+ private IntInterval[] customInt1Within;
+ private IntInterval[] customInt1NotWithin;
+ private IntInterval[] customInt2Within;
+ private IntInterval[] customInt2NotWithin;
+ private IntInterval[] customInt3Within;
+ private IntInterval[] customInt3NotWithin;
+ private IntInterval[] customInt4Within;
+ private IntInterval[] customInt4NotWithin;
+ private IntInterval[] customInt5Within;
+ private IntInterval[] customInt5NotWithin;
+ private IntInterval[] customInt6Within;
+ private IntInterval[] customInt6NotWithin;
+ private IntInterval[] customInt7Within;
+ private IntInterval[] customInt7NotWithin;
+ private IntInterval[] customInt8Within;
+ private IntInterval[] customInt8NotWithin;
@SuppressWarnings("unused")
public WorkbasketPriorityReportBuilderImpl(
@@ -292,6 +327,162 @@ public class WorkbasketPriorityReportBuilderImpl implements WorkbasketPriorityRe
return this;
}
+ @Override
+ public Builder customIntAttributeIn(TaskCustomIntField customIntField, Integer... values)
+ throws InvalidArgumentException {
+ if (values.length == 0) {
+ throw new InvalidArgumentException(
+ "At least one Integer has to be provided as a search parameter");
+ }
+ switch (customIntField) {
+ case CUSTOM_INT_1:
+ this.customInt1In = values;
+ break;
+ case CUSTOM_INT_2:
+ this.customInt2In = values;
+ break;
+ case CUSTOM_INT_3:
+ this.customInt3In = values;
+ break;
+ case CUSTOM_INT_4:
+ this.customInt4In = values;
+ break;
+ case CUSTOM_INT_5:
+ this.customInt5In = values;
+ break;
+ case CUSTOM_INT_6:
+ this.customInt6In = values;
+ break;
+ case CUSTOM_INT_7:
+ this.customInt7In = values;
+ break;
+ case CUSTOM_INT_8:
+ this.customInt8In = values;
+ break;
+ default:
+ throw new SystemException("Unknown custom int attribute '" + customIntField + "'");
+ }
+
+ return this;
+ }
+
+ @Override
+ public Builder customIntAttributeNotIn(TaskCustomIntField customIntField, Integer... values)
+ throws InvalidArgumentException {
+ if (values.length == 0) {
+ throw new InvalidArgumentException(
+ "At least one Integer has to be provided as a search parameter");
+ }
+ switch (customIntField) {
+ case CUSTOM_INT_1:
+ this.customInt1NotIn = values;
+ break;
+ case CUSTOM_INT_2:
+ this.customInt2NotIn = values;
+ break;
+ case CUSTOM_INT_3:
+ this.customInt3NotIn = values;
+ break;
+ case CUSTOM_INT_4:
+ this.customInt4NotIn = values;
+ break;
+ case CUSTOM_INT_5:
+ this.customInt5NotIn = values;
+ break;
+ case CUSTOM_INT_6:
+ this.customInt6NotIn = values;
+ break;
+ case CUSTOM_INT_7:
+ this.customInt7NotIn = values;
+ break;
+ case CUSTOM_INT_8:
+ this.customInt8NotIn = values;
+ break;
+ default:
+ throw new SystemException("Unknown custom int attribute '" + customIntField + "'");
+ }
+
+ return this;
+ }
+
+ @Override
+ public Builder customIntAttributeWithin(
+ TaskCustomIntField customIntField, IntInterval... values) {
+ for (IntInterval i : values) {
+ if (!i.isValid()) {
+ throw new IllegalArgumentException("IntInterval " + i + " is invalid.");
+ }
+ }
+ switch (customIntField) {
+ case CUSTOM_INT_1:
+ this.customInt1Within = values;
+ break;
+ case CUSTOM_INT_2:
+ this.customInt2Within = values;
+ break;
+ case CUSTOM_INT_3:
+ this.customInt3Within = values;
+ break;
+ case CUSTOM_INT_4:
+ this.customInt4Within = values;
+ break;
+ case CUSTOM_INT_5:
+ this.customInt5Within = values;
+ break;
+ case CUSTOM_INT_6:
+ this.customInt6Within = values;
+ break;
+ case CUSTOM_INT_7:
+ this.customInt7Within = values;
+ break;
+ case CUSTOM_INT_8:
+ this.customInt8Within = values;
+ break;
+ default:
+ throw new SystemException("Unknown custom int attribute '" + customIntField + "'");
+ }
+ return this;
+ }
+
+ @Override
+ public Builder customIntAttributeNotWithin(
+ TaskCustomIntField customIntField, IntInterval... values) {
+ for (IntInterval i : values) {
+ if (!i.isValid()) {
+ throw new IllegalArgumentException("IntInterval " + i + " is invalid.");
+ }
+ }
+ switch (customIntField) {
+ case CUSTOM_INT_1:
+ this.customInt1NotWithin = values;
+ break;
+ case CUSTOM_INT_2:
+ this.customInt2NotWithin = values;
+ break;
+ case CUSTOM_INT_3:
+ this.customInt3NotWithin = values;
+ break;
+ case CUSTOM_INT_4:
+ this.customInt4NotWithin = values;
+ break;
+ case CUSTOM_INT_5:
+ this.customInt5NotWithin = values;
+ break;
+ case CUSTOM_INT_6:
+ this.customInt6NotWithin = values;
+ break;
+ case CUSTOM_INT_7:
+ this.customInt7NotWithin = values;
+ break;
+ case CUSTOM_INT_8:
+ this.customInt8NotWithin = values;
+ break;
+ default:
+ throw new SystemException("Unknown custom int attribute '" + customIntField + "'");
+ }
+ return this;
+ }
+
@Override
public Builder customAttributeLike(TaskCustomField customField, String... strings)
throws InvalidArgumentException {
diff --git a/lib/taskana-core/src/test/java/acceptance/report/ProvideWorkbasketPriorityReportAccTest.java b/lib/taskana-core/src/test/java/acceptance/report/ProvideWorkbasketPriorityReportAccTest.java
index 46e431220..8094f7db7 100644
--- a/lib/taskana-core/src/test/java/acceptance/report/ProvideWorkbasketPriorityReportAccTest.java
+++ b/lib/taskana-core/src/test/java/acceptance/report/ProvideWorkbasketPriorityReportAccTest.java
@@ -6,11 +6,18 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
import java.util.Arrays;
import java.util.List;
+import java.util.stream.Stream;
+import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
+import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.function.ThrowingConsumer;
+import pro.taskana.common.api.IntInterval;
import pro.taskana.common.api.exceptions.MismatchedRoleException;
+import pro.taskana.common.internal.util.Pair;
import pro.taskana.common.test.security.JaasExtension;
import pro.taskana.common.test.security.WithAccessId;
import pro.taskana.monitor.api.MonitorService;
@@ -19,10 +26,10 @@ import pro.taskana.monitor.api.reports.WorkbasketPriorityReport;
import pro.taskana.monitor.api.reports.header.PriorityColumnHeader;
import pro.taskana.monitor.api.reports.row.Row;
import pro.taskana.task.api.TaskCustomField;
+import pro.taskana.task.api.TaskCustomIntField;
import pro.taskana.task.api.TaskState;
import pro.taskana.workbasket.api.WorkbasketType;
-/** Acceptance test for all "workbasket priority report" scenarios. */
@ExtendWith(JaasExtension.class)
class ProvideWorkbasketPriorityReportAccTest extends AbstractReportAccTest {
@@ -329,4 +336,173 @@ class ProvideWorkbasketPriorityReportAccTest extends AbstractReportAccTest {
int[] row1 = report.getRow("USER-1-1").getCells();
assertThat(row1).isEqualTo(new int[] {1, 0, 0});
}
+
+ @WithAccessId(user = "monitor")
+ @TestFactory
+ Stream should_ApplyFilter_When_QueryingForCustomIntIn() {
+ List> testCases =
+ List.of(
+ Pair.of(TaskCustomIntField.CUSTOM_INT_1, 1),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_2, 2),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_3, 3),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_4, 4),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_5, 5),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_6, 6),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_7, 7),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_8, 8));
+
+ ThrowingConsumer> test =
+ p -> {
+ WorkbasketPriorityReport report =
+ MONITOR_SERVICE
+ .createWorkbasketPriorityReportBuilder()
+ .withColumnHeaders(DEFAULT_TEST_HEADERS)
+ .customIntAttributeIn(p.getLeft(), p.getRight())
+ .inWorkingDays()
+ .buildReport();
+ assertThat(report).isNotNull();
+ assertThat(report.rowSize()).isEqualTo(5);
+ assertThat(report.getRow("USER-1-1").getCells()).isEqualTo(new int[] {20, 0, 0});
+ };
+
+ return DynamicTest.stream(testCases.iterator(), p -> p.getLeft().name(), test);
+ }
+
+ @WithAccessId(user = "monitor")
+ @TestFactory
+ Stream should_ApplyFilter_When_QueryingForCustomIntNotIn() {
+ List> testCases =
+ List.of(
+ Pair.of(TaskCustomIntField.CUSTOM_INT_1, 1),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_2, 2),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_3, 3),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_4, 4),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_5, 5),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_6, 6),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_7, 7),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_8, 8));
+
+ ThrowingConsumer> test =
+ p -> {
+ WorkbasketPriorityReport report =
+ MONITOR_SERVICE
+ .createWorkbasketPriorityReportBuilder()
+ .withColumnHeaders(DEFAULT_TEST_HEADERS)
+ .customIntAttributeNotIn(p.getLeft(), p.getRight())
+ .inWorkingDays()
+ .buildReport();
+ assertThat(report).isNotNull();
+ assertThat(report.rowSize()).isZero();
+ };
+
+ return DynamicTest.stream(testCases.iterator(), p -> p.getLeft().name(), test);
+ }
+
+ @WithAccessId(user = "monitor")
+ @TestFactory
+ Stream should_ApplyFilter_When_QueryingForCustomIntWithin() {
+ List> testCases =
+ List.of(
+ Pair.of(TaskCustomIntField.CUSTOM_INT_1, new IntInterval(1, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_2, new IntInterval(2, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_3, new IntInterval(3, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_4, new IntInterval(4, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_5, new IntInterval(5, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_6, new IntInterval(6, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_7, new IntInterval(7, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_8, new IntInterval(8, null)));
+
+ ThrowingConsumer> test =
+ p -> {
+ WorkbasketPriorityReport report =
+ MONITOR_SERVICE
+ .createWorkbasketPriorityReportBuilder()
+ .withColumnHeaders(DEFAULT_TEST_HEADERS)
+ .customIntAttributeWithin(p.getLeft(), p.getRight())
+ .inWorkingDays()
+ .buildReport();
+ assertThat(report).isNotNull();
+ assertThat(report.rowSize()).isEqualTo(5);
+ assertThat(report.getRow("USER-1-1").getCells()).isEqualTo(new int[] {20, 0, 0});
+ };
+
+ return DynamicTest.stream(testCases.iterator(), p -> p.getLeft().name(), test);
+ }
+
+ @WithAccessId(user = "monitor")
+ @TestFactory
+ Stream should_ApplyFilter_When_QueryingForCustomIntNotWithin() {
+ List> testCases =
+ List.of(
+ Pair.of(TaskCustomIntField.CUSTOM_INT_1, new IntInterval(3, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_2, new IntInterval(4, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_3, new IntInterval(5, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_4, new IntInterval(6, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_5, new IntInterval(7, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_6, new IntInterval(8, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_7, new IntInterval(9, null)),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_8, new IntInterval(10, null)));
+
+ ThrowingConsumer> test =
+ p -> {
+ WorkbasketPriorityReport report =
+ MONITOR_SERVICE
+ .createWorkbasketPriorityReportBuilder()
+ .withColumnHeaders(DEFAULT_TEST_HEADERS)
+ .customIntAttributeNotWithin(p.getLeft(), p.getRight())
+ .inWorkingDays()
+ .buildReport();
+ assertThat(report).isNotNull();
+ assertThat(report.rowSize()).isEqualTo(5);
+ assertThat(report.getRow("USER-1-1").getCells()).isEqualTo(new int[] {20, 0, 0});
+ };
+
+ return DynamicTest.stream(testCases.iterator(), p -> p.getLeft().name(), test);
+ }
+
+ @WithAccessId(user = "monitor")
+ @TestFactory
+ Stream should_ThrowException_When_FilteringByCustomIntWithinWithInvalidIntervals() {
+ List> testCases =
+ List.of(
+ Pair.of(TaskCustomIntField.CUSTOM_INT_1, new IntInterval[] {new IntInterval(4, 1)}),
+ // Only first interval invalid
+ Pair.of(
+ TaskCustomIntField.CUSTOM_INT_2,
+ new IntInterval[] {new IntInterval(null, null), new IntInterval(0, null)}),
+ // Only second interval invalid
+ Pair.of(
+ TaskCustomIntField.CUSTOM_INT_3,
+ new IntInterval[] {new IntInterval(-1, 5), new IntInterval(null, null)}),
+ // Both intervals invalid
+ Pair.of(
+ TaskCustomIntField.CUSTOM_INT_4,
+ new IntInterval[] {new IntInterval(0, -5), new IntInterval(-2, -10)}),
+ // One interval invalid
+ Pair.of(
+ TaskCustomIntField.CUSTOM_INT_5, new IntInterval[] {new IntInterval(null, null)}),
+ Pair.of(TaskCustomIntField.CUSTOM_INT_6, new IntInterval[] {new IntInterval(0, -5)}),
+ Pair.of(
+ TaskCustomIntField.CUSTOM_INT_7,
+ new IntInterval[] {new IntInterval(null, null), new IntInterval(null, null)}),
+ Pair.of(
+ TaskCustomIntField.CUSTOM_INT_8, new IntInterval[] {new IntInterval(123, 122)}));
+
+ ThrowingConsumer> test =
+ p -> {
+ ThrowingCallable result =
+ () ->
+ MONITOR_SERVICE
+ .createWorkbasketPriorityReportBuilder()
+ .withColumnHeaders(DEFAULT_TEST_HEADERS)
+ .customIntAttributeWithin(p.getLeft(), p.getRight())
+ .inWorkingDays()
+ .buildReport();
+ assertThatThrownBy(result)
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("IntInterval");
+ };
+
+ return DynamicTest.stream(testCases.iterator(), p -> p.getLeft().name(), test);
+ }
}