diff --git a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/PeriodType.java b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/PeriodType.java index c389fbbf4642..84eba85b2b05 100644 --- a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/PeriodType.java +++ b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/PeriodType.java @@ -258,7 +258,7 @@ public static List getPeriodTypePeriods( /** * Returns the ISO period name for the given {@link ResultSet} row. Requires that a column - * pe_start_date of type date and a column pt_name are present. + * startDate of type date and a column periodType are present. * * @param calendar the {@link Calendar}. * @param rs the {@link ResultSet}. diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EnrollmentAnalyticsService.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EnrollmentAnalyticsService.java index 225b9e270498..0190f1eb97be 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EnrollmentAnalyticsService.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EnrollmentAnalyticsService.java @@ -36,35 +36,6 @@ * @author Markus Bekken */ public interface EnrollmentAnalyticsService { - String ITEM_TEI = "tei"; - - String ITEM_PI = "pi"; - - String ITEM_ENROLLMENT_DATE = "enrollmentdate"; - - String ITEM_INCIDENT_DATE = "incidentdate"; - - String ITEM_STORED_BY = "storedby"; - - String ITEM_CREATED_BY_DISPLAY_NAME = "createdbydisplayname"; - - String ITEM_LAST_UPDATED_BY_DISPLAY_NAME = "lastupdatedbydisplayname"; - - String ITEM_LAST_UPDATED = "lastupdated"; - - String ITEM_GEOMETRY = "geometry"; - - String ITEM_LONGITUDE = "longitude"; - - String ITEM_LATITUDE = "latitude"; - - String ITEM_ORG_UNIT_NAME = "ouname"; - - String ITEM_ORG_UNIT_NAME_HIERARCHY = "ounamehierarchy"; - - String ITEM_ORG_UNIT_CODE = "oucode"; - - String ITEM_PROGRAM_STATUS = "programstatus"; /** * Returns a list of enrollments matching the given query. diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventAnalyticsService.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventAnalyticsService.java index 12588da2c5d1..3f4794718a15 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventAnalyticsService.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventAnalyticsService.java @@ -40,53 +40,6 @@ * @author Lars Helge Overland */ public interface EventAnalyticsService { - String ITEM_EVENT = "psi"; - - String ITEM_TRACKED_ENTITY_INSTANCE = "tei"; - - String ITEM_PROGRAM_INSTANCE = "pi"; - - String ITEM_PROGRAM_STAGE = "ps"; - - String ITEM_EVENT_DATE = "eventdate"; - - String ITEM_STORED_BY = "storedby"; - - String ITEM_CREATED_BY_DISPLAY_NAME = "createdbydisplayname"; - - String ITEM_LAST_UPDATED_BY_DISPLAY_NAME = "lastupdatedbydisplayname"; - - String ITEM_LAST_UPDATED = "lastupdated"; - - String ITEM_SCHEDULED_DATE = "scheduleddate"; - - String ITEM_ENROLLMENT_DATE = "enrollmentdate"; - - String ITEM_INCIDENT_DATE = "incidentdate"; - - String ITEM_GEOMETRY = "geometry"; - - String ITEM_LONGITUDE = "longitude"; - - String ITEM_LATITUDE = "latitude"; - - String ITEM_ORG_UNIT_NAME = "ouname"; - - String ITEM_ORG_UNIT_NAME_HIERARCHY = "ounamehierarchy"; - - String ITEM_ORG_UNIT_CODE = "oucode"; - - String ITEM_COUNT = "count"; - - String ITEM_CENTER = "center"; - - String ITEM_EXTENT = "extent"; - - String ITEM_POINTS = "points"; - - String ITEM_PROGRAM_STATUS = "programstatus"; - - String ITEM_EVENT_STATUS = "eventstatus"; /** * Generates aggregated event data for the given query. diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEnrollmentAnalyticsService.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEnrollmentAnalyticsService.java index 994b492a0221..0f1e1dc128a0 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEnrollmentAnalyticsService.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEnrollmentAnalyticsService.java @@ -30,6 +30,21 @@ import static com.google.common.base.Preconditions.checkNotNull; import static org.hisp.dhis.analytics.DataQueryParams.VALUE_HEADER_NAME; import static org.hisp.dhis.analytics.DataQueryParams.VALUE_ID; +import static org.hisp.dhis.analytics.common.ColumnHeader.CREATED_BY_DISPLAY_NAME; +import static org.hisp.dhis.analytics.common.ColumnHeader.ENROLLMENT; +import static org.hisp.dhis.analytics.common.ColumnHeader.ENROLLMENT_DATE; +import static org.hisp.dhis.analytics.common.ColumnHeader.GEOMETRY; +import static org.hisp.dhis.analytics.common.ColumnHeader.INCIDENT_DATE; +import static org.hisp.dhis.analytics.common.ColumnHeader.LAST_UPDATED; +import static org.hisp.dhis.analytics.common.ColumnHeader.LAST_UPDATED_BY_DISPLAY_NAME; +import static org.hisp.dhis.analytics.common.ColumnHeader.LATITUDE; +import static org.hisp.dhis.analytics.common.ColumnHeader.LONGITUDE; +import static org.hisp.dhis.analytics.common.ColumnHeader.ORG_UNIT_CODE; +import static org.hisp.dhis.analytics.common.ColumnHeader.ORG_UNIT_NAME; +import static org.hisp.dhis.analytics.common.ColumnHeader.ORG_UNIT_NAME_HIERARCHY; +import static org.hisp.dhis.analytics.common.ColumnHeader.PROGRAM_STATUS; +import static org.hisp.dhis.analytics.common.ColumnHeader.STORED_BY; +import static org.hisp.dhis.analytics.common.ColumnHeader.TEI; import static org.hisp.dhis.common.ValueType.DATE; import static org.hisp.dhis.common.ValueType.NUMBER; import static org.hisp.dhis.common.ValueType.TEXT; @@ -59,35 +74,6 @@ @Service("org.hisp.dhis.analytics.event.EnrollmentAnalyticsService") public class DefaultEnrollmentAnalyticsService extends AbstractAnalyticsService implements EnrollmentAnalyticsService { - private static final String NAME_TEI = "Tracked entity instance"; - - private static final String NAME_PI = "Enrollment"; - - private static final String NAME_GEOMETRY = "Geometry"; - - private static final String NAME_ENROLLMENT_DATE = "Enrollment date"; - - private static final String NAME_INCIDENT_DATE = "Incident date"; - - private static final String NAME_STORED_BY = "Stored by"; - - private static final String NAME_CREATED_BY_DISPLAY_NAME = "Created by"; - - private static final String NAME_LAST_UPDATED_BY_DISPLAY_NAME = "Last updated by"; - - private static final String NAME_LAST_UPDATED = "Last updated on"; - - private static final String NAME_LONGITUDE = "Longitude"; - - private static final String NAME_LATITUDE = "Latitude"; - - private static final String NAME_ORG_UNIT_NAME = "Organisation unit name"; - - private static final String NAME_ORG_UNIT_NAME_HIERARCHY = "Organisation unit name hierarchy"; - - private static final String NAME_ORG_UNIT_CODE = "Organisation unit code"; - - private static final String NAME_PROGRAM_STATUS = "Program status"; private final EnrollmentAnalyticsManager enrollmentAnalyticsManager; @@ -127,43 +113,55 @@ protected Grid createGridWithHeaders(EventQueryParams params) { } return new ListGrid() - .addHeader(new GridHeader(ITEM_PI, NAME_PI, TEXT, false, true)) - .addHeader(new GridHeader(ITEM_TEI, NAME_TEI, TEXT, false, true)) + .addHeader(new GridHeader(ENROLLMENT.getItem(), ENROLLMENT.getName(), TEXT, false, true)) + .addHeader(new GridHeader(TEI.getItem(), TEI.getName(), TEXT, false, true)) .addHeader( new GridHeader( - ITEM_ENROLLMENT_DATE, - LabelMapper.getEnrollmentDateLabel(params.getProgram(), NAME_ENROLLMENT_DATE), + ENROLLMENT_DATE.getItem(), + LabelMapper.getEnrollmentDateLabel(params.getProgram(), ENROLLMENT_DATE.getName()), DATE, false, true)) .addHeader( new GridHeader( - ITEM_INCIDENT_DATE, - LabelMapper.getIncidentDateLabel(params.getProgram(), NAME_INCIDENT_DATE), + INCIDENT_DATE.getItem(), + LabelMapper.getIncidentDateLabel(params.getProgram(), INCIDENT_DATE.getName()), DATE, false, true)) - .addHeader(new GridHeader(ITEM_STORED_BY, NAME_STORED_BY, TEXT, false, true)) + .addHeader(new GridHeader(STORED_BY.getItem(), STORED_BY.getName(), TEXT, false, true)) .addHeader( new GridHeader( - ITEM_CREATED_BY_DISPLAY_NAME, NAME_CREATED_BY_DISPLAY_NAME, TEXT, false, true)) + CREATED_BY_DISPLAY_NAME.getItem(), + CREATED_BY_DISPLAY_NAME.getName(), + TEXT, + false, + true)) .addHeader( new GridHeader( - ITEM_LAST_UPDATED_BY_DISPLAY_NAME, - NAME_LAST_UPDATED_BY_DISPLAY_NAME, + LAST_UPDATED_BY_DISPLAY_NAME.getItem(), + LAST_UPDATED_BY_DISPLAY_NAME.getName(), TEXT, false, true)) - .addHeader(new GridHeader(ITEM_LAST_UPDATED, NAME_LAST_UPDATED, DATE, false, true)) - .addHeader(new GridHeader(ITEM_GEOMETRY, NAME_GEOMETRY, TEXT, false, true)) - .addHeader(new GridHeader(ITEM_LONGITUDE, NAME_LONGITUDE, NUMBER, false, true)) - .addHeader(new GridHeader(ITEM_LATITUDE, NAME_LATITUDE, NUMBER, false, true)) - .addHeader(new GridHeader(ITEM_ORG_UNIT_NAME, NAME_ORG_UNIT_NAME, TEXT, false, true)) + .addHeader( + new GridHeader(LAST_UPDATED.getItem(), LAST_UPDATED.getName(), DATE, false, true)) + .addHeader(new GridHeader(GEOMETRY.getItem(), GEOMETRY.getName(), TEXT, false, true)) + .addHeader(new GridHeader(LONGITUDE.getItem(), LONGITUDE.getName(), NUMBER, false, true)) + .addHeader(new GridHeader(LATITUDE.getItem(), LATITUDE.getName(), NUMBER, false, true)) + .addHeader( + new GridHeader(ORG_UNIT_NAME.getItem(), ORG_UNIT_NAME.getName(), TEXT, false, true)) .addHeader( new GridHeader( - ITEM_ORG_UNIT_NAME_HIERARCHY, NAME_ORG_UNIT_NAME_HIERARCHY, TEXT, false, true)) - .addHeader(new GridHeader(ITEM_ORG_UNIT_CODE, NAME_ORG_UNIT_CODE, TEXT, false, true)) - .addHeader(new GridHeader(ITEM_PROGRAM_STATUS, NAME_PROGRAM_STATUS, TEXT, false, true)); + ORG_UNIT_NAME_HIERARCHY.getItem(), + ORG_UNIT_NAME_HIERARCHY.getName(), + TEXT, + false, + true)) + .addHeader( + new GridHeader(ORG_UNIT_CODE.getItem(), ORG_UNIT_CODE.getName(), TEXT, false, true)) + .addHeader( + new GridHeader(PROGRAM_STATUS.getItem(), PROGRAM_STATUS.getName(), TEXT, false, true)); } @Override diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventAnalyticsService.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventAnalyticsService.java index 6be654aaedcf..6863c4570632 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventAnalyticsService.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventAnalyticsService.java @@ -42,6 +42,25 @@ import static org.hisp.dhis.analytics.DataQueryParams.NUMERATOR_ID; import static org.hisp.dhis.analytics.DataQueryParams.VALUE_HEADER_NAME; import static org.hisp.dhis.analytics.DataQueryParams.VALUE_ID; +import static org.hisp.dhis.analytics.common.ColumnHeader.CREATED_BY_DISPLAY_NAME; +import static org.hisp.dhis.analytics.common.ColumnHeader.ENROLLMENT_DATE; +import static org.hisp.dhis.analytics.common.ColumnHeader.EVENT; +import static org.hisp.dhis.analytics.common.ColumnHeader.EVENT_DATE; +import static org.hisp.dhis.analytics.common.ColumnHeader.EVENT_STATUS; +import static org.hisp.dhis.analytics.common.ColumnHeader.GEOMETRY; +import static org.hisp.dhis.analytics.common.ColumnHeader.INCIDENT_DATE; +import static org.hisp.dhis.analytics.common.ColumnHeader.LAST_UPDATED; +import static org.hisp.dhis.analytics.common.ColumnHeader.LAST_UPDATED_BY_DISPLAY_NAME; +import static org.hisp.dhis.analytics.common.ColumnHeader.LATITUDE; +import static org.hisp.dhis.analytics.common.ColumnHeader.LONGITUDE; +import static org.hisp.dhis.analytics.common.ColumnHeader.ORG_UNIT_CODE; +import static org.hisp.dhis.analytics.common.ColumnHeader.ORG_UNIT_NAME; +import static org.hisp.dhis.analytics.common.ColumnHeader.ORG_UNIT_NAME_HIERARCHY; +import static org.hisp.dhis.analytics.common.ColumnHeader.PROGRAM_INSTANCE; +import static org.hisp.dhis.analytics.common.ColumnHeader.PROGRAM_STAGE; +import static org.hisp.dhis.analytics.common.ColumnHeader.PROGRAM_STATUS; +import static org.hisp.dhis.analytics.common.ColumnHeader.SCHEDULED_DATE; +import static org.hisp.dhis.analytics.common.ColumnHeader.STORED_BY; import static org.hisp.dhis.analytics.event.LabelMapper.getEnrollmentDateLabel; import static org.hisp.dhis.analytics.event.LabelMapper.getEventDateLabel; import static org.hisp.dhis.analytics.event.LabelMapper.getIncidentDateLabel; @@ -68,6 +87,7 @@ import org.hisp.dhis.analytics.EventAnalyticsDimensionalItem; import org.hisp.dhis.analytics.Rectangle; import org.hisp.dhis.analytics.cache.AnalyticsCache; +import org.hisp.dhis.analytics.common.ColumnHeader; import org.hisp.dhis.analytics.data.handler.SchemeIdResponseMapper; import org.hisp.dhis.analytics.event.EnrollmentAnalyticsManager; import org.hisp.dhis.analytics.event.EventAnalyticsManager; @@ -119,54 +139,6 @@ public class DefaultEventAnalyticsService extends AbstractAnalyticsService PERIOD_DIM_ID, "period", ORGUNIT_DIM_ID, "organisationunit"); - private static final String NAME_EVENT = "Event"; - - private static final String NAME_TEI = "Tracked entity instance"; - - private static final String NAME_PROGRAM_INSTANCE = "Program instance"; - - private static final String NAME_PROGRAM_STAGE = "Program stage"; - - private static final String NAME_EVENT_DATE = "Event date"; - - private static final String NAME_STORED_BY = "Stored by"; - - private static final String NAME_CREATED_BY_DISPLAY_NAME = "Created by"; - - private static final String NAME_LAST_UPDATED_BY_DISPLAY_NAME = "Last updated by"; - - private static final String NAME_LAST_UPDATED = "Last updated on"; - - private static final String NAME_SCHEDULED_DATE = "Scheduled date"; - - private static final String NAME_ENROLLMENT_DATE = "Enrollment date"; - - private static final String NAME_INCIDENT_DATE = "Incident date"; - - private static final String NAME_GEOMETRY = "Geometry"; - - private static final String NAME_LONGITUDE = "Longitude"; - - private static final String NAME_LATITUDE = "Latitude"; - - private static final String NAME_ORG_UNIT_NAME = "Organisation unit name"; - - private static final String NAME_ORG_UNIT_NAME_HIERARCHY = "Organisation unit name hierarchy"; - - private static final String NAME_ORG_UNIT_CODE = "Organisation unit code"; - - private static final String NAME_COUNT = "Count"; - - private static final String NAME_CENTER = "Center"; - - private static final String NAME_EXTENT = "Extent"; - - private static final String NAME_POINTS = "Points"; - - private static final String NAME_PROGRAM_STATUS = "Program status"; - - private static final String NAME_EVENT_STATUS = "Event status"; - private static final Option OPT_TRUE = new Option("Yes", "1"); private static final Option OPT_FALSE = new Option("No", "0"); @@ -661,10 +633,18 @@ public Grid getEventClusters(EventQueryParams params) { // Headers // --------------------------------------------------------------------- - grid.addHeader(new GridHeader(ITEM_COUNT, NAME_COUNT, NUMBER, false, false)) - .addHeader(new GridHeader(ITEM_CENTER, NAME_CENTER, TEXT, false, false)) - .addHeader(new GridHeader(ITEM_EXTENT, NAME_EXTENT, TEXT, false, false)) - .addHeader(new GridHeader(ITEM_POINTS, NAME_POINTS, TEXT, false, false)); + grid.addHeader( + new GridHeader( + ColumnHeader.COUNT.getItem(), ColumnHeader.COUNT.getName(), NUMBER, false, false)) + .addHeader( + new GridHeader( + ColumnHeader.CENTER.getItem(), ColumnHeader.CENTER.getName(), TEXT, false, false)) + .addHeader( + new GridHeader( + ColumnHeader.EXTENT.getItem(), ColumnHeader.EXTENT.getName(), TEXT, false, false)) + .addHeader( + new GridHeader( + ColumnHeader.POINTS.getItem(), ColumnHeader.POINTS.getName(), TEXT, false, false)); // --------------------------------------------------------------------- // Data @@ -707,31 +687,37 @@ public Rectangle getRectangle(EventQueryParams params) { protected Grid createGridWithHeaders(EventQueryParams params) { Grid grid = new ListGrid(); - grid.addHeader(new GridHeader(ITEM_EVENT, NAME_EVENT, TEXT, false, true)) - .addHeader(new GridHeader(ITEM_PROGRAM_STAGE, NAME_PROGRAM_STAGE, TEXT, false, true)) + grid.addHeader(new GridHeader(EVENT.getItem(), EVENT.getName(), TEXT, false, true)) + .addHeader( + new GridHeader(PROGRAM_STAGE.getItem(), PROGRAM_STAGE.getName(), TEXT, false, true)) .addHeader( new GridHeader( - ITEM_EVENT_DATE, - getEventDateLabel(params.getProgramStage(), NAME_EVENT_DATE), + EVENT_DATE.getItem(), + getEventDateLabel(params.getProgramStage(), EVENT_DATE.getName()), DATE, false, true)) - .addHeader(new GridHeader(ITEM_STORED_BY, NAME_STORED_BY, TEXT, false, true)) + .addHeader(new GridHeader(STORED_BY.getItem(), STORED_BY.getName(), TEXT, false, true)) .addHeader( new GridHeader( - ITEM_CREATED_BY_DISPLAY_NAME, NAME_CREATED_BY_DISPLAY_NAME, TEXT, false, true)) + CREATED_BY_DISPLAY_NAME.getItem(), + CREATED_BY_DISPLAY_NAME.getName(), + TEXT, + false, + true)) .addHeader( new GridHeader( - ITEM_LAST_UPDATED_BY_DISPLAY_NAME, - NAME_LAST_UPDATED_BY_DISPLAY_NAME, + LAST_UPDATED_BY_DISPLAY_NAME.getItem(), + LAST_UPDATED_BY_DISPLAY_NAME.getName(), TEXT, false, true)) - .addHeader(new GridHeader(ITEM_LAST_UPDATED, NAME_LAST_UPDATED, DATE, false, true)) + .addHeader( + new GridHeader(LAST_UPDATED.getItem(), LAST_UPDATED.getName(), DATE, false, true)) .addHeader( new GridHeader( - ITEM_SCHEDULED_DATE, - getScheduledDateLabel(params.getProgramStage(), NAME_SCHEDULED_DATE), + SCHEDULED_DATE.getItem(), + getScheduledDateLabel(params.getProgramStage(), SCHEDULED_DATE.getName()), DATE, false, true)); @@ -739,33 +725,44 @@ protected Grid createGridWithHeaders(EventQueryParams params) { if (params.getProgram().isRegistration()) { grid.addHeader( new GridHeader( - ITEM_ENROLLMENT_DATE, - getEnrollmentDateLabel(params.getProgram(), NAME_ENROLLMENT_DATE), + ENROLLMENT_DATE.getItem(), + getEnrollmentDateLabel(params.getProgram(), ENROLLMENT_DATE.getName()), DATE, false, true)) .addHeader( new GridHeader( - ITEM_INCIDENT_DATE, - getIncidentDateLabel(params.getProgram(), NAME_INCIDENT_DATE), + INCIDENT_DATE.getItem(), + getIncidentDateLabel(params.getProgram(), INCIDENT_DATE.getName()), DATE, false, true)) - .addHeader(new GridHeader(ITEM_TRACKED_ENTITY_INSTANCE, NAME_TEI, TEXT, false, true)) .addHeader( - new GridHeader(ITEM_PROGRAM_INSTANCE, NAME_PROGRAM_INSTANCE, TEXT, false, true)); + new GridHeader( + ColumnHeader.TEI.getItem(), ColumnHeader.TEI.getName(), TEXT, false, true)) + .addHeader( + new GridHeader( + PROGRAM_INSTANCE.getItem(), PROGRAM_INSTANCE.getName(), TEXT, false, true)); } - grid.addHeader(new GridHeader(ITEM_GEOMETRY, NAME_GEOMETRY, TEXT, false, true)) - .addHeader(new GridHeader(ITEM_LONGITUDE, NAME_LONGITUDE, NUMBER, false, true)) - .addHeader(new GridHeader(ITEM_LATITUDE, NAME_LATITUDE, NUMBER, false, true)) - .addHeader(new GridHeader(ITEM_ORG_UNIT_NAME, NAME_ORG_UNIT_NAME, TEXT, false, true)) + grid.addHeader(new GridHeader(GEOMETRY.getItem(), GEOMETRY.getName(), TEXT, false, true)) + .addHeader(new GridHeader(LONGITUDE.getItem(), LONGITUDE.getName(), NUMBER, false, true)) + .addHeader(new GridHeader(LATITUDE.getItem(), LATITUDE.getName(), NUMBER, false, true)) + .addHeader( + new GridHeader(ORG_UNIT_NAME.getItem(), ORG_UNIT_NAME.getName(), TEXT, false, true)) .addHeader( new GridHeader( - ITEM_ORG_UNIT_NAME_HIERARCHY, NAME_ORG_UNIT_NAME_HIERARCHY, TEXT, false, true)) - .addHeader(new GridHeader(ITEM_ORG_UNIT_CODE, NAME_ORG_UNIT_CODE, TEXT, false, true)) - .addHeader(new GridHeader(ITEM_PROGRAM_STATUS, NAME_PROGRAM_STATUS, TEXT, false, true)) - .addHeader(new GridHeader(ITEM_EVENT_STATUS, NAME_EVENT_STATUS, TEXT, false, true)); + ORG_UNIT_NAME_HIERARCHY.getItem(), + ORG_UNIT_NAME_HIERARCHY.getName(), + TEXT, + false, + true)) + .addHeader( + new GridHeader(ORG_UNIT_CODE.getItem(), ORG_UNIT_CODE.getName(), TEXT, false, true)) + .addHeader( + new GridHeader(PROGRAM_STATUS.getItem(), PROGRAM_STATUS.getName(), TEXT, false, true)) + .addHeader( + new GridHeader(EVENT_STATUS.getItem(), EVENT_STATUS.getName(), TEXT, false, true)); return grid; } diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventDataQueryService.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventDataQueryService.java index d1b5044cc634..6998f6a3e48a 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventDataQueryService.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventDataQueryService.java @@ -28,18 +28,6 @@ package org.hisp.dhis.analytics.event.data; import static org.apache.commons.lang3.ObjectUtils.firstNonNull; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_CREATED_BY_DISPLAY_NAME; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_ENROLLMENT_DATE; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_EVENT_DATE; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_EVENT_STATUS; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_INCIDENT_DATE; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_LAST_UPDATED; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_LAST_UPDATED_BY_DISPLAY_NAME; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_ORG_UNIT_CODE; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_ORG_UNIT_NAME; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_ORG_UNIT_NAME_HIERARCHY; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_PROGRAM_STATUS; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_SCHEDULED_DATE; import static org.hisp.dhis.analytics.event.data.DefaultEventCoordinateService.COL_NAME_GEOMETRY_LIST; import static org.hisp.dhis.analytics.event.data.DefaultEventCoordinateService.COL_NAME_PI_GEOMETRY; import static org.hisp.dhis.analytics.event.data.DefaultEventCoordinateService.COL_NAME_PSI_GEOMETRY; @@ -72,6 +60,7 @@ import org.hisp.dhis.analytics.DataQueryService; import org.hisp.dhis.analytics.EventOutputType; import org.hisp.dhis.analytics.OrgUnitField; +import org.hisp.dhis.analytics.common.ColumnHeader; import org.hisp.dhis.analytics.event.EventDataQueryService; import org.hisp.dhis.analytics.event.EventQueryParams; import org.hisp.dhis.analytics.event.QueryItemLocator; @@ -584,19 +573,21 @@ private DimensionalItemObject getValueDimension(String value) { @Getter @RequiredArgsConstructor enum SortableItems { - ENROLLMENT_DATE(ITEM_ENROLLMENT_DATE, COL_NAME_ENROLLMENTDATE), - INCIDENT_DATE(ITEM_INCIDENT_DATE, COL_NAME_INCIDENTDATE), - EVENT_DATE(ITEM_EVENT_DATE, COL_NAME_EVENTDATE), - SCHEDULED_DATE(ITEM_SCHEDULED_DATE, COL_NAME_DUEDATE), - ORG_UNIT_NAME(ITEM_ORG_UNIT_NAME), - ORG_UNIT_NAME_HIERARCHY(ITEM_ORG_UNIT_NAME_HIERARCHY), - ORG_UNIT_CODE(ITEM_ORG_UNIT_CODE), + ENROLLMENT_DATE(ColumnHeader.ENROLLMENT_DATE.getItem(), COL_NAME_ENROLLMENTDATE), + INCIDENT_DATE(ColumnHeader.INCIDENT_DATE.getItem(), COL_NAME_INCIDENTDATE), + EVENT_DATE(ColumnHeader.EVENT_DATE.getItem(), COL_NAME_EVENTDATE), + SCHEDULED_DATE(ColumnHeader.SCHEDULED_DATE.getItem(), COL_NAME_DUEDATE), + ORG_UNIT_NAME(ColumnHeader.ORG_UNIT_NAME.getItem()), + ORG_UNIT_NAME_HIERARCHY(ColumnHeader.ORG_UNIT_NAME_HIERARCHY.getItem()), + ORG_UNIT_CODE(ColumnHeader.ORG_UNIT_CODE.getItem()), PROGRAM_STATUS( - ITEM_PROGRAM_STATUS, COL_NAME_PROGRAM_STATUS_EVENTS, COL_NAME_PROGRAM_STATUS_ENROLLMENTS), - EVENT_STATUS(ITEM_EVENT_STATUS, COL_NAME_EVENT_STATUS), - CREATED_BY_DISPLAY_NAME(ITEM_CREATED_BY_DISPLAY_NAME), - LAST_UPDATED_BY_DISPLAY_NAME(ITEM_LAST_UPDATED_BY_DISPLAY_NAME), - LAST_UPDATED(ITEM_LAST_UPDATED); + ColumnHeader.PROGRAM_STATUS.getItem(), + COL_NAME_PROGRAM_STATUS_EVENTS, + COL_NAME_PROGRAM_STATUS_ENROLLMENTS), + EVENT_STATUS(ColumnHeader.EVENT_STATUS.getItem(), COL_NAME_EVENT_STATUS), + CREATED_BY_DISPLAY_NAME(ColumnHeader.CREATED_BY_DISPLAY_NAME.getItem()), + LAST_UPDATED_BY_DISPLAY_NAME(ColumnHeader.LAST_UPDATED_BY_DISPLAY_NAME.getItem()), + LAST_UPDATED(ColumnHeader.LAST_UPDATED.getItem()); private final String itemName; diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/JdbcEventAnalyticsManager.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/JdbcEventAnalyticsManager.java index 0464afc06a7c..d15985970bb1 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/JdbcEventAnalyticsManager.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/JdbcEventAnalyticsManager.java @@ -32,8 +32,8 @@ import static org.apache.commons.lang3.time.DateUtils.addYears; import static org.hisp.dhis.analytics.DataType.BOOLEAN; import static org.hisp.dhis.analytics.DataType.NUMERIC; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_LATITUDE; -import static org.hisp.dhis.analytics.event.EventAnalyticsService.ITEM_LONGITUDE; +import static org.hisp.dhis.analytics.common.ColumnHeader.LATITUDE; +import static org.hisp.dhis.analytics.common.ColumnHeader.LONGITUDE; import static org.hisp.dhis.analytics.event.data.OrgUnitTableJoiner.joinOrgUnitTables; import static org.hisp.dhis.analytics.table.JdbcEventAnalyticsTableManager.OU_GEOMETRY_COL_SUFFIX; import static org.hisp.dhis.analytics.util.AnalyticsSqlUtils.ANALYTICS_TBL_ALIAS; @@ -169,7 +169,8 @@ private void getEvents(EventQueryParams params, Grid grid, String sql, boolean u int index = 1; for (GridHeader header : grid.getHeaders()) { - if (ITEM_LONGITUDE.equals(header.getName()) || ITEM_LATITUDE.equals(header.getName())) { + if (LONGITUDE.getItem().equals(header.getName()) + || LATITUDE.getItem().equals(header.getName())) { double val = rowSet.getDouble(index); grid.addValue(Precision.round(val, COORD_DEC)); } else { diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/JdbcAnalyticsTableManager.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/JdbcAnalyticsTableManager.java index bb20119e464d..dc98e3b9a2b0 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/JdbcAnalyticsTableManager.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/JdbcAnalyticsTableManager.java @@ -561,23 +561,23 @@ private List getValueColumns() { */ private List getOutlierStatsColumns() { return List.of( - new AnalyticsTableColumn(quote("de_uid"), CHARACTER_11, NOT_NULL, "de.uid"), - new AnalyticsTableColumn(quote("coc_uid"), CHARACTER_11, NOT_NULL, "co.uid"), - new AnalyticsTableColumn(quote("aoc_uid"), CHARACTER_11, NOT_NULL, "ao.uid"), - new AnalyticsTableColumn(quote("ou_uid"), CHARACTER_11, NOT_NULL, "ou.uid"), - new AnalyticsTableColumn(quote("dataelementid"), INTEGER, NOT_NULL, "dv.dataelementid") - .withIndexColumns(List.of(quote("dataelementid"))), + + // TODO: Do not export IDs into analytics. We work only with UIDs. new AnalyticsTableColumn(quote("sourceid"), INTEGER, NOT_NULL, "dv.sourceid"), new AnalyticsTableColumn(quote("periodid"), INTEGER, NOT_NULL, "dv.periodid"), new AnalyticsTableColumn( quote("categoryoptioncomboid"), INTEGER, NOT_NULL, "dv.categoryoptioncomboid"), new AnalyticsTableColumn( quote("attributeoptioncomboid"), INTEGER, NOT_NULL, "dv.attributeoptioncomboid"), + new AnalyticsTableColumn(quote("dataelementid"), INTEGER, NOT_NULL, "dv.dataelementid") + .withIndexColumns(List.of(quote("dataelementid"))), + + // TODO: Remove all these name columns from here. Analytics tables should not have them. new AnalyticsTableColumn(quote("de_name"), VARCHAR_255, "de.name"), new AnalyticsTableColumn(quote("ou_name"), VARCHAR_255, "ou.name"), new AnalyticsTableColumn(quote("coc_name"), VARCHAR_255, "co.name"), new AnalyticsTableColumn(quote("aoc_name"), VARCHAR_255, "ao.name"), - new AnalyticsTableColumn(quote("pt_name"), VARCHAR_255, "pt.name"), + new AnalyticsTableColumn(quote("petype"), VARCHAR_255, "pt.name"), new AnalyticsTableColumn(quote("path"), VARCHAR_255, "ou.path"), // mean new AnalyticsTableColumn(quote("avg_middle_value"), DOUBLE, "stats.avg_middle_value"), diff --git a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/analytics/common/ColumnHeader.java b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/analytics/common/ColumnHeader.java new file mode 100644 index 000000000000..342a7acc8b5f --- /dev/null +++ b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/analytics/common/ColumnHeader.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2004-2023, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.analytics.common; + +/** Keeps the association between an "item" abbreviation and its respective name. */ +public enum ColumnHeader { + TEI("tei", "Tracked entity instance"), + ENROLLMENT("pi", "Enrollment"), + GEOMETRY("geometry", "Geometry"), + ENROLLMENT_DATE("enrollmentdate", "Enrollment date"), + INCIDENT_DATE("incidentdate", "Incident date"), + STORED_BY("storedby", "Stored by"), + CREATED_BY_DISPLAY_NAME("createdbydisplayname", "Created by"), + LAST_UPDATED_BY_DISPLAY_NAME("lastupdatedbydisplayname", "Last updated by"), + LAST_UPDATED("lastupdated", "Last updated on"), + LONGITUDE("longitude", "Longitude"), + LATITUDE("latitude", "Latitude"), + ORG_UNIT_NAME("ouname", "Organisation unit name"), + ORG_UNIT_NAME_HIERARCHY("ounamehierarchy", "Organisation unit name hierarchy"), + ORG_UNIT_CODE("oucode", "Organisation unit code"), + ORG_UNIT("ou", "Organisation unit"), + PROGRAM_STATUS("programstatus", "Program status"), + EVENT("psi", "Event"), + PROGRAM_INSTANCE("pi", "Program instance"), + PROGRAM_STAGE("ps", "Program stage"), + EVENT_DATE("eventdate", "Event date"), + SCHEDULED_DATE("scheduleddate", "Scheduled date"), + COUNT("count", "Count"), + CENTER("center", "Center"), + EXTENT("extent", "Extent"), + POINTS("points", "Points"), + EVENT_STATUS("eventstatus", "Event status"), + DIMENSION("dx", "Data"), + DIMENSION_NAME("dxname", "Event status"), + PERIOD("pe", "Event status"), + CATEGORY_OPTION_COMBO("coc", "Category option combo"), + CATEGORY_OPTION_COMBO_NAME("cocname", "Category option combo name"), + ATTRIBUTE_OPTION_COMBO("aoc", "Attribute option combo"), + ATTRIBUTE_OPTION_COMBO_NAME("aocname", "Attribute option combo name"), + VALUE("value", "Value"), + MEDIAN("median", "Median"), + MEAN("mean", "Mean"), + MEDIAN_ABS_DEVIATION("medianabsdeviation", "Median absolute deviation"), + STANDARD_DEVIATION("stddev", "Standard deviation"), + ABSOLUTE_DEVIATION("absdev", "Absolute deviation"), + MODIFIED_ZSCORE("modifiedzscore", "Modified zScore"), + ZSCORE("zscore", "zScore"), + LOWER_BOUNDARY("lowerbound", "Lower boundary"), + UPPER_BOUNDARY("upperbound", "Upper boundary"); + + private final String item; + private final String name; + + ColumnHeader(String item, String name) { + this.item = item; + this.name = name; + } + + public String getItem() { + return item; + } + + public String getName() { + return name; + } +} diff --git a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/OutlierDetectionQuery.java b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/OutlierDetectionQuery.java index 46182a3a9571..2788c904a123 100644 --- a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/OutlierDetectionQuery.java +++ b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/OutlierDetectionQuery.java @@ -27,10 +27,12 @@ */ package org.hisp.dhis.outlierdetection; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.ArrayList; +import static org.hisp.dhis.outlierdetection.OutlierDetectionAlgorithm.Z_SCORE; + import java.util.Date; -import java.util.List; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; import lombok.Data; /** @@ -40,25 +42,35 @@ */ @Data public class OutlierDetectionQuery { - @JsonProperty private List ds = new ArrayList<>(); + private Set ds = new HashSet<>(); + + private Set dx = new HashSet<>(); + + private Date startDate; - @JsonProperty private List de = new ArrayList<>(); + private Date endDate; - @JsonProperty private Date startDate; + private Set ou = new HashSet<>(); - @JsonProperty private Date endDate; + private OutlierDetectionAlgorithm algorithm = Z_SCORE; - @JsonProperty private List ou = new ArrayList<>(); + private Double threshold; - @JsonProperty private OutlierDetectionAlgorithm algorithm = OutlierDetectionAlgorithm.Z_SCORE; + private Date dataStartDate; - @JsonProperty private Double threshold; + private Date dataEndDate; - @JsonProperty private Date dataStartDate; + private Order orderBy; - @JsonProperty private Date dataEndDate; + private Integer maxResults; - @JsonProperty private Order orderBy; + /** + * This parameter selects the headers to be returned in the response. We use a LinkedHashSet + * because the other matters. + */ + private Set headers = new LinkedHashSet<>(); - @JsonProperty private Integer maxResults; + public boolean hasHeaders() { + return headers != null && !headers.isEmpty(); + } } diff --git a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/parser/OutlierDetectionQueryParser.java b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/parser/OutlierDetectionQueryParser.java index f82677ef23c7..1f8be0ecd161 100644 --- a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/parser/OutlierDetectionQueryParser.java +++ b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/parser/OutlierDetectionQueryParser.java @@ -67,7 +67,7 @@ public OutlierDetectionRequest getFromQuery(OutlierDetectionQuery query) { .map(DataElement::getUid) .collect(Collectors.toList()); - de.addAll(query.getDe()); + de.addAll(query.getDx()); List dataElements = idObjectManager.getByUid(DataElement.class, de); List orgUnits = diff --git a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/processor/AnalyticsZScoreSqlStatementProcessor.java b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/processor/AnalyticsZScoreSqlStatementProcessor.java index d035a9623eeb..e1aa5e001669 100644 --- a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/processor/AnalyticsZScoreSqlStatementProcessor.java +++ b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/processor/AnalyticsZScoreSqlStatementProcessor.java @@ -27,17 +27,17 @@ */ package org.hisp.dhis.outlierdetection.processor; +import static org.apache.commons.lang3.StringUtils.EMPTY; +import static org.hisp.dhis.outlierdetection.Order.MEAN_ABS_DEV; +import static org.hisp.dhis.outlierdetection.OutlierDetectionAlgorithm.MOD_Z_SCORE; import static org.hisp.dhis.outlierdetection.OutliersSqlParamName.DATA_ELEMENT_IDS; import static org.hisp.dhis.outlierdetection.OutliersSqlParamName.END_DATE; import static org.hisp.dhis.outlierdetection.OutliersSqlParamName.MAX_RESULTS; import static org.hisp.dhis.outlierdetection.OutliersSqlParamName.START_DATE; import static org.hisp.dhis.outlierdetection.OutliersSqlParamName.THRESHOLD; -import org.apache.commons.lang3.StringUtils; -import org.hisp.dhis.outlierdetection.Order; import org.hisp.dhis.outlierdetection.OutlierDetectionAlgorithm; import org.hisp.dhis.outlierdetection.OutlierDetectionRequest; -import org.hisp.dhis.outlierdetection.OutliersSqlParamName; import org.hisp.dhis.outlierdetection.util.OutlierDetectionUtils; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.SqlParameterSource; @@ -71,39 +71,38 @@ public class AnalyticsZScoreSqlStatementProcessor implements OutlierSqlStatement @Override public String getSqlStatement(OutlierDetectionRequest request) { if (request == null) { - return StringUtils.EMPTY; + return EMPTY; } String ouPathClause = OutlierDetectionUtils.getOrgUnitPathClause(request.getOrgUnits(), "ax"); - boolean modifiedZ = request.getAlgorithm() == OutlierDetectionAlgorithm.MOD_Z_SCORE; + boolean modifiedZ = request.getAlgorithm() == MOD_Z_SCORE; String middleValue = modifiedZ ? " ax.percentile_middle_value" : " ax.avg_middle_value"; String order = - request.getOrderBy() == Order.MEAN_ABS_DEV + request.getOrderBy() == MEAN_ABS_DEV ? "middle_value_abs_dev" : request.getOrderBy().getKey(); - String thresholdParam = OutliersSqlParamName.THRESHOLD.getKey(); + String thresholdParam = THRESHOLD.getKey(); String sql = "select * from (select " - + "ax.dataelementid, " - + "ax.de_uid, " - + "ax.ou_uid, " - + "ax.coc_uid, " - + "ax.aoc_uid, " + + "ax.dx as de_uid, " + + "ax.ou as ou_uid, " + + "ax.co as coc_uid, " + + "ax.ao as aoc_uid, " + "ax.de_name, " + "ax.ou_name, " + "ax.coc_name, " + "ax.aoc_name, " + "ax.value, " + "ax.pestartdate as pe_start_date, " - + "ax.pt_name, " + + "ax.petype as pt_name, " + middleValue + " as middle_value, " - + "ax.std_dev as std_dev, " - + "ax.mad as mad, " + + "ax.std_dev, " + + "ax.mad, " + "abs(ax.value::double precision - " + middleValue + ") as middle_value_abs_dev, "; @@ -137,17 +136,14 @@ public String getSqlStatement(OutlierDetectionRequest request) { + ") " + "and " + ouPathClause - + " " - + "and ax.pestartdate >= :" + + " and ax.pestartdate >= :" + START_DATE.getKey() - + " " - + "and ax.peenddate <= :" + + " and ax.peenddate <= :" + END_DATE.getKey() + ") t1 " + "where t1.z_score > :" + thresholdParam - + " " - + "order by " + + " order by " + order + " desc " + "limit :" diff --git a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/service/AbstractOutlierDetectionManager.java b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/service/AbstractOutlierDetectionManager.java index 0e98ebe14893..71b4975c5f3f 100644 --- a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/service/AbstractOutlierDetectionManager.java +++ b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/service/AbstractOutlierDetectionManager.java @@ -27,6 +27,8 @@ */ package org.hisp.dhis.outlierdetection.service; +import static java.lang.Double.NaN; +import static org.hisp.dhis.outlierdetection.OutlierDetectionAlgorithm.MOD_Z_SCORE; import static org.hisp.dhis.outlierdetection.util.OutlierDetectionUtils.withExceptionHandling; import static org.hisp.dhis.period.PeriodType.getIsoPeriod; @@ -35,7 +37,6 @@ import java.util.List; import lombok.extern.slf4j.Slf4j; import org.hisp.dhis.calendar.Calendar; -import org.hisp.dhis.outlierdetection.OutlierDetectionAlgorithm; import org.hisp.dhis.outlierdetection.OutlierDetectionRequest; import org.hisp.dhis.outlierdetection.OutlierValue; import org.hisp.dhis.outlierdetection.processor.OutlierSqlStatementProcessor; @@ -69,11 +70,11 @@ public List getOutlierValues(OutlierDetectionRequest request) { String sql = sqlStatementProcessor.getSqlStatement(request); SqlParameterSource params = sqlStatementProcessor.getSqlParameterSource(request); Calendar calendar = PeriodType.getCalendar(); - boolean modifiedZ = request.getAlgorithm() == OutlierDetectionAlgorithm.MOD_Z_SCORE; + boolean modifiedZ = request.getAlgorithm() == MOD_Z_SCORE; return withExceptionHandling( () -> jdbcTemplate.query(sql, params, getRowMapper(calendar, modifiedZ))) - .orElse(null); + .orElse(List.of()); } /** @@ -94,10 +95,9 @@ protected abstract RowMapper getRowMapper( * @throws SQLException */ protected OutlierValue getOutlierValue(Calendar calendar, ResultSet rs) throws SQLException { - OutlierValue outlier = new OutlierValue(); - String isoPeriod = getIsoPeriod(calendar, rs.getString("pt_name"), rs.getDate("pe_start_date")); + OutlierValue outlier = new OutlierValue(); outlier.setDe(rs.getString("de_uid")); outlier.setDeName(rs.getString("de_name")); outlier.setPe(isoPeriod); @@ -129,7 +129,7 @@ protected void addZScoreBasedParamsToOutlierValue( } outlierValue.setAbsDev(rs.getDouble("middle_value_abs_dev")); - outlierValue.setZScore(outlierValue.getStdDev() == 0 ? Double.NaN : rs.getDouble("z_score")); + outlierValue.setZScore(outlierValue.getStdDev() == 0 ? NaN : rs.getDouble("z_score")); outlierValue.setLowerBound(rs.getDouble("lower_bound")); outlierValue.setUpperBound(rs.getDouble("upper_bound")); } diff --git a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/service/AnalyticsOutlierDetectionService.java b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/service/AnalyticsOutlierDetectionService.java index 4c573f97168a..07dee98e4bbe 100644 --- a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/service/AnalyticsOutlierDetectionService.java +++ b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/service/AnalyticsOutlierDetectionService.java @@ -27,17 +27,36 @@ */ package org.hisp.dhis.outlierdetection.service; +import static org.hisp.dhis.analytics.common.ColumnHeader.ABSOLUTE_DEVIATION; +import static org.hisp.dhis.analytics.common.ColumnHeader.ATTRIBUTE_OPTION_COMBO; +import static org.hisp.dhis.analytics.common.ColumnHeader.ATTRIBUTE_OPTION_COMBO_NAME; +import static org.hisp.dhis.analytics.common.ColumnHeader.CATEGORY_OPTION_COMBO; +import static org.hisp.dhis.analytics.common.ColumnHeader.CATEGORY_OPTION_COMBO_NAME; +import static org.hisp.dhis.analytics.common.ColumnHeader.DIMENSION; +import static org.hisp.dhis.analytics.common.ColumnHeader.DIMENSION_NAME; +import static org.hisp.dhis.analytics.common.ColumnHeader.LOWER_BOUNDARY; +import static org.hisp.dhis.analytics.common.ColumnHeader.MEDIAN; +import static org.hisp.dhis.analytics.common.ColumnHeader.MEDIAN_ABS_DEVIATION; +import static org.hisp.dhis.analytics.common.ColumnHeader.ORG_UNIT; +import static org.hisp.dhis.analytics.common.ColumnHeader.ORG_UNIT_NAME; +import static org.hisp.dhis.analytics.common.ColumnHeader.PERIOD; +import static org.hisp.dhis.analytics.common.ColumnHeader.STANDARD_DEVIATION; +import static org.hisp.dhis.analytics.common.ColumnHeader.UPPER_BOUNDARY; +import static org.hisp.dhis.analytics.common.ColumnHeader.VALUE; +import static org.hisp.dhis.common.ValueType.NUMBER; +import static org.hisp.dhis.common.ValueType.TEXT; +import static org.hisp.dhis.outlierdetection.OutlierDetectionAlgorithm.MOD_Z_SCORE; + import java.io.IOException; import java.io.OutputStream; import java.io.Writer; import java.util.List; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.hisp.dhis.analytics.common.ColumnHeader; import org.hisp.dhis.common.Grid; import org.hisp.dhis.common.GridHeader; import org.hisp.dhis.common.IllegalQueryException; -import org.hisp.dhis.common.ValueType; -import org.hisp.dhis.outlierdetection.OutlierDetectionAlgorithm; import org.hisp.dhis.outlierdetection.OutlierDetectionRequest; import org.hisp.dhis.outlierdetection.OutlierDetectionResponse; import org.hisp.dhis.outlierdetection.OutlierValue; @@ -125,27 +144,58 @@ public void getOutlierValuesAsHtmlCss(OutlierDetectionRequest request, Writer wr } private void setHeaders(Grid grid, OutlierDetectionRequest request) { - boolean isModifiedZScore = request.getAlgorithm() == OutlierDetectionAlgorithm.MOD_Z_SCORE; - - grid.addHeader(new GridHeader("data element", ValueType.TEXT)); - grid.addHeader(new GridHeader("data element name", ValueType.TEXT)); - grid.addHeader(new GridHeader("period", ValueType.TEXT)); - grid.addHeader(new GridHeader("organisation unit", ValueType.TEXT)); - grid.addHeader(new GridHeader("organisation unit name", ValueType.TEXT)); - grid.addHeader(new GridHeader("category option", ValueType.TEXT)); - grid.addHeader(new GridHeader("category option name", ValueType.TEXT)); - grid.addHeader(new GridHeader("attribute option", ValueType.TEXT)); - grid.addHeader(new GridHeader("attribute option name", ValueType.TEXT)); - grid.addHeader(new GridHeader("value", ValueType.NUMBER)); - grid.addHeader(new GridHeader(isModifiedZScore ? "median" : "mean", ValueType.NUMBER)); + boolean isModifiedZScore = request.getAlgorithm() == MOD_Z_SCORE; + + String meanOrMedianItem = isModifiedZScore ? MEDIAN.getItem() : ColumnHeader.MEAN.getItem(); + String meanOrMedianName = isModifiedZScore ? MEDIAN.getName() : ColumnHeader.MEAN.getName(); + + String deviationItem = + isModifiedZScore ? MEDIAN_ABS_DEVIATION.getItem() : STANDARD_DEVIATION.getItem(); + String deviationName = + isModifiedZScore ? MEDIAN_ABS_DEVIATION.getName() : STANDARD_DEVIATION.getName(); + + grid.addHeader(new GridHeader(DIMENSION.getItem(), DIMENSION.getName(), TEXT, false, false)); + grid.addHeader( + new GridHeader(DIMENSION_NAME.getItem(), DIMENSION_NAME.getName(), TEXT, false, false)); + grid.addHeader(new GridHeader(PERIOD.getItem(), PERIOD.getName(), TEXT, false, false)); + grid.addHeader(new GridHeader(ORG_UNIT.getItem(), ORG_UNIT.getName(), TEXT, false, false)); + grid.addHeader( + new GridHeader(ORG_UNIT_NAME.getItem(), ORG_UNIT_NAME.getName(), TEXT, false, false)); + grid.addHeader( + new GridHeader( + CATEGORY_OPTION_COMBO.getItem(), CATEGORY_OPTION_COMBO.getName(), TEXT, false, false)); grid.addHeader( new GridHeader( - isModifiedZScore ? "median absolute deviation" : "stdDev", ValueType.NUMBER)); - grid.addHeader(new GridHeader("absDev", ValueType.NUMBER)); + CATEGORY_OPTION_COMBO_NAME.getItem(), + CATEGORY_OPTION_COMBO_NAME.getName(), + TEXT, + false, + false)); + grid.addHeader( + new GridHeader( + ATTRIBUTE_OPTION_COMBO.getItem(), + ATTRIBUTE_OPTION_COMBO.getName(), + TEXT, + false, + false)); + grid.addHeader( + new GridHeader( + ATTRIBUTE_OPTION_COMBO_NAME.getItem(), + ATTRIBUTE_OPTION_COMBO_NAME.getName(), + TEXT, + false, + false)); + grid.addHeader(new GridHeader(VALUE.getItem(), VALUE.getName(), NUMBER, false, false)); + grid.addHeader(new GridHeader(meanOrMedianItem, meanOrMedianName, NUMBER, false, false)); + grid.addHeader(new GridHeader(deviationItem, deviationName, NUMBER, false, false)); + grid.addHeader( + new GridHeader( + ABSOLUTE_DEVIATION.getItem(), ABSOLUTE_DEVIATION.getName(), NUMBER, false, false)); + grid.addHeader(new GridHeader(isModifiedZScore ? "modifiedzscore" : "zscore", NUMBER)); + grid.addHeader( + new GridHeader(LOWER_BOUNDARY.getItem(), LOWER_BOUNDARY.getName(), NUMBER, false, false)); grid.addHeader( - new GridHeader(isModifiedZScore ? "modified zScore" : "zScore", ValueType.NUMBER)); - grid.addHeader(new GridHeader("lowerBound", ValueType.NUMBER)); - grid.addHeader(new GridHeader("upperBound", ValueType.NUMBER)); + new GridHeader(UPPER_BOUNDARY.getItem(), UPPER_BOUNDARY.getName(), NUMBER, false, false)); } private void setMetaData( @@ -161,8 +211,7 @@ private void setRows( Grid grid, List outlierValues, OutlierDetectionRequest request) { outlierValues.forEach( v -> { - boolean isModifiedZScore = - request.getAlgorithm() == OutlierDetectionAlgorithm.MOD_Z_SCORE; + boolean isModifiedZScore = request.getAlgorithm() == MOD_Z_SCORE; grid.addRow(); grid.addValue(v.getDe()); grid.addValue(v.getDeName()); diff --git a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/service/AnalyticsZScoreOutlierDetectionManager.java b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/service/AnalyticsZScoreOutlierDetectionManager.java index d7995caf8074..a7dd7a8a25dd 100644 --- a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/service/AnalyticsZScoreOutlierDetectionManager.java +++ b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/service/AnalyticsZScoreOutlierDetectionManager.java @@ -76,7 +76,7 @@ protected void addZScoreBasedParamsToOutlierValue( if (modifiedZ) { outlierValue.setStdDev(rs.getDouble("mad")); } else { - outlierValue.setStdDev(rs.getDouble("std_dev")); + outlierValue.setStdDev(rs.getDouble("stddev")); } super.addZScoreBasedParamsToOutlierValue(outlierValue, rs, modifiedZ); diff --git a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/util/OutlierDetectionUtils.java b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/util/OutlierDetectionUtils.java index 77b3feb6de77..a6e9c6321960 100644 --- a/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/util/OutlierDetectionUtils.java +++ b/dhis-2/dhis-services/dhis-service-validation/src/main/java/org/hisp/dhis/outlierdetection/util/OutlierDetectionUtils.java @@ -29,6 +29,8 @@ import static org.hisp.dhis.feedback.ErrorCode.E2208; import static org.hisp.dhis.feedback.ErrorCode.E7131; +import static org.hisp.dhis.util.SqlExceptionUtils.ERR_MSG_SILENT_FALLBACK; +import static org.hisp.dhis.util.SqlExceptionUtils.ERR_MSG_TABLE_NOT_EXISTING; import static org.hisp.dhis.util.SqlExceptionUtils.relationDoesNotExist; import java.util.List; @@ -39,9 +41,7 @@ import org.hisp.dhis.common.IllegalQueryException; import org.hisp.dhis.common.QueryRuntimeException; import org.hisp.dhis.commons.util.TextUtils; -import org.hisp.dhis.feedback.ErrorCode; import org.hisp.dhis.organisationunit.OrganisationUnit; -import org.hisp.dhis.util.SqlExceptionUtils; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.jdbc.BadSqlGrammarException; @@ -80,21 +80,21 @@ public static Optional withExceptionHandling(Supplier supplier) { return Optional.ofNullable(supplier.get()); } catch (BadSqlGrammarException ex) { if (relationDoesNotExist(ex.getSQLException())) { - log.info(SqlExceptionUtils.ERR_MSG_TABLE_NOT_EXISTING, ex); + log.info(ERR_MSG_TABLE_NOT_EXISTING, ex); + throw ex; + } else { + log.info(ERR_MSG_SILENT_FALLBACK, ex); throw ex; } - log.info(SqlExceptionUtils.ERR_MSG_SILENT_FALLBACK, ex); } catch (QueryRuntimeException ex) { log.error("Internal runtime exception", ex); throw ex; } catch (DataIntegrityViolationException ex) { log.error(E2208.getMessage(), ex); - throw new IllegalQueryException(ErrorCode.E2208); + throw new IllegalQueryException(E2208); } catch (DataAccessResourceFailureException ex) { log.error(E7131.getMessage(), ex); throw new QueryRuntimeException(E7131); } - - return Optional.empty(); } } diff --git a/dhis-2/dhis-services/dhis-service-validation/src/test/java/org/hisp/dhis/outlierdetection/processor/AnalyticsZscoreSqlStatementProcessorTest.java b/dhis-2/dhis-services/dhis-service-validation/src/test/java/org/hisp/dhis/outlierdetection/processor/AnalyticsZscoreSqlStatementProcessorTest.java index 5f685a6e1d72..711013d15d41 100644 --- a/dhis-2/dhis-services/dhis-service-validation/src/test/java/org/hisp/dhis/outlierdetection/processor/AnalyticsZscoreSqlStatementProcessorTest.java +++ b/dhis-2/dhis-services/dhis-service-validation/src/test/java/org/hisp/dhis/outlierdetection/processor/AnalyticsZscoreSqlStatementProcessorTest.java @@ -83,7 +83,7 @@ void testGetSqlStatement() { .build(); String sql = subject.getSqlStatement(request); String expected = - "select * from (select ax.dataelementid, ax.de_uid, ax.ou_uid, ax.coc_uid, ax.aoc_uid, ax.de_name, ax.ou_name, ax.coc_name, ax.aoc_name, ax.value, ax.pestartdate as pe_start_date, ax.pt_name, ax.avg_middle_value as middle_value, ax.std_dev as std_dev, ax.mad as mad, abs(ax.value::double precision - ax.avg_middle_value) as middle_value_abs_dev, (case when ax.std_dev = 0 then 0 else abs(ax.value::double precision - ax.avg_middle_value ) / ax.std_dev end) as z_score, ax.avg_middle_value - (ax.std_dev * :threshold) as lower_bound, ax.avg_middle_value + (ax.std_dev * :threshold) as upper_bound from analytics ax where dataelementid in (:data_element_ids) and (ax.\"path\" like '/ouabcdefghA%' or ax.\"path\" like '/ouabcdefghB%') and ax.pestartdate >= :start_date and ax.peenddate <= :end_date) t1 where t1.z_score > :threshold order by middle_value_abs_dev desc limit :max_results "; + "select * from (select ax.dx as de_uid, ax.ou as ou_uid, ax.co as coc_uid, ax.ao as aoc_uid, ax.de_name, ax.ou_name, ax.coc_name, ax.aoc_name, ax.value, ax.pestartdate as pe_start_date, ax.petype as pt_name, ax.avg_middle_value as middle_value, ax.std_dev, ax.mad, abs(ax.value::double precision - ax.avg_middle_value) as middle_value_abs_dev, (case when ax.std_dev = 0 then 0 else abs(ax.value::double precision - ax.avg_middle_value ) / ax.std_dev end) as z_score, ax.avg_middle_value - (ax.std_dev * :threshold) as lower_bound, ax.avg_middle_value + (ax.std_dev * :threshold) as upper_bound from analytics ax where dataelementid in (:data_element_ids) and (ax.\"path\" like '/ouabcdefghA%' or ax.\"path\" like '/ouabcdefghB%') and ax.pestartdate >= :start_date and ax.peenddate <= :end_date) t1 where t1.z_score > :threshold order by middle_value_abs_dev desc limit :max_results "; assertEquals(expected, sql); } diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/outlierdetection/service/OutlierDetectionServiceMinMaxTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/outlierdetection/service/OutlierDetectionServiceMinMaxTest.java index 9d0c978f3d4c..4e09a5ac3a55 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/outlierdetection/service/OutlierDetectionServiceMinMaxTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/outlierdetection/service/OutlierDetectionServiceMinMaxTest.java @@ -31,6 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import com.google.common.collect.Lists; +import java.util.Set; import java.util.stream.Stream; import org.hisp.dhis.analytics.AggregationType; import org.hisp.dhis.category.CategoryOptionCombo; @@ -117,10 +118,10 @@ public void setUpTest() { @Test void testGetFromQuery() { OutlierDetectionQuery query = new OutlierDetectionQuery(); - query.setDe(Lists.newArrayList("deabcdefghA", "deabcdefghB")); + query.setDx(Set.of("deabcdefghA", "deabcdefghB")); query.setStartDate(getDate(2020, 1, 1)); query.setEndDate(getDate(2020, 6, 1)); - query.setOu(Lists.newArrayList("ouabcdefghA", "ouabcdefghB")); + query.setOu(Set.of("ouabcdefghA", "ouabcdefghB")); query.setAlgorithm(OutlierDetectionAlgorithm.MIN_MAX); query.setMaxResults(200); OutlierDetectionRequest request = parser.getFromQuery(query); diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/outlierdetection/service/OutlierDetectionServiceModifiedZScoreTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/outlierdetection/service/OutlierDetectionServiceModifiedZScoreTest.java index 70ea1c810204..22b3a8d55e1f 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/outlierdetection/service/OutlierDetectionServiceModifiedZScoreTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/outlierdetection/service/OutlierDetectionServiceModifiedZScoreTest.java @@ -39,6 +39,7 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; +import java.util.Set; import java.util.stream.Stream; import org.hisp.dhis.analytics.AggregationType; import org.hisp.dhis.category.CategoryOptionCombo; @@ -120,10 +121,10 @@ public void setUpTest() { @Test void testGetFromQuery() { OutlierDetectionQuery query = new OutlierDetectionQuery(); - query.setDe(List.of("deabcdefghA", "deabcdefghB")); + query.setDx(Set.of("deabcdefghA", "deabcdefghB")); query.setStartDate(getDate(2020, 1, 1)); query.setEndDate(getDate(2020, 6, 1)); - query.setOu(List.of("ouabcdefghA", "ouabcdefghB")); + query.setOu(Set.of("ouabcdefghA", "ouabcdefghB")); query.setAlgorithm(OutlierDetectionAlgorithm.MOD_Z_SCORE); query.setThreshold(2.5); query.setMaxResults(100); diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/outlierdetection/service/OutlierDetectionServiceZScoreTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/outlierdetection/service/OutlierDetectionServiceZScoreTest.java index 5b99f36ffaf3..b4d37c4a6d0e 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/outlierdetection/service/OutlierDetectionServiceZScoreTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/outlierdetection/service/OutlierDetectionServiceZScoreTest.java @@ -37,6 +37,7 @@ import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.Set; import java.util.stream.Stream; import org.hisp.dhis.analytics.AggregationType; import org.hisp.dhis.category.CategoryOptionCombo; @@ -121,10 +122,10 @@ public void setUpTest() { @Test void testGetFromQuery() { OutlierDetectionQuery query = new OutlierDetectionQuery(); - query.setDe(List.of("deabcdefghA", "deabcdefghB")); + query.setDx(Set.of("deabcdefghA", "deabcdefghB")); query.setStartDate(getDate(2020, 1, 1)); query.setEndDate(getDate(2020, 6, 1)); - query.setOu(List.of("ouabcdefghA", "ouabcdefghB")); + query.setOu(Set.of("ouabcdefghA", "ouabcdefghB")); query.setAlgorithm(OutlierDetectionAlgorithm.Z_SCORE); query.setThreshold(2.5); query.setMaxResults(100); diff --git a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/outlierdetection/AnalyticsOutlierDetectionController.java b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/outlierdetection/AnalyticsOutlierDetectionController.java index fa858238eee2..e590ecd804ae 100644 --- a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/outlierdetection/AnalyticsOutlierDetectionController.java +++ b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/outlierdetection/AnalyticsOutlierDetectionController.java @@ -27,6 +27,7 @@ */ package org.hisp.dhis.webapi.controller.outlierdetection; +import static org.hisp.dhis.common.cache.CacheStrategy.NO_CACHE; import static org.hisp.dhis.webapi.utils.ContextUtils.CONTENT_TYPE_CSV; import static org.hisp.dhis.webapi.utils.ContextUtils.CONTENT_TYPE_EXCEL; import static org.hisp.dhis.webapi.utils.ContextUtils.CONTENT_TYPE_HTML; @@ -39,7 +40,6 @@ import org.hisp.dhis.common.DhisApiVersion; import org.hisp.dhis.common.Grid; import org.hisp.dhis.common.OpenApi; -import org.hisp.dhis.common.cache.CacheStrategy; import org.hisp.dhis.outlierdetection.OutlierDetectionQuery; import org.hisp.dhis.outlierdetection.OutlierDetectionRequest; import org.hisp.dhis.outlierdetection.parser.OutlierDetectionQueryParser; @@ -72,15 +72,20 @@ public class AnalyticsOutlierDetectionController { public Grid getOutliersJson(OutlierDetectionQuery query) { OutlierDetectionRequest request = getFromQuery(query); - return outlierService.getOutlierValues(request); + Grid grid = outlierService.getOutlierValues(request); + + if (query.hasHeaders()) { + grid.retainColumns(query.getHeaders()); + } + + return grid; } @GetMapping(value = RESOURCE_PATH + ".csv") public void getOutliersCsv(OutlierDetectionQuery query, HttpServletResponse response) throws IOException { OutlierDetectionRequest request = getFromQuery(query); - contextUtils.configureResponse( - response, CONTENT_TYPE_CSV, CacheStrategy.NO_CACHE, "outlierdata.csv", true); + contextUtils.configureResponse(response, CONTENT_TYPE_CSV, NO_CACHE, "outlierdata.csv", true); outlierService.getOutlierValuesAsCsv(request, response.getWriter()); } @@ -89,7 +94,7 @@ public void getOutliersCsv(OutlierDetectionQuery query, HttpServletResponse resp public void getOutliersXml(OutlierDetectionQuery query, HttpServletResponse response) throws IOException { OutlierDetectionRequest request = getFromQuery(query); - contextUtils.configureResponse(response, CONTENT_TYPE_XML, CacheStrategy.NO_CACHE); + contextUtils.configureResponse(response, CONTENT_TYPE_XML, NO_CACHE); outlierService.getOutlierValuesAsXml(request, response.getOutputStream()); } @@ -98,8 +103,7 @@ public void getOutliersXml(OutlierDetectionQuery query, HttpServletResponse resp public void getOutliersXls(OutlierDetectionQuery query, HttpServletResponse response) throws IOException { OutlierDetectionRequest request = getFromQuery(query); - contextUtils.configureResponse( - response, CONTENT_TYPE_EXCEL, CacheStrategy.NO_CACHE, "outlierdata.xls", true); + contextUtils.configureResponse(response, CONTENT_TYPE_EXCEL, NO_CACHE, "outlierdata.xls", true); outlierService.getOutlierValuesAsXls(request, response.getOutputStream()); } @@ -109,7 +113,7 @@ public void getOutliersHtml(OutlierDetectionQuery query, HttpServletResponse res throws IOException { OutlierDetectionRequest request = getFromQuery(query); - contextUtils.configureResponse(response, CONTENT_TYPE_HTML, CacheStrategy.NO_CACHE); + contextUtils.configureResponse(response, CONTENT_TYPE_HTML, NO_CACHE); outlierService.getOutlierValuesAsHtml(request, response.getWriter()); } @@ -118,7 +122,7 @@ public void getOutliersHtml(OutlierDetectionQuery query, HttpServletResponse res public void getOutliersHtmlCss(OutlierDetectionQuery query, HttpServletResponse response) throws IOException { OutlierDetectionRequest request = getFromQuery(query); - contextUtils.configureResponse(response, CONTENT_TYPE_HTML, CacheStrategy.NO_CACHE); + contextUtils.configureResponse(response, CONTENT_TYPE_HTML, NO_CACHE); outlierService.getOutlierValuesAsHtmlCss(request, response.getWriter()); }