From 09fea164f0dcd2e37f7f59119fc4c682c76ed937 Mon Sep 17 00:00:00 2001 From: manu Date: Thu, 21 Dec 2023 11:09:01 +0100 Subject: [PATCH 1/2] fix: [ANDROAPP-5803] new scheduled event date --- .../data/EventDetailsRepository.kt | 10 ++- .../domain/ConfigureEventReportDate.kt | 36 +++++----- .../eventDetails/models/EventDate.kt | 2 +- .../eventDetails/ui/EventDetailsFragment.kt | 1 - .../eventDetails/ui/EventDetailsViewModel.kt | 3 - .../domain/ConfigureEventReportDateTest.kt | 65 +++++++++++++++++++ 6 files changed, 89 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/data/EventDetailsRepository.kt b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/data/EventDetailsRepository.kt index 7388e7890c..d51d0100f5 100644 --- a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/data/EventDetailsRepository.kt +++ b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/data/EventDetailsRepository.kt @@ -24,7 +24,6 @@ import org.hisp.dhis.android.core.maintenance.D2Error import org.hisp.dhis.android.core.organisationunit.OrganisationUnit import org.hisp.dhis.android.core.program.Program import org.hisp.dhis.android.core.program.ProgramStage -import java.util.Calendar import java.util.Date class EventDetailsRepository( @@ -72,7 +71,7 @@ class EventDetailsRepository( return programStage?.minDaysFromStart() ?: 0 } - fun getStageLastDate(enrollmentUid: String?): Date { + fun getStageLastDate(enrollmentUid: String?): Date? { val activeEvents = d2.eventModule().events().byEnrollmentUid().eq(enrollmentUid).byProgramStageUid() .eq(programStageUid) @@ -89,7 +88,7 @@ class EventDetailsRepository( } if (scheduleEvents.isNotEmpty()) scheduleDate = scheduleEvents[0].dueDate() - return activeDate ?: (scheduleDate ?: Calendar.getInstance().time) + return activeDate ?: scheduleDate } fun hasAccessDataWrite(): Boolean { @@ -111,6 +110,11 @@ class EventDetailsRepository( return enrollment.enrollmentDate() } + fun getEnrollmentIncidentDate(uid: String?): Date? { + val enrollment = d2.enrollmentModule().enrollments().uid(uid).blockingGet() + return enrollment?.incidentDate() + } + fun getFilteredOrgUnits(date: String?, parentUid: String?): List { val organisationUnits = parentUid?.let { getOrgUnitsByParentUid(it) diff --git a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/domain/ConfigureEventReportDate.kt b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/domain/ConfigureEventReportDate.kt index d98aba0998..f410379261 100644 --- a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/domain/ConfigureEventReportDate.kt +++ b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/domain/ConfigureEventReportDate.kt @@ -13,7 +13,6 @@ import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.models.EventDa import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.providers.EventDetailResourcesProvider import org.hisp.dhis.android.core.period.PeriodType import org.hisp.dhis.android.core.program.ProgramStage -import java.util.Calendar import java.util.Calendar.DAY_OF_YEAR import java.util.Date import java.util.Locale @@ -106,27 +105,24 @@ class ConfigureEventReportDate( } private fun getNextScheduleDate(): Date { - val isGeneratedEventBasedOnEnrollment = - repository.getProgramStage()?.generatedByEnrollmentDate() - - val initialDate = if (isGeneratedEventBasedOnEnrollment == true) { - val enrollmentDate = repository.getEnrollmentDate(enrollmentId) - DateUtils.getInstance().getCalendarByDate(enrollmentDate) - } else { - val date = DateUtils.getInstance().calendar - date.time = repository.getStageLastDate(enrollmentId) + val scheduleDate = repository.getStageLastDate(enrollmentId)?.let { + val lastStageDate = DateUtils.getInstance().getCalendarByDate(it) + lastStageDate.add(DAY_OF_YEAR, getScheduleInterval()) + lastStageDate + } ?: run { + val enrollmentDate = with(repository) { + when (getProgramStage()?.generatedByEnrollmentDate()) { + true -> getEnrollmentDate(enrollmentId) + else -> getEnrollmentIncidentDate(enrollmentId) + ?: getEnrollmentDate(enrollmentId) + } + } + val date = DateUtils.getInstance().getCalendarByDate(enrollmentDate) + val minDateFromStart = repository.getMinDaysFromStartByProgramStage() + date.add(DAY_OF_YEAR, minDateFromStart) date } - - if (getScheduleInterval() > 0) { - initialDate.add(Calendar.DAY_OF_YEAR, getScheduleInterval()) - } - val minDateFromStart = - repository.getMinDaysFromStartByProgramStage() - if (minDateFromStart > 0) { - initialDate.add(DAY_OF_YEAR, minDateFromStart) - } - return DateUtils.getInstance().getNextPeriod(null, initialDate.time, 0) + return DateUtils.getInstance().getNextPeriod(null, scheduleDate.time, 0) } private fun getCurrentDay() = DateUtils.getInstance().today diff --git a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/models/EventDate.kt b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/models/EventDate.kt index e962af72f1..ff99840afd 100644 --- a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/models/EventDate.kt +++ b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/models/EventDate.kt @@ -10,7 +10,7 @@ data class EventDate( val currentDate: Date? = null, val minDate: Date? = null, val maxDate: Date? = null, - var scheduleInterval: Int = 0, + val scheduleInterval: Int = 0, val allowFutureDates: Boolean = true, val periodType: PeriodType? = null, ) diff --git a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/ui/EventDetailsFragment.kt b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/ui/EventDetailsFragment.kt index 171e6fa43c..6a5afa0949 100644 --- a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/ui/EventDetailsFragment.kt +++ b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/ui/EventDetailsFragment.kt @@ -296,7 +296,6 @@ class EventDetailsFragment : FragmentGlobalAbstract() { dialog.setInitialDate(viewModel.eventDate.value.currentDate) dialog.setMinDate(viewModel.eventDate.value.minDate) dialog.setMaxDate(viewModel.eventDate.value.maxDate) - dialog.setScheduleInterval(viewModel.eventDate.value.scheduleInterval) dialog.isFutureDatesAllowed(viewModel.eventDate.value.allowFutureDates) dialog.setListener( object : OnDatePickerListener { diff --git a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/ui/EventDetailsViewModel.kt b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/ui/EventDetailsViewModel.kt index 6ffe3f4685..614e1232a8 100644 --- a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/ui/EventDetailsViewModel.kt +++ b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/ui/EventDetailsViewModel.kt @@ -86,9 +86,6 @@ class EventDetailsViewModel( viewModelScope.launch { configureEventReportDate().collect { _eventDate.value = it - if (_eventDate.value.scheduleInterval > 0) { - _eventDate.value.scheduleInterval = 0 - } } configureOrgUnit(eventDate.value.currentDate) diff --git a/app/src/test/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/domain/ConfigureEventReportDateTest.kt b/app/src/test/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/domain/ConfigureEventReportDateTest.kt index 2274838f52..7d60498f92 100644 --- a/app/src/test/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/domain/ConfigureEventReportDateTest.kt +++ b/app/src/test/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/domain/ConfigureEventReportDateTest.kt @@ -119,6 +119,7 @@ class ConfigureEventReportDateTest { repository = repository, periodUtils = periodUtils, enrollmentId = ENROLLMENT_ID, + scheduleInterval = 6, ) val lastEventDate = "13/2/2022" @@ -126,6 +127,37 @@ class ConfigureEventReportDateTest { whenever( repository.getStageLastDate(ENROLLMENT_ID), ) doReturn DateUtils.uiDateFormat().parse(lastEventDate) + + // When reportDate is invoked + val eventDate = configureEventReportDate.invoke().first() + + // Then date should be next period + assert(eventDate.dateValue == nextEventDate) + } + + @Test + fun `Get next period when creating first scheduled event generated by enrollment date`() = runBlocking { + // Given the creation of new scheduled event + configureEventReportDate = ConfigureEventReportDate( + creationType = EventCreationType.SCHEDULE, + resourceProvider = resourcesProvider, + repository = repository, + periodUtils = periodUtils, + enrollmentId = ENROLLMENT_ID, + scheduleInterval = 6, + ) + + val lastEventDate = "13/2/2022" + val nextEventDate = "19/2/2022" + whenever( + repository.getStageLastDate(ENROLLMENT_ID), + ) doReturn null + whenever( + repository.getProgramStage()?.generatedByEnrollmentDate(), + ) doReturn true + whenever( + repository.getEnrollmentDate(ENROLLMENT_ID), + ) doReturn DateUtils.uiDateFormat().parse(lastEventDate) whenever( repository.getMinDaysFromStartByProgramStage(), ) doReturn 6 @@ -137,6 +169,39 @@ class ConfigureEventReportDateTest { assert(eventDate.dateValue == nextEventDate) } + @Test + fun `Get next period when creating first scheduled event generated by incident date`() = runBlocking { + // Given the creation of new scheduled event + configureEventReportDate = ConfigureEventReportDate( + creationType = EventCreationType.SCHEDULE, + resourceProvider = resourcesProvider, + repository = repository, + periodUtils = periodUtils, + enrollmentId = ENROLLMENT_ID, + ) + + val lastEventDate = "13/2/2022" + val nextEventDate = "15/2/2022" + whenever( + repository.getStageLastDate(ENROLLMENT_ID), + ) doReturn null + whenever( + repository.getProgramStage()?.generatedByEnrollmentDate(), + ) doReturn false + whenever( + repository.getEnrollmentIncidentDate(ENROLLMENT_ID), + ) doReturn DateUtils.uiDateFormat().parse(lastEventDate) + whenever( + repository.getMinDaysFromStartByProgramStage(), + ) doReturn 2 + + // When reportDate is invoked + val eventDate = configureEventReportDate.invoke().first() + + // Then date should be next period + assert(eventDate.dateValue == nextEventDate) + } + @Test fun `Should hide field when scheduled`() = runBlocking { // Given an scheduled event From b6ba88e4b4d2483f4f59d298a78b1b54d88461aa Mon Sep 17 00:00:00 2001 From: manu Date: Thu, 21 Dec 2023 13:49:48 +0100 Subject: [PATCH 2/2] test: [ANDROAPP-5803] check schedule date --- .../teidashboard/TeiDashboardTest.kt | 3 +- .../teidashboard/robot/TeiDashboardRobot.kt | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardTest.kt b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardTest.kt index 90370f5491..7e6ab907dd 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardTest.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardTest.kt @@ -164,7 +164,7 @@ class TeiDashboardTest : BaseTest() { clickOnScheduleNew() clickOnFirstReferralEvent() clickOnReferralNextButton() - checkEventWasCreated(LAB_MONITORING) + checkEventWasCreatedWithDate(LAB_MONITORING, LAB_MONITORING_SCHEDULE_DATE) } } @@ -375,6 +375,7 @@ class TeiDashboardTest : BaseTest() { const val USER = "android" const val LAB_MONITORING = "Lab monitoring" + const val LAB_MONITORING_SCHEDULE_DATE = "10/9/2019" const val API_TEI_1_RESPONSE_OK = "mocks/teilist/teilist_1.json" const val API_TEI_2_RESPONSE_OK = "mocks/teilist/teilist_2.json" diff --git a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/robot/TeiDashboardRobot.kt b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/robot/TeiDashboardRobot.kt index 61efd8eb10..4b9540e94e 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/robot/TeiDashboardRobot.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/robot/TeiDashboardRobot.kt @@ -185,6 +185,37 @@ class TeiDashboardRobot : BaseRobot() { ) } + fun checkEventWasCreatedWithDate(eventName: String, eventDate: String) { + onView(withId(R.id.tei_recycler)) + .check( + matches( + allOf( + isDisplayed(), + isNotEmpty(), + atPosition( + 1, + hasDescendant( + allOf( + hasSibling( + allOf( + withId(R.id.programStageName), + withText(eventName), + ), + ), + hasSibling( + allOf( + withId(R.id.event_date), + withText(eventDate), + ), + ), + ), + ), + ), + ), + ), + ) + } + fun clickOnMenuDeactivate() { onView(withText(R.string.deactivate)).perform(click()) }