From e841f7db382ffadc9cce55eadd843ca21128b3c4 Mon Sep 17 00:00:00 2001 From: Enrico Colasante Date: Mon, 30 Dec 2024 09:53:35 -0300 Subject: [PATCH] fix: Always add default order as last order param in tracker exporters [DHIS2-17671] (#19551) (#19569) --- .../enrollment/HibernateEnrollmentStore.java | 2 +- .../tracker/export/event/JdbcEventStore.java | 2 +- .../HibernateRelationshipStore.java | 8 +- .../HibernateTrackedEntityStore.java | 4 +- .../OrderAndPaginationExporterTest.java | 95 +++++++++++++++++++ .../tracker/event_and_enrollment.json | 16 ++++ 6 files changed, 121 insertions(+), 6 deletions(-) diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/enrollment/HibernateEnrollmentStore.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/enrollment/HibernateEnrollmentStore.java index 869f7e658d22..8fcd246a1caa 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/enrollment/HibernateEnrollmentStore.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/enrollment/HibernateEnrollmentStore.java @@ -273,7 +273,7 @@ private static String orderBy(List orders) { orderJoiner.add( order.getField() + " " + (order.getDirection().isAscending() ? "asc" : "desc")); } - return " order by " + orderJoiner; + return " order by " + orderJoiner + ", " + DEFAULT_ORDER; } @Getter 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 67f50b39a3d9..c79db906e8e9 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 @@ -1532,7 +1532,7 @@ private String getOrderQuery(EventQueryParams params) { } if (!orderFields.isEmpty()) { - return "order by " + StringUtils.join(orderFields, ',') + " "; + return "order by " + StringUtils.join(orderFields, ',') + ", " + DEFAULT_ORDER + " "; } else { return "order by " + DEFAULT_ORDER + " "; } diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/relationship/HibernateRelationshipStore.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/relationship/HibernateRelationshipStore.java index 6c5c86e6e380..79797a73b9fd 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/relationship/HibernateRelationshipStore.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/relationship/HibernateRelationshipStore.java @@ -32,6 +32,7 @@ import java.util.Set; import java.util.function.Function; import java.util.function.LongSupplier; +import java.util.stream.Stream; import javax.annotation.Nonnull; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; @@ -245,10 +246,13 @@ private String getRelationshipEntityType(T entity private List orderBy( RelationshipQueryParams queryParams, CriteriaBuilder builder, Root root) { + List defaultOrder = orderBy(List.of(DEFAULT_ORDER), builder, root); if (!queryParams.getOrder().isEmpty()) { - return orderBy(queryParams.getOrder(), builder, root); + return Stream.concat( + orderBy(queryParams.getOrder(), builder, root).stream(), defaultOrder.stream()) + .toList(); } else { - return orderBy(List.of(DEFAULT_ORDER), builder, root); + return defaultOrder; } } diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/HibernateTrackedEntityStore.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/HibernateTrackedEntityStore.java index ac6b8bc4066e..799e2bc8152f 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/HibernateTrackedEntityStore.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/HibernateTrackedEntityStore.java @@ -987,10 +987,10 @@ private String getQueryOrderBy(TrackedEntityQueryParams params, boolean innerOrd } if (!orderFields.isEmpty()) { - return "ORDER BY " + StringUtils.join(orderFields, ',') + SPACE; + return "ORDER BY " + StringUtils.join(orderFields, ',') + ", " + DEFAULT_ORDER + SPACE; } - return "ORDER BY " + DEFAULT_ORDER + " "; + return "ORDER BY " + DEFAULT_ORDER + SPACE; } /** diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/OrderAndPaginationExporterTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/OrderAndPaginationExporterTest.java index 8ed8a0eab9b5..bbe7c347f7ca 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/OrderAndPaginationExporterTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/OrderAndPaginationExporterTest.java @@ -211,6 +211,33 @@ void shouldReturnPaginatedTrackedEntitiesGivenNonDefaultPageSizeAndTotalPages() trackedEntityService.getTrackedEntities(params, new PageParams(3, 3, true)).getItems()); } + @Test + void shouldOrderTrackedEntitiesByInactiveAndByDefaultOrder() + throws ForbiddenException, BadRequestException, NotFoundException { + List expected = + Stream.of( + get(TrackedEntity.class, "QesgJkTyTCk"), + get(TrackedEntity.class, "dUE514NMOlo"), + get(TrackedEntity.class, "mHWCacsGYYn")) + .sorted(Comparator.comparing(TrackedEntity::getId).reversed()) // reversed = desc + .map(TrackedEntity::getUid) + .toList(); + + TrackedEntityOperationParams params = + TrackedEntityOperationParams.builder() + .organisationUnits(Set.of(orgUnit.getUid())) + .orgUnitMode(SELECTED) + .trackedEntityUids(Set.of("mHWCacsGYYn", "QesgJkTyTCk", "dUE514NMOlo")) + .trackedEntityTypeUid(trackedEntityType.getUid()) + .orderBy("inactive", SortDirection.ASC) + .user(importUser) + .build(); + + List trackedEntities = getTrackedEntities(params); + + assertEquals(expected, trackedEntities); + } + @Test void shouldOrderTrackedEntitiesByPrimaryKeyDescByDefault() throws ForbiddenException, BadRequestException, NotFoundException { @@ -586,6 +613,28 @@ void shouldOrderTrackedEntitiesByInactiveAsc() assertEquals(List.of("dUE514NMOlo", "QS6w44flWAf"), trackedEntities); } + @Test + void shouldOrderEnrollmentsByStatusAndByDefaultOrder() + throws ForbiddenException, BadRequestException { + List expected = + Stream.of(get(Enrollment.class, "HDWTYSYkICe"), get(Enrollment.class, "GYWSSZunTLk")) + .sorted(Comparator.comparing(Enrollment::getId).reversed()) // reversed = desc + .map(Enrollment::getUid) + .toList(); + + EnrollmentOperationParams operationParams = + EnrollmentOperationParams.builder() + .orgUnitUids(Set.of("DiszpKrYNg8")) + .orgUnitMode(SELECTED) + .enrollmentUids(Set.of("HDWTYSYkICe", "GYWSSZunTLk")) + .orderBy("status", SortDirection.DESC) + .build(); + + List actual = getEnrollments(operationParams); + + assertEquals(expected, actual); + } + @Test void shouldReturnPaginatedEnrollmentsGivenNonDefaultPageSize() throws ForbiddenException, BadRequestException { @@ -700,6 +749,29 @@ void shouldOrderEnrollmentsByEnrolledAtDesc() throws ForbiddenException, BadRequ assertEquals(List.of("TvctPPhpD8z", "nxP7UnKhomJ"), enrollments); } + @Test + void shouldOrderEventsByStatusAndByDefaultOrder() throws ForbiddenException, BadRequestException { + List expected = + Stream.of( + get(Event.class, "ck7DzdxqLqA"), + get(Event.class, "kWjSezkXHVp"), + get(Event.class, "OTmjvJDn0Fu")) + .sorted(Comparator.comparing(Event::getId).reversed()) // reversed = desc + .map(Event::getUid) + .toList(); + + EventOperationParams operationParams = + eventParamsBuilder + .orgUnitUid("DiszpKrYNg8") + .events(Set.of("ck7DzdxqLqA", "kWjSezkXHVp", "OTmjvJDn0Fu")) + .orderBy("status", SortDirection.DESC) + .build(); + + List actual = getEvents(operationParams); + + assertEquals(expected, actual); + } + @Test void shouldReturnPaginatedEventsWithNotesGivenNonDefaultPageSize() throws ForbiddenException, BadRequestException { @@ -1308,6 +1380,29 @@ void shouldOrderByFieldInAscendingOrderWhenModeDescendants( assertEquals(List.of(firstEvent, secondEvent), events); } + @Test + void shouldOrderRelationshipsByCreatedAtClientAndByDefaultOrder() + throws ForbiddenException, NotFoundException { + Relationship oLT07jKRu9e = get(Relationship.class, "fHn74P5T3r1"); + Relationship yZxjxJli9mO = get(Relationship.class, "yZxjxJli9mO"); + List expected = + Stream.of(oLT07jKRu9e, yZxjxJli9mO) + .sorted(Comparator.comparing(Relationship::getId).reversed()) // reversed = desc + .map(Relationship::getUid) + .toList(); + + RelationshipOperationParams params = + RelationshipOperationParams.builder() + .type(TrackerType.TRACKED_ENTITY) + .identifier("dUE514NMOlo") + .orderBy("createdAtClient", SortDirection.DESC) + .build(); + + List relationships = getRelationships(params); + + assertEquals(expected, relationships); + } + @Test void shouldOrderRelationshipsByPrimaryKeyDescByDefault() throws ForbiddenException, NotFoundException { diff --git a/dhis-2/dhis-test-integration/src/test/resources/tracker/event_and_enrollment.json b/dhis-2/dhis-test-integration/src/test/resources/tracker/event_and_enrollment.json index ffe16ba9f31c..8b6c319d6ceb 100644 --- a/dhis-2/dhis-test-integration/src/test/resources/tracker/event_and_enrollment.json +++ b/dhis-2/dhis-test-integration/src/test/resources/tracker/event_and_enrollment.json @@ -1253,6 +1253,22 @@ "to": { "event": "pTzf9KYMk72" } + }, + { + "relationship": "fHn74P5T3r1", + "relationshipType": { + "idScheme": "UID", + "identifier": "TV9oB9LT3sh" + }, + "createdAtClient": "2018-11-01T13:24:37.118", + "bidirectional": false, + "deleted": false, + "from": { + "trackedEntity": "dUE514NMOlo" + }, + "to": { + "event": "D9PbzJY8bJM" + } } ], "username": "system-process"