Skip to content

Commit a394af5

Browse files
Merge pull request #5840 from simpledotorg/master
2 parents 2a317eb + 5630d1d commit a394af5

16 files changed

Lines changed: 174 additions & 30 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
- Update Titration nudge threshold for diabetic patients in SriLanka from `140/90` to `130/80`
2020
- Add BMI container to patient registration screen
21+
- Add BMI container to patient summary screen
2122

2223
## 2026.05.11
2324

app/src/main/java/org/simple/clinic/medicalhistory/ui/BMIContainer.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import org.simple.clinic.common.ui.components.ButtonSize
2222
import org.simple.clinic.common.ui.components.TextButton
2323
import org.simple.clinic.common.ui.theme.SimpleTheme
2424
import org.simple.clinic.patientattribute.BMIReading
25+
import kotlin.math.roundToInt
2526

2627
@Composable
2728
fun BMIContainer(
@@ -67,7 +68,7 @@ fun BMIContainer(
6768

6869
val bmiText = buildAnnotatedString {
6970
if (isBmiRecorded) {
70-
append(bmiReading.calculateBMI().toString())
71+
append(bmiReading.calculateBMI()?.roundToInt().toString())
7172

7273
append(" ")
7374

app/src/main/java/org/simple/clinic/summary/PatientSummaryEffect.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ data class UpdateTobaccoUse(
9393
val isUsingSmokelessTobacco: MedicalHistoryAnswer
9494
) : PatientSummaryEffect()
9595

96+
data object LoadBMIFeature : PatientSummaryEffect()
97+
9698
sealed class PatientSummaryViewEffect : PatientSummaryEffect()
9799

98100
data class HandleEditClick(
@@ -119,9 +121,9 @@ data class ShowScheduleAppointmentSheet(
119121
val currentFacility: Facility
120122
) : PatientSummaryViewEffect()
121123

122-
data object ShowDiagnosisRequiredError: PatientSummaryViewEffect()
124+
data object ShowDiagnosisRequiredError : PatientSummaryViewEffect()
123125

124-
data object ShowDiagnosisOrReferralRequiredError: PatientSummaryViewEffect()
126+
data object ShowDiagnosisOrReferralRequiredError : PatientSummaryViewEffect()
125127

126128
data object ShowHypertensionDiagnosisRequiredError : PatientSummaryViewEffect()
127129

app/src/main/java/org/simple/clinic/summary/PatientSummaryEffectHandler.kt

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class PatientSummaryEffectHandler @AssistedInject constructor(
104104
.addConsumer(PatientSummaryViewEffect::class.java, viewEffectsConsumer::accept)
105105
.addTransformer(LoadPatientRegistrationData::class.java, checkPatientRegistrationData())
106106
.addTransformer(CheckIfCDSSPilotIsEnabled::class.java, checkIfCDSSPilotIsEnabled())
107+
.addTransformer(LoadBMIFeature::class.java, loadBMIFeature())
107108
.addTransformer(LoadLatestScheduledAppointment::class.java, loadLatestScheduledAppointment())
108109
.addConsumer(UpdatePatientReassignmentStatus::class.java, { updatePatientReassignmentState(it.patientUuid, it.status) }, schedulersProvider.io())
109110
.addTransformer(CheckPatientReassignmentStatus::class.java, checkPatientReassignmentStatus())
@@ -390,9 +391,21 @@ class PatientSummaryEffectHandler @AssistedInject constructor(
390391
.map {
391392
val currentFacilityId = currentFacility.get().uuid
392393
CDSSPilotStatusChecked(isPilotEnabledForFacility =
393-
country.isoCountryCode == Country.ETHIOPIA ||
394-
country.isoCountryCode == Country.SRI_LANKA ||
395-
cdssPilotFacilities.get().contains(currentFacilityId)
394+
country.isoCountryCode == Country.ETHIOPIA ||
395+
country.isoCountryCode == Country.SRI_LANKA ||
396+
cdssPilotFacilities.get().contains(currentFacilityId)
397+
)
398+
}
399+
}
400+
}
401+
402+
private fun loadBMIFeature(): ObservableTransformer<LoadBMIFeature, PatientSummaryEvent> {
403+
return ObservableTransformer { effects ->
404+
effects
405+
.observeOn(schedulersProvider.io())
406+
.map {
407+
BMIFeatureLoaded(
408+
isEnabled = feature.isEnabled(Feature.ShowBMIContainer)
396409
)
397410
}
398411
}
@@ -689,7 +702,7 @@ class PatientSummaryEffectHandler @AssistedInject constructor(
689702
loggedInUserUuid = currentUser.get().uuid,
690703
uuid = uuidGenerator.v4(),
691704
)
692-
BMISaved
705+
BMISaved(createNewBMIEntry.reading)
693706
}
694707
}
695708
}

app/src/main/java/org/simple/clinic/summary/PatientSummaryEvent.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,18 @@ data class BMIReadingAdded(
187187
val bmiReading: BMIReading
188188
) : PatientSummaryEvent()
189189

190+
data class BMISaved(
191+
val bmiReading: BMIReading
192+
) : PatientSummaryEvent()
193+
190194
data object AddBMIClicked : PatientSummaryEvent()
191195

192-
data object AddCholesterolClicked: PatientSummaryEvent()
196+
data object AddCholesterolClicked : PatientSummaryEvent()
193197

194198
data object CholesterolAdded : PatientSummaryEvent()
195199

196-
data object BMISaved : PatientSummaryEvent()
200+
201+
data class BMIFeatureLoaded(
202+
val isEnabled: Boolean
203+
) : PatientSummaryEvent()
197204

app/src/main/java/org/simple/clinic/summary/PatientSummaryInit.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ class PatientSummaryInit : Init<PatientSummaryModel, PatientSummaryEffect> {
99
override fun init(model: PatientSummaryModel): First<PatientSummaryModel, PatientSummaryEffect> {
1010
val effects = mutableSetOf(
1111
LoadPatientSummaryProfile(model.patientUuid),
12-
CheckIfCDSSPilotIsEnabled
12+
CheckIfCDSSPilotIsEnabled,
13+
LoadBMIFeature,
14+
LoadBMiReading(model.patientUuid),
1315
)
1416

1517
if (!model.hasUserLoggedInStatus || !model.hasLoadedCurrentFacility) {

app/src/main/java/org/simple/clinic/summary/PatientSummaryModel.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import org.simple.clinic.cvdrisk.StatinInfo
66
import org.simple.clinic.facility.Facility
77
import org.simple.clinic.overdue.Appointment
88
import org.simple.clinic.patient.PatientStatus
9+
import org.simple.clinic.patientattribute.BMIReading
910
import org.simple.clinic.summary.teleconsultation.sync.MedicalOfficer
1011
import org.simple.clinic.user.User
1112
import org.simple.clinic.util.ParcelableOptional
@@ -30,6 +31,8 @@ data class PatientSummaryModel(
3031
val hasShownDiagnosisWarningDialog: Boolean,
3132
val statinInfo: StatinInfo?,
3233
val hasShownTobaccoUseDialog: Boolean,
34+
val showBMIContainer: Boolean,
35+
val bmiReading: BMIReading?
3336
) : Parcelable, PatientSummaryChildModel {
3437

3538
companion object {
@@ -50,6 +53,8 @@ data class PatientSummaryModel(
5053
hasShownDiagnosisWarningDialog = false,
5154
statinInfo = null,
5255
hasShownTobaccoUseDialog = false,
56+
showBMIContainer = false,
57+
bmiReading = null
5358
)
5459
}
5560
}
@@ -138,4 +143,13 @@ data class PatientSummaryModel(
138143
fun showTobaccoUseDialog(): PatientSummaryModel {
139144
return copy(hasShownTobaccoUseDialog = true)
140145
}
146+
147+
fun bmiVisibilityUpdated(isEnabled: Boolean): PatientSummaryModel {
148+
return copy(showBMIContainer = isEnabled)
149+
}
150+
151+
fun bmiReadingsLoaded(bmiReading: BMIReading?): PatientSummaryModel {
152+
return copy(bmiReading = bmiReading)
153+
}
154+
141155
}

app/src/main/java/org/simple/clinic/summary/PatientSummaryScreen.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import org.simple.clinic.feature.Feature
4949
import org.simple.clinic.feature.Features
5050
import org.simple.clinic.home.HomeScreenKey
5151
import org.simple.clinic.medicalhistory.Answer
52+
import org.simple.clinic.medicalhistory.ui.BMIContainer
5253
import org.simple.clinic.mobius.DeferredEventSource
5354
import org.simple.clinic.mobius.ViewRenderer
5455
import org.simple.clinic.navigation.v2.HandlesBack
@@ -142,6 +143,9 @@ class PatientSummaryScreen :
142143
private val facilityNameAndDateTextView
143144
get() = binding.facilityNameAndDateTextView
144145

146+
private val bmiContainerComposeView
147+
get() = binding.bmiContainerComposeView
148+
145149
private val labelRegistered
146150
get() = binding.labelRegistered
147151

@@ -197,6 +201,8 @@ class PatientSummaryScreen :
197201
private var showClinicalDecisionAlert by mutableStateOf(false)
198202
private var animateClinicalDecisionSupportAlert by mutableStateOf(false)
199203

204+
private var bmiReading by mutableStateOf<BMIReading?>(null)
205+
200206
override fun defaultModel(): PatientSummaryModel {
201207
return PatientSummaryModel.from(screenKey.intention, screenKey.patientUuid)
202208
}
@@ -334,6 +340,17 @@ class PatientSummaryScreen :
334340
}
335341
}
336342
}
343+
344+
bmiContainerComposeView.setContent {
345+
SimpleTheme {
346+
BMIContainer(
347+
bmiReading = bmiReading,
348+
onAddOrClick = {
349+
additionalEvents.notify(AddBMIClicked)
350+
}
351+
)
352+
}
353+
}
337354
}
338355

339356
private fun handleScreenResult(requestKey: Parcelable, result: Succeeded) {
@@ -829,6 +846,15 @@ class PatientSummaryScreen :
829846
this.statinInfo = statinInfo
830847
}
831848

849+
override fun showBMIContainer(bmiReading: BMIReading?) {
850+
bmiContainerComposeView.visibility = VISIBLE
851+
this.bmiReading = bmiReading
852+
}
853+
854+
override fun hideBMIContainer() {
855+
bmiContainerComposeView.visibility = GONE
856+
}
857+
832858
override fun showReassignPatientWarningSheet(
833859
patientUuid: UUID,
834860
currentFacility: Facility,

app/src/main/java/org/simple/clinic/summary/PatientSummaryScreenUi.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.simple.clinic.summary
22

33
import org.simple.clinic.cvdrisk.StatinInfo
4+
import org.simple.clinic.patientattribute.BMIReading
45

56
interface PatientSummaryScreenUi {
67
fun renderPatientSummaryToolbar(patientSummaryProfile: PatientSummaryProfile)
@@ -21,4 +22,6 @@ interface PatientSummaryScreenUi {
2122
fun hideClinicalDecisionSupportAlert()
2223
fun hideClinicalDecisionSupportAlertWithoutAnimation()
2324
fun updateStatinAlert(statinInfo: StatinInfo)
25+
fun showBMIContainer(bmiReading: BMIReading?)
26+
fun hideBMIContainer()
2427
}

app/src/main/java/org/simple/clinic/summary/PatientSummaryUpdate.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,18 @@ class PatientSummaryUpdate(
110110
is AddTobaccoUseClicked -> dispatch(ShowTobaccoStatusDialog)
111111
is TobaccoUseAnswered -> dispatch(UpdateTobaccoUse(model.patientUuid, event.isSmoker, event.isUsingSmokelessTobacco))
112112
is BMIReadingAdded -> dispatch(CreateNewBMIEntry(model.patientUuid, event.bmiReading))
113-
is AddBMIClicked -> dispatch(LoadBMiReading(model.patientUuid))
113+
is AddBMIClicked -> dispatch(OpenBMIEntrySheet(model.bmiReading))
114114
is AddCholesterolClicked -> dispatch(OpenCholesterolEntrySheet(model.patientUuid))
115115
CholesterolAdded -> dispatch(CalculateLabBasedCVDRisk(model.patientSummaryProfile!!.patient))
116-
is BMIReadingLoaded -> dispatch(OpenBMIEntrySheet(event.bmiReading))
117-
is BMISaved -> dispatch(CalculateNonLabBasedCVDRisk(model.patientSummaryProfile!!.patient))
116+
is BMIReadingLoaded -> next(model.bmiReadingsLoaded(event.bmiReading))
117+
is BMISaved -> {
118+
next(
119+
model.copy(bmiReading = event.bmiReading),
120+
setOf(CalculateNonLabBasedCVDRisk(model.patientSummaryProfile!!.patient))
121+
)
122+
}
123+
124+
is BMIFeatureLoaded -> next(model.bmiVisibilityUpdated(event.isEnabled))
118125
}
119126
}
120127

0 commit comments

Comments
 (0)