diff --git a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/category/CategoryCombo.java b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/category/CategoryCombo.java index b8b804117d5a..11246bd5533d 100644 --- a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/category/CategoryCombo.java +++ b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/category/CategoryCombo.java @@ -27,6 +27,7 @@ */ package org.hisp.dhis.category; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; @@ -195,6 +196,11 @@ public boolean hasOptionCombos() { return optionCombos != null && !optionCombos.isEmpty(); } + @JsonIgnore + public List getDataDimensionCategories() { + return categories.stream().filter(Category::isDataDimension).toList(); + } + // ------------------------------------------------------------------------- // Logic // ------------------------------------------------------------------------- diff --git a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObjectUtils.java b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObjectUtils.java index f0d2ceae6cc3..a7786ad46813 100644 --- a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObjectUtils.java +++ b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObjectUtils.java @@ -141,7 +141,6 @@ public static DimensionalObject linkAssociations( EventAnalyticalObject eventAnalyticalObject, DimensionalObject dimensionalObject, Attribute parent) { - // Associating event repetitions. List repetitions = eventAnalyticalObject.getEventRepetitions(); if (isNotEmpty(repetitions)) { diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/AbstractEventJdbcTableManager.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/AbstractEventJdbcTableManager.java index 0b07dced4214..225991dcba23 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/AbstractEventJdbcTableManager.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/AbstractEventJdbcTableManager.java @@ -38,7 +38,7 @@ import java.util.Map; import org.hisp.dhis.analytics.AnalyticsTableHookService; import org.hisp.dhis.analytics.partition.PartitionManager; -import org.hisp.dhis.analytics.table.model.AnalyticsColumnType; +import org.hisp.dhis.analytics.table.model.AnalyticsDimensionType; import org.hisp.dhis.analytics.table.model.AnalyticsTableColumn; import org.hisp.dhis.analytics.table.model.AnalyticsTablePartition; import org.hisp.dhis.analytics.table.model.Skip; @@ -259,7 +259,7 @@ protected List getTrackedEntityAttributeColumns(Program pr columns.add( AnalyticsTableColumn.builder() .name(attribute.getUid()) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(dataType) .selectExpression(sql) .skipIndex(skipIndex) @@ -272,7 +272,7 @@ protected List getTrackedEntityAttributeColumns(Program pr columns.add( AnalyticsTableColumn.builder() .name((attribute.getUid() + OU_NAME_COL_SUFFIX)) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(TEXT) .selectExpression(ouNameSql) .skipIndex(SKIP) diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/AbstractJdbcTableManager.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/AbstractJdbcTableManager.java index 1d16314a85cf..94a49a3ea16a 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/AbstractJdbcTableManager.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/AbstractJdbcTableManager.java @@ -54,7 +54,7 @@ import org.hisp.dhis.analytics.AnalyticsTableType; import org.hisp.dhis.analytics.AnalyticsTableUpdateParams; import org.hisp.dhis.analytics.partition.PartitionManager; -import org.hisp.dhis.analytics.table.model.AnalyticsColumnType; +import org.hisp.dhis.analytics.table.model.AnalyticsDimensionType; import org.hisp.dhis.analytics.table.model.AnalyticsTable; import org.hisp.dhis.analytics.table.model.AnalyticsTableColumn; import org.hisp.dhis.analytics.table.model.AnalyticsTablePartition; @@ -537,7 +537,7 @@ protected List getOrganisationUnitGroupSetColumns() { String name = ougs.getUid(); return AnalyticsTableColumn.builder() .name(name) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(CHARACTER_11) .selectExpression("ougs." + quote(name)) .skipIndex(skipIndex(ougs)) @@ -554,7 +554,7 @@ protected List getDataElementGroupSetColumns() { String name = degs.getUid(); return AnalyticsTableColumn.builder() .name(name) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(CHARACTER_11) .selectExpression("degs." + quote(name)) .skipIndex(skipIndex(degs)) @@ -571,7 +571,7 @@ protected List getDisaggregationCategoryOptionGroupSetColu String name = cogs.getUid(); return AnalyticsTableColumn.builder() .name(name) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(CHARACTER_11) .selectExpression("dcs." + quote(name)) .skipIndex(skipIndex(cogs)) @@ -588,7 +588,7 @@ protected List getAttributeCategoryOptionGroupSetColumns() String name = cogs.getUid(); return AnalyticsTableColumn.builder() .name(name) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(CHARACTER_11) .selectExpression("acs." + quote(name)) .skipIndex(skipIndex(cogs)) @@ -605,7 +605,7 @@ protected List getDisaggregationCategoryColumns() { String name = category.getUid(); return AnalyticsTableColumn.builder() .name(name) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(CHARACTER_11) .selectExpression("dcs." + quote(name)) .skipIndex(skipIndex(category)) @@ -622,7 +622,7 @@ protected List getAttributeCategoryColumns() { String name = category.getUid(); return AnalyticsTableColumn.builder() .name(name) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(CHARACTER_11) .selectExpression("acs." + quote(name)) .skipIndex(skipIndex(category)) diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/JdbcEventAnalyticsTableManager.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/JdbcEventAnalyticsTableManager.java index 077b1284393a..08999c31c8ff 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/JdbcEventAnalyticsTableManager.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/JdbcEventAnalyticsTableManager.java @@ -55,7 +55,7 @@ import org.hisp.dhis.analytics.AnalyticsTableType; import org.hisp.dhis.analytics.AnalyticsTableUpdateParams; import org.hisp.dhis.analytics.partition.PartitionManager; -import org.hisp.dhis.analytics.table.model.AnalyticsColumnType; +import org.hisp.dhis.analytics.table.model.AnalyticsDimensionType; import org.hisp.dhis.analytics.table.model.AnalyticsTable; import org.hisp.dhis.analytics.table.model.AnalyticsTableColumn; import org.hisp.dhis.analytics.table.model.AnalyticsTablePartition; @@ -398,53 +398,14 @@ private String getPartitionClause(AnalyticsTablePartition partition) { */ private List getColumns(Program program) { List columns = new ArrayList<>(fixedColumns); - - if (program.hasNonDefaultCategoryCombo()) { - List categories = program.getCategoryCombo().getCategories(); - - for (Category category : categories) { - if (category.isDataDimension()) { - columns.add( - AnalyticsTableColumn.builder() - .name(category.getUid()) - .columnType(AnalyticsColumnType.DYNAMIC) - .dataType(CHARACTER_11) - .selectExpression("acs." + quote(category.getUid())) - .created(category.getCreated()) - .build()); - } - } - } - + columns.addAll(getAttributeCategoryColumns(program)); columns.addAll(getOrganisationUnitLevelColumns()); columns.add(getOrganisationUnitNameHierarchyColumn()); columns.addAll(getOrganisationUnitGroupSetColumns()); columns.addAll(getAttributeCategoryOptionGroupSetColumns()); columns.addAll(getPeriodTypeColumns("dps")); - - columns.addAll( - program.getAnalyticsDataElements().stream() - .map(de -> getColumnForDataElement(de, false)) - .flatMap(Collection::stream) - .toList()); - - columns.addAll( - program.getAnalyticsDataElementsWithLegendSet().stream() - .map(de -> getColumnForDataElement(de, true)) - .flatMap(Collection::stream) - .toList()); - - columns.addAll( - program.getNonConfidentialTrackedEntityAttributes().stream() - .map(tea -> getColumnForTrackedEntityAttribute(tea, false)) - .flatMap(Collection::stream) - .toList()); - - columns.addAll( - program.getNonConfidentialTrackedEntityAttributesWithLegendSet().stream() - .map(tea -> getColumnForTrackedEntityAttribute(tea, true)) - .flatMap(Collection::stream) - .toList()); + columns.addAll(getDataElementColumns(program)); + columns.addAll(getAttributeColumns(program)); if (program.isRegistration()) { columns.add(EventAnalyticsColumn.TRACKED_ENTITY); @@ -469,6 +430,52 @@ protected AnalyticsTableColumn getPartitionColumn() { .build(); } + /** + * Returns columns for attribute categories of the given program. + * + * @param program the {@link Program}. + * @return a list of {@link AnalyticsTableColumn}. + */ + private List getAttributeCategoryColumns(Program program) { + if (program.hasNonDefaultCategoryCombo()) { + List categories = program.getCategoryCombo().getDataDimensionCategories(); + return categories.stream() + .map( + category -> + AnalyticsTableColumn.builder() + .name(category.getUid()) + .dimensionType(AnalyticsDimensionType.DYNAMIC) + .dataType(CHARACTER_11) + .selectExpression("acs." + quote(category.getUid())) + .created(category.getCreated()) + .build()) + .toList(); + } + + return List.of(); + } + + /** + * Returns columns for data elements of the given program. + * + * @param program the {@link Program}. + * @return a list of {@link AnalyticsTableColumn}. + */ + private List getDataElementColumns(Program program) { + List columns = new ArrayList<>(); + columns.addAll( + program.getAnalyticsDataElements().stream() + .map(de -> getColumnForDataElement(de, false)) + .flatMap(Collection::stream) + .toList()); + columns.addAll( + program.getAnalyticsDataElementsWithLegendSet().stream() + .map(de -> getColumnForDataElement(de, true)) + .flatMap(Collection::stream) + .toList()); + return columns; + } + /** * Returns a column for the given data element. If the value type of the data element is {@link * ValueType#ORGANISATION_UNIT}, an extra column will be included. @@ -496,7 +503,7 @@ private List getColumnForDataElement( columns.add( AnalyticsTableColumn.builder() .name(dataElement.getUid()) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(dataType) .selectExpression(sql) .skipIndex(skipIndex) @@ -523,7 +530,7 @@ private List getColumnForOrgUnitDataElement( columns.add( AnalyticsTableColumn.builder() .name((dataElement.getUid() + OU_GEOMETRY_COL_SUFFIX)) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(GEOMETRY) .selectExpression(geoSql) .indexType(IndexType.GIST) @@ -536,7 +543,7 @@ private List getColumnForOrgUnitDataElement( columns.add( AnalyticsTableColumn.builder() .name((dataElement.getUid() + OU_NAME_COL_SUFFIX)) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(TEXT) .selectExpression(ouNameSql) .skipIndex(SKIP) @@ -545,6 +552,34 @@ private List getColumnForOrgUnitDataElement( return columns; } + /** + * Returns columns for attributes of the given program. + * + * @param program the {@link Program}. + * @return a list of {@link AnalyticsTableColumn}. + */ + private List getAttributeColumns(Program program) { + List columns = new ArrayList<>(); + columns.addAll( + program.getNonConfidentialTrackedEntityAttributes().stream() + .map(tea -> getColumnForTrackedEntityAttribute(tea, false)) + .flatMap(Collection::stream) + .toList()); + columns.addAll( + program.getNonConfidentialTrackedEntityAttributesWithLegendSet().stream() + .map(tea -> getColumnForTrackedEntityAttribute(tea, true)) + .flatMap(Collection::stream) + .toList()); + return columns; + } + + /** + * Returns a list of columns based on the given attribute. + * + * @param attribute the {@link TrackedEntityAttribute}. + * @param withLegendSet indicates whether the attribute has a legend set. + * @return a list of {@link AnaylyticsTableColumn}. + */ private List getColumnForTrackedEntityAttribute( TrackedEntityAttribute attribute, boolean withLegendSet) { List columns = new ArrayList<>(); @@ -562,7 +597,7 @@ private List getColumnForTrackedEntityAttribute( columns.add( AnalyticsTableColumn.builder() .name(attribute.getUid()) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(dataType) .selectExpression(sql) .skipIndex(skipIndex) @@ -633,7 +668,7 @@ private List getColumnsForOrgUnitTrackedEntityAttribute( columns.add( AnalyticsTableColumn.builder() .name((attribute.getUid() + OU_GEOMETRY_COL_SUFFIX)) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(GEOMETRY) .selectExpression(geoSql) .indexType(IndexType.GIST) @@ -646,7 +681,7 @@ private List getColumnsForOrgUnitTrackedEntityAttribute( columns.add( AnalyticsTableColumn.builder() .name((attribute.getUid() + OU_NAME_COL_SUFFIX)) - .columnType(AnalyticsColumnType.DYNAMIC) + .dimensionType(AnalyticsDimensionType.DYNAMIC) .dataType(TEXT) .selectExpression(ouNameSql) .skipIndex(SKIP) diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/model/AnalyticsColumnType.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/model/AnalyticsDimensionType.java similarity index 97% rename from dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/model/AnalyticsColumnType.java rename to dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/model/AnalyticsDimensionType.java index e00267ed3717..cd54f16e4e60 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/model/AnalyticsColumnType.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/model/AnalyticsDimensionType.java @@ -31,7 +31,7 @@ * Represents a type of dimension, either static, meaning fixed, or dynamic, meaning based on a * dimensional configuration entity. */ -public enum AnalyticsColumnType { +public enum AnalyticsDimensionType { STATIC, DYNAMIC; } diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/model/AnalyticsTableColumn.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/model/AnalyticsTableColumn.java index 2f04beb6f675..537b473493e5 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/model/AnalyticsTableColumn.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/model/AnalyticsTableColumn.java @@ -74,7 +74,8 @@ public class AnalyticsTableColumn { @Builder.Default private final List indexColumns = List.of(); /** The column type indicates the column origin. */ - @Builder.Default private final AnalyticsColumnType columnType = AnalyticsColumnType.STATIC; + @Builder.Default + private final AnalyticsDimensionType dimensionType = AnalyticsDimensionType.STATIC; /** Date of creation of the underlying data dimension. */ private final Date created; @@ -104,8 +105,8 @@ public boolean isSkipIndex() { } /** Indicates whether the column type is set to a non-default value. */ - public boolean isStatic() { - return AnalyticsColumnType.STATIC == columnType; + public boolean isStaticDimension() { + return AnalyticsDimensionType.STATIC == dimensionType; } @Override diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/util/AnalyticsIndexHelper.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/util/AnalyticsIndexHelper.java index 07d05742ff2e..6d984a71c2b4 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/util/AnalyticsIndexHelper.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/util/AnalyticsIndexHelper.java @@ -154,7 +154,7 @@ private static void maybeAddTextLowerIndex( boolean isSingleColumn = indexColumns.size() == 1; if (column.getDataType() == TEXT - && !column.isStatic() + && !column.isStaticDimension() && isValidUid(columnName) && isSingleColumn) { String name = indexName + "_lower"; @@ -178,7 +178,7 @@ private static void maybeAddDateSortOrderIndex( boolean isSingleColumn = indexColumns.size() == 1; - if (column.getDataType() == TIMESTAMP && column.isStatic() && isSingleColumn) { + if (column.getDataType() == TIMESTAMP && column.isStaticDimension() && isSingleColumn) { indexes.add( Index.builder() .name(indexName + "_desc")