diff --git a/dhis-2/dhis-services/dhis-service-program-rule/src/main/java/org/hisp/dhis/programrule/engine/DefaultProgramRuleEntityMapperService.java b/dhis-2/dhis-services/dhis-service-program-rule/src/main/java/org/hisp/dhis/programrule/engine/DefaultProgramRuleEntityMapperService.java index e0a37449ee7d..89f6f10f080f 100644 --- a/dhis-2/dhis-services/dhis-service-program-rule/src/main/java/org/hisp/dhis/programrule/engine/DefaultProgramRuleEntityMapperService.java +++ b/dhis-2/dhis-services/dhis-service-program-rule/src/main/java/org/hisp/dhis/programrule/engine/DefaultProgramRuleEntityMapperService.java @@ -440,6 +440,7 @@ public RuleEvent toMappedRuleEvent(ProgramStageInstance psi) { psi.getProgramStage().getUid(), RuleEvent.Status.valueOf(psi.getStatus().toString()), ObjectUtils.defaultIfNull(psi.getExecutionDate(), psi.getDueDate()), + psi.getCreated(), psi.getDueDate(), orgUnit, orgUnitCode, diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/converter/EventTrackerConverterService.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/converter/EventTrackerConverterService.java index 02fc9c414fcb..d29323ec3a0b 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/converter/EventTrackerConverterService.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/converter/EventTrackerConverterService.java @@ -168,6 +168,10 @@ public ProgramStageInstance fromForRuleEngine(TrackerPreheat preheat, Event even ProgramStageInstance psi = from(preheat, event, null); // merge data values from DB psi.getEventDataValues().addAll(getProgramStageInstanceDataValues(preheat, event)); + ProgramStageInstance savedEvent = preheat.getEvent(event.getUid()); + if (savedEvent != null) { + psi.setCreated(savedEvent.getCreated()); + } return psi; } diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/programrule/ProgramRuleAssignActionTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/programrule/ProgramRuleAssignActionTest.java index 72e946d37303..41a8052b09d3 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/programrule/ProgramRuleAssignActionTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/programrule/ProgramRuleAssignActionTest.java @@ -34,11 +34,13 @@ import static org.hisp.dhis.tracker.report.TrackerErrorCode.E1308; import static org.hisp.dhis.tracker.report.TrackerErrorCode.E1310; 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 java.io.IOException; import java.util.List; import java.util.stream.Collectors; +import org.hisp.dhis.common.CodeGenerator; import org.hisp.dhis.dataelement.DataElement; import org.hisp.dhis.dxf2.metadata.objectbundle.ObjectBundle; import org.hisp.dhis.eventdatavalue.EventDataValue; @@ -63,6 +65,7 @@ import org.hisp.dhis.tracker.TrackerTest; import org.hisp.dhis.tracker.report.TrackerImportReport; import org.hisp.dhis.util.DateUtils; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -162,6 +165,61 @@ void shouldImportEventAndCorrectlyAssignPreviousEventDataValue( assertContainsOnly(List.of(previousEventDataValue), eventDataValues); } + @Test + void + shouldImportEventAndCorrectlyAssignPreviousEventDataValueConsideringCreateAtWhenOccurredAtIsSame() + throws IOException { + String firstEventUid = CodeGenerator.generateUid(); + String secondEventUid = CodeGenerator.generateUid(); + String thirdEventUid = CodeGenerator.generateUid(); + String fourthEventUid = CodeGenerator.generateUid(); + + // Events are imported separately to have different createdAt + TrackerImportParams firstEvent = getEvent(firstEventUid, "2024-01-11", "FIRST"); + trackerImportService.importTracker(firstEvent); + + TrackerImportParams fourthEvent = getEvent(fourthEventUid, "2024-01-26", "FOURTH"); + trackerImportService.importTracker(fourthEvent); + + TrackerImportParams secondEvent = getEvent(secondEventUid, "2024-01-25", "SECOND"); + trackerImportService.importTracker(secondEvent); + + TrackerImportParams thirdEvent = getEvent(thirdEventUid, "2024-01-25", "THIRD"); + trackerImportService.importTracker(thirdEvent); + + assignPreviousEventProgramRule(); + + dbmsManager.clearSession(); + dbmsManager.flushSession(); + + TrackerImportParams trackerImportParams = + TrackerImportParams.builder() + .events( + List.of( + firstEvent.getEvents().get(0), + secondEvent.getEvents().get(0), + thirdEvent.getEvents().get(0), + fourthEvent.getEvents().get(0))) + .importStrategy(TrackerImportStrategy.CREATE_AND_UPDATE) + .build(); + + TrackerImportReport importReport = trackerImportService.importTracker(trackerImportParams); + + List firstEventDataValues = getValueForAssignedDataElement(firstEventUid); + List secondEventDataValues = getValueForAssignedDataElement(secondEventUid); + List thirdEventDataValues = getValueForAssignedDataElement(thirdEventUid); + List fourthEventDataValues = getValueForAssignedDataElement(fourthEventUid); + + Assertions.assertAll( + () -> + assertEquals( + E1308, importReport.getValidationReport().getWarnings().get(0).getWarningCode()), + () -> assertIsEmpty(firstEventDataValues), + () -> assertContainsOnly(List.of("FIRST"), secondEventDataValues), + () -> assertContainsOnly(List.of("SECOND"), thirdEventDataValues), + () -> assertContainsOnly(List.of("THIRD"), fourthEventDataValues)); + } + @Test void shouldImportWithWarningWhenDataElementWithSameValueIsAssignedByAssignRule() throws IOException { @@ -224,6 +282,27 @@ void shouldNotImportWhenDataElementWithDifferentValueIsAssignedByAssignRule() th assertEquals(E1308, importReport.getValidationReport().getWarnings().get(0).getWarningCode()); } + private TrackerImportParams getEvent(String eventUid, String occurredDate, String value) + throws IOException { + TrackerImportParams trackerImportParams = + fromJson("tracker/programrule/event_without_date.json"); + trackerImportParams + .getEvents() + .get(0) + .setOccurredAt(DateUtils.instantFromDateAsString(occurredDate)); + trackerImportParams.getEvents().get(0).setEvent(eventUid); + trackerImportParams.getEvents().get(0).getDataValues().iterator().next().setValue(value); + + return trackerImportParams; + } + + private List getValueForAssignedDataElement(String eventUid) { + return manager.get(ProgramStageInstance.class, eventUid).getEventDataValues().stream() + .filter(dv -> dv.getDataElement().equals("DATAEL00002")) + .map(EventDataValue::getValue) + .collect(Collectors.toList()); + } + private void assignProgramRule() { ProgramRule programRule = createProgramRule('F', program, null, "true"); programRuleService.addProgramRule(programRule); diff --git a/dhis-2/dhis-test-integration/src/test/resources/tracker/programrule/event_without_date.json b/dhis-2/dhis-test-integration/src/test/resources/tracker/programrule/event_without_date.json new file mode 100644 index 000000000000..72ef4ca0d72e --- /dev/null +++ b/dhis-2/dhis-test-integration/src/test/resources/tracker/programrule/event_without_date.json @@ -0,0 +1,43 @@ +{ + "trackedEntities": [], + "enrollments": [], + "events": [ + { + "status": "COMPLETED", + "program": { + "idScheme": "UID", + "identifier": "BFcipDERJnf" + }, + "programStage": { + "idScheme": "UID", + "identifier": "NpsdDv6kKSO" + }, + "enrollment": "TvctPPhpD8u", + "orgUnit": { + "idScheme": "UID", + "identifier": "h4w96yEMlzO" + }, + "relationships": [], + "scheduledAt": "2019-01-25T12:10:38.100", + "storedBy": "admin", + "deleted": false, + "attributeOptionCombo": { + "idScheme": "UID" + }, + "attributeCategoryOptions": [], + + "dataValues": [ + { + "storedBy": "admin", + "providedElsewhere": false, + "dataElement": { + "idScheme": "UID", + "identifier": "DATAEL00001" + } + } + ], + "notes": [] + } + ], + "relationships": [] +} \ No newline at end of file diff --git a/dhis-2/pom.xml b/dhis-2/pom.xml index 8cf56a539382..bf27d5d7a799 100644 --- a/dhis-2/pom.xml +++ b/dhis-2/pom.xml @@ -86,7 +86,7 @@ - 2.1.8.0 + 2.1.8.2 1.4.4 @@ -429,6 +429,11 @@ + + org.hisp.dhis.lib.expression + expression-parser + 1.0.1 + @@ -1785,9 +1790,20 @@ false daily - central + central-mirror https://maven-central.storage-download.googleapis.com/maven2/ + + + true + + + false + daily + + central + https://repo1.maven.org/maven2 + never