diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/event/JdbcEventStore.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/event/JdbcEventStore.java index af893a197e50..6c3bc2583546 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/event/JdbcEventStore.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/event/JdbcEventStore.java @@ -159,18 +159,18 @@ class JdbcEventStore implements EventStore { private static final String COLUMN_PROGRAM_UID = "p_uid"; private static final String COLUMN_PROGRAM_CODE = "p_code"; private static final String COLUMN_PROGRAM_NAME = "p_name"; - private static final String COLUMN_PROGRAM_ATTRIBUTE_VALUES = "p_attribute_values"; + private static final String COLUMN_PROGRAM_ATTRIBUTE_VALUES = "p_attributevalues"; private static final String COLUMN_PROGRAM_STAGE_UID = "ps_uid"; private static final String COLUMN_PROGRAM_STAGE_CODE = "ps_code"; private static final String COLUMN_PROGRAM_STAGE_NAME = "ps_name"; - private static final String COLUMN_PROGRAM_STAGE_ATTRIBUTE_VALUES = "ps_attribute_values"; + private static final String COLUMN_PROGRAM_STAGE_ATTRIBUTE_VALUES = "ps_attributevalues"; private static final String COLUMN_ENROLLMENT_UID = "en_uid"; private static final String COLUMN_ENROLLMENT_STATUS = "en_status"; private static final String COLUMN_ENROLLMENT_DATE = "en_enrollmentdate"; private static final String COLUMN_ORG_UNIT_UID = "orgunit_uid"; private static final String COLUMN_ORG_UNIT_CODE = "orgunit_code"; private static final String COLUMN_ORG_UNIT_NAME = "orgunit_name"; - private static final String COLUMN_ORG_UNIT_ATTRIBUTE_VALUES = "orgunit_attribute_values"; + private static final String COLUMN_ORG_UNIT_ATTRIBUTE_VALUES = "orgunit_attributevalues"; private static final String COLUMN_TRACKEDENTITY_UID = "te_uid"; private static final String COLUMN_EVENT_OCCURRED_DATE = "ev_occurreddate"; private static final String COLUMN_ENROLLMENT_FOLLOWUP = "en_followup"; @@ -185,13 +185,17 @@ class JdbcEventStore implements EventStore { private static final String COLUMN_EVENT_LAST_UPDATED_AT_CLIENT = "ev_lastupdatedatclient"; private static final String COLUMN_EVENT_COMPLETED_BY = "ev_completedby"; private static final String COLUMN_EVENT_ATTRIBUTE_OPTION_COMBO_UID = "coc_uid"; + private static final String COLUMN_EVENT_ATTRIBUTE_OPTION_COMBO_NAME = "coc_name"; + private static final String COLUMN_EVENT_ATTRIBUTE_OPTION_COMBO_CODE = "coc_code"; + private static final String COLUMN_EVENT_ATTRIBUTE_OPTION_COMBO_ATTRIBUTE_VALUES = + "coc_attributevalues"; private static final String COLUMN_EVENT_COMPLETED_DATE = "ev_completeddate"; private static final String COLUMN_EVENT_DELETED = "ev_deleted"; private static final String COLUMN_EVENT_ASSIGNED_USER_USERNAME = "user_assigned_username"; private static final String COLUMN_EVENT_ASSIGNED_USER_DISPLAY_NAME = "user_assigned_name"; private static final String COLUMN_USER_UID = "u_uid"; - private static final String COLUMN_ORG_UNIT_PATH = "ou_path"; private static final String DEFAULT_ORDER = COLUMN_EVENT_ID + " desc"; + private static final String COLUMN_ORG_UNIT_PATH = "ou_path"; private static final String USER_SCOPE_ORG_UNIT_PATH_LIKE_MATCH_QUERY = " ou.path like CONCAT(orgunit.path, '%') "; private static final String CUSTOM_ORG_UNIT_PATH_LIKE_MATCH_QUERY = @@ -340,6 +344,11 @@ private List fetchEvents(EventQueryParams queryParams, PageParams pagePar CategoryOptionCombo coc = new CategoryOptionCombo(); coc.setUid(resultSet.getString(COLUMN_EVENT_ATTRIBUTE_OPTION_COMBO_UID)); + coc.setCode(resultSet.getString(COLUMN_EVENT_ATTRIBUTE_OPTION_COMBO_CODE)); + coc.setName(resultSet.getString(COLUMN_EVENT_ATTRIBUTE_OPTION_COMBO_NAME)); + coc.setAttributeValues( + AttributeValues.of( + resultSet.getString(COLUMN_EVENT_ATTRIBUTE_OPTION_COMBO_ATTRIBUTE_VALUES))); Set options = Arrays.stream(resultSet.getString("co_uids").split(TextUtils.COMMA)) .map( @@ -754,12 +763,15 @@ private String getEventSelectQuery( "au.firstName as user_assigned_first_name, au.surName as user_assigned_surname, ") .append("au.username as ") .append(COLUMN_EVENT_ASSIGNED_USER_USERNAME) - .append(",") - .append("coc_agg.uid as ") + .append(", coc_agg.uid as ") .append(COLUMN_EVENT_ATTRIBUTE_OPTION_COMBO_UID) - .append(", ") - .append("coc_agg.co_uids AS co_uids, ") - .append("coc_agg.co_count AS option_size, "); + .append(", coc_agg.code as ") + .append(COLUMN_EVENT_ATTRIBUTE_OPTION_COMBO_CODE) + .append(", coc_agg.name as ") + .append(COLUMN_EVENT_ATTRIBUTE_OPTION_COMBO_NAME) + .append(", coc_agg.attributevalues as ") + .append(COLUMN_EVENT_ATTRIBUTE_OPTION_COMBO_ATTRIBUTE_VALUES) + .append(", coc_agg.co_uids AS co_uids, coc_agg.co_count AS option_size, "); for (Order order : params.getOrder()) { if (order.getField() instanceof TrackedEntityAttribute tea) @@ -1447,13 +1459,13 @@ private String addLastUpdatedFilters( private String getCategoryOptionComboQuery(User user) { String joinCondition = """ - inner join (select coc.uid, coc.attributevalues, coc.code, coc.categoryoptioncomboid as\ - id, string_agg(co.uid, ',') as co_uids, count(co.categoryoptionid) as co_count from\ - categoryoptioncombo coc inner join categoryoptioncombos_categoryoptions cocco on\ - coc.categoryoptioncomboid = cocco.categoryoptioncomboid inner join categoryoption\ - co on cocco.categoryoptionid = co.categoryoptionid group by\ - coc.categoryoptioncomboid \ - """; + inner join (select coc.uid, coc.code, coc.name, coc.attributevalues, coc.categoryoptioncomboid as\ + id, string_agg(co.uid, ',') as co_uids, count(co.categoryoptionid) as co_count from\ + categoryoptioncombo coc inner join categoryoptioncombos_categoryoptions cocco on\ + coc.categoryoptioncomboid = cocco.categoryoptioncomboid inner join categoryoption\ + co on cocco.categoryoptionid = co.categoryoptionid group by\ + coc.categoryoptioncomboid \ +"""; if (!isSuper(user)) { joinCondition = diff --git a/dhis-2/dhis-support/dhis-support-test/src/main/resources/tracker/simple_metadata.json b/dhis-2/dhis-support/dhis-support-test/src/main/resources/tracker/simple_metadata.json index be855cb062ec..484f971828e8 100644 --- a/dhis-2/dhis-support/dhis-support-test/src/main/resources/tracker/simple_metadata.json +++ b/dhis-2/dhis-support/dhis-support-test/src/main/resources/tracker/simple_metadata.json @@ -5,7 +5,7 @@ "categoryOptionAttribute": true, "categoryOptionComboAttribute": true, "dataElementAttribute": true, - "name": "some attribute", + "name": "idScheme related attribute", "organisationUnitAttribute": true, "programAttribute": true, "programStageAttribute": true, @@ -221,6 +221,14 @@ }, { "id": "SeWJkpLAyLt", + "attributeValues": [ + { + "attribute": { + "id": "j45AR9cBQKc" + }, + "value": "categoryOptionCombo SeWJkpLAyLt" + } + ], "categoryCombo": { "id": "O4VaNks6tta" }, @@ -672,21 +680,21 @@ "attribute": { "id": "j45AR9cBQKc" }, - "value": "multi-org-attribute" + "value": "orgUnit DiszpKrYNg8" } ], - "code": "org3", + "code": "DiszpKrYNg8 code", "created": "2020-05-31T08:56:15.922", - "description": "test-orgunit-3", + "description": "DiszpKrYNg8 description", "lastUpdated": "2020-05-31T11:41:22.384", "lastUpdatedBy": { "id": "tTgjgobT1oS" }, "level": 1, - "name": "test-orgunit-3", + "name": "DiszpKrYNg8 name", "openingDate": "2020-05-31T00:00:00.000", "path": "/DiszpKrYNg8", - "shortName": "test-orgunit-3", + "shortName": "DiszpKrYNg8 shortName", "user": { "id": "tTgjgobT1oS" } @@ -1009,7 +1017,7 @@ "attribute": { "id": "j45AR9cBQKc" }, - "value": "multi-program-stage-attribute" + "value": "programStage qLZC0lvvxQH" } ], "autoGenerateEvent": true, @@ -1421,13 +1429,13 @@ "attribute": { "id": "j45AR9cBQKc" }, - "value": "multi-program-attribute" + "value": "program iS7eutanDry" } ], "categoryCombo": { "id": "O4VaNks6tta" }, - "code": "multi-program", + "code": "iS7eutanDry code", "completeEventsExpiryDays": 0, "created": "2022-04-22T05:57:48.409", "displayIncidentDate": true, diff --git a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/IdSchemeExportControllerTest.java b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/IdSchemeExportControllerTest.java index 3933c871e30a..8ddfe11406e9 100644 --- a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/IdSchemeExportControllerTest.java +++ b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/IdSchemeExportControllerTest.java @@ -42,6 +42,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.hisp.dhis.attribute.Attribute; +import org.hisp.dhis.category.CategoryOptionCombo; import org.hisp.dhis.common.IdentifiableObject; import org.hisp.dhis.common.IdentifiableObjectManager; import org.hisp.dhis.dxf2.metadata.objectbundle.ObjectBundle; @@ -98,6 +99,7 @@ class IdSchemeExportControllerTest extends PostgresControllerIntegrationTestBase private OrganisationUnit orgUnit; private ProgramStage programStage; private Program program; + private CategoryOptionCombo categoryOptionCombo; private User importUser; @@ -130,9 +132,10 @@ void setUp() throws IOException { assertNoErrors( trackerImportService.importTracker(params, fromJson("tracker/event_and_enrollment.json"))); get(Attribute.class, METADATA_ATTRIBUTE); // ensure this is created in setup - orgUnit = get(OrganisationUnit.class, "h4w96yEMlzO"); - program = get(Program.class, "BFcipDERJnf"); - programStage = get(ProgramStage.class, "NpsdDv6kKSO"); + orgUnit = get(OrganisationUnit.class, "DiszpKrYNg8"); + program = get(Program.class, "iS7eutanDry"); + programStage = get(ProgramStage.class, "qLZC0lvvxQH"); + categoryOptionCombo = get(CategoryOptionCombo.class, "SeWJkpLAyLt"); manager.flush(); manager.clear(); @@ -143,20 +146,39 @@ void setUp() throws IOException { void shouldExportMetadataUsingGivenIdScheme(TrackerIdSchemeParam idSchemeParam) { switchContextToUser(importUser); + // maps JSON fields to idScheme request parameters + Map idSchemeRequestParams = + Map.of( + "orgUnit", + "orgUnit", + "program", + "program", + "programStage", + "programStage", + "attributeOptionCombo", + "categoryOptionCombo"); // maps JSON fields to metadata Map metadata = - Map.of("orgUnit", orgUnit, "program", program, "programStage", programStage); + Map.of( + "orgUnit", + orgUnit, + "program", + program, + "programStage", + programStage, + "attributeOptionCombo", + categoryOptionCombo); String fields = metadata.keySet().stream().collect(Collectors.joining(",")); String idSchemes = metadata.keySet().stream() - .map(m -> m + "IdScheme=" + idSchemeParam) + .map(m -> idSchemeRequestParams.get(m) + "IdScheme=" + idSchemeParam) .collect(Collectors.joining("&")); - Event d9PbzJY8bJM = get(Event.class, "D9PbzJY8bJM"); + Event qRYjLTiJTrA = get(Event.class, "QRYjLTiJTrA"); JsonEvent actual = GET( "/tracker/events/{id}?fields={fields}&{idSchemes}", - d9PbzJY8bJM.getUid(), + qRYjLTiJTrA.getUid(), fields, idSchemes) .content(HttpStatus.OK) diff --git a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/trackedentity/TrackedEntitiesExportControllerPostgresTest.java b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/trackedentity/TrackedEntitiesExportControllerPostgresTest.java index c6e83aa1c9fe..8dff7f95e871 100644 --- a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/trackedentity/TrackedEntitiesExportControllerPostgresTest.java +++ b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/trackedentity/TrackedEntitiesExportControllerPostgresTest.java @@ -96,7 +96,7 @@ class TrackedEntitiesExportControllerPostgresTest extends PostgresControllerInte @BeforeEach void setUp() throws IOException { this.renderService = _renderService; - setUpMetadata("tracker/simple_metadata_changelog.json"); + setUpMetadata("tracker/simple_metadata.json"); User importUser = userService.getUser("tTgjgobT1oS"); injectSecurityContextUser(importUser); diff --git a/dhis-2/dhis-test-web-api/src/test/resources/tracker/simple_metadata_changelog.json b/dhis-2/dhis-test-web-api/src/test/resources/tracker/simple_metadata_changelog.json deleted file mode 100644 index 1fe668a7a40c..000000000000 --- a/dhis-2/dhis-test-web-api/src/test/resources/tracker/simple_metadata_changelog.json +++ /dev/null @@ -1,216 +0,0 @@ -{ - "attributes": [ - { - "id": "j45AR9cBQKc", - "name": "some attribute", - "sharing": { - "owner": "PQD6wXJ2r5j", - "public": "rw------" - }, - "valueType": "TEXT", - "mandatory": false, - "unique": true, - "programAttribute": true, - "programStageAttribute": true, - "trackedEntityTypeAttribute": true, - "trackedEntityAttributeAttribute": true, - "organisationUnitAttribute": true, - "dataElementAttribute": true, - "relationshipTypeAttribute": true, - "categoryOptionAttribute": true, - "categoryOptionComboAttribute": true - } - ], - "trackedEntityTypes": [ - { - "name": "Person", - "id": "ja8NY4PW7Xm", - "publicAccess": "rw------", - "description": "person", - "maxTeiCountToReturn": 0, - "allowAuditLog": true, - "featureType": "NONE", - "minAttributesRequiredToSearch": 1, - "user": { - "id": "tTgjgobT1oS" - }, - "sharing": { - "external": false, - "public": "rwrw----" - }, - "trackedEntityTypeAttributes": [ - { - "displayInList": true, - "displayName": "Person Given name", - "displayShortName": "null Given name", - "externalAccess": false, - "favorite": false, - "favorites": [], - "id": "hKZ9AJpnVcG", - "name": "Person Given name", - "searchable": true, - "trackedEntityAttribute": { - "id": "numericAttr" - }, - "trackedEntityType": { - "id": "ja8NY4PW7Xm" - }, - "valueType": "TEXT" - } - ] - }, - { - "name": "Inaccessible person", - "id": "Ip8NY4PW7Xm", - "publicAccess": "rw------", - "description": "person", - "maxTeiCountToReturn": 0, - "allowAuditLog": false, - "featureType": "NONE", - "minAttributesRequiredToSearch": 1, - "user": { - "id": "tTgjgobT1oS" - }, - "sharing": { - "external": false, - "public": "--------" - } - } - ], - "users": [ - { - "code": "tracker admin", - "id": "tTgjgobT1oS", - "password": "Test123###...", - "surname": "tracker Surnameadmin", - "firstName": "tracker FirstNameadmin", - "name": "tracker admin", - "lastLogin": "2020-05-31T08:55:38.571", - "displayName": "tracker admin", - "externalAuth": false, - "externalAccess": false, - "disabled": false, - "twoFA": false, - "passwordLastUpdated": "2020-05-31T08:55:28.232", - "invitation": false, - "selfRegistered": false, - "favorite": false, - "username": "trackeradmin", - "access": { - "read": true, - "update": true, - "externalize": true, - "delete": true, - "write": true, - "manage": true - }, - "userRoles": [ - { - "id": "nJ4Ml8ads4M" - } - ], - "teiSearchOrganisationUnits": [ - { - "id": "h4w96yEMlzO" - } - ], - "organisationUnits": [ - { - "id": "h4w96yEMlzO" - } - ] - } - ], - "organisationUnits": [ - { - "id": "h4w96yEMlzO", - "name": "test-orgunit", - "code": "test-orgunit-code", - "level": 1, - "publicAccess": "rwrw----", - "shortName": "test-orgunit", - "description": "test-orgunit", - "path": "/h4w96yEMlzO", - "openingDate": "2020-05-31T00:00:00.000", - "user": { - "id": "tTgjgobT1oS" - } - } - ], - "programs": [ - { - "id": "BFcipDERJnf", - "name": "test-program", - "shortName": "test-program", - "publicAccess": "rwrw----", - "completeEventsExpiryDays": 0, - "ignoreOverdueEvents": false, - "skipOffline": false, - "minAttributesRequiredToSearch": 1, - "displayFrontPageList": false, - "onlyEnrollOnce": false, - "programType": "WITH_REGISTRATION", - "accessLevel": "OPEN", - "version": 2, - "maxTeiCountToReturn": 0, - "selectIncidentDatesInFuture": false, - "displayIncidentDate": true, - "selectEnrollmentDatesInFuture": false, - "expiryDays": 0, - "useFirstStageDuringRegistration": false, - "categoryCombo": { - "id": "bjDvmb4bfuf" - }, - "trackedEntityType": { - "id": "ja8NY4PW7Xm" - }, - "user": { - "id": "tTgjgobT1oS" - }, - "organisationUnits": [ - { - "id": "h4w96yEMlzO" - } - ] - } - ], - "userRoles": [ - { - "code": "tracker Superuser", - "name": "tracker Superuser", - "id": "nJ4Ml8ads4M", - "publicAccess": "--------", - "description": "tracker Superuser", - "user": { - "id": "tTgjgobT1oS" - }, - "authorities": [ - "F_TRACKED_ENTITY_INSTANCE_SEARCH_IN_ALL_ORGUNITS", - "ALL" - ] - } - ], - "trackedEntityAttributes": [ - { - "id": "numericAttr", - "name": "numeric-attribute", - "shortName": "numeric-attribute", - "aggregationType": "NONE", - "displayInListNoProgram": false, - "publicAccess": "rw------", - "pattern": "", - "skipSynchronization": false, - "generated": false, - "displayOnVisitSchedule": false, - "valueType": "INTEGER", - "formName": "numeric-attribute", - "orgunitScope": false, - "confidential": false, - "unique": false, - "inherit": false, - "user": { - "id": "tTgjgobT1oS" - } - } - ] -} \ No newline at end of file diff --git a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/tracker/export/MetadataMapper.java b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/tracker/export/MetadataMapper.java index 8461f7bce2bf..e202a52af525 100644 --- a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/tracker/export/MetadataMapper.java +++ b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/tracker/export/MetadataMapper.java @@ -27,6 +27,7 @@ */ package org.hisp.dhis.webapi.controller.tracker.export; +import org.hisp.dhis.category.CategoryOptionCombo; import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.program.Program; import org.hisp.dhis.program.ProgramStage; @@ -52,4 +53,10 @@ default String map(ProgramStage programStage, @Context TrackerIdSchemeParams idS default String map(OrganisationUnit orgUnit, @Context TrackerIdSchemeParams idSchemeParams) { return idSchemeParams.getOrgUnitIdScheme().getIdentifier(orgUnit); } + + @Named("categoryOptionComboToString") + default String map( + CategoryOptionCombo categoryOptionCombo, @Context TrackerIdSchemeParams idSchemeParams) { + return idSchemeParams.getCategoryOptionComboIdScheme().getIdentifier(categoryOptionCombo); + } } diff --git a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/tracker/export/event/EventMapper.java b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/tracker/export/event/EventMapper.java index 3cbdf289e6c7..9dfd5e354152 100644 --- a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/tracker/export/event/EventMapper.java +++ b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/tracker/export/event/EventMapper.java @@ -116,7 +116,10 @@ public interface EventMapper { @Mapping(target = "createdAtClient", source = "createdAtClient") @Mapping(target = "updatedAt", source = "lastUpdated") @Mapping(target = "updatedAtClient", source = "lastUpdatedAtClient") - @Mapping(target = "attributeOptionCombo", source = "attributeOptionCombo.uid") + @Mapping( + target = "attributeOptionCombo", + source = "attributeOptionCombo", + qualifiedByName = "categoryOptionComboToString") @Mapping(target = "attributeCategoryOptions", source = "attributeOptionCombo.categoryOptions") @Mapping(target = "completedAt", source = "completedDate") @Mapping(target = "createdBy", source = "createdByUserInfo")