Skip to content

Commit

Permalink
fix: /tracker/trackedEntites?order=enrolledAt returns wrong order [2.…
Browse files Browse the repository at this point in the history
…39] (#17612)

* fix: join condition

* fix: compile
  • Loading branch information
lucaCambi77 authored May 29, 2024
1 parent 22d1da8 commit 74f8584
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -890,20 +890,25 @@ private String getOwnerOrgUnit(TrackedEntityInstanceQueryParams params) {

/**
* Generates an INNER JOIN for program instances. If the param we need to order by is enrolledAt,
* we need to join the program instance table to be able to select and order by this value
* we need to join the program instance table to be able to select and order by this value. We
* restrict the join condition to a specific program if specified in the request.
*
* @param params
* @return a SQL INNER JOIN for program instances
*/
private String getFromSubQueryJoinProgramInstanceConditions(
TrackedEntityInstanceQueryParams params) {
if (params.getOrders().stream().anyMatch(p -> ENROLLED_AT.isPropertyEqualTo(p.getField()))) {
return new StringBuilder(" INNER JOIN programinstance ")
.append(PROGRAM_INSTANCE_ALIAS)
.append(" ON ")
.append(PROGRAM_INSTANCE_ALIAS + "." + "trackedentityinstanceid")
.append("= TEI.trackedentityinstanceid ")
.toString();

String join =
"INNER JOIN programinstance %1$s ON %1$s.trackedentityinstanceid = TEI.trackedentityinstanceid";

return !params.hasProgram()
? String.format(join, PROGRAM_INSTANCE_ALIAS)
: String.format(
join + " AND %1$s.programid = %2$s",
PROGRAM_INSTANCE_ALIAS,
params.getProgram().getId());
}

return "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,19 @@
import org.hisp.dhis.common.QueryItem;
import org.hisp.dhis.common.SlimPager;
import org.hisp.dhis.common.ValueType;
import org.hisp.dhis.dxf2.events.TrackedEntityInstanceParams;
import org.hisp.dhis.dxf2.events.event.Event;
import org.hisp.dhis.dxf2.events.event.EventQueryParams;
import org.hisp.dhis.dxf2.events.event.EventService;
import org.hisp.dhis.dxf2.events.event.Events;
import org.hisp.dhis.dxf2.events.trackedentity.TrackedEntityInstance;
import org.hisp.dhis.dxf2.events.trackedentity.TrackedEntityInstanceService;
import org.hisp.dhis.organisationunit.OrganisationUnit;
import org.hisp.dhis.program.Program;
import org.hisp.dhis.program.ProgramStageInstance;
import org.hisp.dhis.trackedentity.TrackedEntityAttribute;
import org.hisp.dhis.trackedentity.TrackedEntityInstanceQueryParams;
import org.hisp.dhis.trackedentity.TrackedEntityType;
import org.hisp.dhis.user.User;
import org.hisp.dhis.webapi.controller.event.mapper.OrderParam;
import org.hisp.dhis.webapi.controller.event.mapper.OrderParam.SortDirection;
Expand All @@ -75,12 +80,20 @@ class OrderAndPaginationExporterTest extends TrackerTest {

@Autowired private EventService eventService;

@Autowired private TrackedEntityInstanceService trackedEntityService;

@Autowired private TrackerImportService trackerImportService;

@Autowired private IdentifiableObjectManager manager;

private OrganisationUnit orgUnit;

private TrackedEntityType trackedEntityType;

private User importUser;

private Program program;

final Function<EventQueryParams, List<String>> eventsFunction =
(params) ->
eventService.getEvents(params).getEvents().stream()
Expand All @@ -94,14 +107,16 @@ class OrderAndPaginationExporterTest extends TrackerTest {
@Override
protected void initTest() throws IOException {
setUpMetadata("tracker/simple_metadata.json");
User importUser = userService.getUser("M5zQapPyTZI");
importUser = userService.getUser("M5zQapPyTZI");
assertNoErrors(
trackerImportService.importTracker(
fromJson("tracker/event_and_enrollment.json", importUser.getUid())));
orgUnit = get(OrganisationUnit.class, "h4w96yEMlzO");

pTzf9KYMk72 = get(ProgramStageInstance.class, "pTzf9KYMk72");
D9PbzJY8bJM = get(ProgramStageInstance.class, "D9PbzJY8bJM");
trackedEntityType = get(TrackedEntityType.class, "ja8NY4PW7Xm");
program = get(Program.class, "BFcipDERJnf");

// to test that events are only returned if the user has read access to ALL COs of an events COC
CategoryOption categoryOption = get(CategoryOption.class, "yMj2MnmNI8L");
Expand Down Expand Up @@ -692,6 +707,66 @@ void shouldOrderEventsByLastUpdatedInAscendingOrderWhenLastUpdatedAscSupplied()
}
}

@Test
void shouldOrderTrackedEntitiesByEnrolledAtAsc() {
TrackedEntityInstanceQueryParams params = new TrackedEntityInstanceQueryParams();

params.addOrganisationUnit(orgUnit);
params.setOrganisationUnitMode(SELECTED);
params.setTrackedEntityInstanceUids(Set.of("QS6w44flWAf", "dUE514NMOlo"));
params.setTrackedEntityType(trackedEntityType);
params.setUser(importUser);
params.setOrders(List.of(new OrderParam("enrolledAt", SortDirection.ASC)));

List<String> trackedEntities = getTrackedEntities(params);

assertEquals(List.of("QS6w44flWAf", "dUE514NMOlo"), trackedEntities);
}

@Test
void shouldOrderTrackedEntitiesByEnrolledAtDescWithNoProgramInParams() {
TrackedEntityInstanceQueryParams params = new TrackedEntityInstanceQueryParams();

params.addOrganisationUnit(orgUnit);
params.setOrganisationUnitMode(SELECTED);
params.setTrackedEntityInstanceUids(Set.of("QS6w44flWAf", "dUE514NMOlo"));
params.setTrackedEntityType(trackedEntityType);
params.setUser(importUser);
params.setOrders(List.of(new OrderParam("enrolledAt", SortDirection.DESC)));

List<String> trackedEntities = getTrackedEntities(params);

assertEquals(
List.of("QS6w44flWAf", "dUE514NMOlo"),
trackedEntities); // QS6w44flWAf has 2 enrollments, one of which has an enrollment with
// enrolled date greater than the enrollment in dUE514NMOlo
}

@Test
void shouldOrderTrackedEntitiesByEnrolledAtDescWithProgramInParams() {

TrackedEntityInstanceQueryParams params = new TrackedEntityInstanceQueryParams();

params.setProgram(program);
params.addOrganisationUnit(orgUnit);
params.setOrganisationUnitMode(SELECTED);
params.setTrackedEntityInstanceUids(Set.of("QS6w44flWAf", "dUE514NMOlo"));
params.setUser(importUser);
params.setOrders(List.of(new OrderParam("enrolledAt", SortDirection.DESC)));

List<String> trackedEntities = getTrackedEntities(params);

assertEquals(List.of("dUE514NMOlo", "QS6w44flWAf"), trackedEntities);
}

private List<String> getTrackedEntities(TrackedEntityInstanceQueryParams params) {
return trackedEntityService
.getTrackedEntityInstances(params, TrackedEntityInstanceParams.FALSE, false, false)
.stream()
.map(TrackedEntityInstance::getTrackedEntityInstance)
.collect(Collectors.toList());
}

private static QueryItem queryItem(TrackedEntityAttribute tea) {
return new QueryItem(
tea,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,29 @@
"attributes": [],
"notes": []
},
{
"enrollment": "nxP8UnKhomJ",
"createdAtClient": "2017-01-26T13:48:13.363",
"trackedEntity": "QS6w44flWAf",
"program": {
"idScheme": "UID",
"identifier": "shPjYNifvMK"
},
"status": "ACTIVE",
"orgUnit": {
"idScheme": "UID",
"identifier": "uoNW0E3xXUy"
},
"enrolledAt": "2021-04-28T12:05:00.000",
"occurredAt": "2021-04-28T12:05:00.000",
"scheduledAt": "2021-04-28T12:05:00.000",
"followUp": false,
"deleted": false,
"events": [],
"relationships": [],
"attributes": [],
"notes": []
},
{
"enrollment": "TvctPPhpD8z",
"createdAtClient": "2017-01-26T13:48:13.363",
Expand Down

0 comments on commit 74f8584

Please sign in to comment.