From 4bea754f4c5161261968079717d67636f3edfec6 Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 5 Jul 2024 08:42:36 +0200 Subject: [PATCH] fix: [ANDROAPP-6093] crash when overriding cat combo in data sets (#3712) Signed-off-by: Pablo --- .../dataSetSection/DataValueRepository.kt | 132 +++++++----------- .../org/dhis2/commons/date/DateUtils.java | 19 +++ 2 files changed, 68 insertions(+), 83 deletions(-) diff --git a/app/src/main/java/org/dhis2/usescases/datasets/dataSetTable/dataSetSection/DataValueRepository.kt b/app/src/main/java/org/dhis2/usescases/datasets/dataSetTable/dataSetSection/DataValueRepository.kt index 20bca865b6..280a6bdc93 100644 --- a/app/src/main/java/org/dhis2/usescases/datasets/dataSetTable/dataSetSection/DataValueRepository.kt +++ b/app/src/main/java/org/dhis2/usescases/datasets/dataSetTable/dataSetSection/DataValueRepository.kt @@ -8,13 +8,13 @@ import io.reactivex.Single import org.dhis2.bindings.decimalFormat import org.dhis2.commons.bindings.dataValueConflicts import org.dhis2.commons.data.tuples.Pair +import org.dhis2.commons.date.DateUtils import org.dhis2.composetable.model.TableCell import org.dhis2.data.dhislogic.AUTH_DATAVALUE_ADD import org.dhis2.data.forms.dataentry.tablefields.FieldViewModel import org.dhis2.data.forms.dataentry.tablefields.FieldViewModelFactoryImpl import org.dhis2.data.forms.dataentry.tablefields.spinner.SpinnerViewModel import org.dhis2.usescases.datasets.dataSetTable.DataSetTableModel -import org.dhis2.utils.DateUtils import org.hisp.dhis.android.core.D2 import org.hisp.dhis.android.core.arch.helpers.UidsHelper import org.hisp.dhis.android.core.arch.repositories.scope.RepositoryScope @@ -61,6 +61,7 @@ class DataValueRepository( ?.categoryComboUid() }?.distinct() } + else -> { val dataElementsSectionUid = d2.dataSetModule().sections().withDataElements() .byDataSetUid().eq(dataSetUid) @@ -157,29 +158,16 @@ class DataValueRepository( dataElement: DataElement, override: List?, ): DataElement { - return override - ?.firstOrNull { - it.dataElement().uid() == dataElement.uid() && it.categoryCombo() != null - }?.let { - DataElement.builder() - .uid(dataElement.uid()) - .code(dataElement.code()) - .name(dataElement.name()) - .displayName(dataElement.displayName()) - .shortName(dataElement.shortName()) - .displayShortName(dataElement.displayShortName()) - .description(dataElement.description()) - .displayDescription(dataElement.displayDescription()) - .valueType(dataElement.valueType()) - .zeroIsSignificant(dataElement.zeroIsSignificant()) - .aggregationType(dataElement.aggregationType()) - .formName(dataElement.formName()) - .domainType(dataElement.domainType()) - .displayFormName(dataElement.displayFormName()) - .optionSet(dataElement.optionSet()) - .categoryCombo(it.categoryCombo()).build() - } - ?: dataElement + val dataSetElement = override?.firstOrNull { + it.dataElement().uid() == dataElement.uid() && it.categoryCombo() != null + } + return if (dataSetElement != null) { + dataElement.toBuilder() + .categoryCombo(dataSetElement.categoryCombo()) + .build() + } else { + dataElement + } } private fun getDataValues(): Flowable> { @@ -290,6 +278,7 @@ class DataValueRepository( .get() .map { section -> section.greyedFields() } .toFlowable() + else -> Flowable.just(ArrayList()) } @@ -319,45 +308,38 @@ class DataValueRepository( private fun getDataElements(categoryCombo: CategoryCombo): Flowable> { return if (sectionUid != "NO_SECTION") { - val listDataElements = - d2.dataSetModule().sections().withDataElements().byDataSetUid().eq(dataSetUid) - .uid(sectionUid).blockingGet()?.dataElements() - val dataElementsOverride: MutableList = - ArrayList() - val dataSetElements = - d2.dataSetModule().dataSets().withDataSetElements().uid(dataSetUid).blockingGet() - ?.dataSetElements() - listDataElements - ?.map { transformDataElement(it, dataSetElements) } - ?.filter { it.categoryComboUid() == categoryCombo.uid() } - ?.forEach { dataElementsOverride.add(it) } + val dataElementsInSection = d2.dataSetModule().sections().withDataElements() + .byDataSetUid().eq(dataSetUid) + .uid(sectionUid) + .blockingGet() + ?.dataElements() + + val dataSetElements = d2.dataSetModule().dataSets().withDataSetElements() + .uid(dataSetUid) + .blockingGet() + ?.dataSetElements() Flowable.just( - dataElementsOverride, + dataElementsInSection + ?.map { transformDataElement(it, dataSetElements) } + ?.filter { it.categoryComboUid() == categoryCombo.uid() }, ) } else { - val dataElementUids: MutableList = - ArrayList() - val dataSetElements = - d2.dataSetModule().dataSets().withDataSetElements().byUid().eq(dataSetUid).one() - .blockingGet()?.dataSetElements() - for (dataSetElement in dataSetElements!!) { - if (dataSetElement.categoryCombo() != null && - categoryCombo.uid() == dataSetElement.categoryCombo()!!.uid() - ) { - dataElementUids.add(dataSetElement.dataElement().uid()) - } else { - val uid = d2.dataElementModule().dataElements() - .uid(dataSetElement.dataElement().uid()).blockingGet()?.categoryComboUid() - if (categoryCombo.uid() == uid) { - dataElementUids.add(dataSetElement.dataElement().uid()) - } - } - } - d2.dataElementModule().dataElements() - .byUid().`in`(dataElementUids) + val dataSetElementsInDataset = + d2.dataSetModule().dataSets().withDataSetElements() + .uid(dataSetUid) + .blockingGet() + ?.dataSetElements() + + val dataElements = d2.dataElementModule().dataElements() + .byUid().`in`(dataSetElementsInDataset?.map { it.dataElement().uid() }) .orderByName(RepositoryScope.OrderByDirection.ASC) - .get().toFlowable() + .blockingGet() + + Flowable.just( + dataElements.map { transformDataElement(it, dataSetElementsInDataset) } + .filter { it.categoryComboUid() == categoryCombo.uid() }, + ) } } @@ -403,6 +385,7 @@ class DataValueRepository( .blockingIsEmpty() hasDataValueAuthority && canWriteCatOption && canWriteOrgUnit } + else -> Flowable.just(false) } } @@ -490,35 +473,13 @@ class DataValueRepository( } fun getDataTableModel(categoryCombo: CategoryCombo): Observable { - return Flowable.zip< - List, - Map>>>, - List, - List, - List, - DataTableModel, - >( + return Flowable.zip( getDataElements(categoryCombo), getCatOptions(categoryCombo.uid()), getDataValues(), getGreyFields(), getCompulsoryDataElements(), - ) { dataElements: List, - optionsWithCategory: Map< - String, - List< - List< - Pair< - CategoryOption, - Category, - >, - >, - >, - >, - dataValues: List, - disabledDataElements: List, - compulsoryCells: List, - -> + ) { dataElements, optionsWithCategory, dataValues, disabledDataElements, compulsoryCells -> var options: List> = ArrayList() for ((_, value) in optionsWithCategory) { options = getCatOptionCombos(value, 0, ArrayList(), null) @@ -663,7 +624,7 @@ class DataValueRepository( .byDataElementUid().eq(dataElement.uid()) .byCategoryOptionComboUid().eq(categoryOptionCombo.uid()) .blockingGet() - ?.find { it.dataElement() == dataElement.uid() } + .find { it.dataElement() == dataElement.uid() } ?.syncState() val conflictInField = @@ -672,6 +633,7 @@ class DataValueRepository( State.ERROR, State.WARNING, -> true + else -> false } }?.filter { @@ -685,10 +647,13 @@ class DataValueRepository( conflictInField != null && error != null -> conflictInField + listOf(error) + valueStateSyncState == State.ERROR && conflictInField != null -> conflictInField + error != null -> listOf(error) + else -> null } @@ -696,6 +661,7 @@ class DataValueRepository( valueStateSyncState == State.WARNING && conflictInField != null -> conflictInField + else -> null } diff --git a/commons/src/main/java/org/dhis2/commons/date/DateUtils.java b/commons/src/main/java/org/dhis2/commons/date/DateUtils.java index 70f5d4a4cf..59f19866de 100644 --- a/commons/src/main/java/org/dhis2/commons/date/DateUtils.java +++ b/commons/src/main/java/org/dhis2/commons/date/DateUtils.java @@ -3,6 +3,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.hisp.dhis.android.core.dataset.DataInputPeriod; import org.hisp.dhis.android.core.event.EventStatus; import org.hisp.dhis.android.core.period.PeriodType; @@ -769,4 +770,22 @@ public static int[] getDifference(Date startDate, Date endDate) { org.joda.time.Period interval = new org.joda.time.Period(startDate.getTime(), endDate.getTime(), org.joda.time.PeriodType.yearMonthDayTime()); return new int[]{interval.getYears(), interval.getMonths(), interval.getDays()}; } + + public Boolean isDataSetExpired(int expiredDays, Date periodInitialDate) { + return Calendar.getInstance().getTime().getTime() > periodInitialDate.getTime() + TimeUnit.DAYS.toMillis(expiredDays); + } + + public Boolean isInsideInputPeriod(DataInputPeriod dataInputPeriodModel) { + if (dataInputPeriodModel.openingDate() == null && dataInputPeriodModel.closingDate() != null) + return Calendar.getInstance().getTime().getTime() < dataInputPeriodModel.closingDate().getTime(); + + if (dataInputPeriodModel.openingDate() != null && dataInputPeriodModel.closingDate() == null) + return dataInputPeriodModel.openingDate().getTime() < Calendar.getInstance().getTime().getTime(); + + if (dataInputPeriodModel.openingDate() == null && dataInputPeriodModel.closingDate() == null) + return true; + + return dataInputPeriodModel.openingDate().getTime() < Calendar.getInstance().getTime().getTime() + && Calendar.getInstance().getTime().getTime() < dataInputPeriodModel.closingDate().getTime(); + } }