Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the Practitioner selection screen on the In-app reporting workflow #2605

Merged
merged 15 commits into from
Jul 21, 2023
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import android.os.Parcelable
import androidx.compose.foundation.layout.Arrangement
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import org.smartregister.fhircore.engine.domain.model.ActionConfig
import org.smartregister.fhircore.engine.domain.model.ViewType
import org.smartregister.fhircore.engine.util.extension.interpolate

Expand All @@ -41,6 +42,7 @@ data class ColumnProperties(
val arrangement: ColumnArrangement? = null,
val children: List<ViewProperties> = emptyList(),
val showDivider: String = "false",
val actions: List<ActionConfig> = emptyList(),
) : ViewProperties(), Parcelable {
override fun interpolate(computedValuesMap: Map<String, Any>): ColumnProperties {
return this.copy(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import android.os.Parcelable
import androidx.compose.foundation.layout.Arrangement
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import org.smartregister.fhircore.engine.domain.model.ActionConfig
import org.smartregister.fhircore.engine.domain.model.ViewType
import org.smartregister.fhircore.engine.util.extension.interpolate

Expand All @@ -40,6 +41,7 @@ data class RowProperties(
val arrangement: RowArrangement? = null,
val wrapContent: Boolean = false,
val children: List<ViewProperties> = emptyList(),
val actions: List<ActionConfig> = emptyList(),
) : ViewProperties(), Parcelable {
override fun interpolate(computedValuesMap: Map<String, Any>): RowProperties {
return this.copy(
Expand Down
1 change: 1 addition & 0 deletions android/engine/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,5 @@
<string name="unsynced_resources">Unsynced Resources</string>
<string name="all_data_synced">All data synced</string>
<string name="invalid_offline_login_state">User set up required. Enable your internet connection </string>
<string name="select_date_range">Select Date Range</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ class ReportTypeSelectorScreenTest {
dateRange = null,
reportPeriodRange = mapOf(),
onBackPressed = {},
onGenerateReport = {},
onSelectReportDate = {},
onDateRangeSelected = {},
onReportTypeSelected = {},
onSubjectRemoved = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ constructor(
endDateFormatted: String,
subjects: List<String>,
existing: List<MeasureReport>,
practitionerId: String?,
): List<MeasureReport> {
val measureReport = mutableListOf<MeasureReport>()
try {
Expand All @@ -83,21 +84,23 @@ constructor(
subjects
.map {
runMeasureReport(
measureUrl,
MeasureReportViewModel.SUBJECT,
startDateFormatted,
endDateFormatted,
it,
measureUrl = measureUrl,
reportType = MeasureReportViewModel.SUBJECT,
startDateFormatted = startDateFormatted,
endDateFormatted = endDateFormatted,
subject = it,
practitionerId = practitionerId,
)
}
.forEach { subject -> measureReport.add(subject) }
} else {
runMeasureReport(
measureUrl,
MeasureReportViewModel.POPULATION,
startDateFormatted,
endDateFormatted,
null,
measureUrl = measureUrl,
reportType = MeasureReportViewModel.POPULATION,
startDateFormatted = startDateFormatted,
endDateFormatted = endDateFormatted,
subject = null,
practitionerId = practitionerId,
)
.also { measureReport.add(it) }
}
Expand Down Expand Up @@ -135,14 +138,15 @@ constructor(
startDateFormatted: String,
endDateFormatted: String,
subject: String?,
practitionerId: String?,
): MeasureReport {
return fhirOperator.evaluateMeasure(
measureUrl = measureUrl,
start = startDateFormatted,
end = endDateFormatted,
reportType = reportType,
subject = subject,
practitioner = null,
practitioner = practitionerId,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
package org.smartregister.fhircore.quest.navigation

sealed class MeasureReportNavigationScreen(val route: String) {
object MeasureReportList : MeasureReportNavigationScreen("reportMeasuresList")
object MeasureReportModule : MeasureReportNavigationScreen("reportMeasuresModule")

object ReportTypeSelector : MeasureReportNavigationScreen("reportTypeSelector")
object ReportDateSelector : MeasureReportNavigationScreen("reportDateSelector")

object SubjectsList : MeasureReportNavigationScreen("subjectsList")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ sealed class MeasureReportEvent {
data class OnSelectMeasure(
val reportConfigurations: List<ReportConfiguration>? = emptyList(),
val navController: NavController,
val practitionerId: String? = "",
) : MeasureReportEvent()

data class OnDateRangeSelected(val newDateRange: androidx.core.util.Pair<Long, Long>) :
MeasureReportEvent()

data class GenerateReport(val navController: NavController, val context: Context) :
MeasureReportEvent()
data class OnDateSelected(
val navController: NavController,
val context: Context,
val practitionerId: String? = null,
) : MeasureReportEvent()

data class OnReportTypeChanged(
val measureReportType: MeasureReport.MeasureReportType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class MeasureReportFragment : Fragment() {
AppTheme {
MeasureReportMainScreen(
reportId = measureReportFragmentArgs.reportId,
practitionerId = measureReportFragmentArgs.resourceId,
measureReportViewModel = measureReportViewModel,
mainNavController = findNavController(),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,25 @@
package org.smartregister.fhircore.quest.ui.report.measure

import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.navigation.NavController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import org.smartregister.fhircore.quest.R
import org.smartregister.fhircore.quest.navigation.MeasureReportNavigationScreen
import org.smartregister.fhircore.quest.navigation.NavigationArg
import org.smartregister.fhircore.quest.ui.report.measure.screens.MeasureReportListScreen
import org.smartregister.fhircore.quest.ui.report.measure.screens.MeasureReportResultScreen
import org.smartregister.fhircore.quest.ui.report.measure.screens.MeasureReportSubjectsScreen
import org.smartregister.fhircore.quest.ui.report.measure.screens.ReportTypeSelectorScreen
import org.smartregister.fhircore.quest.ui.report.measure.screens.ReportDateSelectorScreen

@Composable
fun MeasureReportMainScreen(
reportId: String,
practitionerId: String,
mainNavController: NavController,
measureReportViewModel: MeasureReportViewModel,
) {
Expand All @@ -41,37 +44,39 @@ fun MeasureReportMainScreen(

NavHost(
navController = navController,
startDestination = MeasureReportNavigationScreen.MeasureReportList.route,
startDestination = MeasureReportNavigationScreen.ReportDateSelector.route,
) {
// Display list of supported measures for reporting
composable(MeasureReportNavigationScreen.MeasureReportList.route) {
composable(MeasureReportNavigationScreen.MeasureReportModule.route) {
MeasureReportListScreen(
mainNavController = mainNavController,
dataList = measureReportViewModel.reportMeasuresList(reportId),
onReportMeasureClicked = { measureReportRowData ->
measureReportViewModel.onEvent(
MeasureReportEvent.OnSelectMeasure(measureReportRowData, navController),
MeasureReportEvent.OnSelectMeasure(
reportConfigurations = measureReportRowData,
navController = navController,
practitionerId = practitionerId,
),
)
},
)
}
// Choose report type; for either individual or population
// Page for selecting report date
composable(
route =
MeasureReportNavigationScreen.ReportTypeSelector.route +
NavigationArg.routePathsOf(NavigationArg.SCREEN_TITLE),
route = MeasureReportNavigationScreen.ReportDateSelector.route,
arguments =
listOf(
navArgument(NavigationArg.SCREEN_TITLE) {
type = NavType.StringType
defaultValue = ""
},
),
) { stackEntry ->
val screenTitle: String = stackEntry.arguments?.getString(NavigationArg.SCREEN_TITLE) ?: ""
ReportTypeSelectorScreen(
) {
ReportDateSelectorScreen(
reportId = reportId,
screenTitle = screenTitle,
practitionerId = practitionerId,
screenTitle = stringResource(R.string.select_date_range),
navController = navController,
measureReportViewModel = measureReportViewModel,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ import org.smartregister.fhircore.quest.data.report.measure.MeasureReportPagingS
import org.smartregister.fhircore.quest.data.report.measure.MeasureReportRepository
import org.smartregister.fhircore.quest.data.report.measure.MeasureReportSubjectsPagingSource
import org.smartregister.fhircore.quest.navigation.MeasureReportNavigationScreen
import org.smartregister.fhircore.quest.navigation.NavigationArg
import org.smartregister.fhircore.quest.ui.report.measure.models.MeasureReportIndividualResult
import org.smartregister.fhircore.quest.ui.report.measure.models.MeasureReportPopulationResult
import org.smartregister.fhircore.quest.ui.report.measure.models.ReportRangeSelectionData
Expand Down Expand Up @@ -161,14 +160,8 @@ constructor(
reportConfigurations.clear()
reportConfigurations.addAll(it)
}
event.navController.navigate(
MeasureReportNavigationScreen.ReportTypeSelector.route +
NavigationArg.bindArgumentsOf(
Pair(NavigationArg.SCREEN_TITLE, reportConfigurations.firstOrNull()?.module ?: ""),
),
)
}
is MeasureReportEvent.GenerateReport -> {

// generate report
if (selectedDate != null) {
reportTypeState.value = MeasureReport.MeasureReportType.SUMMARY
reportTypeSelectorUiState.value =
Expand All @@ -178,7 +171,18 @@ constructor(
)
}
refreshData()
evaluateMeasure(event.navController)
event.practitionerId?.let { evaluateMeasure(event.navController, practitionerId = it) }
}
is MeasureReportEvent.OnDateSelected -> {
if (selectedDate != null) {
reportTypeState.value = MeasureReport.MeasureReportType.SUMMARY
reportTypeSelectorUiState.value =
reportTypeSelectorUiState.value.copy(
startDate = selectedDate.firstDayOfMonth().formatDate(SDF_D_MMM_YYYY_WITH_COMA),
endDate = selectedDate.lastDayOfMonth().formatDate(SDF_D_MMM_YYYY_WITH_COMA),
)
}
event.navController.navigate(MeasureReportNavigationScreen.MeasureReportModule.route)
}
is MeasureReportEvent.OnDateRangeSelected -> {
// Update dateRange and format start/end dates e.g 16 Nov, 2020 - 29 Oct, 2021
Expand Down Expand Up @@ -260,7 +264,7 @@ constructor(
}

// TODO: Enhancement - use FhirPathEngine evaluator for data extraction
fun evaluateMeasure(navController: NavController) {
fun evaluateMeasure(navController: NavController, practitionerId: String? = null) {
// Run evaluate measure only for existing report
if (reportConfigurations.isNotEmpty()) {
// Retrieve and parse dates to (2020-11-16)
Expand All @@ -282,13 +286,14 @@ constructor(
val result =
reportConfigurations.flatMap { config ->
val subjects = measureReportRepository.fetchSubjects(config)

val existing =
retrievePreviouslyGeneratedMeasureReports(
fhirEngine,
startDateFormatted,
endDateFormatted,
config.url,
listOf(),
fhirEngine = fhirEngine,
startDateFormatted = startDateFormatted,
endDateFormatted = endDateFormatted,
measureUrl = config.url,
subjects = listOf(),
)

// if report is of current month or does not exist generate a new one and replace
Expand All @@ -304,11 +309,12 @@ constructor(
}

measureReportRepository.evaluatePopulationMeasure(
config.url,
startDateFormatted,
endDateFormatted,
subjects,
existing,
measureUrl = config.url,
startDateFormatted = startDateFormatted,
endDateFormatted = endDateFormatted,
subjects = subjects,
existing = existing,
practitionerId = practitionerId,
)
} else {
existing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,9 @@ const val YEAR_TEST_TAG = "YEAR_TEST_TAG"
const val MONTH_TEST_TAG = "MONTH_TEST_TAG"

@Composable
fun ReportTypeSelectorScreen(
fun ReportDateSelectorScreen(
reportId: String,
practitionerId: String = "",
screenTitle: String,
navController: NavController,
measureReportViewModel: MeasureReportViewModel,
Expand All @@ -120,13 +121,13 @@ fun ReportTypeSelectorScreen(
// Reset UI state
measureReportViewModel.resetState()
navController.popBackStack(
route = MeasureReportNavigationScreen.MeasureReportList.route,
route = MeasureReportNavigationScreen.MeasureReportModule.route,
inclusive = false,
)
},
onGenerateReport = { date ->
onSelectReportDate = { date ->
measureReportViewModel.onEvent(
MeasureReportEvent.GenerateReport(navController, context),
MeasureReportEvent.OnDateSelected(navController, context, practitionerId = practitionerId),
date,
)
},
Expand All @@ -151,7 +152,7 @@ fun ReportFilterSelector(
reportPeriodRange: Map<String, List<ReportRangeSelectionData>>,
modifier: Modifier = Modifier,
onBackPressed: () -> Unit,
onGenerateReport: (date: Date?) -> Unit,
onSelectReportDate: (date: Date?) -> Unit,
onDateRangeSelected: (Pair<Long, Long>) -> Unit,
onReportTypeSelected: (MeasureReportType) -> Unit,
onSubjectRemoved: (MeasureReportSubjectViewData) -> Unit,
Expand Down Expand Up @@ -214,7 +215,7 @@ fun ReportFilterSelector(
) {
if (showFixedRangeSelection) {
FixedMonthYearListing(
onMonthSelected = onGenerateReport,
onMonthSelected = onSelectReportDate,
showProgressIndicator = uiState.showProgressIndicator,
reportGenerationRange = reportPeriodRange,
innerPadding = innerPadding,
Expand All @@ -228,7 +229,7 @@ fun ReportFilterSelector(
uiState.endDate.isNotEmpty() &&
(uiState.subjectViewData != null ||
reportTypeState.value == MeasureReportType.SUMMARY),
onGenerateReportClicked = { onGenerateReport.invoke(null) },
onGenerateReportClicked = { onSelectReportDate.invoke(null) },
showProgressIndicator = uiState.showProgressIndicator,
dateRange = dateRange!!,
onDateRangeSelected = onDateRangeSelected,
Expand Down Expand Up @@ -548,7 +549,7 @@ fun FixedRangeListPreview() {
dateRange = null,
reportPeriodRange = ranges,
onBackPressed = {},
onGenerateReport = {},
onSelectReportDate = {},
onDateRangeSelected = {},
onReportTypeSelected = {},
onSubjectRemoved = {},
Expand All @@ -571,7 +572,7 @@ fun ReportFilterPreview() {
dateRange = dateRange,
reportPeriodRange = mapOf(),
onBackPressed = {},
onGenerateReport = {},
onSelectReportDate = {},
onDateRangeSelected = {},
onReportTypeSelected = {},
onSubjectRemoved = {},
Expand Down
Loading