diff --git a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/hibernate/HibernateEnrollmentStore.java b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/hibernate/HibernateEnrollmentStore.java index 1a415add41c0..cf32bec26f36 100644 --- a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/hibernate/HibernateEnrollmentStore.java +++ b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/hibernate/HibernateEnrollmentStore.java @@ -30,8 +30,8 @@ import static com.google.common.base.Preconditions.checkNotNull; import static org.hisp.dhis.common.IdentifiableObjectUtils.getUids; import static org.hisp.dhis.commons.util.TextUtils.getQuotedCommaDelimitedString; +import static org.hisp.dhis.util.DateUtils.getLongDateString; import static org.hisp.dhis.util.DateUtils.getLongGmtDateString; -import static org.hisp.dhis.util.DateUtils.getMediumDateString; import static org.hisp.dhis.util.DateUtils.nowMinusDuration; import com.google.common.collect.Lists; @@ -156,10 +156,7 @@ private QueryWithOrderBy buildEnrollmentHql(EnrollmentQueryParams params) { + "'"; } else if (params.hasLastUpdated()) { hql += - hlp.whereAnd() - + "en.lastUpdated >= '" - + getMediumDateString(params.getLastUpdated()) - + "'"; + hlp.whereAnd() + "en.lastUpdated >= '" + getLongDateString(params.getLastUpdated()) + "'"; } if (params.hasTrackedEntity()) { @@ -212,7 +209,7 @@ private QueryWithOrderBy buildEnrollmentHql(EnrollmentQueryParams params) { hql += hlp.whereAnd() + "en.enrollmentDate >= '" - + getMediumDateString(params.getProgramStartDate()) + + getLongDateString(params.getProgramStartDate()) + "'"; } @@ -220,7 +217,7 @@ private QueryWithOrderBy buildEnrollmentHql(EnrollmentQueryParams params) { hql += hlp.whereAnd() + "en.enrollmentDate <= '" - + getMediumDateString(params.getProgramEndDate()) + + getLongDateString(params.getProgramEndDate()) + "'"; } diff --git a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/trackedentity/hibernate/HibernateTrackedEntityStore.java b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/trackedentity/hibernate/HibernateTrackedEntityStore.java index e524e2d2fb37..ed5f6f24f49e 100644 --- a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/trackedentity/hibernate/HibernateTrackedEntityStore.java +++ b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/trackedentity/hibernate/HibernateTrackedEntityStore.java @@ -47,8 +47,8 @@ import static org.hisp.dhis.trackedentity.TrackedEntityQueryParams.TRACKED_ENTITY_ID; import static org.hisp.dhis.trackedentity.TrackedEntityQueryParams.TRACKED_ENTITY_TYPE_ID; import static org.hisp.dhis.util.DateUtils.addDays; +import static org.hisp.dhis.util.DateUtils.getLongDateString; import static org.hisp.dhis.util.DateUtils.getLongGmtDateString; -import static org.hisp.dhis.util.DateUtils.getMediumDateString; import com.google.common.collect.Lists; import java.util.ArrayList; @@ -625,14 +625,14 @@ private String getFromSubQueryTrackedEntityConditions( trackedEntity .append(whereAnd.whereAnd()) .append(" TE.lastupdated >= '") - .append(getMediumDateString(params.getLastUpdatedStartDate())) + .append(getLongDateString(params.getLastUpdatedStartDate())) .append(SINGLE_QUOTE); } if (params.hasLastUpdatedEndDate()) { trackedEntity .append(whereAnd.whereAnd()) .append(" TE.lastupdated < '") - .append(getMediumDateString(addDays(params.getLastUpdatedEndDate(), 1))) + .append(getLongDateString(addDays(params.getLastUpdatedEndDate(), 1))) .append(SINGLE_QUOTE); } } @@ -641,7 +641,7 @@ private String getFromSubQueryTrackedEntityConditions( if (params.getSkipChangedBefore() != null) { trackedEntity .append(" AND TE.lastupdated >= '") - .append(getMediumDateString(params.getSkipChangedBefore())) + .append(getLongDateString(params.getSkipChangedBefore())) .append(SINGLE_QUOTE); } } @@ -940,28 +940,28 @@ private String getFromSubQueryEnrollmentConditions( if (params.hasProgramEnrollmentStartDate()) { program .append("AND EN.enrollmentdate >= '") - .append(getMediumDateString(params.getProgramEnrollmentStartDate())) + .append(getLongDateString(params.getProgramEnrollmentStartDate())) .append("' "); } if (params.hasProgramEnrollmentEndDate()) { program .append("AND EN.enrollmentdate <= '") - .append(getMediumDateString(params.getProgramEnrollmentEndDate())) + .append(getLongDateString(params.getProgramEnrollmentEndDate())) .append("' "); } if (params.hasProgramIncidentStartDate()) { program .append("AND EN.incidentdate >= '") - .append(getMediumDateString(params.getProgramIncidentStartDate())) + .append(getLongDateString(params.getProgramIncidentStartDate())) .append("' "); } if (params.hasProgramIncidentEndDate()) { program .append("AND EN.incidentdate <= '") - .append(getMediumDateString(params.getProgramIncidentEndDate())) + .append(getLongDateString(params.getProgramIncidentEndDate())) .append("' "); } @@ -999,8 +999,8 @@ private String getFromSubQueryEvent(TrackedEntityQueryParams params) { } if (params.hasEventStatus()) { - String start = getMediumDateString(params.getEventStartDate()); - String end = getMediumDateString(params.getEventEndDate()); + String start = getLongDateString(params.getEventStartDate()); + String end = getLongDateString(params.getEventEndDate()); if (params.isEventStatus(EventStatus.COMPLETED)) { events 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 79a0d3cdf3a0..156170e36521 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 @@ -29,8 +29,8 @@ import static org.hisp.dhis.common.IdentifiableObjectUtils.getUids; import static org.hisp.dhis.commons.util.TextUtils.getQuotedCommaDelimitedString; +import static org.hisp.dhis.util.DateUtils.getLongDateString; import static org.hisp.dhis.util.DateUtils.getLongGmtDateString; -import static org.hisp.dhis.util.DateUtils.getMediumDateString; import static org.hisp.dhis.util.DateUtils.nowMinusDuration; import java.util.List; @@ -170,10 +170,7 @@ private QueryWithOrderBy buildEnrollmentHql(EnrollmentQueryParams params) { + "'"; } else if (params.hasLastUpdated()) { hql += - hlp.whereAnd() - + "en.lastUpdated >= '" - + getMediumDateString(params.getLastUpdated()) - + "'"; + hlp.whereAnd() + "en.lastUpdated >= '" + getLongDateString(params.getLastUpdated()) + "'"; } if (params.hasTrackedEntity()) { @@ -226,7 +223,7 @@ private QueryWithOrderBy buildEnrollmentHql(EnrollmentQueryParams params) { hql += hlp.whereAnd() + "en.enrollmentDate >= '" - + getMediumDateString(params.getProgramStartDate()) + + getLongDateString(params.getProgramStartDate()) + "'"; } @@ -234,7 +231,7 @@ private QueryWithOrderBy buildEnrollmentHql(EnrollmentQueryParams params) { hql += hlp.whereAnd() + "en.enrollmentDate <= '" - + getMediumDateString(params.getProgramEndDate()) + + getLongDateString(params.getProgramEndDate()) + "'"; } 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 b5bd958725d1..9c5abf9046ba 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 @@ -32,9 +32,8 @@ import static org.hisp.dhis.common.IdentifiableObjectUtils.getIdentifiers; import static org.hisp.dhis.commons.util.TextUtils.getCommaDelimitedString; import static org.hisp.dhis.commons.util.TextUtils.getQuotedCommaDelimitedString; -import static org.hisp.dhis.util.DateUtils.addDays; +import static org.hisp.dhis.util.DateUtils.getLongDateString; import static org.hisp.dhis.util.DateUtils.getLongGmtDateString; -import static org.hisp.dhis.util.DateUtils.getMediumDateString; import java.util.ArrayList; import java.util.Collection; @@ -511,14 +510,14 @@ private String getFromSubQueryTrackedEntityConditions( trackedEntity .append(whereAnd.whereAnd()) .append(" TE.lastupdated >= '") - .append(getMediumDateString(params.getLastUpdatedStartDate())) + .append(getLongDateString(params.getLastUpdatedStartDate())) .append(SINGLE_QUOTE); } if (params.hasLastUpdatedEndDate()) { trackedEntity .append(whereAnd.whereAnd()) - .append(" TE.lastupdated < '") - .append(getMediumDateString(addDays(params.getLastUpdatedEndDate(), 1))) + .append(" TE.lastupdated <= '") + .append(getLongDateString(params.getLastUpdatedEndDate())) .append(SINGLE_QUOTE); } } @@ -738,28 +737,28 @@ private String getFromSubQueryEnrollmentConditions( if (params.hasProgramEnrollmentStartDate()) { program .append("AND EN.enrollmentdate >= '") - .append(getMediumDateString(params.getProgramEnrollmentStartDate())) + .append(getLongDateString(params.getProgramEnrollmentStartDate())) .append("' "); } if (params.hasProgramEnrollmentEndDate()) { program .append("AND EN.enrollmentdate <= '") - .append(getMediumDateString(params.getProgramEnrollmentEndDate())) + .append(getLongDateString(params.getProgramEnrollmentEndDate())) .append("' "); } if (params.hasProgramIncidentStartDate()) { program .append("AND EN.incidentdate >= '") - .append(getMediumDateString(params.getProgramIncidentStartDate())) + .append(getLongDateString(params.getProgramIncidentStartDate())) .append("' "); } if (params.hasProgramIncidentEndDate()) { program .append("AND EN.incidentdate <= '") - .append(getMediumDateString(params.getProgramIncidentEndDate())) + .append(getLongDateString(params.getProgramIncidentEndDate())) .append("' "); } @@ -796,8 +795,8 @@ private String getFromSubQueryEvent(TrackedEntityQueryParams params) { } if (params.hasEventStatus()) { - String start = getMediumDateString(params.getEventStartDate()); - String end = getMediumDateString(params.getEventEndDate()); + String start = getLongDateString(params.getEventStartDate()); + String end = getLongDateString(params.getEventEndDate()); if (params.isEventStatus(EventStatus.COMPLETED)) { events diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityOperationParams.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityOperationParams.java index c248942abbb4..341796becc6a 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityOperationParams.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityOperationParams.java @@ -149,9 +149,6 @@ public class TrackedEntityOperationParams { /** Indicates whether the search is for synchronization purposes (for Program Data sync job). */ private boolean synchronizationQuery; - /** Indicates a point in the time used to decide the data that should not be synchronized */ - private Date skipChangedBefore; - /** * Potential Duplicate query parameter value. If null, we don't check whether a TE is a * potentialDuplicate or not diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityQueryParams.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityQueryParams.java index d5ed783e5c1e..80a33dab1148 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityQueryParams.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityQueryParams.java @@ -42,7 +42,6 @@ import lombok.ToString; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.SetUtils; -import org.apache.commons.lang3.time.DateUtils; import org.hisp.dhis.common.AssignedUserQueryParam; import org.hisp.dhis.common.AssignedUserSelectionMode; import org.hisp.dhis.common.BaseIdentifiableObject; @@ -436,9 +435,7 @@ public TrackedEntityQueryParams setProgramEnrollmentStartDate(Date programEnroll } public Date getProgramEnrollmentEndDate() { - return programEnrollmentEndDate != null - ? DateUtils.addDays(programEnrollmentEndDate, 1) - : programEnrollmentEndDate; + return programEnrollmentEndDate; } public TrackedEntityQueryParams setProgramEnrollmentEndDate(Date programEnrollmentEndDate) { @@ -456,9 +453,7 @@ public TrackedEntityQueryParams setProgramIncidentStartDate(Date programIncident } public Date getProgramIncidentEndDate() { - return programIncidentEndDate != null - ? DateUtils.addDays(programIncidentEndDate, 1) - : programIncidentEndDate; + return programIncidentEndDate; } public TrackedEntityQueryParams setProgramIncidentEndDate(Date programIncidentEndDate) { diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/test/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityOperationParamsMapperTest.java b/dhis-2/dhis-services/dhis-service-tracker/src/test/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityOperationParamsMapperTest.java index 5929f9121425..330ad78f4f97 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/test/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityOperationParamsMapperTest.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/test/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityOperationParamsMapperTest.java @@ -72,7 +72,6 @@ import org.hisp.dhis.tracker.export.Order; import org.hisp.dhis.user.CurrentUserService; import org.hisp.dhis.user.User; -import org.hisp.dhis.util.DateUtils; import org.hisp.dhis.webapi.controller.event.mapper.SortDirection; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -203,8 +202,7 @@ void testMapping() throws BadRequestException, ForbiddenException { params.getProgramEnrollmentStartDate(), is(operationParams.getProgramEnrollmentStartDate())); assertThat( - params.getProgramEnrollmentEndDate(), - is(DateUtils.addDays(operationParams.getProgramEnrollmentEndDate(), 1))); + params.getProgramEnrollmentEndDate(), is(operationParams.getProgramEnrollmentEndDate())); assertThat(params.getEventStatus(), is(EventStatus.COMPLETED)); assertThat(params.getEventStartDate(), is(operationParams.getEventStartDate())); assertThat(params.getEventEndDate(), is(operationParams.getEventEndDate())); @@ -252,7 +250,7 @@ void testMappingProgramEnrollmentEndDate() throws BadRequestException, Forbidden TrackedEntityQueryParams params = mapper.map(operationParams); - assertEquals(DateUtils.addDays(date, 1), params.getProgramEnrollmentEndDate()); + assertEquals(date, params.getProgramEnrollmentEndDate()); } @Test diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/trackedentity/TrackedEntityServiceTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/trackedentity/TrackedEntityServiceTest.java index 80f0e0ba66ff..7880f7fbdd17 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/trackedentity/TrackedEntityServiceTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/trackedentity/TrackedEntityServiceTest.java @@ -27,11 +27,14 @@ */ package org.hisp.dhis.trackedentity; +import static org.hisp.dhis.utils.Assertions.assertContainsOnly; +import static org.hisp.dhis.utils.Assertions.assertIsEmpty; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import java.time.ZoneId; import java.util.Date; import java.util.HashSet; import java.util.List; @@ -804,6 +807,60 @@ void shouldCountZeroEntitiesWhenNonePresent() { assertEquals(0, trackedEntitiesCounter); } + @Test + void shouldReturnTrackedEntityIfTEWasUpdatedAfterPassedDateAndTime() { + Date oneHourBeforeLastUpdated = + Date.from( + entityInstanceA1 + .getLastUpdated() + .toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDateTime() + .minusHours(1) + .atZone(ZoneId.systemDefault()) + .toInstant()); + injectSecurityContext(superUser); + entityInstanceA1.setTrackedEntityType(trackedEntityType); + entityInstanceService.addTrackedEntity(entityInstanceA1); + + TrackedEntityQueryParams params = new TrackedEntityQueryParams(); + params.setOrgUnits(Set.of(organisationUnit)); + params.setTrackedEntityType(trackedEntityType); + params.setLastUpdatedStartDate(oneHourBeforeLastUpdated); + + List trackedEntities = + entityInstanceService.getTrackedEntities(params, true, true); + + assertContainsOnly(List.of(entityInstanceA1), trackedEntities); + } + + @Test + void shouldReturnEmptyIfTEWasUpdatedBeforePassedDateAndTime() { + Date oneHourAfterLastUpdated = + Date.from( + entityInstanceA1 + .getLastUpdated() + .toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDateTime() + .plusHours(1) + .atZone(ZoneId.systemDefault()) + .toInstant()); + injectSecurityContext(superUser); + entityInstanceA1.setTrackedEntityType(trackedEntityType); + entityInstanceService.addTrackedEntity(entityInstanceA1); + + TrackedEntityQueryParams params = new TrackedEntityQueryParams(); + params.setOrgUnits(Set.of(organisationUnit)); + params.setTrackedEntityType(trackedEntityType); + params.setLastUpdatedStartDate(oneHourAfterLastUpdated); + + List trackedEntities = + entityInstanceService.getTrackedEntities(params, true, true); + + assertIsEmpty(trackedEntities); + } + private void initializeEntityInstance(TrackedEntity entityInstance) { entityInstance.setTrackedEntityType(trackedEntityType); entityInstanceService.addTrackedEntity(entityInstance); diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/TrackerTestUtils.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/TrackerTestUtils.java index 0d32ef687b02..2479671e8290 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/TrackerTestUtils.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/TrackerTestUtils.java @@ -27,6 +27,8 @@ */ package org.hisp.dhis.tracker; +import java.time.temporal.ChronoUnit; +import java.util.Date; import java.util.List; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; @@ -38,4 +40,20 @@ public class TrackerTestUtils { public static List uids(List identifiableObject) { return identifiableObject.stream().map(BaseIdentifiableObject::getUid).toList(); } + + public static Date oneHourAfter(Date date) { + return Date.from(date.toInstant().plus(1, ChronoUnit.HOURS)); + } + + public static Date oneHourBefore(Date date) { + return Date.from(date.toInstant().minus(1, ChronoUnit.HOURS)); + } + + public static Date twoHoursAfter(Date date) { + return Date.from(date.toInstant().plus(2, ChronoUnit.HOURS)); + } + + public static Date twoHoursBefore(Date date) { + return Date.from(date.toInstant().minus(2, ChronoUnit.HOURS)); + } } diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/enrollment/EnrollmentServiceTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/enrollment/EnrollmentServiceTest.java index 1ba53d8ceb73..2a90de732c46 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/enrollment/EnrollmentServiceTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/enrollment/EnrollmentServiceTest.java @@ -27,6 +27,8 @@ */ package org.hisp.dhis.tracker.export.enrollment; +import static org.hisp.dhis.tracker.TrackerTestUtils.oneHourAfter; +import static org.hisp.dhis.tracker.TrackerTestUtils.oneHourBefore; import static org.hisp.dhis.tracker.TrackerTestUtils.uids; import static org.hisp.dhis.utils.Assertions.assertContains; import static org.hisp.dhis.utils.Assertions.assertContainsOnly; @@ -102,12 +104,14 @@ class EnrollmentServiceTest extends TransactionalIntegrationTest { private Relationship relationshipA; + private OrganisationUnit orgUnitA; + @Override protected void setUpTest() throws Exception { userService = _userService; admin = preCreateInjectAdminUser(); - OrganisationUnit orgUnitA = createOrganisationUnit('A'); + orgUnitA = createOrganisationUnit('A'); manager.save(orgUnitA, false); OrganisationUnit orgUnitB = createOrganisationUnit('B'); manager.save(orgUnitB, false); @@ -456,6 +460,110 @@ void shouldFailGettingEnrollmentsByTrackedEntityWhenUserHasNoAccessToTrackedEnti assertContains("access to tracked entity type", exception.getMessage()); } + @Test + void shouldReturnEnrollmentIfEnrollmentWasUpdatedBeforePassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourBeforeLastUpdated = oneHourBefore(enrollmentA.getLastUpdated()); + + EnrollmentOperationParams operationParams = + EnrollmentOperationParams.builder() + .orgUnitUids(Set.of(orgUnitA.getUid())) + .lastUpdated(oneHourBeforeLastUpdated) + .build(); + + List enrollments = enrollmentService.getEnrollments(operationParams); + + assertContainsOnly(List.of(enrollmentA), enrollments); + } + + @Test + void shouldReturnEmptyIfEnrollmentWasUpdatedAfterPassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourAfterLastUpdated = oneHourAfter(enrollmentA.getLastUpdated()); + + EnrollmentOperationParams operationParams = + EnrollmentOperationParams.builder() + .orgUnitUids(Set.of(orgUnitA.getUid())) + .lastUpdated(oneHourAfterLastUpdated) + .build(); + + List enrollments = enrollmentService.getEnrollments(operationParams); + + assertIsEmpty(enrollments); + } + + @Test + void shouldReturnEnrollmentIfEnrollmentStartedBeforePassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + programA.getSharing().setPublicAccess(AccessStringHelper.FULL); + Date oneHourBeforeEnrollmentDate = oneHourBefore(enrollmentA.getEnrollmentDate()); + + EnrollmentOperationParams operationParams = + EnrollmentOperationParams.builder() + .orgUnitUids(Set.of(orgUnitA.getUid())) + .programUid(programA.getUid()) + .programStartDate(oneHourBeforeEnrollmentDate) + .build(); + + List enrollments = enrollmentService.getEnrollments(operationParams); + + assertContainsOnly(List.of(enrollmentA), enrollments); + } + + @Test + void shouldReturnEmptyIfEnrollmentStartedAfterPassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + programA.getSharing().setPublicAccess(AccessStringHelper.FULL); + Date oneHourAfterEnrollmentDate = oneHourAfter(enrollmentA.getEnrollmentDate()); + + EnrollmentOperationParams operationParams = + EnrollmentOperationParams.builder() + .orgUnitUids(Set.of(orgUnitA.getUid())) + .programUid(programA.getUid()) + .programStartDate(oneHourAfterEnrollmentDate) + .build(); + + List enrollments = enrollmentService.getEnrollments(operationParams); + + assertIsEmpty(enrollments); + } + + @Test + void shouldReturnEnrollmentIfEnrollmentEndedAfterPassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + programA.getSharing().setPublicAccess(AccessStringHelper.FULL); + Date oneHourAfterEnrollmentDate = oneHourAfter(enrollmentA.getEnrollmentDate()); + + EnrollmentOperationParams operationParams = + EnrollmentOperationParams.builder() + .orgUnitUids(Set.of(orgUnitA.getUid())) + .programUid(programA.getUid()) + .programEndDate(oneHourAfterEnrollmentDate) + .build(); + + List enrollments = enrollmentService.getEnrollments(operationParams); + + assertContainsOnly(List.of(enrollmentA), enrollments); + } + + @Test + void shouldReturnEmptyIfEnrollmentEndedBeforePassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + programA.getSharing().setPublicAccess(AccessStringHelper.FULL); + Date oneHourBeforeEnrollmentDate = oneHourBefore(enrollmentA.getEnrollmentDate()); + + EnrollmentOperationParams operationParams = + EnrollmentOperationParams.builder() + .orgUnitUids(Set.of(orgUnitA.getUid())) + .programUid(programA.getUid()) + .programEndDate(oneHourBeforeEnrollmentDate) + .build(); + + List enrollments = enrollmentService.getEnrollments(operationParams); + + assertIsEmpty(enrollments); + } + private static List attributeUids(Enrollment enrollment) { return enrollment.getTrackedEntity().getTrackedEntityAttributeValues().stream() .map(v -> v.getAttribute().getUid()) diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityServiceTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityServiceTest.java index 6f75b5adc36a..0b90c0681517 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityServiceTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityServiceTest.java @@ -29,6 +29,10 @@ import static org.hisp.dhis.common.OrganisationUnitSelectionMode.DESCENDANTS; import static org.hisp.dhis.common.OrganisationUnitSelectionMode.SELECTED; +import static org.hisp.dhis.tracker.TrackerTestUtils.oneHourAfter; +import static org.hisp.dhis.tracker.TrackerTestUtils.oneHourBefore; +import static org.hisp.dhis.tracker.TrackerTestUtils.twoHoursAfter; +import static org.hisp.dhis.tracker.TrackerTestUtils.twoHoursBefore; import static org.hisp.dhis.util.DateUtils.parseDate; import static org.hisp.dhis.utils.Assertions.assertContains; import static org.hisp.dhis.utils.Assertions.assertContainsOnly; @@ -270,6 +274,7 @@ protected void setUpTest() throws Exception { eventA.setProgramStage(programStageA1); eventA.setOrganisationUnit(orgUnitA); eventA.setAttributeOptionCombo(defaultCategoryOptionCombo); + eventA.setExecutionDate(parseDate("2021-05-27T12:05:00.000")); eventA.setDueDate(parseDate("2021-02-27T12:05:00.000")); eventA.setCompletedDate(parseDate("2021-02-27T11:05:00.000")); eventA.setCompletedBy("herb"); @@ -552,6 +557,300 @@ void shouldReturnTrackedEntityIfGivenFilterMatches() assertContainsOnly(List.of(trackedEntityA), trackedEntities); } + @Test + void shouldReturnTrackedEntityIfTEWasUpdatedAfterPassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourBeforeLastUpdated = oneHourBefore(trackedEntityA.getLastUpdated()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .trackedEntityTypeUid(trackedEntityTypeA.getUid()) + .lastUpdatedStartDate(oneHourBeforeLastUpdated) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertContainsOnly(List.of(trackedEntityA), trackedEntities); + } + + @Test + void shouldReturnEmptyIfTEWasUpdatedBeforePassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourAfterLastUpdated = oneHourAfter(trackedEntityA.getLastUpdated()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .trackedEntityTypeUid(trackedEntityTypeA.getUid()) + .lastUpdatedStartDate(oneHourAfterLastUpdated) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertIsEmpty(trackedEntities); + } + + @Test + void shouldReturnTrackedEntityIfTEWasUpdatedBeforePassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourAfterLastUpdated = oneHourAfter(trackedEntityA.getLastUpdated()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .trackedEntityTypeUid(trackedEntityTypeA.getUid()) + .lastUpdatedEndDate(oneHourAfterLastUpdated) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertContainsOnly(List.of(trackedEntityA), trackedEntities); + } + + @Test + void shouldReturnEmptyIfTEWasUpdatedAfterPassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourBeforeLastUpdated = oneHourBefore(trackedEntityA.getLastUpdated()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .trackedEntityTypeUid(trackedEntityTypeA.getUid()) + .lastUpdatedEndDate(oneHourBeforeLastUpdated) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertIsEmpty(trackedEntities); + } + + @Test + void shouldReturnTrackedEntityIfTEWasEnrolledAfterPassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourBeforeEnrollmentDate = oneHourBefore(enrollmentA.getEnrollmentDate()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .programUid(programA.getUid()) + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .programEnrollmentStartDate(oneHourBeforeEnrollmentDate) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertContainsOnly(List.of(trackedEntityA), trackedEntities); + } + + @Test + void shouldReturnEmptyIfTEWasEnrolledBeforePassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourAfterEnrollmentDate = oneHourAfter(enrollmentA.getEnrollmentDate()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .programUid(programA.getUid()) + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .programEnrollmentStartDate(oneHourAfterEnrollmentDate) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertIsEmpty(trackedEntities); + } + + @Test + void shouldReturnTrackedEntityIfTEWasEnrolledBeforePassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourAfterEnrollmentDate = oneHourAfter(enrollmentA.getEnrollmentDate()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .programUid(programA.getUid()) + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .programEnrollmentEndDate(oneHourAfterEnrollmentDate) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertContainsOnly(List.of(trackedEntityA), trackedEntities); + } + + @Test + void shouldReturnEmptyIfTEWasEnrolledAfterPassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourBeforeEnrollmentDate = oneHourBefore(enrollmentA.getEnrollmentDate()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .programUid(programA.getUid()) + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .programEnrollmentEndDate(oneHourBeforeEnrollmentDate) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertIsEmpty(trackedEntities); + } + + @Test + void shouldReturnTrackedEntityIfEnrollmentOccurredAfterPassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourBeforeIncidentDate = oneHourBefore(enrollmentA.getIncidentDate()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .programUid(programA.getUid()) + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .programIncidentStartDate(oneHourBeforeIncidentDate) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertContainsOnly(List.of(trackedEntityA), trackedEntities); + } + + @Test + void shouldReturnEmptyIfEnrollmentOccurredBeforePassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourAfterIncidentDate = oneHourAfter(enrollmentA.getIncidentDate()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .programUid(programA.getUid()) + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .programIncidentStartDate(oneHourAfterIncidentDate) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertIsEmpty(trackedEntities); + } + + @Test + void shouldReturnTrackedEntityIfEnrollmentOccurredBeforePassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourAfterIncidentDate = oneHourAfter(enrollmentA.getIncidentDate()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .programUid(programA.getUid()) + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .programIncidentEndDate(oneHourAfterIncidentDate) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertContainsOnly(List.of(trackedEntityA), trackedEntities); + } + + @Test + void shouldReturnEmptyIfEnrollmentOccurredPassedDateAndTime() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourBeforeIncidentDate = oneHourBefore(enrollmentA.getIncidentDate()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .programUid(programA.getUid()) + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .programIncidentEndDate(oneHourBeforeIncidentDate) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertIsEmpty(trackedEntities); + } + + @Test + void shouldReturnTrackedEntityIfEventOccurredBetweenPassedDateAndTimes() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourBeforeEventDate = oneHourBefore(eventA.getExecutionDate()); + Date oneHourAfterEventDate = oneHourAfter(eventA.getExecutionDate()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .programUid(programA.getUid()) + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .eventStatus(EventStatus.ACTIVE) + .eventStartDate(oneHourBeforeEventDate) + .eventEndDate(oneHourAfterEventDate) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertContainsOnly(List.of(trackedEntityA), trackedEntities); + } + + @Test + void shouldReturnEmptyIfEventOccurredBeforePassedDateAndTimes() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourAfterEventDate = oneHourAfter(eventA.getExecutionDate()); + Date twoHoursAfterEventDate = twoHoursAfter(eventA.getExecutionDate()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .programUid(programA.getUid()) + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .eventStatus(EventStatus.ACTIVE) + .eventStartDate(oneHourAfterEventDate) + .eventEndDate(twoHoursAfterEventDate) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertIsEmpty(trackedEntities); + } + + @Test + void shouldReturnEmptyIfEventOccurredAfterPassedDateAndTimes() + throws ForbiddenException, NotFoundException, BadRequestException { + Date oneHourBeforeEventDate = oneHourBefore(eventA.getExecutionDate()); + Date twoHoursBeforeEventDate = twoHoursBefore(eventA.getExecutionDate()); + + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .programUid(programA.getUid()) + .organisationUnits(Set.of(orgUnitA.getUid())) + .orgUnitMode(SELECTED) + .eventStatus(EventStatus.ACTIVE) + .eventStartDate(twoHoursBeforeEventDate) + .eventEndDate(oneHourBeforeEventDate) + .user(user) + .build(); + + List trackedEntities = trackedEntityService.getTrackedEntities(operationParams); + + assertIsEmpty(trackedEntities); + } + @Test void shouldReturnEmptyCollectionIfGivenFilterDoesNotMatch() throws ForbiddenException, NotFoundException, BadRequestException { @@ -595,7 +894,7 @@ void shouldReturnTrackedEntityWithLastUpdatedParameter() .orgUnitMode(SELECTED) .trackedEntityTypeUid(trackedEntityTypeA.getUid()) .lastUpdatedStartDate(Date.from(Instant.now().minus(1, ChronoUnit.DAYS))) - .lastUpdatedEndDate(new Date()) + .lastUpdatedEndDate(Date.from(Instant.now().plus(1, ChronoUnit.MINUTES))) .user(user) .build(); @@ -610,7 +909,7 @@ void shouldReturnTrackedEntityWithLastUpdatedParameter() .orgUnitMode(SELECTED) .trackedEntityTypeUid(trackedEntityTypeA.getUid()) .lastUpdatedStartDate(Date.from(Instant.now().plus(1, ChronoUnit.DAYS))) - .lastUpdatedEndDate(new Date()) + .lastUpdatedEndDate(Date.from(Instant.now().plus(1, ChronoUnit.MINUTES))) .user(user) .build();