Skip to content

Commit

Permalink
fix: [ANDROAPP-64659] Implement no periods available functionality (#…
Browse files Browse the repository at this point in the history
…3884)

* fix: [ANDROAPP-64659] Implement no periods available functionality, correct app version

* fix: [ANDROAPP-6659] take into account last stage event date for showing next period
  • Loading branch information
xavimolloy authored Nov 15, 2024
1 parent 2a6b92a commit 0c2386c
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package org.dhis2.data.dhislogic

import org.dhis2.commons.Constants
import org.dhis2.utils.DateUtils
import org.dhis2.commons.date.DateUtils
import org.hisp.dhis.android.core.enrollment.Enrollment
import org.hisp.dhis.android.core.maintenance.D2Error
import org.hisp.dhis.android.core.program.ProgramStage
import timber.log.Timber
import java.util.Calendar
import java.util.Date

class EnrollmentEventGenerator(
private val generatorRepository: EnrollmentEventGeneratorRepository,
Expand Down Expand Up @@ -121,10 +122,11 @@ class EnrollmentEventGenerator(
calendar.set(Calendar.SECOND, 0)
calendar.set(Calendar.MILLISECOND, 0)
var eventDate = calendar.time

val currentDate = DateUtils.getInstance().getStartOfDay(Date())
periodType?.let { eventDate = generatorRepository.periodStartingDate(it, eventDate) }

generatorRepository.setEventDate(eventUid, eventDate)
if (eventDate.before(currentDate) || eventDate == currentDate) {
generatorRepository.setEventDate(eventUid, eventDate)
}
} catch (d2Error: D2Error) {
Timber.e(d2Error)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,11 @@ class EnrollmentActivity : ActivityGlobalAbstract(), EnrollmentView {
}

override fun openEvent(eventUid: String) {
if (presenter.isEventScheduleOrSkipped(eventUid)) {
val suggestedEventDateIsNotFutureDate = presenter.suggestedReportDateIsNotFutureDate(eventUid)
if (presenter.isEventScheduleOrSkipped(eventUid) && suggestedEventDateIsNotFutureDate) {
val scheduleEventIntent = ScheduledEventActivity.getIntent(this, eventUid)
openEventForResult.launch(scheduleEventIntent)
} else {
} else if (suggestedEventDateIsNotFutureDate) {
val eventCreationIntent = Intent(abstracContext, EventCaptureActivity::class.java)
eventCreationIntent.putExtras(
EventCaptureActivity.getActivityBundle(
Expand All @@ -185,6 +186,8 @@ class EnrollmentActivity : ActivityGlobalAbstract(), EnrollmentView {
),
)
startActivityForResult(eventCreationIntent, RQ_EVENT)
} else {
openDashboard(presenter.getEnrollment()?.uid()!!)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import io.reactivex.processors.PublishProcessor
import org.dhis2.bindings.profilePicturePath
import org.dhis2.commons.bindings.trackedEntityTypeForTei
import org.dhis2.commons.data.TeiAttributesInfo
import org.dhis2.commons.date.DateUtils
import org.dhis2.commons.matomo.Actions.Companion.CREATE_TEI
import org.dhis2.commons.matomo.Categories.Companion.TRACKER_LIST
import org.dhis2.commons.matomo.Labels.Companion.CLICK
Expand All @@ -31,6 +32,8 @@ import org.hisp.dhis.android.core.program.Program
import org.hisp.dhis.android.core.trackedentity.TrackedEntityAttributeValue
import org.hisp.dhis.android.core.trackedentity.TrackedEntityInstanceObjectRepository
import timber.log.Timber
import java.util.Calendar.DAY_OF_YEAR
import java.util.Date

private const val TAG = "EnrollmentPresenter"

Expand Down Expand Up @@ -238,4 +241,22 @@ class EnrollmentPresenterImpl(
event?.status() == EventStatus.SKIPPED ||
event?.status() == EventStatus.OVERDUE
}

fun suggestedReportDateIsNotFutureDate(eventUid: String): Boolean {
return try {
val event = eventCollectionRepository.uid(eventUid).blockingGet()
val programStage = d2.programModule().programStages().uid(event?.programStage()).blockingGet()
val enrollment = enrollmentObjectRepository.blockingGet()
val generatedByEnrollment = programStage?.generatedByEnrollmentDate() ?: false
val startDate = if (generatedByEnrollment) enrollment?.enrollmentDate() else enrollment?.incidentDate()
val calendar = DateUtils.getInstance().getCalendarByDate(startDate)
calendar.add(DAY_OF_YEAR, programStage?.minDaysFromStart() ?: 0)
val minStartReportEventDate = calendar.time
val currentDate = DateUtils.getInstance().getStartOfDay(Date())
return minStartReportEventDate.before(currentDate) || minStartReportEventDate == currentDate
} catch (e: Exception) {
Timber.d(e.message)
true
}
}
}
16 changes: 3 additions & 13 deletions form/src/main/java/org/dhis2/form/data/EventRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import org.hisp.dhis.android.core.program.ProgramStageDataElement
import org.hisp.dhis.android.core.program.ProgramStageSection
import org.hisp.dhis.android.core.program.SectionRenderingType
import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor
import java.util.Calendar.DAY_OF_YEAR
import java.util.Date

class EventRepository(
Expand Down Expand Up @@ -477,13 +476,8 @@ class EventRepository(
?: getEnrollmentDate(enrollmentUid)
}
val calendar = DateUtils.getInstance().getCalendarByDate(minEventDate)
if (stageLastDate == null) {
val minDaysFromStart = getMinDaysFromStartByProgramStage(programStage)
calendar.add(DAY_OF_YEAR, minDaysFromStart)
} else {
calendar.add(DAY_OF_YEAR, programStage?.standardInterval() ?: 0)
}
return dateUtils.getNextPeriod(programStage?.periodType(), calendar.time ?: event?.eventDate(), 1)

return dateUtils.getNextPeriod(programStage?.periodType(), calendar.time ?: event?.eventDate(), if (stageLastDate == null) 0 else 1)
}

private fun getStageLastDate(): Date? {
Expand All @@ -499,7 +493,7 @@ class EventRepository(
d2.eventModule().events().byEnrollmentUid().eq(enrollmentUid).byProgramStageUid()
.eq(programStageUid)
.byDeleted().isFalse
.orderByDueDate(RepositoryScope.OrderByDirection.DESC).blockingGet()
.orderByDueDate(RepositoryScope.OrderByDirection.DESC).blockingGet().filter { it.uid() != eventUid }

var activeDate: Date? = null
var scheduleDate: Date? = null
Expand All @@ -516,10 +510,6 @@ class EventRepository(
}
}

private fun getMinDaysFromStartByProgramStage(programStage: ProgramStage?): Int {
return programStage?.minDaysFromStart() ?: 0
}

private fun getEnrollmentDate(uid: String?): Date? {
val enrollment = d2.enrollmentModule().enrollments().byUid().eq(uid).blockingGet().first()
return enrollment.enrollmentDate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,20 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.res.stringResource
import org.dhis2.commons.date.DateUtils
import org.dhis2.form.R
import org.dhis2.form.extensions.inputState
import org.dhis2.form.extensions.legend
import org.dhis2.form.extensions.supportingText
import org.dhis2.form.model.FieldUiModel
import org.dhis2.form.ui.event.RecyclerViewUiEvents
import org.hisp.dhis.mobile.ui.designsystem.component.DropdownInputField
import org.hisp.dhis.mobile.ui.designsystem.component.DropdownItem
import org.hisp.dhis.mobile.ui.designsystem.component.InputDropDown
import org.hisp.dhis.mobile.ui.designsystem.component.InputShellState
import org.hisp.dhis.mobile.ui.designsystem.component.InputStyle
import java.util.Date

@Composable
fun ProvidePeriodSelector(
Expand All @@ -24,38 +30,74 @@ fun ProvidePeriodSelector(
focusRequester: FocusRequester,
uiEventHandler: (RecyclerViewUiEvents) -> Unit,
) {
var selectedItem by remember(fieldUiModel.displayName) {
mutableStateOf(
fieldUiModel.displayName,
val currentDate = DateUtils.getInstance().getStartOfDay(Date())
if ((fieldUiModel.periodSelector?.minDate?.after(currentDate) == true)) {
ProvideEmptyPeriodSelector(
modifier = modifier,
name = fieldUiModel.label,
inputStyle = inputStyle,
)
} else {
var selectedItem by remember(fieldUiModel.displayName) {
mutableStateOf(
fieldUiModel.displayName,
)
}

DropdownInputField(
modifier = modifier,
title = fieldUiModel.label,
state = fieldUiModel.inputState(),
inputStyle = inputStyle,
legendData = fieldUiModel.legend(),
supportingTextData = fieldUiModel.supportingText(),
isRequiredField = fieldUiModel.mandatory,
selectedItem = DropdownItem(selectedItem ?: ""),
onResetButtonClicked = {
selectedItem = null
fieldUiModel.onClear()
},
onDropdownIconClick = {
uiEventHandler(
RecyclerViewUiEvents.SelectPeriod(
uid = fieldUiModel.uid,
title = fieldUiModel.label,
periodType = fieldUiModel.periodSelector!!.type,
minDate = fieldUiModel.periodSelector!!.minDate,
maxDate = fieldUiModel.periodSelector!!.maxDate,
),
)
},
onFocusChanged = {},
focusRequester = focusRequester,
expanded = false,
)
}
}

@Composable
fun ProvideEmptyPeriodSelector(
modifier: Modifier = Modifier,
name: String,
inputStyle: InputStyle,
) {
var selectedItem by remember {
mutableStateOf("")
}

DropdownInputField(
InputDropDown(
modifier = modifier,
title = fieldUiModel.label,
state = fieldUiModel.inputState(),
title = name,
state = InputShellState.UNFOCUSED,
inputStyle = inputStyle,
legendData = fieldUiModel.legend(),
supportingTextData = fieldUiModel.supportingText(),
isRequiredField = fieldUiModel.mandatory,
selectedItem = DropdownItem(selectedItem ?: ""),
selectedItem = DropdownItem(selectedItem),
onResetButtonClicked = {
selectedItem = null
fieldUiModel.onClear()
selectedItem = ""
},
onDropdownIconClick = {
uiEventHandler(
RecyclerViewUiEvents.SelectPeriod(
uid = fieldUiModel.uid,
title = fieldUiModel.label,
periodType = fieldUiModel.periodSelector!!.type,
minDate = fieldUiModel.periodSelector!!.minDate,
maxDate = fieldUiModel.periodSelector!!.maxDate,
),
)
onItemSelected = { newSelectedDropdownItem ->
selectedItem = newSelectedDropdownItem.label
},
onFocusChanged = {},
focusRequester = focusRequester,
expanded = false,
dropdownItems = listOf(DropdownItem(stringResource(id = R.string.no_periods))),
isRequiredField = false,
)
}
2 changes: 2 additions & 0 deletions form/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,6 @@
<string name="no_options">No options available</string>
<string name="cat_combo">Cat combo</string>
<string name="storage_permission_denied">Storage permission is not granted.\nYou need to enable it to use this feature.</string>
<string name="no_periods">No periods available</string>

</resources>
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
sdk = "34"
minSdk = "21"
vCode = "136"
vName = "3.1.1-DEV"
vName = "3.1.0"
gradle = "8.6.1"
kotlin = '2.0.20'
hilt = '2.47'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,12 @@ class CreateEventUseCaseRepository(
} else {
currentDate
}
val eventRepository = d2.eventModule().events().uid(eventUid)
eventRepository.setEventDate(eventDate)

if(eventDate.before(currentDate) || eventDate == currentDate) {
val eventRepository = d2.eventModule().events().uid(eventUid)
eventRepository.setEventDate(eventDate)
}

}

private fun getStageLastDate(enrollmentUid: String?, programStageUid: String?): Date? {
Expand Down

0 comments on commit 0c2386c

Please sign in to comment.