From 2ee4dbf3b849984b1a9317deac190a70b26df0bf Mon Sep 17 00:00:00 2001 From: Pablo Pajuelo Cabezas Date: Wed, 4 Dec 2024 11:28:43 +0100 Subject: [PATCH 1/2] fix: options not hiding/showing with program rules --- .../org/dhis2/form/data/FormRepositoryImpl.kt | 18 ++++++++++-- .../data/metadata/FormBaseConfiguration.kt | 28 +++++++++++++++---- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/form/src/main/java/org/dhis2/form/data/FormRepositoryImpl.kt b/form/src/main/java/org/dhis2/form/data/FormRepositoryImpl.kt index ac791f613d..0895fd5083 100644 --- a/form/src/main/java/org/dhis2/form/data/FormRepositoryImpl.kt +++ b/form/src/main/java/org/dhis2/form/data/FormRepositoryImpl.kt @@ -48,6 +48,7 @@ class FormRepositoryImpl( private var runDataIntegrity: Boolean = false private var calculationLoop: Int = 0 private var backupList: List = emptyList() + private val fieldsWithOptionEffects = mutableListOf() private val disableCollapsableSections: Boolean? = dataEntryRepository.disableCollapsableSections() @@ -522,9 +523,22 @@ class FormRepositoryImpl( } } + fieldsWithOptionEffects.forEach { field -> + field.optionSet?.let { optionSetUid -> + fetchOptions(field.uid, optionSetUid) + } + } + + fieldsWithOptionEffects.clear() + ruleEffectsResult?.fieldsWithOptionEffects()?.forEach { fieldWithOptionEffect -> - itemList.find { it.uid == fieldWithOptionEffect }?.let { - it.optionSet?.let { optionSetUid -> fetchOptions(it.uid, optionSetUid) } + val item = itemList.find { it.uid == fieldWithOptionEffect } + + item?.let { field -> + field.optionSet?.let { optionSetUid -> + fetchOptions(field.uid, optionSetUid) + } + fieldsWithOptionEffects.add(field) } } diff --git a/form/src/main/java/org/dhis2/form/data/metadata/FormBaseConfiguration.kt b/form/src/main/java/org/dhis2/form/data/metadata/FormBaseConfiguration.kt index 511e379d38..cacc2cc5ea 100644 --- a/form/src/main/java/org/dhis2/form/data/metadata/FormBaseConfiguration.kt +++ b/form/src/main/java/org/dhis2/form/data/metadata/FormBaseConfiguration.kt @@ -41,12 +41,28 @@ open class FormBaseConfiguration(private val d2: D2) { .getPagingData(10) }.map { pagingData -> pagingData.filter { option -> - !optionsToHide.contains(option.uid()) && - !optionGroupsToHide.contains(option.uid()) && - ( - optionGroupsToShow.isEmpty() || - optionGroupsToShow.contains(option.uid()) - ) + + val optionInGroupToHide = d2.optionModule().optionGroups() + .withOptions() + .byUid().`in`(optionGroupsToHide) + .blockingGet().find { optionGroup -> + optionGroup.options()?.map { it.uid() }?.contains(option.uid()) == true + } != null + + val optionInGroupToShow = d2.optionModule().optionGroups() + .withOptions() + .byUid().`in`(optionGroupsToShow) + .blockingGet().find { optionGroup -> + optionGroup.options()?.map { it.uid() }?.contains(option.uid()) == true + } != null + + val hideOption = if (optionGroupsToShow.isEmpty()) { + optionsToHide.contains(option.uid()) || optionInGroupToHide + } else { + !optionInGroupToShow + } + + !hideOption } } } From ba3b8cdfe90b5b868560025cf24f0c710f4fdf4a Mon Sep 17 00:00:00 2001 From: Pablo Pajuelo Cabezas Date: Wed, 4 Dec 2024 12:42:17 +0100 Subject: [PATCH 2/2] fix: remove code smells --- .../data/metadata/FormBaseConfiguration.kt | 8 ++-- .../dhis2/form/data/FormRepositoryImplTest.kt | 40 ++++++++++++++++++- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/form/src/main/java/org/dhis2/form/data/metadata/FormBaseConfiguration.kt b/form/src/main/java/org/dhis2/form/data/metadata/FormBaseConfiguration.kt index cacc2cc5ea..6155035ccc 100644 --- a/form/src/main/java/org/dhis2/form/data/metadata/FormBaseConfiguration.kt +++ b/form/src/main/java/org/dhis2/form/data/metadata/FormBaseConfiguration.kt @@ -45,16 +45,16 @@ open class FormBaseConfiguration(private val d2: D2) { val optionInGroupToHide = d2.optionModule().optionGroups() .withOptions() .byUid().`in`(optionGroupsToHide) - .blockingGet().find { optionGroup -> + .blockingGet().any { optionGroup -> optionGroup.options()?.map { it.uid() }?.contains(option.uid()) == true - } != null + } val optionInGroupToShow = d2.optionModule().optionGroups() .withOptions() .byUid().`in`(optionGroupsToShow) - .blockingGet().find { optionGroup -> + .blockingGet().any { optionGroup -> optionGroup.options()?.map { it.uid() }?.contains(option.uid()) == true - } != null + } val hideOption = if (optionGroupsToShow.isEmpty()) { optionsToHide.contains(option.uid()) || optionInGroupToHide diff --git a/form/src/test/java/org/dhis2/form/data/FormRepositoryImplTest.kt b/form/src/test/java/org/dhis2/form/data/FormRepositoryImplTest.kt index abc6debd58..09fec26410 100644 --- a/form/src/test/java/org/dhis2/form/data/FormRepositoryImplTest.kt +++ b/form/src/test/java/org/dhis2/form/data/FormRepositoryImplTest.kt @@ -2,11 +2,14 @@ package org.dhis2.form.data import androidx.databinding.ObservableField import io.reactivex.Flowable +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.emptyFlow import org.dhis2.commons.prefs.PreferenceProvider import org.dhis2.form.model.ActionType import org.dhis2.form.model.EventCategory import org.dhis2.form.model.FieldUiModel import org.dhis2.form.model.FieldUiModelImpl +import org.dhis2.form.model.OptionSetConfiguration import org.dhis2.form.model.RowAction import org.dhis2.form.model.SectionUiModelImpl import org.dhis2.form.model.StoreResult @@ -30,6 +33,7 @@ import org.junit.Before import org.junit.Test import org.mockito.kotlin.any import org.mockito.kotlin.anyOrNull +import org.mockito.kotlin.atLeast import org.mockito.kotlin.doReturn import org.mockito.kotlin.doReturnConsecutively import org.mockito.kotlin.mock @@ -200,6 +204,14 @@ class FormRepositoryImplTest { mutableMapOf(Pair("field", "uid001")), ), ), + RuleEffect( + "rule2", + RuleAction( + "option1", + ProgramRuleActionType.HIDEOPTION.name, + mutableMapOf(Pair("field", "uid004")), + ), + ), ) whenever(dataEntryRepository.isEvent()) doReturn true @@ -215,12 +227,21 @@ class FormRepositoryImplTest { fieldsToUpdate = listOf(FieldWithNewValue("uid001", "newValue")), configurationErrors = emptyList(), stagesToHide = emptyList(), - optionsToHide = emptyMap(), + optionsToHide = mapOf( + "uid004" to listOf("option1"), + ), optionGroupsToHide = emptyMap(), optionGroupsToShow = emptyMap(), ) - verify(rulesUtilsProvider, times(1)).applyRuleEffects( + whenever(dataEntryRepository.options(any(), any(), any(), any()))doReturn Pair( + MutableStateFlow(""), + emptyFlow(), + ) + + repository.composeList() + + verify(rulesUtilsProvider, atLeast(1)).applyRuleEffects( any(), any(), any(), @@ -441,6 +462,21 @@ class FormRepositoryImplTest { optionSetConfiguration = null, autocompleteList = null, ), + FieldUiModelImpl( + uid = "uid004", + value = null, + label = "field4", + valueType = ValueType.TEXT, + programStageSection = "section1", + uiEventFactory = null, + optionSet = "optionSetUid", + optionSetConfiguration = OptionSetConfiguration( + MutableStateFlow(""), + {}, + emptyFlow(), + ), + autocompleteList = null, + ), ) private fun section1() = SectionUiModelImpl(