Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ data class OverflowMenuItem(
val titleResource: Int,
val confirmAction: Boolean = false,
val titleColor: Color = Color.Black.copy(alpha = 0.7f)
)
) {
var hidden: Boolean = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import org.smartregister.fhircore.engine.util.DateUtils
import org.smartregister.fhircore.engine.util.DateUtils.isToday
import org.smartregister.fhircore.engine.util.DateUtils.today

const val GUARDIAN_VISIT_CODE = "guardian-visit"

fun Task.hasPastEnd() =
this.hasExecutionPeriod() &&
this.executionPeriod.hasEnd() &&
Expand All @@ -45,3 +47,8 @@ fun Task.clinicVisitOrder(systemTag: String) =
.filter { it.isDigitsOnly() }
.map { it.toInt() }
.firstOrNull()

fun Task.isGuardianVisit(systemTag: String) =
this.meta.tag.filter { it.system.equals(systemTag, true) }.any {
it.code.replace("_", "-").equals(GUARDIAN_VISIT_CODE, true)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2021 Ona Systems, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.smartregister.fhircore.engine.domain.model

import org.junit.Assert
import org.junit.Test
import org.smartregister.fhircore.engine.R

class OverflowMenuItemTest {

@Test
fun `default OverflowMenuItem hidden state false`() {
val overflowMenuItem = OverflowMenuItem(R.id.menu_item_logout, R.string.logout)
Assert.assertFalse(overflowMenuItem.hidden)
}

@Test
fun `setHidden updates hidden`() {
val overflowMenuItem = OverflowMenuItem(R.id.menu_item_logout, R.string.logout)
Assert.assertFalse(overflowMenuItem.hidden)
overflowMenuItem.hidden = true
Assert.assertTrue(overflowMenuItem.hidden)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ enum class OverflowMenuHost(val overflowMenuItems: List<OverflowMenuItem>) {
),
NEWLY_DIAGNOSED_PROFILE(
listOf(
OverflowMenuItem(R.id.client_clinic_visit, R.string.client_clinic_visit),
OverflowMenuItem(R.id.client_visit, R.string.client_visit).apply { hidden = true },
OverflowMenuItem(R.id.guardian_visit, R.string.guardian_visit),
OverflowMenuItem(R.id.viral_load_results, R.string.viral_load_results),
OverflowMenuItem(R.id.edit_profile, R.string.edit_profile),
Expand All @@ -86,7 +86,7 @@ enum class OverflowMenuHost(val overflowMenuItems: List<OverflowMenuItem>) {
),
ART_CLIENT_PROFILE(
listOf(
OverflowMenuItem(R.id.client_clinic_visit, R.string.client_clinic_visit),
OverflowMenuItem(R.id.client_visit, R.string.client_visit).apply { hidden = true },
OverflowMenuItem(R.id.guardian_visit, R.string.guardian_visit),
OverflowMenuItem(R.id.viral_load_results, R.string.viral_load_results),
OverflowMenuItem(R.id.edit_profile, R.string.edit_profile),
Expand All @@ -102,7 +102,6 @@ enum class OverflowMenuHost(val overflowMenuItems: List<OverflowMenuItem>) {
),
EXPOSED_INFANT_PROFILE(
listOf(
OverflowMenuItem(R.id.exposed_infant_clinic_visit, R.string.exposed_infant_clinic_visit),
OverflowMenuItem(R.id.hiv_test_and_results, R.string.hiv_test_and_results),
OverflowMenuItem(R.id.edit_profile, R.string.edit_profile),
OverflowMenuItem(R.id.guardian_management, R.string.guardian_management),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ fun PatientProfileScreen(
expanded = showOverflowMenu,
onDismissRequest = { showOverflowMenu = false }
) {
viewState.overflowMenuItems.forEach {
viewState.visibleOverflowMenuItems().forEach {
DropdownMenuItem(
onClick = {
showOverflowMenu = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ package org.smartregister.fhircore.quest.ui.patient.profile

import org.smartregister.fhircore.engine.domain.model.OverflowMenuItem

data class PatientProfileUiState(val overflowMenuItems: List<OverflowMenuItem> = emptyList())
data class PatientProfileUiState(val overflowMenuItems: List<OverflowMenuItem> = emptyList()) {
fun visibleOverflowMenuItems() = overflowMenuItems.filterNot { it.hidden }
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ import kotlinx.coroutines.launch
import org.hl7.fhir.r4.model.ResourceType
import org.smartregister.fhircore.engine.appfeature.AppFeature
import org.smartregister.fhircore.engine.appfeature.model.HealthModule
import org.smartregister.fhircore.engine.configuration.ConfigurationRegistry
import org.smartregister.fhircore.engine.configuration.app.AppConfigClassification
import org.smartregister.fhircore.engine.configuration.app.ApplicationConfiguration
import org.smartregister.fhircore.engine.data.local.register.PatientRegisterRepository
import org.smartregister.fhircore.engine.domain.model.HealthStatus
import org.smartregister.fhircore.engine.domain.model.ProfileData
import org.smartregister.fhircore.engine.ui.questionnaire.QuestionnaireActivity
import org.smartregister.fhircore.engine.ui.questionnaire.QuestionnaireType
import org.smartregister.fhircore.engine.util.extension.asReference
import org.smartregister.fhircore.engine.util.extension.isGuardianVisit
import org.smartregister.fhircore.engine.util.extension.launchQuestionnaire
import org.smartregister.fhircore.engine.util.extension.launchQuestionnaireForResult
import org.smartregister.fhircore.quest.R
Expand All @@ -51,6 +55,7 @@ class PatientProfileViewModel
constructor(
val overflowMenuFactory: OverflowMenuFactory,
val patientRegisterRepository: PatientRegisterRepository,
val configurationRegistry: ConfigurationRegistry,
val profileViewDataMapper: ProfileViewDataMapper
) : ViewModel() {

Expand All @@ -64,6 +69,11 @@ constructor(
val patientProfileViewData: MutableState<ProfileViewData.PatientProfileViewData> =
mutableStateOf(ProfileViewData.PatientProfileViewData())

var patientProfileData: ProfileData? = null

val applicationConfiguration: ApplicationConfiguration
get() = configurationRegistry.retrieveConfiguration(AppConfigClassification.APPLICATION)

fun fetchPatientProfileData(
appFeatureName: String?,
healthModule: HealthModule,
Expand All @@ -73,6 +83,7 @@ constructor(
viewModelScope.launch {
patientRegisterRepository.loadPatientProfileData(appFeatureName, healthModule, patientId)
?.let {
patientProfileData = it
patientProfileViewData.value =
profileViewDataMapper.transformInputToOutputModel(it) as
ProfileViewData.PatientProfileViewData
Expand Down Expand Up @@ -110,6 +121,30 @@ constructor(
}
}

fun filterGuardianVisitTasks() {
if (patientProfileData != null) {
val hivPatientProfileData = patientProfileData as ProfileData.HivProfileData
val newProfileData =
hivPatientProfileData.copy(
tasks =
hivPatientProfileData.tasks.filter {
it.isGuardianVisit(applicationConfiguration.patientTypeFilterTagViaMetaCodingSystem)
}
)
patientProfileViewData.value =
profileViewDataMapper.transformInputToOutputModel(newProfileData) as
ProfileViewData.PatientProfileViewData
}
}

fun undoGuardianVisitTasksFilter() {
if (patientProfileData != null) {
patientProfileViewData.value =
profileViewDataMapper.transformInputToOutputModel(patientProfileData!!) as
ProfileViewData.PatientProfileViewData
}
}

fun onEvent(event: PatientProfileEvent) =
when (event) {
is PatientProfileEvent.LoadQuestionnaire ->
Expand All @@ -125,6 +160,32 @@ constructor(
clientIdentifier = event.patientId,
questionnaireType = QuestionnaireType.EDIT
)
R.id.guardian_visit -> {
val updatedMenuItems =
patientProfileUiState.value.overflowMenuItems.map {
when (it.id) {
R.id.guardian_visit -> it.apply { hidden = true }
R.id.client_visit -> it.apply { hidden = false }
else -> it
}
}
patientProfileUiState.value =
patientProfileUiState.value.copy(overflowMenuItems = updatedMenuItems)
filterGuardianVisitTasks()
}
R.id.client_visit -> {
val updatedMenuItems =
patientProfileUiState.value.overflowMenuItems.map {
when (it.id) {
R.id.guardian_visit -> it.apply { hidden = false }
R.id.client_visit -> it.apply { hidden = true }
else -> it
}
}
patientProfileUiState.value =
patientProfileUiState.value.copy(overflowMenuItems = updatedMenuItems)
undoGuardianVisitTasksFilter()
}
R.id.view_family -> {
event.familyId?.let { familyId ->
val urlParams =
Expand Down
4 changes: 2 additions & 2 deletions android/quest/src/main/res/values/ids.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
<item name="individual_details" type="id"/>
<item name="view_family" type="id"/>
<item name="record_as_anc" type="id" />
<item name="client_clinic_visit" type="id"/>
<item name="client_visit" type="id"/>
<item name="guardian_visit" type="id"/>
<item name="viral_load_results" type="id"/>
<item name="edit_profile" type="id"/>
<item name="guardian_management" type="id"/>
<item name="exposed_infant_clinic_visit" type="id"/>
<item name="exposed_infant_visit" type="id"/>
<item name="clinic_history" type="id"/>
<item name="hiv_test_and_results" type="id"/>
<item name="hiv_test_and_next_appointment" type="id"/>
Expand Down
4 changes: 2 additions & 2 deletions android/quest/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@
<string name="individual_details">Individual details</string>
<string name="view_family">View family</string>

<string name="client_clinic_visit">Client Clinic Visit</string>
<string name="client_visit">Client Visit</string>
<string name="guardian_visit">Guardian Visit</string>
<string name="viral_load_results">Viral Load Results</string>
<string name="edit_profile">Edit Profile</string>
<string name="guardian_management">Guardian Management</string>
<string name="exposed_infant_clinic_visit">Exposed Infant Clinic Visit</string>
<string name="exposed_infant_visit">Exposed Infant Visit</string>
<string name="clinic_history">Clinic History</string>
<string name="hiv_test_and_results">HIV Test and Results</string>
<string name="hiv_test_and_next_appointment">HIV Test and Next Appointment</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@

package org.smartregister.fhircore.quest.navigation

import androidx.compose.ui.graphics.Color
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import javax.inject.Inject
import org.junit.Assert
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.smartregister.fhircore.engine.domain.model.OverflowMenuItem
import org.smartregister.fhircore.quest.R
import org.smartregister.fhircore.quest.robolectric.RobolectricTest

@HiltAndroidTest
Expand Down Expand Up @@ -52,7 +55,7 @@ class OverflowMenuFactoryTest : RobolectricTest() {
val uiProfileExposedInfant =
overflowMenuFactory.retrieveOverflowMenuItems(OverflowMenuHost.EXPOSED_INFANT_PROFILE)
Assert.assertNotNull(uiProfileExposedInfant)
Assert.assertEquals(6, uiProfileExposedInfant.size)
Assert.assertEquals(5, uiProfileExposedInfant.size)

val uiProfileChildContact =
overflowMenuFactory.retrieveOverflowMenuItems(OverflowMenuHost.CHILD_CONTACT_PROFILE)
Expand All @@ -79,4 +82,40 @@ class OverflowMenuFactoryTest : RobolectricTest() {
Assert.assertNotNull(uiProfilePatient)
Assert.assertEquals(4, uiProfilePatient.size)
}

@Test
fun `client_visit menu items should be hidden for new diagnosed and art clients`() {
val newlyDiagnosedClientVisitMenuItem =
overflowMenuFactory.retrieveOverflowMenuItems(OverflowMenuHost.NEWLY_DIAGNOSED_PROFILE)
.first { it.id == R.id.client_visit }
val artClientClientVisitMenuItem =
overflowMenuFactory.retrieveOverflowMenuItems(OverflowMenuHost.ART_CLIENT_PROFILE).first {
it.id == R.id.client_visit
}
Assert.assertTrue(newlyDiagnosedClientVisitMenuItem.hidden)
Assert.assertTrue(artClientClientVisitMenuItem.hidden)
}

@Test
fun `first newly_diagnosed_profile menuitem should be client_visit`() {
val firstMenuItem =
overflowMenuFactory
.retrieveOverflowMenuItems(OverflowMenuHost.NEWLY_DIAGNOSED_PROFILE)
.first()
Assert.assertEquals(
OverflowMenuItem(R.id.client_visit, R.string.client_visit).apply { hidden = true },
firstMenuItem
)
}

@Test
fun testOverflowMenuItemConstructor() {
val overflowItem =
OverflowMenuItem(R.id.client_visit, R.string.client_visit).apply { hidden = true }
Assert.assertEquals(R.id.client_visit, overflowItem.id)
Assert.assertEquals(R.string.client_visit, overflowItem.titleResource)
Assert.assertEquals(false, overflowItem.confirmAction)
Assert.assertEquals(true, overflowItem.hidden)
Assert.assertEquals(Color.Black.copy(alpha = 0.7f), overflowItem.titleColor)
}
}