From e9f836e1f573e9ab0f3c83cb56979b530034099a Mon Sep 17 00:00:00 2001 From: kapmaurya Date: Tue, 27 May 2025 15:39:21 +0530 Subject: [PATCH 01/18] cmp-report migration --- .../kotlin/cmp/navigation/di/KoinModules.kt | 2 +- .../component/MifosTextFieldDropdown.kt | 3 +- feature/report/build.gradle.kts | 24 ++-- .../{main => androidMain}/AndroidManifest.xml | 0 .../feature_report_ic_report_item.xml | 0 .../composeResources}/values/strings.xml | 0 .../mifos/feature/report/di/ReportModule.kt | 0 .../report/navigation/ReportNavigation.kt | 4 +- .../report/navigation/ReportScreens.kt | 0 .../feature/report/report/ReportScreen.kt | 76 ++++++------ .../feature/report/report/ReportUiState.kt | 4 +- .../feature/report/report/ReportViewModel.kt | 15 ++- .../report/reportDetail/ReportDetailScreen.kt | 110 ++++++++++-------- .../reportDetail/ReportDetailUiState.kt | 4 +- .../reportDetail/ReportDetailViewModel.kt | 12 +- .../report/runReport/RunReportScreen.kt | 37 +++--- .../report/runReport/RunReportUiState.kt | 3 +- .../report/runReport/RunReportViewModel.kt | 9 +- gradle/libs.versions.toml | 2 + settings.gradle.kts | 2 +- 20 files changed, 169 insertions(+), 138 deletions(-) rename feature/report/src/{main => androidMain}/AndroidManifest.xml (100%) rename feature/report/src/{main/res => commonMain/composeResources}/drawable/feature_report_ic_report_item.xml (100%) rename feature/report/src/{main/res => commonMain/composeResources}/values/strings.xml (100%) rename feature/report/src/{main/java => commonMain/kotlin}/com/mifos/feature/report/di/ReportModule.kt (100%) rename feature/report/src/{main/java => commonMain/kotlin}/com/mifos/feature/report/navigation/ReportNavigation.kt (98%) rename feature/report/src/{main/java => commonMain/kotlin}/com/mifos/feature/report/navigation/ReportScreens.kt (100%) rename feature/report/src/{main/java => commonMain/kotlin}/com/mifos/feature/report/report/ReportScreen.kt (72%) rename feature/report/src/{main/java => commonMain/kotlin}/com/mifos/feature/report/report/ReportUiState.kt (77%) rename feature/report/src/{main/java => commonMain/kotlin}/com/mifos/feature/report/report/ReportViewModel.kt (77%) rename feature/report/src/{main/java => commonMain/kotlin}/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt (88%) rename feature/report/src/{main/java => commonMain/kotlin}/com/mifos/feature/report/reportDetail/ReportDetailUiState.kt (81%) rename feature/report/src/{main/java => commonMain/kotlin}/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt (90%) rename feature/report/src/{main/java => commonMain/kotlin}/com/mifos/feature/report/runReport/RunReportScreen.kt (89%) rename feature/report/src/{main/java => commonMain/kotlin}/com/mifos/feature/report/runReport/RunReportUiState.kt (83%) rename feature/report/src/{main/java => commonMain/kotlin}/com/mifos/feature/report/runReport/RunReportViewModel.kt (80%) diff --git a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt index 6a3552c2658..3ccacb53ea2 100644 --- a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt +++ b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt @@ -59,7 +59,7 @@ object KoinModules { NoteModule, // OfflineModule, // PathTrackingModule, -// ReportModule, + ReportModule, // SavingsModule, // SearchModule, // SettingsModule, diff --git a/core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosTextFieldDropdown.kt b/core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosTextFieldDropdown.kt index 4b6e416193e..c67a1a19c85 100644 --- a/core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosTextFieldDropdown.kt +++ b/core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosTextFieldDropdown.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import org.jetbrains.compose.resources.StringResource @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -42,7 +43,7 @@ fun MifosTextFieldDropdown( modifier: Modifier = Modifier .fillMaxWidth() .padding(start = 16.dp, end = 16.dp), - label: Int? = null, + label: StringResource = null, labelString: String? = null, readOnly: Boolean = false, ) { diff --git a/feature/report/build.gradle.kts b/feature/report/build.gradle.kts index 84692c67ace..41e90825d2a 100644 --- a/feature/report/build.gradle.kts +++ b/feature/report/build.gradle.kts @@ -8,21 +8,23 @@ * See https://github.com/openMF/android-client/blob/master/LICENSE.md */ plugins { - alias(libs.plugins.mifos.android.feature) - alias(libs.plugins.mifos.android.library.compose) - alias(libs.plugins.mifos.android.library.jacoco) + alias(libs.plugins.mifos.cmp.feature) } android { namespace = "com.mifos.feature.report" } +kotlin { + sourceSets { + commonMain.dependencies { + implementation(compose.material3) + implementation(compose.components.resources) + implementation(compose.ui) + api(projects.core.domain) + } + } +} dependencies { - - implementation(projects.core.domain) - - //DBFlow dependencies - testImplementation(libs.hilt.android.testing) - - implementation(libs.kotlinx.serialization.json) -} \ No newline at end of file + implementation(libs.androidx.ui.android) +} diff --git a/feature/report/src/main/AndroidManifest.xml b/feature/report/src/androidMain/AndroidManifest.xml similarity index 100% rename from feature/report/src/main/AndroidManifest.xml rename to feature/report/src/androidMain/AndroidManifest.xml diff --git a/feature/report/src/main/res/drawable/feature_report_ic_report_item.xml b/feature/report/src/commonMain/composeResources/drawable/feature_report_ic_report_item.xml similarity index 100% rename from feature/report/src/main/res/drawable/feature_report_ic_report_item.xml rename to feature/report/src/commonMain/composeResources/drawable/feature_report_ic_report_item.xml diff --git a/feature/report/src/main/res/values/strings.xml b/feature/report/src/commonMain/composeResources/values/strings.xml similarity index 100% rename from feature/report/src/main/res/values/strings.xml rename to feature/report/src/commonMain/composeResources/values/strings.xml diff --git a/feature/report/src/main/java/com/mifos/feature/report/di/ReportModule.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/di/ReportModule.kt similarity index 100% rename from feature/report/src/main/java/com/mifos/feature/report/di/ReportModule.kt rename to feature/report/src/commonMain/kotlin/com/mifos/feature/report/di/ReportModule.kt diff --git a/feature/report/src/main/java/com/mifos/feature/report/navigation/ReportNavigation.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt similarity index 98% rename from feature/report/src/main/java/com/mifos/feature/report/navigation/ReportNavigation.kt rename to feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt index cfaadc5e447..257f50d6921 100644 --- a/feature/report/src/main/java/com/mifos/feature/report/navigation/ReportNavigation.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt @@ -22,7 +22,9 @@ import com.mifos.feature.report.report.ReportScreen import com.mifos.feature.report.reportDetail.ReportDetailScreen import com.mifos.feature.report.runReport.RunReportScreen import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json +//import kotlinx.serialization.json.Json + + fun NavGraphBuilder.reportNavGraph( navController: NavController, diff --git a/feature/report/src/main/java/com/mifos/feature/report/navigation/ReportScreens.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportScreens.kt similarity index 100% rename from feature/report/src/main/java/com/mifos/feature/report/navigation/ReportScreens.kt rename to feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportScreens.kt diff --git a/feature/report/src/main/java/com/mifos/feature/report/report/ReportScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt similarity index 72% rename from feature/report/src/main/java/com/mifos/feature/report/report/ReportScreen.kt rename to feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt index 4531cc85b85..5ca1386af9b 100644 --- a/feature/report/src/main/java/com/mifos/feature/report/report/ReportScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt @@ -9,10 +9,6 @@ */ package com.mifos.feature.report.report -import android.Manifest -import android.os.Build -import android.os.Environment -import android.widget.Toast import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyRow @@ -33,22 +29,19 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color.Companion.Black import androidx.compose.ui.graphics.Color.Companion.White -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp -import androidx.core.content.ContextCompat.getString import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.mifos.core.designsystem.component.MifosScaffold import com.mifos.core.designsystem.component.PermissionBox import com.mifos.core.model.objects.runreport.FullParameterListResponse -import com.mifos.feature.report.R +import com.mifos.core.ui.util.DevicePreview +import core.designsystem.generated.resources.Res import kotlinx.coroutines.launch -import org.koin.androidx.compose.koinViewModel +import org.jetbrains.compose.resources.getString +import org.jetbrains.compose.resources.stringResource +import org.koin.compose.viewmodel.koinViewModel @Composable internal fun ReportScreen( @@ -66,7 +59,8 @@ internal fun ReportScreen( exportReport = { val reportDirectoryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) - .toString() + getString(context, R.string.feature_report_export_csv_directory) + .toString() + getString(context, Res.string.feature_report_export_csv_directory) + viewModel.exportCsv( report = report, reportDirectoryPath = reportDirectoryPath, @@ -91,7 +85,7 @@ internal fun ReportScreen( when (state) { is ReportUiState.Initial -> Unit is ReportUiState.Message -> { - Toast.makeText(context, stringResource(id = state.message), Toast.LENGTH_SHORT).show() + Toast.makeText(context, stringResource(state.message), Toast.LENGTH_SHORT).show() } } @@ -105,10 +99,10 @@ internal fun ReportScreen( Manifest.permission.WRITE_EXTERNAL_STORAGE, ) }, - title = stringResource(R.string.feature_report_permission_required), - description = stringResource(R.string.feature_report_external_approve_permission_description), - confirmButtonText = stringResource(R.string.feature_report_proceed), - dismissButtonText = stringResource(R.string.feature_report_dismiss), + title = stringResource(Res.string.feature_report_permission_required), + description = stringResource(Res.string.feature_report_external_approve_permission_description), + confirmButtonText = stringResource(Res.string.feature_report_proceed), + dismissButtonText = stringResource(Res.string.feature_report_dismiss), onGranted = { LaunchedEffect(key1 = Unit) { scope.launch { @@ -121,7 +115,7 @@ internal fun ReportScreen( MifosScaffold( modifier = modifier, - title = stringResource(R.string.feature_report_title), + title = stringResource(Res.string.feature_report_title), onBackPressed = onBackPressed, actions = { TextButton( @@ -130,7 +124,7 @@ internal fun ReportScreen( }, colors = ButtonDefaults.textButtonColors(White), ) { - Text(text = stringResource(id = R.string.feature_report_export_csv), color = Black) + Text(text = stringResource(Res.string.feature_report_export_csv), color = Black) } }, snackbarHostState = snackbarHostState, @@ -161,24 +155,24 @@ internal fun ReportScreen( } } -private class ReportUiStateProvider : PreviewParameterProvider { - - override val values: Sequence - get() = sequenceOf( - ReportUiState.Initial, - ReportUiState.Message(R.string.feature_report_export_csv), - ) -} - -@Preview(showBackground = true) -@Composable -private fun ReportScreenPreview( - @PreviewParameter(ReportUiStateProvider::class) state: ReportUiState, -) { - ReportScreen( - state = state, - report = FullParameterListResponse(emptyList(), emptyList()), - onBackPressed = { }, - exportReport = { }, - ) -} +//private class ReportUiStateProvider : PreviewParameterProvider { +// +// override val values: Sequence +// get() = sequenceOf( +// ReportUiState.Initial, +// ReportUiState.Message(Res.string.feature_report_export_csv), +// ) +//} +// +//@DevicePreview +//@Composable +//private fun ReportScreenPreview( +// @PreviewParameter(ReportUiStateProvider::class) state: ReportUiState, +//) { +// ReportScreen( +// state = state, +// report = FullParameterListResponse(emptyList(), emptyList()), +// onBackPressed = { }, +// exportReport = { }, +// ) +//} diff --git a/feature/report/src/main/java/com/mifos/feature/report/report/ReportUiState.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportUiState.kt similarity index 77% rename from feature/report/src/main/java/com/mifos/feature/report/report/ReportUiState.kt rename to feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportUiState.kt index 2fd2f77ac8b..c29035ae3ac 100644 --- a/feature/report/src/main/java/com/mifos/feature/report/report/ReportUiState.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportUiState.kt @@ -9,9 +9,11 @@ */ package com.mifos.feature.report.report +import org.jetbrains.compose.resources.StringResource + sealed class ReportUiState { data object Initial : ReportUiState() - data class Message(val message: Int) : ReportUiState() + data class Message(val message: StringResource) : ReportUiState() } diff --git a/feature/report/src/main/java/com/mifos/feature/report/report/ReportViewModel.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt similarity index 77% rename from feature/report/src/main/java/com/mifos/feature/report/report/ReportViewModel.kt rename to feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt index 087a7f30930..88029e5e8bb 100644 --- a/feature/report/src/main/java/com/mifos/feature/report/report/ReportViewModel.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt @@ -9,12 +9,16 @@ */ package com.mifos.feature.report.report +import androidclient.feature.report.generated.resources.Res +import androidclient.feature.report.generated.resources.feature_report_export_started +import androidclient.feature.report.generated.resources.feature_report_exported_successfully +import androidclient.feature.report.generated.resources.feature_report_unable_to_create_directory +import androidclient.feature.report.generated.resources.feature_report_unable_to_export import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.mifos.core.common.utils.Constants import com.mifos.core.model.objects.runreport.FullParameterListResponse -import com.mifos.feature.report.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -22,6 +26,7 @@ import kotlinx.coroutines.launch import kotlinx.serialization.json.Json import java.io.File import java.io.FileWriter +import kotlinx.coroutines.IO class ReportViewModel( savedStateHandle: SavedStateHandle, @@ -37,7 +42,7 @@ class ReportViewModel( fun exportCsv(report: FullParameterListResponse, reportDirectoryPath: String) = viewModelScope.launch(Dispatchers.IO) { - _reportUiState.value = ReportUiState.Message(R.string.feature_report_export_started) + _reportUiState.value = ReportUiState.Message(Res.string.feature_report_export_started) val timestamp = System.currentTimeMillis() val reportPath = "$reportDirectoryPath$timestamp.csv" val reportDirectory = File(reportDirectoryPath) @@ -46,7 +51,7 @@ class ReportViewModel( val makeRequiredDirectories = reportDirectory.mkdirs() if (!makeRequiredDirectories) { _reportUiState.value = - ReportUiState.Message(R.string.feature_report_unable_to_create_directory) + ReportUiState.Message(Res.string.feature_report_unable_to_create_directory) } } @@ -75,9 +80,9 @@ class ReportViewModel( fileWriter.close() } catch (e: Exception) { _reportUiState.value = - ReportUiState.Message(R.string.feature_report_unable_to_export) + ReportUiState.Message(Res.string.feature_report_unable_to_export) } _reportUiState.value = - ReportUiState.Message(R.string.feature_report_exported_successfully) + ReportUiState.Message(Res.string.feature_report_exported_successfully) } } diff --git a/feature/report/src/main/java/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt similarity index 88% rename from feature/report/src/main/java/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt rename to feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt index 3c75ba22fe5..85121722210 100644 --- a/feature/report/src/main/java/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt @@ -9,6 +9,15 @@ */ package com.mifos.feature.report.reportDetail +import androidclient.feature.report.generated.resources.Res +import androidclient.feature.report.generated.resources.feature_report_currency +import androidclient.feature.report.generated.resources.feature_report_details +import androidclient.feature.report.generated.resources.feature_report_failed_to_load_report_details +import androidclient.feature.report.generated.resources.feature_report_gl_account +import androidclient.feature.report.generated.resources.feature_report_obligation_date +import androidclient.feature.report.generated.resources.feature_report_par_type +import androidclient.feature.report.generated.resources.feature_report_run_report +import androidclient.feature.report.generated.resources.feature_report_saving_account import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -47,11 +56,9 @@ import androidx.compose.ui.graphics.Color.Companion.Blue import androidx.compose.ui.graphics.Color.Companion.Gray import androidx.compose.ui.graphics.Color.Companion.White import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp @@ -65,8 +72,9 @@ import com.mifos.core.designsystem.component.MifosTextFieldDropdown import com.mifos.core.model.objects.runreport.DataRow import com.mifos.core.model.objects.runreport.FullParameterListResponse import com.mifos.core.model.objects.runreport.client.ClientReportTypeItem -import com.mifos.feature.report.R -import org.koin.androidx.compose.koinViewModel +import com.mifos.core.ui.util.DevicePreview +import org.jetbrains.compose.resources.stringResource +import org.koin.compose.viewmodel.koinViewModel @Composable internal fun ReportDetailScreen( @@ -210,21 +218,21 @@ internal fun ReportDetailScreen( MifosScaffold( modifier = modifier, - title = stringResource(id = R.string.feature_report_details), + title = stringResource(Res.string.feature_report_details), onBackPressed = onBackPressed, actions = { TextButton( onClick = { runReport(runReportDetail) }, colors = ButtonDefaults.textButtonColors(White), ) { - Text(text = stringResource(id = R.string.feature_report_run_report), color = Black) + Text(text = stringResource(Res.string.feature_report_run_report), color = Black) } }, snackbarHostState = snackbarHostState, ) { paddingValues -> Box(modifier = Modifier.padding(paddingValues)) { when (state) { - is ReportDetailUiState.Error -> MifosSweetError(message = stringResource(id = state.message)) { + is ReportDetailUiState.Error -> MifosSweetError(message = stringResource(state.message)) { onRetry() } @@ -368,7 +376,7 @@ private fun RunReportContent( .background(Blue, CircleShape), ) { Icon( - painter = painterResource(id = R.drawable.feature_report_ic_report_item), + painter = painterResource(Res.drawable.feature_report_ic_report_item), contentDescription = null, tint = Black, ) @@ -430,7 +438,7 @@ private fun RunReportContent( selectedOffice = value selectedOfficeId = officeList[index].row.first() }, - label = R.string.feature_report_office, + label = Res.string.feature_report_office, options = officeList.map { it.row[1] }, readOnly = true, ) @@ -447,7 +455,7 @@ private fun RunReportContent( selectedLoanPurpose = value selectedLoanPurposeId = loanPurposeList[index].row.first() }, - label = R.string.feature_report_loan_purpose, + label = Res.string.feature_report_loan_purpose, options = loanPurposeList.map { it.row[1] }, readOnly = true, ) @@ -464,7 +472,7 @@ private fun RunReportContent( selectedLoanOfficer = value selectedLoanOfficerId = reportOffices[index].row.first() }, - label = R.string.feature_report_loan_officer, + label = Res.string.feature_report_loan_officer, options = reportOffices.map { it.row[1] }, readOnly = true, ) @@ -481,7 +489,7 @@ private fun RunReportContent( selectedProducts = value selectedProductsId = reportProducts[index].row.first() }, - label = R.string.feature_report_product, + label = Res.string.feature_report_product, options = reportProducts.map { it.row[1] }, readOnly = true, ) @@ -498,7 +506,7 @@ private fun RunReportContent( selectedFund = value selectedFundId = fundList[index].row.first() }, - label = R.string.feature_report_fund, + label = Res.string.feature_report_fund, options = fundList.map { it.row[1] }, readOnly = true, ) @@ -515,7 +523,7 @@ private fun RunReportContent( selectedCurrency = value selectedCurrencyId = currencyList[index].row.first() }, - label = R.string.feature_report_currency, + label = Res.string.feature_report_currency, options = currencyList.map { it.row[1] }, readOnly = true, ) @@ -532,7 +540,7 @@ private fun RunReportContent( selectedParCalculator = value selectedParCalculatorId = parCalculatorList[index].row.first() }, - label = R.string.feature_report_par_type, + label = Res.string.feature_report_par_type, options = parCalculatorList.map { it.row[1] }, readOnly = true, ) @@ -549,7 +557,7 @@ private fun RunReportContent( selectedSavingsAccountDeposit = value selectedSavingsAccountDepositId = savingsAccountDepositList[index].row.first() }, - label = R.string.feature_report_saving_account, + label = Res.string.feature_report_saving_account, options = savingsAccountDepositList.map { it.row[1] }, readOnly = true, ) @@ -566,7 +574,7 @@ private fun RunReportContent( selectedGlAccount = value selectedGlAccountId = glAccountList[index].row.first() }, - label = R.string.feature_report_gl_account, + label = Res.string.feature_report_gl_account, options = glAccountList.map { it.row[1] }, readOnly = true, ) @@ -583,7 +591,7 @@ private fun RunReportContent( selectedObligationDate = value selectedObligationDateId = obligationDateList[index].row.first() }, - label = R.string.feature_report_obligation_date, + label = Res.string.feature_report_obligation_date, options = obligationDateList.map { it.row[1] }, readOnly = true, ) @@ -592,36 +600,36 @@ private fun RunReportContent( } } -private class ReportDetailUiStateProvider : PreviewParameterProvider { - - override val values: Sequence - get() = sequenceOf( - ReportDetailUiState.Error(R.string.feature_report_failed_to_load_report_details), - ReportDetailUiState.Loading, - ReportDetailUiState.ParameterDetailsSuccess, - ) -} - -@Preview(showBackground = true) -@Composable -private fun ReportDetailScreenPreview( - @PreviewParameter(ReportDetailUiStateProvider::class) state: ReportDetailUiState, -) { - ReportDetailScreen( - reportItem = ClientReportTypeItem(), - state = state, - onBackPressed = {}, - onRetry = {}, - officeList = emptyList(), - loanPurposeList = emptyList(), - fundList = emptyList(), - currencyList = emptyList(), - parCalculatorList = emptyList(), - savingsAccountDepositList = emptyList(), - glAccountList = emptyList(), - obligationDateList = emptyList(), - reportOffices = emptyList(), - reportProducts = emptyList(), - runReport = {}, - ) -} +//private class ReportDetailUiStateProvider : PreviewParameterProvider { +// +// override val values: Sequence +// get() = sequenceOf( +// ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details), +// ReportDetailUiState.Loading, +// ReportDetailUiState.ParameterDetailsSuccess, +// ) +//} +// +//@DevicePreview +//@Composable +//private fun ReportDetailScreenPreview( +// @PreviewParameter(ReportDetailUiStateProvider::class) state: ReportDetailUiState, +//) { +// ReportDetailScreen( +// reportItem = ClientReportTypeItem(), +// state = state, +// onBackPressed = {}, +// onRetry = {}, +// officeList = emptyList(), +// loanPurposeList = emptyList(), +// fundList = emptyList(), +// currencyList = emptyList(), +// parCalculatorList = emptyList(), +// savingsAccountDepositList = emptyList(), +// glAccountList = emptyList(), +// obligationDateList = emptyList(), +// reportOffices = emptyList(), +// reportProducts = emptyList(), +// runReport = {}, +// ) +//} diff --git a/feature/report/src/main/java/com/mifos/feature/report/reportDetail/ReportDetailUiState.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailUiState.kt similarity index 81% rename from feature/report/src/main/java/com/mifos/feature/report/reportDetail/ReportDetailUiState.kt rename to feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailUiState.kt index 88ca4accc0b..628ac79b9b1 100644 --- a/feature/report/src/main/java/com/mifos/feature/report/reportDetail/ReportDetailUiState.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailUiState.kt @@ -9,6 +9,8 @@ */ package com.mifos.feature.report.reportDetail +import org.jetbrains.compose.resources.StringResource + /** * Created by Aditya Gupta on 12/08/23. */ @@ -16,7 +18,7 @@ sealed class ReportDetailUiState { data object Loading : ReportDetailUiState() - data class Error(val message: Int) : ReportDetailUiState() + data class Error(val message: StringResource) : ReportDetailUiState() data object ParameterDetailsSuccess : ReportDetailUiState() } diff --git a/feature/report/src/main/java/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt similarity index 90% rename from feature/report/src/main/java/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt rename to feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt index 01c872738cf..03d136d42a0 100644 --- a/feature/report/src/main/java/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt @@ -9,6 +9,8 @@ */ package com.mifos.feature.report.reportDetail +import androidclient.feature.report.generated.resources.Res +import androidclient.feature.report.generated.resources.feature_report_failed_to_load_report_details import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -22,8 +24,8 @@ import com.mifos.core.domain.useCases.GetRunReportWithQueryUseCase import com.mifos.core.model.objects.runreport.DataRow import com.mifos.core.model.objects.runreport.FullParameterListResponse import com.mifos.core.model.objects.runreport.client.ClientReportTypeItem -import com.mifos.feature.report.R import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch @@ -68,7 +70,7 @@ class ReportDetailViewModel( when (result) { is Resource.Error -> _reportDetailUiState.value = - ReportDetailUiState.Error(R.string.feature_report_failed_to_load_report_details) + ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) is Resource.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading @@ -101,7 +103,7 @@ class ReportDetailViewModel( when (result) { is Resource.Error -> _reportDetailUiState.value = - ReportDetailUiState.Error(R.string.feature_report_failed_to_load_report_details) + ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) is Resource.Loading -> Unit @@ -119,7 +121,7 @@ class ReportDetailViewModel( when (result) { is Resource.Error -> _reportDetailUiState.value = - ReportDetailUiState.Error(R.string.feature_report_failed_to_load_report_details) + ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) is Resource.Loading -> Unit @@ -137,7 +139,7 @@ class ReportDetailViewModel( when (result) { is Resource.Error -> _reportDetailUiState.value = - ReportDetailUiState.Error(R.string.feature_report_failed_to_load_report_details) + ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) is Resource.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading diff --git a/feature/report/src/main/java/com/mifos/feature/report/runReport/RunReportScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt similarity index 89% rename from feature/report/src/main/java/com/mifos/feature/report/runReport/RunReportScreen.kt rename to feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt index cf154d86c29..467596c5322 100644 --- a/feature/report/src/main/java/com/mifos/feature/report/runReport/RunReportScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt @@ -11,6 +11,14 @@ package com.mifos.feature.report.runReport +import androidclient.feature.report.generated.resources.Res +import androidclient.feature.report.generated.resources.feature_report_accounting +import androidclient.feature.report.generated.resources.feature_report_all +import androidclient.feature.report.generated.resources.feature_report_client +import androidclient.feature.report.generated.resources.feature_report_fund +import androidclient.feature.report.generated.resources.feature_report_loan +import androidclient.feature.report.generated.resources.feature_report_savings +import androidclient.feature.report.generated.resources.feature_report_xbrl import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -50,12 +58,10 @@ import androidx.compose.ui.graphics.Color.Companion.Blue import androidx.compose.ui.graphics.Color.Companion.DarkGray import androidx.compose.ui.graphics.Color.Companion.White import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp @@ -66,8 +72,9 @@ import com.mifos.core.designsystem.component.MifosMenuDropDownItem import com.mifos.core.designsystem.component.MifosSweetError import com.mifos.core.designsystem.icon.MifosIcons import com.mifos.core.model.objects.runreport.client.ClientReportTypeItem -import com.mifos.feature.report.R -import org.koin.androidx.compose.koinViewModel +import com.mifos.core.ui.util.DevicePreview +import org.jetbrains.compose.resources.stringResource +import org.koin.compose.viewmodel.koinViewModel @Composable internal fun RunReportScreen( @@ -164,7 +171,7 @@ internal fun RunReportScreen( onDismissRequest = { showMenu = false }, ) { MifosMenuDropDownItem( - option = stringResource(id = R.string.feature_report_client), + option = stringResource(Res.string.feature_report_client), onClick = { onMenuClick(MenuItems.Client) menuTitle = MenuItems.Client.name @@ -172,7 +179,7 @@ internal fun RunReportScreen( }, ) MifosMenuDropDownItem( - option = stringResource(id = R.string.feature_report_loan), + option = stringResource(Res.string.feature_report_loan), onClick = { onMenuClick(MenuItems.Loan) menuTitle = MenuItems.Loan.name @@ -180,7 +187,7 @@ internal fun RunReportScreen( }, ) MifosMenuDropDownItem( - option = stringResource(id = R.string.feature_report_savings), + option = stringResource(Res.string.feature_report_savings), onClick = { onMenuClick(MenuItems.Savings) menuTitle = MenuItems.Savings.name @@ -188,7 +195,7 @@ internal fun RunReportScreen( }, ) MifosMenuDropDownItem( - option = stringResource(id = R.string.feature_report_fund), + option = stringResource(Res.string.feature_report_fund), onClick = { onMenuClick(MenuItems.Fund) menuTitle = MenuItems.Fund.name @@ -196,7 +203,7 @@ internal fun RunReportScreen( }, ) MifosMenuDropDownItem( - option = stringResource(id = R.string.feature_report_accounting), + option = stringResource(Res.string.feature_report_accounting), onClick = { onMenuClick(MenuItems.Accounting) menuTitle = MenuItems.Accounting.name @@ -204,7 +211,7 @@ internal fun RunReportScreen( }, ) MifosMenuDropDownItem( - option = stringResource(id = R.string.feature_report_xbrl), + option = stringResource(Res.string.feature_report_xbrl), onClick = { onMenuClick(MenuItems.XBRL) menuTitle = MenuItems.XBRL.name @@ -212,7 +219,7 @@ internal fun RunReportScreen( }, ) MifosMenuDropDownItem( - option = stringResource(id = R.string.feature_report_all), + option = stringResource(Res.string.feature_report_all), onClick = { onMenuClick(MenuItems.All) menuTitle = MenuItems.All.name @@ -229,7 +236,7 @@ internal fun RunReportScreen( ) { paddingValues -> Column(modifier = Modifier.padding(paddingValues)) { when (state) { - is RunReportUiState.Error -> MifosSweetError(message = stringResource(id = state.message)) { + is RunReportUiState.Error -> MifosSweetError(message = stringResource(state.message)) { onRetry() } @@ -287,7 +294,7 @@ private fun RunReportCardItem( .background(Blue, CircleShape), ) { Icon( - painter = painterResource(id = R.drawable.feature_report_ic_report_item), + painter = painterResource(Res.drawable.feature_report_ic_report_item), contentDescription = null, tint = Black, ) @@ -353,12 +360,12 @@ class RunReportUiStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( RunReportUiState.Loading, - RunReportUiState.Error(R.string.feature_report_failed_to_fetch_reports), + RunReportUiState.Error(Res.string.feature_report_failed_to_fetch_reports), RunReportUiState.RunReports(sampleRunReports), ) } -@Preview(showBackground = true) +@DevicePreview @Composable private fun RunReportPreview( @PreviewParameter(RunReportUiStateProvider::class) state: RunReportUiState, diff --git a/feature/report/src/main/java/com/mifos/feature/report/runReport/RunReportUiState.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportUiState.kt similarity index 83% rename from feature/report/src/main/java/com/mifos/feature/report/runReport/RunReportUiState.kt rename to feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportUiState.kt index 426fcb3ad05..f0c2562b0d3 100644 --- a/feature/report/src/main/java/com/mifos/feature/report/runReport/RunReportUiState.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportUiState.kt @@ -10,12 +10,13 @@ package com.mifos.feature.report.runReport import com.mifos.core.model.objects.runreport.client.ClientReportTypeItem +import org.jetbrains.compose.resources.StringResource sealed class RunReportUiState { data object Loading : RunReportUiState() - data class Error(val message: Int) : RunReportUiState() + data class Error(val message: StringResource) : RunReportUiState() data class RunReports(val runReports: List) : RunReportUiState() } diff --git a/feature/report/src/main/java/com/mifos/feature/report/runReport/RunReportViewModel.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportViewModel.kt similarity index 80% rename from feature/report/src/main/java/com/mifos/feature/report/runReport/RunReportViewModel.kt rename to feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportViewModel.kt index 57e3192013c..c9c47ba60a2 100644 --- a/feature/report/src/main/java/com/mifos/feature/report/runReport/RunReportViewModel.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportViewModel.kt @@ -9,12 +9,15 @@ */ package com.mifos.feature.report.runReport +import androidclient.feature.report.generated.resources.Res +import androidclient.feature.report.generated.resources.feature_report_failed_to_fetch_reports +import androidclient.feature.report.generated.resources.feature_report_no_reports_found import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.mifos.core.common.utils.Resource import com.mifos.core.domain.useCases.GetReportCategoryUseCase -import com.mifos.feature.report.R import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch @@ -39,7 +42,7 @@ class RunReportViewModel( when (result) { is Resource.Error -> _runReportUiState.value = - RunReportUiState.Error(R.string.feature_report_failed_to_fetch_reports) + RunReportUiState.Error(Res.string.feature_report_failed_to_fetch_reports) is Resource.Loading -> _runReportUiState.value = RunReportUiState.Loading @@ -49,7 +52,7 @@ class RunReportViewModel( _runReportUiState.value = RunReportUiState.RunReports(reports) } else { _runReportUiState.value = - RunReportUiState.Error(R.string.feature_report_no_reports_found) + RunReportUiState.Error(Res.string.feature_report_no_reports_found) } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f7fe94eb882..94c32ba3bb3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -188,6 +188,7 @@ androidPackageName = "AndroidApp" androidPackageNamespace = "org.mifos.client" androidPackageVersion = "1.0.0" uiAndroidVersion = "1.7.8" +uiAndroid = "1.8.2" [libraries] @@ -550,6 +551,7 @@ moko-permission-compose = { group = "dev.icerock.moko", name = "permissions-comp window-size = { group = "dev.chrisbanes.material3", name = "material3-window-size-class-multiplatform", version.ref = "windowsSizeClass" } androidx-material3-android = { group = "androidx.compose.material3", name = "material3-android", version.ref = "material3Android" } +androidx-ui-android = { group = "androidx.compose.ui", name = "ui-android", version.ref = "uiAndroid" } [plugins] diff --git a/settings.gradle.kts b/settings.gradle.kts index 46b188d160c..9d759d287f0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -59,7 +59,7 @@ include(":feature:auth") include(":feature:note") //include(":feature:offline") //include(":feature:path-tracking") -//include(":feature:report") +include(":feature:report") //include(":feature:savings") //include(":feature:search") //include(":feature:settings") From 99d0b1b0a88f5e6251cb0e2d57870c52f6c034a5 Mon Sep 17 00:00:00 2001 From: kapmaurya Date: Tue, 27 May 2025 17:55:10 +0530 Subject: [PATCH 02/18] cmp-report migration --- feature/report/build.gradle.kts | 4 +- .../report/navigation/ReportNavigation.kt | 3 +- .../feature/report/report/ReportScreen.kt | 139 ++++++++++++------ .../feature/report/report/ReportViewModel.kt | 13 +- .../report/reportDetail/ReportDetailScreen.kt | 11 +- .../reportDetail/ReportDetailViewModel.kt | 52 +++++-- gradle/libs.versions.toml | 2 + 7 files changed, 152 insertions(+), 72 deletions(-) diff --git a/feature/report/build.gradle.kts b/feature/report/build.gradle.kts index 41e90825d2a..5b8b34af291 100644 --- a/feature/report/build.gradle.kts +++ b/feature/report/build.gradle.kts @@ -22,9 +22,7 @@ kotlin { implementation(compose.components.resources) implementation(compose.ui) api(projects.core.domain) + implementation(libs.kotlinx.serialization.json.v163) } } } -dependencies { - implementation(libs.androidx.ui.android) -} diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt index 257f50d6921..143dd5e3935 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt @@ -22,7 +22,7 @@ import com.mifos.feature.report.report.ReportScreen import com.mifos.feature.report.reportDetail.ReportDetailScreen import com.mifos.feature.report.runReport.RunReportScreen import kotlinx.serialization.encodeToString -//import kotlinx.serialization.json.Json +import kotlinx.serialization.json.Json @@ -89,6 +89,7 @@ fun NavGraphBuilder.reportScreenRoute( } } + fun NavController.navigateReportDetailsScreen(clientReportTypeItem: ClientReportTypeItem) { val arg = Json.encodeToString(clientReportTypeItem) navigate(ReportScreens.ReportDetailScreen.argument(arg)) diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt index 5ca1386af9b..a3759ee0367 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt @@ -8,6 +8,39 @@ * See https://github.com/openMF/android-client/blob/master/LICENSE.md */ package com.mifos.feature.report.report +// +//import androidx.compose.foundation.layout.Column +//import androidx.compose.foundation.layout.padding +//import androidx.compose.foundation.lazy.LazyRow +//import androidx.compose.foundation.lazy.itemsIndexed +//import androidx.compose.foundation.rememberScrollState +//import androidx.compose.foundation.verticalScroll +//import androidx.compose.material3.ButtonDefaults +//import androidx.compose.material3.SnackbarHostState +//import androidx.compose.material3.Text +//import androidx.compose.material3.TextButton +//import androidx.compose.runtime.Composable +//import androidx.compose.runtime.LaunchedEffect +//import androidx.compose.runtime.getValue +//import androidx.compose.runtime.mutableStateOf +//import androidx.compose.runtime.remember +//import androidx.compose.runtime.rememberCoroutineScope +//import androidx.compose.runtime.setValue +//import androidx.compose.ui.Modifier +//import androidx.compose.ui.graphics.Color.Companion.Black +//import androidx.compose.ui.graphics.Color.Companion.White +//import androidx.compose.ui.text.TextStyle +//import androidx.compose.ui.text.font.FontWeight +//import androidx.compose.ui.unit.dp +//import androidx.lifecycle.compose.collectAsStateWithLifecycle +//import com.mifos.core.designsystem.component.MifosScaffold +//import com.mifos.core.designsystem.component.PermissionBox +//import com.mifos.core.model.objects.runreport.FullParameterListResponse +//import core.designsystem.generated.resources.Res +//import kotlinx.coroutines.launch +//import org.jetbrains.compose.resources.getString +//import org.jetbrains.compose.resources.stringResource +//import org.koin.compose.viewmodel.koinViewModel import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding @@ -16,6 +49,7 @@ import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.DividerDefaults.color import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -34,12 +68,9 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.mifos.core.designsystem.component.MifosScaffold -import com.mifos.core.designsystem.component.PermissionBox import com.mifos.core.model.objects.runreport.FullParameterListResponse -import com.mifos.core.ui.util.DevicePreview import core.designsystem.generated.resources.Res import kotlinx.coroutines.launch -import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.stringResource import org.koin.compose.viewmodel.koinViewModel @@ -50,22 +81,20 @@ internal fun ReportScreen( ) { val report = viewModel.report val state by viewModel.reportUiState.collectAsStateWithLifecycle() - val context = LocalContext.current + // val context = LocalContext.current + val reportDirectoryPath = "/downloads/mifos/reports" ReportScreen( state = state, report = report, onBackPressed = onBackPressed, - exportReport = { - val reportDirectoryPath = - Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) - .toString() + getString(context, Res.string.feature_report_export_csv_directory) - + reportDirectoryPath = reportDirectoryPath, + exportReport = { path -> viewModel.exportCsv( report = report, - reportDirectoryPath = reportDirectoryPath, + reportDirectoryPath = path ) - }, + } ) } @@ -74,43 +103,58 @@ internal fun ReportScreen( state: ReportUiState, report: FullParameterListResponse, onBackPressed: () -> Unit, + reportDirectoryPath: String, modifier: Modifier = Modifier, - exportReport: () -> Unit, + exportReport: (String) -> Unit, ) { - val context = LocalContext.current + //val context = LocalContext.current val scope = rememberCoroutineScope() val snackbarHostState = remember { SnackbarHostState() } - var checkPermission by remember { mutableStateOf(false) } + //var checkPermission by remember { mutableStateOf(false) } + // var showExportMessage by remember { mutableStateOf(false) } - when (state) { - is ReportUiState.Initial -> Unit - is ReportUiState.Message -> { - Toast.makeText(context, stringResource(state.message), Toast.LENGTH_SHORT).show() - } - } +// when (state) { +// is ReportUiState.Initial -> Unit +// is ReportUiState.Message -> { +// //Toast.makeText(context, stringResource(state.message), Toast.LENGTH_SHORT).show() +// showExportMessage = true +// } +// } +// +// if (showExportMessage) { +//// PermissionBox( +//// requiredPermissions = if (Build.VERSION.SDK_INT >= 33) { +//// listOf(Manifest.permission.READ_MEDIA_IMAGES) +//// } else { +//// listOf( +//// Manifest.permission.READ_EXTERNAL_STORAGE, +//// Manifest.permission.WRITE_EXTERNAL_STORAGE, +//// ) +// LaunchedEffect(showExportMessage) { +// snackbarHostState.showSnackbar(message = stringResource(state.message)) +// showExportMessage = false +// } +// } - if (checkPermission) { - PermissionBox( - requiredPermissions = if (Build.VERSION.SDK_INT >= 33) { - listOf(Manifest.permission.READ_MEDIA_IMAGES) - } else { - listOf( - Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.WRITE_EXTERNAL_STORAGE, - ) - }, - title = stringResource(Res.string.feature_report_permission_required), - description = stringResource(Res.string.feature_report_external_approve_permission_description), - confirmButtonText = stringResource(Res.string.feature_report_proceed), - dismissButtonText = stringResource(Res.string.feature_report_dismiss), - onGranted = { - LaunchedEffect(key1 = Unit) { - scope.launch { - exportReport() - } - } - }, - ) +// title = stringResource(Res.string.feature_report_permission_required), +// description = stringResource(Res.string.feature_report_external_approve_permission_description), +// confirmButtonText = stringResource(Res.string.feature_report_proceed), +// dismissButtonText = stringResource(Res.string.feature_report_dismiss), +// onGranted = { +// LaunchedEffect(key1 = Unit) { +// scope.launch { +// exportReport() +// } +// } +// }, +// ) + + if (state is ReportUiState.Message) { + LaunchedEffect(state) { + snackbarHostState.showSnackbar( + message = stringResource(state.message) + ) + } } MifosScaffold( @@ -120,11 +164,18 @@ internal fun ReportScreen( actions = { TextButton( onClick = { - checkPermission = true +// checkPermission = true + scope.launch { + exportReport(reportDirectoryPath) + } }, colors = ButtonDefaults.textButtonColors(White), ) { - Text(text = stringResource(Res.string.feature_report_export_csv), color = Black) + //Text(text = stringResource(Res.string.feature_report_export_csv), color = Black) + Text( + text = stringResource(Res.string.feature_report_export_csv), + color = Black + ) } }, snackbarHostState = snackbarHostState, diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt index 88029e5e8bb..ece3bb67f07 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt @@ -19,14 +19,18 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.mifos.core.common.utils.Constants import com.mifos.core.model.objects.runreport.FullParameterListResponse +import io.ktor.http.ContentDisposition.Companion.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.serialization.json.Json -import java.io.File -import java.io.FileWriter +//import java.io.File +//import java.io.FileWriter import kotlinx.coroutines.IO +import kotlinx.datetime.Clock +import kotlinx.io.files.FileSystem +import okio.Path.Companion.toPath class ReportViewModel( savedStateHandle: SavedStateHandle, @@ -43,9 +47,10 @@ class ReportViewModel( fun exportCsv(report: FullParameterListResponse, reportDirectoryPath: String) = viewModelScope.launch(Dispatchers.IO) { _reportUiState.value = ReportUiState.Message(Res.string.feature_report_export_started) - val timestamp = System.currentTimeMillis() - val reportPath = "$reportDirectoryPath$timestamp.csv" + val timestamp = Clock.System.now().toEpochMilliseconds().toString() + val reportPath = "$reportDirectoryPath$timestamp.csv".toPath() val reportDirectory = File(reportDirectoryPath) + val fileSystem = FileSystem.SYSTEM if (!reportDirectory.exists()) { val makeRequiredDirectories = reportDirectory.mkdirs() diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt index 85121722210..08ebf3411ad 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt @@ -13,9 +13,15 @@ import androidclient.feature.report.generated.resources.Res import androidclient.feature.report.generated.resources.feature_report_currency import androidclient.feature.report.generated.resources.feature_report_details import androidclient.feature.report.generated.resources.feature_report_failed_to_load_report_details +import androidclient.feature.report.generated.resources.feature_report_fund import androidclient.feature.report.generated.resources.feature_report_gl_account +import androidclient.feature.report.generated.resources.feature_report_ic_report_item +import androidclient.feature.report.generated.resources.feature_report_loan_officer +import androidclient.feature.report.generated.resources.feature_report_loan_purpose import androidclient.feature.report.generated.resources.feature_report_obligation_date +import androidclient.feature.report.generated.resources.feature_report_office import androidclient.feature.report.generated.resources.feature_report_par_type +import androidclient.feature.report.generated.resources.feature_report_product import androidclient.feature.report.generated.resources.feature_report_run_report import androidclient.feature.report.generated.resources.feature_report_saving_account import androidx.compose.foundation.background @@ -55,12 +61,9 @@ import androidx.compose.ui.graphics.Color.Companion.Black import androidx.compose.ui.graphics.Color.Companion.Blue import androidx.compose.ui.graphics.Color.Companion.Gray import androidx.compose.ui.graphics.Color.Companion.White -import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -72,7 +75,7 @@ import com.mifos.core.designsystem.component.MifosTextFieldDropdown import com.mifos.core.model.objects.runreport.DataRow import com.mifos.core.model.objects.runreport.FullParameterListResponse import com.mifos.core.model.objects.runreport.client.ClientReportTypeItem -import com.mifos.core.ui.util.DevicePreview +import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource import org.koin.compose.viewmodel.koinViewModel diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt index 03d136d42a0..ad9637829d5 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt @@ -15,6 +15,7 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.mifos.core.common.utils.Constants +import com.mifos.core.common.utils.DataState import com.mifos.core.common.utils.Resource import com.mifos.core.domain.useCases.GetReportFullParameterListUseCase import com.mifos.core.domain.useCases.GetReportParameterDetailsUseCase @@ -37,7 +38,7 @@ class ReportDetailViewModel( private val getRunReportProductUseCase: GetRunReportProductUseCase, private val getRunReportWithQueryUseCase: GetRunReportWithQueryUseCase, private val getRunReportOfficesUseCase: GetRunReportOfficesUseCase, - private val savedStateHandle: SavedStateHandle, + private val savedStateHandle: SavedStateHandle ) : ViewModel() { private val reportName = @@ -68,15 +69,19 @@ class ReportDetailViewModel( viewModelScope.launch(Dispatchers.IO) { getReportFullParameterListUseCase(reportName, parameterType).collect { result -> when (result) { - is Resource.Error -> + is Resource.Error<*> -> _reportDetailUiState.value = ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) - is Resource.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading + is Resource.Loading<*> -> _reportDetailUiState.value = ReportDetailUiState.Loading - is Resource.Success -> + is Resource.Success<*> -> _reportParameterList.value = result.data?.data ?: emptyList() + + is DataState.Error<*> -> TODO() + DataState.Loading -> TODO() + is DataState.Success<*> -> TODO() } } } @@ -85,14 +90,18 @@ class ReportDetailViewModel( viewModelScope.launch(Dispatchers.IO) { getReportParameterDetailsUseCase(parameterName, parameterType).collect { result -> when (result) { - is Resource.Error -> Unit + is Resource.Error<*> -> Unit - is Resource.Loading -> Unit + is Resource.Loading<*> -> Unit - is Resource.Success -> { + is Resource.Success<*> -> { _reportDetail.value = Pair(result.data?.data ?: emptyList(), parameterName) } + + is DataState.Error<*> -> TODO() + DataState.Loading -> TODO() + is DataState.Success<*> -> TODO() } } } @@ -101,16 +110,20 @@ class ReportDetailViewModel( viewModelScope.launch(Dispatchers.IO) { getRunReportOfficesUseCase(parameterName, officeId, parameterType).collect { result -> when (result) { - is Resource.Error -> + is Resource.Error<*> -> _reportDetailUiState.value = ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) - is Resource.Loading -> Unit + is Resource.Loading<*> -> Unit - is Resource.Success -> { + is Resource.Success<*> -> { _reportOffices.value = result.data?.data ?: emptyList() _reportDetailUiState.value = ReportDetailUiState.ParameterDetailsSuccess } + + is DataState.Error<*> -> TODO() + DataState.Loading -> TODO() + is DataState.Success<*> -> TODO() } } } @@ -119,16 +132,20 @@ class ReportDetailViewModel( viewModelScope.launch(Dispatchers.IO) { getRunReportProductUseCase(parameterName, currencyId, parameterType).collect { result -> when (result) { - is Resource.Error -> + is Resource.Error<*> -> _reportDetailUiState.value = ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) - is Resource.Loading -> Unit + is Resource.Loading<*> -> Unit - is Resource.Success -> { + is Resource.Success<*> -> { _reportProducts.value = result.data?.data ?: emptyList() _reportDetailUiState.value = ReportDetailUiState.ParameterDetailsSuccess } + + is DataState.Error<*> -> TODO() + DataState.Loading -> TODO() + is DataState.Success<*> -> TODO() } } } @@ -137,13 +154,16 @@ class ReportDetailViewModel( viewModelScope.launch(Dispatchers.IO) { getRunReportWithQueryUseCase(reportName, options).collect { result -> when (result) { - is Resource.Error -> + is Resource.Error<*> -> _reportDetailUiState.value = ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) - is Resource.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading + is Resource.Loading<*> -> _reportDetailUiState.value = ReportDetailUiState.Loading - is Resource.Success -> _runReport.value = result.data + is Resource.Success<*> -> _runReport.value = result.data + is DataState.Error<*> -> TODO() + DataState.Loading -> TODO() + is DataState.Success<*> -> TODO() } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 94c32ba3bb3..8d86662f55e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -71,6 +71,7 @@ koinAndroid = "4.0.1" koinAndroidxCompose = "3.5.0" kotlinxCoroutinesCoreVersion = "1.10.1" kotlinxCoroutinesRx2 = "1.5.1" +kotlinxSerializationJsonVersion = "1.6.3" legacySupportV4 = "1.0.0" lifecycleCommonJava8 = "2.8.7" lifecycleExtensions = "2.2.0" @@ -230,6 +231,7 @@ android-maps-utils = { module = "com.google.maps.android:android-maps-utils", ve android-iconify-material = { module = "com.joanzapata.iconify:android-iconify-material", version.ref = "androidIconifyMaterial" } #RxAndroid +kotlinx-serialization-json-v163 = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJsonVersion" } mifos-koin-android = { module = "io.insert-koin:koin-android", version.ref = "koinAndroid" } koin-androidx-compose-v350 = { module = "io.insert-koin:koin-androidx-compose", version.ref = "koinAndroidxCompose" } maps-compose = { module = "com.google.maps.android:maps-compose", version.ref = "mapsCompose" } From 99ef9f91c2f2c079306deca1b2024fe06b0865b3 Mon Sep 17 00:00:00 2001 From: kapmaurya Date: Tue, 3 Jun 2025 21:18:36 +0530 Subject: [PATCH 03/18] cmp-search migration --- feature/report/build.gradle.kts | 1 - .../kotlin/com/mifos/feature/report/report/ReportViewModel.kt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/feature/report/build.gradle.kts b/feature/report/build.gradle.kts index 5b8b34af291..ff5991f0279 100644 --- a/feature/report/build.gradle.kts +++ b/feature/report/build.gradle.kts @@ -22,7 +22,6 @@ kotlin { implementation(compose.components.resources) implementation(compose.ui) api(projects.core.domain) - implementation(libs.kotlinx.serialization.json.v163) } } } diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt index ece3bb67f07..e51ecaa4d08 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt @@ -20,11 +20,11 @@ import androidx.lifecycle.viewModelScope import com.mifos.core.common.utils.Constants import com.mifos.core.model.objects.runreport.FullParameterListResponse import io.ktor.http.ContentDisposition.Companion.File +import io.ktor.http.ContentType.Application.Json import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch -import kotlinx.serialization.json.Json //import java.io.File //import java.io.FileWriter import kotlinx.coroutines.IO From a9eda6c0a467a2ef8f7f79979495b8de071f7c1e Mon Sep 17 00:00:00 2001 From: kapmaurya Date: Tue, 27 May 2025 15:39:21 +0530 Subject: [PATCH 04/18] cmp-report migration --- feature/report/build.gradle.kts | 3 +++ .../com/mifos/feature/report/navigation/ReportNavigation.kt | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/feature/report/build.gradle.kts b/feature/report/build.gradle.kts index ff5991f0279..41e90825d2a 100644 --- a/feature/report/build.gradle.kts +++ b/feature/report/build.gradle.kts @@ -25,3 +25,6 @@ kotlin { } } } +dependencies { + implementation(libs.androidx.ui.android) +} diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt index 143dd5e3935..7cfd0f35985 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt @@ -22,7 +22,9 @@ import com.mifos.feature.report.report.ReportScreen import com.mifos.feature.report.reportDetail.ReportDetailScreen import com.mifos.feature.report.runReport.RunReportScreen import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json +//import kotlinx.serialization.json.Json + + From f7896246ff75cbf7c31717b4ffa09054e9cbb245 Mon Sep 17 00:00:00 2001 From: kapmaurya Date: Tue, 3 Jun 2025 21:36:39 +0530 Subject: [PATCH 05/18] cmp-search migration --- feature/report/build.gradle.kts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/feature/report/build.gradle.kts b/feature/report/build.gradle.kts index 41e90825d2a..6ded61c595b 100644 --- a/feature/report/build.gradle.kts +++ b/feature/report/build.gradle.kts @@ -24,7 +24,4 @@ kotlin { api(projects.core.domain) } } -} -dependencies { - implementation(libs.androidx.ui.android) -} +} \ No newline at end of file From a60dae54e2ae2167f10ebcd0144ae00943f96267 Mon Sep 17 00:00:00 2001 From: kapmaurya Date: Thu, 12 Jun 2025 00:14:19 +0530 Subject: [PATCH 06/18] cmp-search migration --- cmp-navigation/build.gradle.kts | 2 +- .../kotlin/cmp/navigation/di/KoinModules.kt | 2 +- .../cmp/navigation/navigation/RootNavGraph.kt | 10 +- .../component/MifosTextFieldDropdown.kt | 4 +- feature/report/build.gradle.kts | 1 + .../report/navigation/ReportNavigation.kt | 2 +- .../feature/report/report/ReportScreen.kt | 184 ++++++++---------- .../feature/report/report/ReportViewModel.kt | 81 +++----- .../report/reportDetail/ReportDetailScreen.kt | 86 ++++++-- gradle/libs.versions.toml | 4 +- settings.gradle.kts | 2 + 11 files changed, 200 insertions(+), 178 deletions(-) diff --git a/cmp-navigation/build.gradle.kts b/cmp-navigation/build.gradle.kts index 1ec95aa98db..83a8d4d69cc 100644 --- a/cmp-navigation/build.gradle.kts +++ b/cmp-navigation/build.gradle.kts @@ -46,7 +46,7 @@ kotlin { implementation(projects.feature.pathTracking) // implementation(projects.feature.report) implementation(projects.feature.savings) - implementation(projects.feature.splash) + // implementation(projects.feature.splash) implementation(projects.feature.settings) implementation(projects.feature.search) diff --git a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt index 4a48259424e..fecc091700c 100644 --- a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt +++ b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt @@ -26,7 +26,7 @@ import com.mifos.feature.pathTracking.di.PathTrackingModule import com.mifos.feature.savings.di.SavingsModule import com.mifos.feature.search.di.SearchModule import com.mifos.feature.settings.di.SettingsModule -import com.mifos.feature.splash.di.SplashModule +//import com.mifos.feature.splash.di.SplashModule import com.mifos.room.di.DaoModule import com.mifos.room.di.HelperModule import com.mifos.room.di.PlatformSpecificDatabaseModule diff --git a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/RootNavGraph.kt b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/RootNavGraph.kt index 6821e125d22..d6dacf15397 100644 --- a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/RootNavGraph.kt +++ b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/RootNavGraph.kt @@ -20,7 +20,7 @@ import com.mifos.core.data.util.NetworkMonitor import com.mifos.feature.auth.navigation.AuthScreens import com.mifos.feature.auth.navigation.authNavGraph import com.mifos.feature.auth.navigation.navigateToLogin -import com.mifos.feature.splash.navigation.splashNavGraph +//import com.mifos.feature.splash.navigation.splashNavGraph @Composable fun RootNavGraph( @@ -40,10 +40,10 @@ fun RootNavGraph( updateServerConfig = {}, ) - splashNavGraph( - navigateLogin = navHostController::navigateToLogin, - navigatePasscode = {}, - ) +// splashNavGraph( +// navigateLogin = navHostController::navigateToLogin, +// navigatePasscode = {}, +// ) composable(MAIN_GRAPH) { App( diff --git a/core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosTextFieldDropdown.kt b/core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosTextFieldDropdown.kt index e1158db4526..228b090a831 100644 --- a/core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosTextFieldDropdown.kt +++ b/core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosTextFieldDropdown.kt @@ -40,6 +40,8 @@ fun MifosTextFieldDropdown( options: List, modifier: Modifier = Modifier .fillMaxWidth() + .padding(horizontal = 16.dp), + label: String? = null, readOnly: Boolean = false, errorMessage: String? = null, ) { @@ -89,4 +91,4 @@ fun MifosTextFieldDropdown( } } } -} +} \ No newline at end of file diff --git a/feature/report/build.gradle.kts b/feature/report/build.gradle.kts index 6ded61c595b..27464127875 100644 --- a/feature/report/build.gradle.kts +++ b/feature/report/build.gradle.kts @@ -22,6 +22,7 @@ kotlin { implementation(compose.components.resources) implementation(compose.ui) api(projects.core.domain) + implementation(libs.kotlinx.serialization.json) } } } \ No newline at end of file diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt index 7cfd0f35985..494fb603b39 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt @@ -22,7 +22,7 @@ import com.mifos.feature.report.report.ReportScreen import com.mifos.feature.report.reportDetail.ReportDetailScreen import com.mifos.feature.report.runReport.RunReportScreen import kotlinx.serialization.encodeToString -//import kotlinx.serialization.json.Json +import kotlinx.serialization.json.Json diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt index a3759ee0367..3ce85761053 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt @@ -1,3 +1,4 @@ + /* * Copyright 2024 Mifos Initiative * @@ -8,40 +9,10 @@ * See https://github.com/openMF/android-client/blob/master/LICENSE.md */ package com.mifos.feature.report.report -// -//import androidx.compose.foundation.layout.Column -//import androidx.compose.foundation.layout.padding -//import androidx.compose.foundation.lazy.LazyRow -//import androidx.compose.foundation.lazy.itemsIndexed -//import androidx.compose.foundation.rememberScrollState -//import androidx.compose.foundation.verticalScroll -//import androidx.compose.material3.ButtonDefaults -//import androidx.compose.material3.SnackbarHostState -//import androidx.compose.material3.Text -//import androidx.compose.material3.TextButton -//import androidx.compose.runtime.Composable -//import androidx.compose.runtime.LaunchedEffect -//import androidx.compose.runtime.getValue -//import androidx.compose.runtime.mutableStateOf -//import androidx.compose.runtime.remember -//import androidx.compose.runtime.rememberCoroutineScope -//import androidx.compose.runtime.setValue -//import androidx.compose.ui.Modifier -//import androidx.compose.ui.graphics.Color.Companion.Black -//import androidx.compose.ui.graphics.Color.Companion.White -//import androidx.compose.ui.text.TextStyle -//import androidx.compose.ui.text.font.FontWeight -//import androidx.compose.ui.unit.dp -//import androidx.lifecycle.compose.collectAsStateWithLifecycle -//import com.mifos.core.designsystem.component.MifosScaffold -//import com.mifos.core.designsystem.component.PermissionBox -//import com.mifos.core.model.objects.runreport.FullParameterListResponse -//import core.designsystem.generated.resources.Res -//import kotlinx.coroutines.launch -//import org.jetbrains.compose.resources.getString -//import org.jetbrains.compose.resources.stringResource -//import org.koin.compose.viewmodel.koinViewModel +import androidclient.feature.report.generated.resources.Res +import androidclient.feature.report.generated.resources.feature_report_export_csv +import androidclient.feature.report.generated.resources.feature_report_title import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyRow @@ -49,7 +20,6 @@ import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.DividerDefaults.color import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -69,32 +39,40 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.mifos.core.designsystem.component.MifosScaffold import com.mifos.core.model.objects.runreport.FullParameterListResponse -import core.designsystem.generated.resources.Res +import com.mifos.core.ui.util.DevicePreview import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource import org.koin.compose.viewmodel.koinViewModel + @Composable internal fun ReportScreen( onBackPressed: () -> Unit, viewModel: ReportViewModel = koinViewModel(), + platformDirPathProvider: () -> String, + showMessage: (String) -> Unit ) { val report = viewModel.report val state by viewModel.reportUiState.collectAsStateWithLifecycle() + // val context = LocalContext.current - val reportDirectoryPath = "/downloads/mifos/reports" ReportScreen( state = state, report = report, onBackPressed = onBackPressed, - reportDirectoryPath = reportDirectoryPath, - exportReport = { path -> - viewModel.exportCsv( - report = report, - reportDirectoryPath = path - ) - } + exportReport = { + val reportDirectoryPath = platformDirPathProvider() +// Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) +// .toString() + getString(context, R.string.feature_report_export_csv_directory) +// viewModel.exportCsv( +// report = report, +// reportDirectoryPath = reportDirectoryPath, +// ) + + viewModel.exportCsv(report = report, reportDirectoryPath = reportDirectoryPath) + }, + showMessage = showMessage ) } @@ -103,58 +81,50 @@ internal fun ReportScreen( state: ReportUiState, report: FullParameterListResponse, onBackPressed: () -> Unit, - reportDirectoryPath: String, modifier: Modifier = Modifier, - exportReport: (String) -> Unit, + exportReport: () -> Unit, + showMessage: (String) -> Unit, ) { //val context = LocalContext.current val scope = rememberCoroutineScope() val snackbarHostState = remember { SnackbarHostState() } - //var checkPermission by remember { mutableStateOf(false) } - // var showExportMessage by remember { mutableStateOf(false) } - -// when (state) { -// is ReportUiState.Initial -> Unit -// is ReportUiState.Message -> { -// //Toast.makeText(context, stringResource(state.message), Toast.LENGTH_SHORT).show() -// showExportMessage = true -// } -// } -// -// if (showExportMessage) { -//// PermissionBox( -//// requiredPermissions = if (Build.VERSION.SDK_INT >= 33) { -//// listOf(Manifest.permission.READ_MEDIA_IMAGES) -//// } else { -//// listOf( -//// Manifest.permission.READ_EXTERNAL_STORAGE, -//// Manifest.permission.WRITE_EXTERNAL_STORAGE, -//// ) -// LaunchedEffect(showExportMessage) { -// snackbarHostState.showSnackbar(message = stringResource(state.message)) -// showExportMessage = false -// } -// } + // var checkPermission by remember { mutableStateOf(false) } + var triggerExport by remember { mutableStateOf(false) } + when (state) { + is ReportUiState.Initial -> Unit + is ReportUiState.Message -> { + val message = stringResource(state.message) + // Toast.makeText(context, stringResource(id = state.message), Toast.LENGTH_SHORT).show() + LaunchedEffect(state.message) { + showMessage(message) + } + } + } + + if (triggerExport) { +// PermissionBox( +// requiredPermissions = if (Build.VERSION.SDK_INT >= 33) { +// listOf(Manifest.permission.READ_MEDIA_IMAGES) +// } else { +// listOf( +// Manifest.permission.READ_EXTERNAL_STORAGE, +// Manifest.permission.WRITE_EXTERNAL_STORAGE, +// ) +// }, // title = stringResource(Res.string.feature_report_permission_required), -// description = stringResource(Res.string.feature_report_external_approve_permission_description), -// confirmButtonText = stringResource(Res.string.feature_report_proceed), -// dismissButtonText = stringResource(Res.string.feature_report_dismiss), +// description = stringResource(R.string.feature_report_external_approve_permission_description), +// confirmButtonText = stringResource(R.string.feature_report_proceed), +// dismissButtonText = stringResource(R.string.feature_report_dismiss), // onGranted = { -// LaunchedEffect(key1 = Unit) { -// scope.launch { -// exportReport() -// } -// } -// }, -// ) - - if (state is ReportUiState.Message) { - LaunchedEffect(state) { - snackbarHostState.showSnackbar( - message = stringResource(state.message) - ) - } + LaunchedEffect(triggerExport) { + scope.launch { + exportReport() + triggerExport = false + } + } + // }, + // ) } MifosScaffold( @@ -164,18 +134,11 @@ internal fun ReportScreen( actions = { TextButton( onClick = { -// checkPermission = true - scope.launch { - exportReport(reportDirectoryPath) - } + triggerExport = true }, colors = ButtonDefaults.textButtonColors(White), ) { - //Text(text = stringResource(Res.string.feature_report_export_csv), color = Black) - Text( - text = stringResource(Res.string.feature_report_export_csv), - color = Black - ) + Text(text = stringResource(Res.string.feature_report_export_csv), color = Black) } }, snackbarHostState = snackbarHostState, @@ -211,11 +174,11 @@ internal fun ReportScreen( // override val values: Sequence // get() = sequenceOf( // ReportUiState.Initial, -// ReportUiState.Message(Res.string.feature_report_export_csv), +// ReportUiState.Message(R.string.feature_report_export_csv), // ) //} // -//@DevicePreview +//@Preview(showBackground = true) //@Composable //private fun ReportScreenPreview( // @PreviewParameter(ReportUiStateProvider::class) state: ReportUiState, @@ -227,3 +190,28 @@ internal fun ReportScreen( // exportReport = { }, // ) //} + +@DevicePreview() +@Composable +fun ReportScreenPreviewInitial() { + ReportScreen( + state = ReportUiState.Initial, + report = FullParameterListResponse(emptyList(), emptyList()), + onBackPressed = {}, + exportReport = {}, + showMessage = {} + ) +} + +@DevicePreview() +@Composable +private fun ReportScreenPreviewMessage() { + ReportScreen( + state = ReportUiState.Message(Res.string.feature_report_export_csv), + report = FullParameterListResponse(emptyList(), emptyList()), + onBackPressed = { }, + exportReport = { }, + showMessage = {} + ) +} + diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt index e51ecaa4d08..3009d0fdc3e 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt @@ -1,36 +1,35 @@ -/* - * Copyright 2024 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/android-client/blob/master/LICENSE.md - */ +///* +// * Copyright 2024 Mifos Initiative +// * +// * This Source Code Form is subject to the terms of the Mozilla Public +// * License, v. 2.0. If a copy of the MPL was not distributed with this +// * file, You can obtain one at https://mozilla.org/MPL/2.0/. +// * +// * See https://github.com/openMF/android-client/blob/master/LICENSE.md +// */ package com.mifos.feature.report.report + import androidclient.feature.report.generated.resources.Res import androidclient.feature.report.generated.resources.feature_report_export_started import androidclient.feature.report.generated.resources.feature_report_exported_successfully -import androidclient.feature.report.generated.resources.feature_report_unable_to_create_directory import androidclient.feature.report.generated.resources.feature_report_unable_to_export import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.mifos.core.common.utils.Constants import com.mifos.core.model.objects.runreport.FullParameterListResponse -import io.ktor.http.ContentDisposition.Companion.File -import io.ktor.http.ContentType.Application.Json import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch -//import java.io.File -//import java.io.FileWriter -import kotlinx.coroutines.IO import kotlinx.datetime.Clock -import kotlinx.io.files.FileSystem +import kotlinx.serialization.json.Json +import okio.FileSystem import okio.Path.Companion.toPath +import okio.SYSTEM +import okio.buffer +import okio.use class ReportViewModel( savedStateHandle: SavedStateHandle, @@ -38,56 +37,38 @@ class ReportViewModel( private val reportParameterString = savedStateHandle.getStateFlow(key = Constants.REPORT_PARAMETER_RESPONSE, initialValue = "") + val report: FullParameterListResponse = - Json.decodeFromString(reportParameterString.value) + Json.decodeFromString(reportParameterString.value) private val _reportUiState = MutableStateFlow(ReportUiState.Initial) val reportUiState = _reportUiState.asStateFlow() - fun exportCsv(report: FullParameterListResponse, reportDirectoryPath: String) = - viewModelScope.launch(Dispatchers.IO) { + fun exportCsv(report: FullParameterListResponse, reportDirectoryPath: String) { + viewModelScope.launch(Dispatchers.Default) { _reportUiState.value = ReportUiState.Message(Res.string.feature_report_export_started) - val timestamp = Clock.System.now().toEpochMilliseconds().toString() - val reportPath = "$reportDirectoryPath$timestamp.csv".toPath() - val reportDirectory = File(reportDirectoryPath) - val fileSystem = FileSystem.SYSTEM - if (!reportDirectory.exists()) { - val makeRequiredDirectories = reportDirectory.mkdirs() - if (!makeRequiredDirectories) { - _reportUiState.value = - ReportUiState.Message(Res.string.feature_report_unable_to_create_directory) - } - } + val timestamp = Clock.System.now().toEpochMilliseconds().toString() + val fileName = "$reportDirectoryPath/$timestamp.csv" + val path = fileName.toPath() try { - val fileWriter = FileWriter(reportPath) + FileSystem.SYSTEM.sink(path).buffer().use { sink -> + val headers = report.columnHeaders.joinToString(",") { it.columnName } + sink.writeUtf8(headers + "\n") - // write headers - val columnSize = report.columnHeaders.size - var count = 1 - for (header in report.columnHeaders) { - fileWriter.append(header.columnName) - if (count == columnSize) { - fileWriter.append("\n") - } else { - fileWriter.append(",") + for (row in report.data) { + val line = row.row.joinToString(",") + sink.writeUtf8(line + "\n") } - count++ } - // write row data - for (row in report.data) { - fileWriter.append(java.lang.String.join(",", row.row)) - fileWriter.append("\n") - } - fileWriter.flush() - fileWriter.close() + _reportUiState.value = + ReportUiState.Message(Res.string.feature_report_exported_successfully) } catch (e: Exception) { _reportUiState.value = ReportUiState.Message(Res.string.feature_report_unable_to_export) } - _reportUiState.value = - ReportUiState.Message(Res.string.feature_report_exported_successfully) } + } } diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt index 08ebf3411ad..6a3613e3939 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt @@ -10,20 +10,10 @@ package com.mifos.feature.report.reportDetail import androidclient.feature.report.generated.resources.Res -import androidclient.feature.report.generated.resources.feature_report_currency import androidclient.feature.report.generated.resources.feature_report_details import androidclient.feature.report.generated.resources.feature_report_failed_to_load_report_details -import androidclient.feature.report.generated.resources.feature_report_fund -import androidclient.feature.report.generated.resources.feature_report_gl_account import androidclient.feature.report.generated.resources.feature_report_ic_report_item -import androidclient.feature.report.generated.resources.feature_report_loan_officer -import androidclient.feature.report.generated.resources.feature_report_loan_purpose -import androidclient.feature.report.generated.resources.feature_report_obligation_date -import androidclient.feature.report.generated.resources.feature_report_office -import androidclient.feature.report.generated.resources.feature_report_par_type -import androidclient.feature.report.generated.resources.feature_report_product import androidclient.feature.report.generated.resources.feature_report_run_report -import androidclient.feature.report.generated.resources.feature_report_saving_account import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -75,6 +65,7 @@ import com.mifos.core.designsystem.component.MifosTextFieldDropdown import com.mifos.core.model.objects.runreport.DataRow import com.mifos.core.model.objects.runreport.FullParameterListResponse import com.mifos.core.model.objects.runreport.client.ClientReportTypeItem +import com.mifos.core.ui.util.DevicePreview import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource import org.koin.compose.viewmodel.koinViewModel @@ -441,7 +432,6 @@ private fun RunReportContent( selectedOffice = value selectedOfficeId = officeList[index].row.first() }, - label = Res.string.feature_report_office, options = officeList.map { it.row[1] }, readOnly = true, ) @@ -458,7 +448,6 @@ private fun RunReportContent( selectedLoanPurpose = value selectedLoanPurposeId = loanPurposeList[index].row.first() }, - label = Res.string.feature_report_loan_purpose, options = loanPurposeList.map { it.row[1] }, readOnly = true, ) @@ -475,7 +464,6 @@ private fun RunReportContent( selectedLoanOfficer = value selectedLoanOfficerId = reportOffices[index].row.first() }, - label = Res.string.feature_report_loan_officer, options = reportOffices.map { it.row[1] }, readOnly = true, ) @@ -492,7 +480,6 @@ private fun RunReportContent( selectedProducts = value selectedProductsId = reportProducts[index].row.first() }, - label = Res.string.feature_report_product, options = reportProducts.map { it.row[1] }, readOnly = true, ) @@ -509,7 +496,6 @@ private fun RunReportContent( selectedFund = value selectedFundId = fundList[index].row.first() }, - label = Res.string.feature_report_fund, options = fundList.map { it.row[1] }, readOnly = true, ) @@ -526,7 +512,6 @@ private fun RunReportContent( selectedCurrency = value selectedCurrencyId = currencyList[index].row.first() }, - label = Res.string.feature_report_currency, options = currencyList.map { it.row[1] }, readOnly = true, ) @@ -543,7 +528,6 @@ private fun RunReportContent( selectedParCalculator = value selectedParCalculatorId = parCalculatorList[index].row.first() }, - label = Res.string.feature_report_par_type, options = parCalculatorList.map { it.row[1] }, readOnly = true, ) @@ -560,7 +544,6 @@ private fun RunReportContent( selectedSavingsAccountDeposit = value selectedSavingsAccountDepositId = savingsAccountDepositList[index].row.first() }, - label = Res.string.feature_report_saving_account, options = savingsAccountDepositList.map { it.row[1] }, readOnly = true, ) @@ -577,7 +560,6 @@ private fun RunReportContent( selectedGlAccount = value selectedGlAccountId = glAccountList[index].row.first() }, - label = Res.string.feature_report_gl_account, options = glAccountList.map { it.row[1] }, readOnly = true, ) @@ -594,7 +576,6 @@ private fun RunReportContent( selectedObligationDate = value selectedObligationDateId = obligationDateList[index].row.first() }, - label = Res.string.feature_report_obligation_date, options = obligationDateList.map { it.row[1] }, readOnly = true, ) @@ -636,3 +617,68 @@ private fun RunReportContent( // runReport = {}, // ) //} +@DevicePreview +@Composable +private fun ReportDetailScreenLoadingPreview() { + ReportDetailScreen( + reportItem = ClientReportTypeItem(), + state = ReportDetailUiState.Loading, + onBackPressed = {}, + onRetry = {}, + officeList = emptyList(), + loanPurposeList = emptyList(), + fundList = emptyList(), + currencyList = emptyList(), + parCalculatorList = emptyList(), + savingsAccountDepositList = emptyList(), + glAccountList = emptyList(), + obligationDateList = emptyList(), + reportOffices = emptyList(), + reportProducts = emptyList(), + runReport = {}, + ) +} + +@DevicePreview +@Composable +private fun ReportDetailScreenErrorPreview() { + ReportDetailScreen( + reportItem = ClientReportTypeItem(), + state = ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details), + onBackPressed = {}, + onRetry = {}, + officeList = emptyList(), + loanPurposeList = emptyList(), + fundList = emptyList(), + currencyList = emptyList(), + parCalculatorList = emptyList(), + savingsAccountDepositList = emptyList(), + glAccountList = emptyList(), + obligationDateList = emptyList(), + reportOffices = emptyList(), + reportProducts = emptyList(), + runReport = {}, + ) +} + +@DevicePreview +@Composable +private fun ReportDetailScreenSuccessPreview() { + ReportDetailScreen( + reportItem = ClientReportTypeItem(), + state = ReportDetailUiState.ParameterDetailsSuccess, + onBackPressed = {}, + onRetry = {}, + officeList = emptyList(), + loanPurposeList = emptyList(), + fundList = emptyList(), + currencyList = emptyList(), + parCalculatorList = emptyList(), + savingsAccountDepositList = emptyList(), + glAccountList = emptyList(), + obligationDateList = emptyList(), + reportOffices = emptyList(), + reportProducts = emptyList(), + runReport = {}, + ) +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8b005762784..05f75adebe1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -94,6 +94,7 @@ multidex = "2.0.1" navigationFragmentKtx = "2.8.5" navigationUiKtx = "2.8.5" okhttpVersion = "4.12.0" +okio = "3.9.0" pagingRuntimeKtx = "3.3.5" playServicesLocation = "21.3.0" playServicesMaps = "19.0.0" @@ -236,6 +237,7 @@ kotlinx-serialization-json-v163 = { module = "org.jetbrains.kotlinx:kotlinx-seri mifos-koin-android = { module = "io.insert-koin:koin-android", version.ref = "koinAndroid" } koin-androidx-compose-v350 = { module = "io.insert-koin:koin-androidx-compose", version.ref = "koinAndroidxCompose" } maps-compose = { module = "com.google.maps.android:maps-compose", version.ref = "mapsCompose" } +okio-v390 = { module = "com.squareup.okio:okio", version.ref = "okio" } retrofit2-kotlinx-serialization-converter = { module = "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter", version.ref = "retrofit2KotlinxSerializationConverter" } rxandroid = { module = "io.reactivex:rxandroid", version.ref = "rxandroidVersion" } rxjava = { module = "io.reactivex:rxjava", version.ref = "rxjava" } @@ -555,7 +557,7 @@ moko-permission-compose = { group = "dev.icerock.moko", name = "permissions-comp window-size = { group = "dev.chrisbanes.material3", name = "material3-window-size-class-multiplatform", version.ref = "windowsSizeClass" } androidx-material3-android = { group = "androidx.compose.material3", name = "material3-android", version.ref = "material3Android" } -androidx-ui-android = { group = "androidx.compose.ui", name = "ui-android", version.ref = "uiAndroid" } + [plugins] diff --git a/settings.gradle.kts b/settings.gradle.kts index 54e0cecbe7e..5904f04172d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -61,4 +61,6 @@ include(":feature:note") include(":feature:settings") //include(":feature:passcode") include(":feature:search") +include(":feature:path-tracking") +include(":feature:savings") From 38c150db4fbfb820d0ac5787e539f5c1412b8034 Mon Sep 17 00:00:00 2001 From: kapmaurya Date: Thu, 12 Jun 2025 23:27:46 +0530 Subject: [PATCH 07/18] cmp-search migration --- .../kotlin/cmp/navigation/di/KoinModules.kt | 1 + .../cmp/navigation/navigation/RootNavGraph.kt | 1 + .../reportDetail/ReportDetailViewModel.kt | 66 +++++++------------ settings.gradle.kts | 1 + 4 files changed, 25 insertions(+), 44 deletions(-) diff --git a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt index 4da74182cdf..e5ab5fa5312 100644 --- a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt +++ b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt @@ -72,6 +72,7 @@ object KoinModules { GroupsModule, // LoanModule, NoteModule, + OfflineModule, SettingsModule, ) } diff --git a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/RootNavGraph.kt b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/RootNavGraph.kt index e3048723fae..04ad9ba4600 100644 --- a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/RootNavGraph.kt +++ b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/RootNavGraph.kt @@ -41,6 +41,7 @@ fun RootNavGraph( updateServerConfig = {}, ) + composable(MAIN_GRAPH) { App( modifier = modifier, diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt index ad9637829d5..f5b7992b398 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt @@ -9,13 +9,10 @@ */ package com.mifos.feature.report.reportDetail -import androidclient.feature.report.generated.resources.Res -import androidclient.feature.report.generated.resources.feature_report_failed_to_load_report_details import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.mifos.core.common.utils.Constants -import com.mifos.core.common.utils.DataState import com.mifos.core.common.utils.Resource import com.mifos.core.domain.useCases.GetReportFullParameterListUseCase import com.mifos.core.domain.useCases.GetReportParameterDetailsUseCase @@ -25,8 +22,8 @@ import com.mifos.core.domain.useCases.GetRunReportWithQueryUseCase import com.mifos.core.model.objects.runreport.DataRow import com.mifos.core.model.objects.runreport.FullParameterListResponse import com.mifos.core.model.objects.runreport.client.ClientReportTypeItem +import com.mifos.feature.report.R import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch @@ -38,7 +35,7 @@ class ReportDetailViewModel( private val getRunReportProductUseCase: GetRunReportProductUseCase, private val getRunReportWithQueryUseCase: GetRunReportWithQueryUseCase, private val getRunReportOfficesUseCase: GetRunReportOfficesUseCase, - private val savedStateHandle: SavedStateHandle + private val savedStateHandle: SavedStateHandle, ) : ViewModel() { private val reportName = @@ -69,19 +66,15 @@ class ReportDetailViewModel( viewModelScope.launch(Dispatchers.IO) { getReportFullParameterListUseCase(reportName, parameterType).collect { result -> when (result) { - is Resource.Error<*> -> + is Resource.Error -> _reportDetailUiState.value = - ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) + ReportDetailUiState.Error(R.string.feature_report_failed_to_load_report_details) - is Resource.Loading<*> -> _reportDetailUiState.value = ReportDetailUiState.Loading + is Resource.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading - is Resource.Success<*> -> + is Resource.Success -> _reportParameterList.value = result.data?.data ?: emptyList() - - is DataState.Error<*> -> TODO() - DataState.Loading -> TODO() - is DataState.Success<*> -> TODO() } } } @@ -90,18 +83,14 @@ class ReportDetailViewModel( viewModelScope.launch(Dispatchers.IO) { getReportParameterDetailsUseCase(parameterName, parameterType).collect { result -> when (result) { - is Resource.Error<*> -> Unit + is Resource.Error -> Unit - is Resource.Loading<*> -> Unit + is Resource.Loading -> Unit - is Resource.Success<*> -> { + is Resource.Success -> { _reportDetail.value = Pair(result.data?.data ?: emptyList(), parameterName) } - - is DataState.Error<*> -> TODO() - DataState.Loading -> TODO() - is DataState.Success<*> -> TODO() } } } @@ -110,20 +99,16 @@ class ReportDetailViewModel( viewModelScope.launch(Dispatchers.IO) { getRunReportOfficesUseCase(parameterName, officeId, parameterType).collect { result -> when (result) { - is Resource.Error<*> -> + is Resource.Error -> _reportDetailUiState.value = - ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) + ReportDetailUiState.Error(R.string.feature_report_failed_to_load_report_details) - is Resource.Loading<*> -> Unit + is Resource.Loading -> Unit - is Resource.Success<*> -> { + is Resource.Success -> { _reportOffices.value = result.data?.data ?: emptyList() _reportDetailUiState.value = ReportDetailUiState.ParameterDetailsSuccess } - - is DataState.Error<*> -> TODO() - DataState.Loading -> TODO() - is DataState.Success<*> -> TODO() } } } @@ -132,20 +117,16 @@ class ReportDetailViewModel( viewModelScope.launch(Dispatchers.IO) { getRunReportProductUseCase(parameterName, currencyId, parameterType).collect { result -> when (result) { - is Resource.Error<*> -> + is Resource.Error -> _reportDetailUiState.value = - ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) + ReportDetailUiState.Error(R.string.feature_report_failed_to_load_report_details) - is Resource.Loading<*> -> Unit + is Resource.Loading -> Unit - is Resource.Success<*> -> { + is Resource.Success -> { _reportProducts.value = result.data?.data ?: emptyList() _reportDetailUiState.value = ReportDetailUiState.ParameterDetailsSuccess } - - is DataState.Error<*> -> TODO() - DataState.Loading -> TODO() - is DataState.Success<*> -> TODO() } } } @@ -154,17 +135,14 @@ class ReportDetailViewModel( viewModelScope.launch(Dispatchers.IO) { getRunReportWithQueryUseCase(reportName, options).collect { result -> when (result) { - is Resource.Error<*> -> + is Resource.Error -> _reportDetailUiState.value = - ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) + ReportDetailUiState.Error(R.string.feature_report_failed_to_load_report_details) - is Resource.Loading<*> -> _reportDetailUiState.value = ReportDetailUiState.Loading + is Resource.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading - is Resource.Success<*> -> _runReport.value = result.data - is DataState.Error<*> -> TODO() - DataState.Loading -> TODO() - is DataState.Success<*> -> TODO() + is Resource.Success -> _runReport.value = result.data } } } -} +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 4dc9d2e94b0..c8b119c5124 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -57,6 +57,7 @@ include(":feature:collectionSheet") include(":feature:groups") //include(":feature:loan") include(":feature:note") +include(":feature:offline") include(":feature:settings") //include(":feature:passcode") include(":feature:search") From b3025bf4c424c5f92b4cb00cefcc1567e30f5d42 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sun, 15 Jun 2025 19:01:52 +0530 Subject: [PATCH 08/18] updated --- settings.gradle.kts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 859adc64e2b..cc2c6cb1199 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -58,9 +58,10 @@ include(":feature:groups") //include(":feature:loan") include(":feature:note") include(":feature:offline") +include(":feature:path-tracking") +include(":feature:report") +include(":feature:savings") +include(":feature:search") include(":feature:settings") //include(":feature:passcode") include(":feature:search") -include(":feature:path-tracking") -include(":feature:savings") - From 3f932fec852642b100dd9fdd3238101c1016ff97 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sun, 15 Jun 2025 19:05:26 +0530 Subject: [PATCH 09/18] updated --- gradle/libs.versions.toml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6e54933696b..8bd98c9267c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -71,7 +71,6 @@ koinAndroid = "4.0.1" koinAndroidxCompose = "3.5.0" kotlinxCoroutinesCoreVersion = "1.10.1" kotlinxCoroutinesRx2 = "1.5.1" -kotlinxSerializationJsonVersion = "1.6.3" legacySupportV4 = "1.0.0" lifecycleCommonJava8 = "2.8.7" lifecycleExtensions = "2.2.0" @@ -94,7 +93,6 @@ multidex = "2.0.1" navigationFragmentKtx = "2.8.5" navigationUiKtx = "2.8.5" okhttpVersion = "4.12.0" -okio = "3.9.0" pagingRuntimeKtx = "3.3.5" playServicesLocation = "21.3.0" playServicesMaps = "19.0.0" @@ -191,7 +189,6 @@ androidPackageName = "AndroidApp" androidPackageNamespace = "org.mifos.client" androidPackageVersion = "1.0.0" uiAndroidVersion = "1.7.8" -uiAndroid = "1.8.2" [libraries] @@ -233,11 +230,9 @@ android-maps-utils = { module = "com.google.maps.android:android-maps-utils", ve android-iconify-material = { module = "com.joanzapata.iconify:android-iconify-material", version.ref = "androidIconifyMaterial" } #RxAndroid -kotlinx-serialization-json-v163 = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJsonVersion" } mifos-koin-android = { module = "io.insert-koin:koin-android", version.ref = "koinAndroid" } koin-androidx-compose-v350 = { module = "io.insert-koin:koin-androidx-compose", version.ref = "koinAndroidxCompose" } maps-compose = { module = "com.google.maps.android:maps-compose", version.ref = "mapsCompose" } -okio-v390 = { module = "com.squareup.okio:okio", version.ref = "okio" } retrofit2-kotlinx-serialization-converter = { module = "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter", version.ref = "retrofit2KotlinxSerializationConverter" } rxandroid = { module = "io.reactivex:rxandroid", version.ref = "rxandroidVersion" } rxjava = { module = "io.reactivex:rxjava", version.ref = "rxjava" } @@ -558,7 +553,6 @@ moko-permission-compose = { group = "dev.icerock.moko", name = "permissions-comp window-size = { group = "dev.chrisbanes.material3", name = "material3-window-size-class-multiplatform", version.ref = "windowsSizeClass" } androidx-material3-android = { group = "androidx.compose.material3", name = "material3-android", version.ref = "material3Android" } - [plugins] # Android & Kotlin Plugins From 79d3a97db5e354090e4fbc02e44796c30d4e3c24 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sun, 15 Jun 2025 19:07:44 +0530 Subject: [PATCH 10/18] revert koinModules --- .../src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt index e59be56a8e3..3051ea826d3 100644 --- a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt +++ b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt @@ -74,6 +74,9 @@ object KoinModules { // LoanModule, NoteModule, OfflineModule, + PathTrackingModule, + SavingsModule, + SearchModule, SettingsModule, ) } From 605f3743e25f8b7a415b4abc6b8f8f2917e966fa Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sun, 15 Jun 2025 19:11:49 +0530 Subject: [PATCH 11/18] clean up --- .../com/mifos/feature/report/navigation/ReportNavigation.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt index 494fb603b39..cfaadc5e447 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/navigation/ReportNavigation.kt @@ -24,10 +24,6 @@ import com.mifos.feature.report.runReport.RunReportScreen import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json - - - - fun NavGraphBuilder.reportNavGraph( navController: NavController, ) { @@ -91,7 +87,6 @@ fun NavGraphBuilder.reportScreenRoute( } } - fun NavController.navigateReportDetailsScreen(clientReportTypeItem: ClientReportTypeItem) { val arg = Json.encodeToString(clientReportTypeItem) navigate(ReportScreens.ReportDetailScreen.argument(arg)) From 5343b0688f3eff77adf63da296b49dbc5daed4e3 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sun, 15 Jun 2025 19:27:34 +0530 Subject: [PATCH 12/18] previews clean up --- feature/report/build.gradle.kts | 1 + .../feature/report/report/ReportScreen.kt | 53 +++-------- .../report/reportDetail/ReportDetailScreen.kt | 93 +++---------------- .../report/runReport/RunReportScreen.kt | 6 +- 4 files changed, 35 insertions(+), 118 deletions(-) diff --git a/feature/report/build.gradle.kts b/feature/report/build.gradle.kts index 27464127875..c5efc267646 100644 --- a/feature/report/build.gradle.kts +++ b/feature/report/build.gradle.kts @@ -23,6 +23,7 @@ kotlin { implementation(compose.ui) api(projects.core.domain) implementation(libs.kotlinx.serialization.json) + implementation(compose.components.uiToolingPreview) } } } \ No newline at end of file diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt index 3ce85761053..7b1f610b796 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt @@ -39,10 +39,12 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.mifos.core.designsystem.component.MifosScaffold import com.mifos.core.model.objects.runreport.FullParameterListResponse -import com.mifos.core.ui.util.DevicePreview import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource import org.koin.compose.viewmodel.koinViewModel +import org.jetbrains.compose.ui.tooling.preview.Preview +import org.jetbrains.compose.ui.tooling.preview.PreviewParameter +import org.jetbrains.compose.ui.tooling.preview.PreviewParameterProvider @Composable @@ -55,8 +57,6 @@ internal fun ReportScreen( val report = viewModel.report val state by viewModel.reportUiState.collectAsStateWithLifecycle() - // val context = LocalContext.current - ReportScreen( state = state, report = report, @@ -169,49 +169,24 @@ internal fun ReportScreen( } } -//private class ReportUiStateProvider : PreviewParameterProvider { -// -// override val values: Sequence -// get() = sequenceOf( -// ReportUiState.Initial, -// ReportUiState.Message(R.string.feature_report_export_csv), -// ) -//} -// -//@Preview(showBackground = true) -//@Composable -//private fun ReportScreenPreview( -// @PreviewParameter(ReportUiStateProvider::class) state: ReportUiState, -//) { -// ReportScreen( -// state = state, -// report = FullParameterListResponse(emptyList(), emptyList()), -// onBackPressed = { }, -// exportReport = { }, -// ) -//} +private class ReportUiStateProvider : PreviewParameterProvider { -@DevicePreview() -@Composable -fun ReportScreenPreviewInitial() { - ReportScreen( - state = ReportUiState.Initial, - report = FullParameterListResponse(emptyList(), emptyList()), - onBackPressed = {}, - exportReport = {}, - showMessage = {} - ) + override val values: Sequence + get() = sequenceOf( + ReportUiState.Initial, + ReportUiState.Message(Res.string.feature_report_export_csv), + ) } -@DevicePreview() +@Preview @Composable -private fun ReportScreenPreviewMessage() { +private fun ReportScreenPreview( + @PreviewParameter(ReportUiStateProvider::class) state: ReportUiState, +) { ReportScreen( - state = ReportUiState.Message(Res.string.feature_report_export_csv), + state = state, report = FullParameterListResponse(emptyList(), emptyList()), onBackPressed = { }, exportReport = { }, - showMessage = {} ) } - diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt index 6a3613e3939..fdc1de8dc4a 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt @@ -65,10 +65,12 @@ import com.mifos.core.designsystem.component.MifosTextFieldDropdown import com.mifos.core.model.objects.runreport.DataRow import com.mifos.core.model.objects.runreport.FullParameterListResponse import com.mifos.core.model.objects.runreport.client.ClientReportTypeItem -import com.mifos.core.ui.util.DevicePreview import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource import org.koin.compose.viewmodel.koinViewModel +import org.jetbrains.compose.ui.tooling.preview.Preview +import org.jetbrains.compose.ui.tooling.preview.PreviewParameter +import org.jetbrains.compose.ui.tooling.preview.PreviewParameterProvider @Composable internal fun ReportDetailScreen( @@ -584,89 +586,24 @@ private fun RunReportContent( } } -//private class ReportDetailUiStateProvider : PreviewParameterProvider { -// -// override val values: Sequence -// get() = sequenceOf( -// ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details), -// ReportDetailUiState.Loading, -// ReportDetailUiState.ParameterDetailsSuccess, -// ) -//} -// -//@DevicePreview -//@Composable -//private fun ReportDetailScreenPreview( -// @PreviewParameter(ReportDetailUiStateProvider::class) state: ReportDetailUiState, -//) { -// ReportDetailScreen( -// reportItem = ClientReportTypeItem(), -// state = state, -// onBackPressed = {}, -// onRetry = {}, -// officeList = emptyList(), -// loanPurposeList = emptyList(), -// fundList = emptyList(), -// currencyList = emptyList(), -// parCalculatorList = emptyList(), -// savingsAccountDepositList = emptyList(), -// glAccountList = emptyList(), -// obligationDateList = emptyList(), -// reportOffices = emptyList(), -// reportProducts = emptyList(), -// runReport = {}, -// ) -//} -@DevicePreview -@Composable -private fun ReportDetailScreenLoadingPreview() { - ReportDetailScreen( - reportItem = ClientReportTypeItem(), - state = ReportDetailUiState.Loading, - onBackPressed = {}, - onRetry = {}, - officeList = emptyList(), - loanPurposeList = emptyList(), - fundList = emptyList(), - currencyList = emptyList(), - parCalculatorList = emptyList(), - savingsAccountDepositList = emptyList(), - glAccountList = emptyList(), - obligationDateList = emptyList(), - reportOffices = emptyList(), - reportProducts = emptyList(), - runReport = {}, - ) -} +private class ReportDetailUiStateProvider : PreviewParameterProvider { -@DevicePreview -@Composable -private fun ReportDetailScreenErrorPreview() { - ReportDetailScreen( - reportItem = ClientReportTypeItem(), - state = ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details), - onBackPressed = {}, - onRetry = {}, - officeList = emptyList(), - loanPurposeList = emptyList(), - fundList = emptyList(), - currencyList = emptyList(), - parCalculatorList = emptyList(), - savingsAccountDepositList = emptyList(), - glAccountList = emptyList(), - obligationDateList = emptyList(), - reportOffices = emptyList(), - reportProducts = emptyList(), - runReport = {}, - ) + override val values: Sequence + get() = sequenceOf( + ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details), + ReportDetailUiState.Loading, + ReportDetailUiState.ParameterDetailsSuccess, + ) } -@DevicePreview +@Preview @Composable -private fun ReportDetailScreenSuccessPreview() { +private fun ReportDetailScreenPreview( + @PreviewParameter(ReportDetailUiStateProvider::class) state: ReportDetailUiState, +) { ReportDetailScreen( reportItem = ClientReportTypeItem(), - state = ReportDetailUiState.ParameterDetailsSuccess, + state = state, onBackPressed = {}, onRetry = {}, officeList = emptyList(), diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt index 467596c5322..45f05bd9505 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt @@ -15,6 +15,7 @@ import androidclient.feature.report.generated.resources.Res import androidclient.feature.report.generated.resources.feature_report_accounting import androidclient.feature.report.generated.resources.feature_report_all import androidclient.feature.report.generated.resources.feature_report_client +import androidclient.feature.report.generated.resources.feature_report_failed_to_fetch_reports import androidclient.feature.report.generated.resources.feature_report_fund import androidclient.feature.report.generated.resources.feature_report_loan import androidclient.feature.report.generated.resources.feature_report_savings @@ -75,6 +76,9 @@ import com.mifos.core.model.objects.runreport.client.ClientReportTypeItem import com.mifos.core.ui.util.DevicePreview import org.jetbrains.compose.resources.stringResource import org.koin.compose.viewmodel.koinViewModel +import org.jetbrains.compose.ui.tooling.preview.Preview +import org.jetbrains.compose.ui.tooling.preview.PreviewParameter +import org.jetbrains.compose.ui.tooling.preview.PreviewParameterProvider @Composable internal fun RunReportScreen( @@ -365,7 +369,7 @@ class RunReportUiStateProvider : PreviewParameterProvider { ) } -@DevicePreview +@Preview @Composable private fun RunReportPreview( @PreviewParameter(RunReportUiStateProvider::class) state: RunReportUiState, From d14bcd1e9c8ed15a5ad605e8f69761a80e24b26d Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sun, 15 Jun 2025 19:32:24 +0530 Subject: [PATCH 13/18] updated --- cmp-navigation/build.gradle.kts | 2 +- .../src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cmp-navigation/build.gradle.kts b/cmp-navigation/build.gradle.kts index b0fa8154b0e..0e92fc73f29 100644 --- a/cmp-navigation/build.gradle.kts +++ b/cmp-navigation/build.gradle.kts @@ -44,7 +44,7 @@ kotlin { implementation(projects.feature.note) implementation(projects.feature.offline) implementation(projects.feature.pathTracking) -// implementation(projects.feature.report) + implementation(projects.feature.report) implementation(projects.feature.savings) implementation(projects.feature.settings) implementation(projects.feature.search) diff --git a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt index 3051ea826d3..742bca794eb 100644 --- a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt +++ b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt @@ -21,6 +21,7 @@ import com.mifos.feature.auth.di.AuthModule import com.mifos.feature.center.di.CenterModule import com.mifos.feature.checker.inbox.task.di.CheckerInboxTaskModule import com.mifos.feature.dataTable.di.DataTableModule +import com.mifos.feature.report.di.ReportModule import com.mifos.feature.groups.di.GroupsModule import com.mifos.feature.individualCollectionSheet.di.CollectionSheetModule import com.mifos.feature.note.di.NoteModule @@ -75,6 +76,7 @@ object KoinModules { NoteModule, OfflineModule, PathTrackingModule, + ReportModule, SavingsModule, SearchModule, SettingsModule, From cf1a2048b2e0929ad980e6eae124850f28cc7397 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sun, 15 Jun 2025 19:44:01 +0530 Subject: [PATCH 14/18] revert back labels --- .../cmp/navigation/navigation/RootNavGraph.kt | 1 - .../feature/report/report/ReportScreen.kt | 1 - .../report/reportDetail/ReportDetailScreen.kt | 20 +++++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/RootNavGraph.kt b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/RootNavGraph.kt index 04ad9ba4600..e3048723fae 100644 --- a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/RootNavGraph.kt +++ b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/RootNavGraph.kt @@ -41,7 +41,6 @@ fun RootNavGraph( updateServerConfig = {}, ) - composable(MAIN_GRAPH) { App( modifier = modifier, diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt index 7b1f610b796..25641820934 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt @@ -1,4 +1,3 @@ - /* * Copyright 2024 Mifos Initiative * diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt index fdc1de8dc4a..ebe2730ad1f 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt @@ -10,10 +10,20 @@ package com.mifos.feature.report.reportDetail import androidclient.feature.report.generated.resources.Res +import androidclient.feature.report.generated.resources.feature_report_currency import androidclient.feature.report.generated.resources.feature_report_details import androidclient.feature.report.generated.resources.feature_report_failed_to_load_report_details +import androidclient.feature.report.generated.resources.feature_report_fund +import androidclient.feature.report.generated.resources.feature_report_gl_account import androidclient.feature.report.generated.resources.feature_report_ic_report_item +import androidclient.feature.report.generated.resources.feature_report_loan_officer +import androidclient.feature.report.generated.resources.feature_report_loan_purpose +import androidclient.feature.report.generated.resources.feature_report_obligation_date +import androidclient.feature.report.generated.resources.feature_report_office +import androidclient.feature.report.generated.resources.feature_report_par_type +import androidclient.feature.report.generated.resources.feature_report_product import androidclient.feature.report.generated.resources.feature_report_run_report +import androidclient.feature.report.generated.resources.feature_report_saving_account import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -434,6 +444,7 @@ private fun RunReportContent( selectedOffice = value selectedOfficeId = officeList[index].row.first() }, + label = stringResource(Res.string.feature_report_office), options = officeList.map { it.row[1] }, readOnly = true, ) @@ -450,6 +461,7 @@ private fun RunReportContent( selectedLoanPurpose = value selectedLoanPurposeId = loanPurposeList[index].row.first() }, + label = stringResource(Res.string.feature_report_loan_purpose), options = loanPurposeList.map { it.row[1] }, readOnly = true, ) @@ -466,6 +478,7 @@ private fun RunReportContent( selectedLoanOfficer = value selectedLoanOfficerId = reportOffices[index].row.first() }, + label = stringResource(Res.string.feature_report_loan_officer), options = reportOffices.map { it.row[1] }, readOnly = true, ) @@ -482,6 +495,7 @@ private fun RunReportContent( selectedProducts = value selectedProductsId = reportProducts[index].row.first() }, + label = stringResource(Res.string.feature_report_product), options = reportProducts.map { it.row[1] }, readOnly = true, ) @@ -498,6 +512,7 @@ private fun RunReportContent( selectedFund = value selectedFundId = fundList[index].row.first() }, + label = stringResource(Res.string.feature_report_fund), options = fundList.map { it.row[1] }, readOnly = true, ) @@ -514,6 +529,7 @@ private fun RunReportContent( selectedCurrency = value selectedCurrencyId = currencyList[index].row.first() }, + label = stringResource(Res.string.feature_report_currency), options = currencyList.map { it.row[1] }, readOnly = true, ) @@ -530,6 +546,7 @@ private fun RunReportContent( selectedParCalculator = value selectedParCalculatorId = parCalculatorList[index].row.first() }, + label = stringResource(Res.string.feature_report_par_type), options = parCalculatorList.map { it.row[1] }, readOnly = true, ) @@ -546,6 +563,7 @@ private fun RunReportContent( selectedSavingsAccountDeposit = value selectedSavingsAccountDepositId = savingsAccountDepositList[index].row.first() }, + label = stringResource(Res.string.feature_report_saving_account), options = savingsAccountDepositList.map { it.row[1] }, readOnly = true, ) @@ -562,6 +580,7 @@ private fun RunReportContent( selectedGlAccount = value selectedGlAccountId = glAccountList[index].row.first() }, + label = stringResource(Res.string.feature_report_gl_account), options = glAccountList.map { it.row[1] }, readOnly = true, ) @@ -578,6 +597,7 @@ private fun RunReportContent( selectedObligationDate = value selectedObligationDateId = obligationDateList[index].row.first() }, + label = stringResource(Res.string.feature_report_obligation_date), options = obligationDateList.map { it.row[1] }, readOnly = true, ) From b3049a055ec684dea7083e3ddafe99f881197bc3 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sun, 15 Jun 2025 21:05:29 +0530 Subject: [PATCH 15/18] revert back labels --- .../feature/report/report/ReportScreen.kt | 53 +++++++--------- .../feature/report/report/ReportViewModel.kt | 2 +- .../report/reportDetail/ReportDetailScreen.kt | 2 +- .../reportDetail/ReportDetailUiState.kt | 3 - .../reportDetail/ReportDetailViewModel.kt | 62 +++++++++---------- .../report/runReport/RunReportScreen.kt | 6 +- .../report/runReport/RunReportViewModel.kt | 9 +-- 7 files changed, 63 insertions(+), 74 deletions(-) diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt index 25641820934..375aad2fc50 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt @@ -10,7 +10,11 @@ package com.mifos.feature.report.report import androidclient.feature.report.generated.resources.Res +import androidclient.feature.report.generated.resources.feature_report_dismiss import androidclient.feature.report.generated.resources.feature_report_export_csv +import androidclient.feature.report.generated.resources.feature_report_external_approve_permission_description +import androidclient.feature.report.generated.resources.feature_report_permission_required +import androidclient.feature.report.generated.resources.feature_report_proceed import androidclient.feature.report.generated.resources.feature_report_title import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding @@ -36,7 +40,9 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.lifecycle.viewmodel.compose.viewModel import com.mifos.core.designsystem.component.MifosScaffold +import com.mifos.core.designsystem.icon.MifosIcons import com.mifos.core.model.objects.runreport.FullParameterListResponse import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource @@ -50,8 +56,6 @@ import org.jetbrains.compose.ui.tooling.preview.PreviewParameterProvider internal fun ReportScreen( onBackPressed: () -> Unit, viewModel: ReportViewModel = koinViewModel(), - platformDirPathProvider: () -> String, - showMessage: (String) -> Unit ) { val report = viewModel.report val state by viewModel.reportUiState.collectAsStateWithLifecycle() @@ -61,17 +65,14 @@ internal fun ReportScreen( report = report, onBackPressed = onBackPressed, exportReport = { - val reportDirectoryPath = platformDirPathProvider() +// val reportDirectoryPath = // Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) // .toString() + getString(context, R.string.feature_report_export_csv_directory) // viewModel.exportCsv( // report = report, // reportDirectoryPath = reportDirectoryPath, // ) - - viewModel.exportCsv(report = report, reportDirectoryPath = reportDirectoryPath) }, - showMessage = showMessage ) } @@ -82,26 +83,19 @@ internal fun ReportScreen( onBackPressed: () -> Unit, modifier: Modifier = Modifier, exportReport: () -> Unit, - showMessage: (String) -> Unit, ) { - //val context = LocalContext.current val scope = rememberCoroutineScope() val snackbarHostState = remember { SnackbarHostState() } - // var checkPermission by remember { mutableStateOf(false) } - var triggerExport by remember { mutableStateOf(false) } + var checkPermission by remember { mutableStateOf(false) } when (state) { is ReportUiState.Initial -> Unit is ReportUiState.Message -> { - val message = stringResource(state.message) - // Toast.makeText(context, stringResource(id = state.message), Toast.LENGTH_SHORT).show() - LaunchedEffect(state.message) { - showMessage(message) - } +// Toast.makeText(context, stringResource(state.message), Toast.LENGTH_SHORT).show() } } - if (triggerExport) { + if (checkPermission) { // PermissionBox( // requiredPermissions = if (Build.VERSION.SDK_INT >= 33) { // listOf(Manifest.permission.READ_MEDIA_IMAGES) @@ -111,19 +105,18 @@ internal fun ReportScreen( // Manifest.permission.WRITE_EXTERNAL_STORAGE, // ) // }, -// title = stringResource(Res.string.feature_report_permission_required), -// description = stringResource(R.string.feature_report_external_approve_permission_description), -// confirmButtonText = stringResource(R.string.feature_report_proceed), -// dismissButtonText = stringResource(R.string.feature_report_dismiss), +// title = Res.string.feature_report_permission_required, +// description = Res.string.feature_report_external_approve_permission_description, +// confirmButtonText = Res.string.feature_report_proceed, +// dismissButtonText = Res.string.feature_report_dismiss, // onGranted = { - LaunchedEffect(triggerExport) { - scope.launch { - exportReport() - triggerExport = false - } - } - // }, - // ) +// LaunchedEffect(key1 = Unit) { +// scope.launch { +// exportReport() +// } +// } +// }, +// ) } MifosScaffold( @@ -133,11 +126,11 @@ internal fun ReportScreen( actions = { TextButton( onClick = { - triggerExport = true + checkPermission = true }, colors = ButtonDefaults.textButtonColors(White), ) { - Text(text = stringResource(Res.string.feature_report_export_csv), color = Black) + Text(text = stringResource(Res.string.feature_report_export_csv)) } }, snackbarHostState = snackbarHostState, diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt index 3009d0fdc3e..3019e119e66 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportViewModel.kt @@ -45,7 +45,7 @@ class ReportViewModel( val reportUiState = _reportUiState.asStateFlow() fun exportCsv(report: FullParameterListResponse, reportDirectoryPath: String) { - viewModelScope.launch(Dispatchers.Default) { + viewModelScope.launch { _reportUiState.value = ReportUiState.Message(Res.string.feature_report_export_started) val timestamp = Clock.System.now().toEpochMilliseconds().toString() diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt index ebe2730ad1f..d3635935cec 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt @@ -231,7 +231,7 @@ internal fun ReportDetailScreen( onClick = { runReport(runReportDetail) }, colors = ButtonDefaults.textButtonColors(White), ) { - Text(text = stringResource(Res.string.feature_report_run_report), color = Black) + Text(text = stringResource(Res.string.feature_report_run_report)) } }, snackbarHostState = snackbarHostState, diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailUiState.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailUiState.kt index 628ac79b9b1..f02ad05c1fb 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailUiState.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailUiState.kt @@ -11,9 +11,6 @@ package com.mifos.feature.report.reportDetail import org.jetbrains.compose.resources.StringResource -/** - * Created by Aditya Gupta on 12/08/23. - */ sealed class ReportDetailUiState { data object Loading : ReportDetailUiState() diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt index f5b7992b398..f730efb0777 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt @@ -9,11 +9,13 @@ */ package com.mifos.feature.report.reportDetail +import androidclient.feature.report.generated.resources.Res +import androidclient.feature.report.generated.resources.feature_report_failed_to_load_report_details import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.mifos.core.common.utils.Constants -import com.mifos.core.common.utils.Resource +import com.mifos.core.common.utils.DataState import com.mifos.core.domain.useCases.GetReportFullParameterListUseCase import com.mifos.core.domain.useCases.GetReportParameterDetailsUseCase import com.mifos.core.domain.useCases.GetRunReportOfficesUseCase @@ -22,8 +24,6 @@ import com.mifos.core.domain.useCases.GetRunReportWithQueryUseCase import com.mifos.core.model.objects.runreport.DataRow import com.mifos.core.model.objects.runreport.FullParameterListResponse import com.mifos.core.model.objects.runreport.client.ClientReportTypeItem -import com.mifos.feature.report.R -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch @@ -63,50 +63,50 @@ class ReportDetailViewModel( val runReport = _runReport.asStateFlow() fun fetchFullParameterList(reportName: String, parameterType: Boolean) = - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch{ getReportFullParameterListUseCase(reportName, parameterType).collect { result -> when (result) { - is Resource.Error -> + is DataState.Error -> _reportDetailUiState.value = - ReportDetailUiState.Error(R.string.feature_report_failed_to_load_report_details) + ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) - is Resource.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading + is DataState.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading - is Resource.Success -> + is DataState.Success -> _reportParameterList.value = - result.data?.data ?: emptyList() + result.data.data } } } fun fetchParameterDetails(parameterName: String, parameterType: Boolean) = - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch{ getReportParameterDetailsUseCase(parameterName, parameterType).collect { result -> when (result) { - is Resource.Error -> Unit + is DataState.Error -> Unit - is Resource.Loading -> Unit + is DataState.Loading -> Unit - is Resource.Success -> { + is DataState.Success -> { _reportDetail.value = - Pair(result.data?.data ?: emptyList(), parameterName) + Pair(result.data.data, parameterName) } } } } fun fetchOffices(parameterName: String, officeId: Int, parameterType: Boolean) = - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch{ getRunReportOfficesUseCase(parameterName, officeId, parameterType).collect { result -> when (result) { - is Resource.Error -> + is DataState.Error -> _reportDetailUiState.value = - ReportDetailUiState.Error(R.string.feature_report_failed_to_load_report_details) + ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) - is Resource.Loading -> Unit + is DataState.Loading -> Unit - is Resource.Success -> { - _reportOffices.value = result.data?.data ?: emptyList() + is DataState.Success -> { + _reportOffices.value = result.data.data _reportDetailUiState.value = ReportDetailUiState.ParameterDetailsSuccess } } @@ -114,17 +114,17 @@ class ReportDetailViewModel( } fun fetchProduct(parameterName: String, currencyId: String, parameterType: Boolean) = - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch{ getRunReportProductUseCase(parameterName, currencyId, parameterType).collect { result -> when (result) { - is Resource.Error -> + is DataState.Error -> _reportDetailUiState.value = - ReportDetailUiState.Error(R.string.feature_report_failed_to_load_report_details) + ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) - is Resource.Loading -> Unit + is DataState.Loading -> Unit - is Resource.Success -> { - _reportProducts.value = result.data?.data ?: emptyList() + is DataState.Success -> { + _reportProducts.value = result.data.data _reportDetailUiState.value = ReportDetailUiState.ParameterDetailsSuccess } } @@ -132,16 +132,16 @@ class ReportDetailViewModel( } fun fetchRunReportWithQuery(reportName: String, options: MutableMap) = - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch { getRunReportWithQueryUseCase(reportName, options).collect { result -> when (result) { - is Resource.Error -> + is DataState.Error -> _reportDetailUiState.value = - ReportDetailUiState.Error(R.string.feature_report_failed_to_load_report_details) + ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) - is Resource.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading + is DataState.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading - is Resource.Success -> _runReport.value = result.data + is DataState.Success -> _runReport.value = result.data } } } diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt index 45f05bd9505..0c616a4176c 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt @@ -17,6 +17,7 @@ import androidclient.feature.report.generated.resources.feature_report_all import androidclient.feature.report.generated.resources.feature_report_client import androidclient.feature.report.generated.resources.feature_report_failed_to_fetch_reports import androidclient.feature.report.generated.resources.feature_report_fund +import androidclient.feature.report.generated.resources.feature_report_ic_report_item import androidclient.feature.report.generated.resources.feature_report_loan import androidclient.feature.report.generated.resources.feature_report_savings import androidclient.feature.report.generated.resources.feature_report_xbrl @@ -58,13 +59,10 @@ import androidx.compose.ui.graphics.Color.Companion.Black import androidx.compose.ui.graphics.Color.Companion.Blue import androidx.compose.ui.graphics.Color.Companion.DarkGray import androidx.compose.ui.graphics.Color.Companion.White -import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -73,7 +71,7 @@ import com.mifos.core.designsystem.component.MifosMenuDropDownItem import com.mifos.core.designsystem.component.MifosSweetError import com.mifos.core.designsystem.icon.MifosIcons import com.mifos.core.model.objects.runreport.client.ClientReportTypeItem -import com.mifos.core.ui.util.DevicePreview +import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource import org.koin.compose.viewmodel.koinViewModel import org.jetbrains.compose.ui.tooling.preview.Preview diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportViewModel.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportViewModel.kt index c9c47ba60a2..dd03dcf54e8 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportViewModel.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportViewModel.kt @@ -14,6 +14,7 @@ import androidclient.feature.report.generated.resources.feature_report_failed_to import androidclient.feature.report.generated.resources.feature_report_no_reports_found import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.mifos.core.common.utils.DataState import com.mifos.core.common.utils.Resource import com.mifos.core.domain.useCases.GetReportCategoryUseCase import kotlinx.coroutines.Dispatchers @@ -40,14 +41,14 @@ class RunReportViewModel( parameterType, ).collect { result -> when (result) { - is Resource.Error -> + is DataState.Error -> _runReportUiState.value = RunReportUiState.Error(Res.string.feature_report_failed_to_fetch_reports) - is Resource.Loading -> _runReportUiState.value = RunReportUiState.Loading + is DataState.Loading -> _runReportUiState.value = RunReportUiState.Loading - is Resource.Success -> { - result.data?.let { reports -> + is DataState.Success -> { + result.data.let { reports -> if (reports.isNotEmpty()) { _runReportUiState.value = RunReportUiState.RunReports(reports) } else { From 6a53f99dc37dd371316feff9dbd9f30107a2e897 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Tue, 17 Jun 2025 15:38:31 +0530 Subject: [PATCH 16/18] Added Serialname --- .../kotlin/cmp/navigation/navigation/FeatureNavHost.kt | 3 +++ .../objects/runreport/client/ClientReportTypeItem.kt | 10 ++++++++++ .../mifos/feature/report/runReport/RunReportScreen.kt | 3 --- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/FeatureNavHost.kt b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/FeatureNavHost.kt index d8fe55c3084..64650754ace 100644 --- a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/FeatureNavHost.kt +++ b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/FeatureNavHost.kt @@ -30,6 +30,7 @@ import com.mifos.feature.note.navigation.navigateToNoteScreen import com.mifos.feature.note.navigation.noteNavGraph import com.mifos.feature.offline.navigation.offlineNavGraph import com.mifos.feature.pathTracking.navigation.pathTrackingNavGraph +import com.mifos.feature.report.navigation.reportNavGraph import com.mifos.feature.savings.navigation.navigateToAddSavingsAccount import com.mifos.feature.savings.navigation.navigateToSavingsAccountSummaryScreen import com.mifos.feature.savings.navigation.savingsNavGraph @@ -118,5 +119,7 @@ internal fun FeatureNavHost( ) pathTrackingNavGraph(appState.navController) + + reportNavGraph(navController = appState.navController) } } diff --git a/core/model/src/commonMain/kotlin/com/mifos/core/model/objects/runreport/client/ClientReportTypeItem.kt b/core/model/src/commonMain/kotlin/com/mifos/core/model/objects/runreport/client/ClientReportTypeItem.kt index 14ec95e9b3d..f3023f97d5e 100644 --- a/core/model/src/commonMain/kotlin/com/mifos/core/model/objects/runreport/client/ClientReportTypeItem.kt +++ b/core/model/src/commonMain/kotlin/com/mifos/core/model/objects/runreport/client/ClientReportTypeItem.kt @@ -11,27 +11,37 @@ package com.mifos.core.model.objects.runreport.client import com.mifos.core.model.utils.Parcelable import com.mifos.core.model.utils.Parcelize +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable + /** * Created by Tarun on 03-08-17. */ @Parcelize @Serializable data class ClientReportTypeItem( + @SerialName("parameter_id") var parameterId: Int? = null, + @SerialName("parameter_name") var parameterName: String? = null, + @SerialName("report_category") var reportCategory: String? = null, + @SerialName("report_id") var reportId: Int? = null, + @SerialName("report_name") var reportName: String? = null, + @SerialName("report_parameter_name") var reportParameterName: String? = null, + @SerialName("report_subtype") var reportSubtype: String? = null, + @SerialName("report_type") var reportType: String? = null, ) : Parcelable diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt index 0c616a4176c..23d7be1362c 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/runReport/RunReportScreen.kt @@ -158,7 +158,6 @@ internal fun RunReportScreen( fontWeight = FontWeight.Medium, fontStyle = FontStyle.Normal, ), - color = Black, textAlign = TextAlign.Start, ) Spacer(modifier = Modifier.width(8.dp)) @@ -279,7 +278,6 @@ private fun RunReportCardItem( .clickable { onReportClick(report) }, - colors = CardDefaults.cardColors(White), ) { Row( modifier = Modifier @@ -298,7 +296,6 @@ private fun RunReportCardItem( Icon( painter = painterResource(Res.drawable.feature_report_ic_report_item), contentDescription = null, - tint = Black, ) } Column( From 0943808d80bc1553ea2a873df95a2855deb9ea7b Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Thu, 19 Jun 2025 11:35:09 +0530 Subject: [PATCH 17/18] updated --- .../core/model/objects/runreport/DataRow.kt | 2 +- .../feature/report/report/ReportScreen.kt | 4 +- .../report/reportDetail/ReportDetailScreen.kt | 408 +++++++++--------- .../reportDetail/ReportDetailViewModel.kt | 68 +-- 4 files changed, 249 insertions(+), 233 deletions(-) diff --git a/core/model/src/commonMain/kotlin/com/mifos/core/model/objects/runreport/DataRow.kt b/core/model/src/commonMain/kotlin/com/mifos/core/model/objects/runreport/DataRow.kt index 00ef9ac203a..8b20138a563 100644 --- a/core/model/src/commonMain/kotlin/com/mifos/core/model/objects/runreport/DataRow.kt +++ b/core/model/src/commonMain/kotlin/com/mifos/core/model/objects/runreport/DataRow.kt @@ -18,4 +18,4 @@ import kotlinx.serialization.Serializable */ @Parcelize @Serializable -data class DataRow(var row: List = listOf()) : Parcelable +data class DataRow(var row: List = listOf()) : Parcelable diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt index 375aad2fc50..3a48d0ff6ae 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/report/ReportScreen.kt @@ -152,7 +152,9 @@ internal fun ReportScreen( ), ) report.data.map { it.row }.forEach { - Text(text = it[index], modifier = Modifier.padding(8.dp)) + if (it[index] != null) { + Text(text = it[index]!!, modifier = Modifier.padding(8.dp)) + } } } } diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt index d3635935cec..a2925645fe2 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt @@ -67,6 +67,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.compose.collectAsStateWithLifecycle +import co.touchlab.kermit.Logger import com.mifos.core.common.utils.Constants import com.mifos.core.designsystem.component.MifosCircularProgress import com.mifos.core.designsystem.component.MifosScaffold @@ -118,13 +119,16 @@ internal fun ReportDetailScreen( var obligationDateList by rememberSaveable { mutableStateOf(emptyList()) } LaunchedEffect(reportDetail) { + Logger.e("Revanth"){ + reportDetail.second + } when (reportDetail.second) { Constants.LOAN_OFFICER_ID_SELECT -> { viewModel.fetchOffices(reportDetail.second, officeId, true) } Constants.LOAN_PRODUCT_ID_SELECT -> { - viewModel.fetchProduct(reportDetail.second, currencyId, true) +// viewModel.fetchProduct(reportDetail.second, currencyId, true) } Constants.LOAN_PURPOSE_ID_SELECT -> { @@ -136,14 +140,17 @@ internal fun ReportDetailScreen( } Constants.CURRENCY_ID_SELECT -> { - currencyId = reportDetail.first.first().row.first() +// currencyId = reportDetail.first.first().row.first() currencyList = reportDetail.first - viewModel.fetchProduct(Constants.LOAN_PRODUCT_ID_SELECT, currencyId, true) +// viewModel.fetchProduct(Constants.LOAN_PRODUCT_ID_SELECT, currencyId, true) } Constants.OFFICE_ID_SELECT -> { officeList = reportDetail.first - officeId = reportDetail.first.first().row.first().toInt() + officeId = reportDetail.first.first().row.first()?.toInt()?:-1 + Logger.e("Revanth"){ + officeId.toString() + } viewModel.fetchOffices(Constants.LOAN_OFFICER_ID_SELECT, officeId, true) } @@ -172,7 +179,9 @@ internal fun ReportDetailScreen( LaunchedEffect(reportParameterList) { reportParameterList.forEach { - viewModel.fetchParameterDetails(it.row.first(), true) + if(it.row.first()!=null){ + viewModel.fetchParameterDetails(it.row.first()!!, true) + } } } @@ -194,7 +203,7 @@ internal fun ReportDetailScreen( runReport = { mapQuery -> runReportEnable = true reportItem.reportName?.let { - viewModel.fetchRunReportWithQuery(it, mapQuery) +// viewModel.fetchRunReportWithQuery(it, mapQuery) } }, ) @@ -315,16 +324,16 @@ private fun RunReportContent( selectedGlAccount, selectedObligationDate, ) { - if (selectedOffice.isNotEmpty()) { - runReportDetail[Constants.R_OFFICE_ID] = selectedOfficeId + if (selectedOffice!=null && selectedOffice!!.isNotEmpty()) { + runReportDetail[Constants.R_OFFICE_ID] = selectedOfficeId!! } if (selectedLoanPurpose.isNotEmpty()) { runReportDetail[Constants.R_LOAN_PURPOSE_ID] = selectedLoanPurposeId } - if (selectedLoanOfficer.isNotEmpty()) { - runReportDetail[Constants.R_LOAN_OFFICER_ID] = selectedLoanOfficerId + if (selectedLoanOfficer!=null && selectedLoanOfficer!!.isNotEmpty()) { + runReportDetail[Constants.R_LOAN_OFFICER_ID] = selectedLoanOfficerId!! } if (selectedProducts.isNotEmpty()) { @@ -432,11 +441,12 @@ private fun RunReportContent( } } + Spacer(modifier = Modifier.height(16.dp)) - if (officeList.isNotEmpty()) { + if (selectedOffice!=null && officeList.isNotEmpty()) { MifosTextFieldDropdown( - value = selectedOffice, + value = selectedOffice!!, onValueChanged = { selectedOffice = it }, @@ -445,197 +455,197 @@ private fun RunReportContent( selectedOfficeId = officeList[index].row.first() }, label = stringResource(Res.string.feature_report_office), - options = officeList.map { it.row[1] }, - readOnly = true, - ) - Spacer(modifier = Modifier.height(16.dp)) - } - - if (loanPurposeList.isNotEmpty()) { - MifosTextFieldDropdown( - value = selectedLoanPurpose, - onValueChanged = { - selectedLoanPurpose = it - }, - onOptionSelected = { index, value -> - selectedLoanPurpose = value - selectedLoanPurposeId = loanPurposeList[index].row.first() - }, - label = stringResource(Res.string.feature_report_loan_purpose), - options = loanPurposeList.map { it.row[1] }, - readOnly = true, - ) - Spacer(modifier = Modifier.height(16.dp)) - } - - if (reportOffices.isNotEmpty()) { - MifosTextFieldDropdown( - value = selectedLoanOfficer, - onValueChanged = { - selectedLoanOfficer = it - }, - onOptionSelected = { index, value -> - selectedLoanOfficer = value - selectedLoanOfficerId = reportOffices[index].row.first() - }, - label = stringResource(Res.string.feature_report_loan_officer), - options = reportOffices.map { it.row[1] }, - readOnly = true, - ) - Spacer(modifier = Modifier.height(16.dp)) - } - - if (reportProducts.isNotEmpty()) { - MifosTextFieldDropdown( - value = selectedProducts, - onValueChanged = { - selectedProducts = it - }, - onOptionSelected = { index, value -> - selectedProducts = value - selectedProductsId = reportProducts[index].row.first() - }, - label = stringResource(Res.string.feature_report_product), - options = reportProducts.map { it.row[1] }, - readOnly = true, - ) - Spacer(modifier = Modifier.height(16.dp)) - } - - if (fundList.isNotEmpty()) { - MifosTextFieldDropdown( - value = selectedFund, - onValueChanged = { - selectedFund = it - }, - onOptionSelected = { index, value -> - selectedFund = value - selectedFundId = fundList[index].row.first() - }, - label = stringResource(Res.string.feature_report_fund), - options = fundList.map { it.row[1] }, - readOnly = true, - ) - Spacer(modifier = Modifier.height(16.dp)) - } - - if (currencyList.isNotEmpty()) { - MifosTextFieldDropdown( - value = selectedCurrency, - onValueChanged = { - selectedCurrency = it - }, - onOptionSelected = { index, value -> - selectedCurrency = value - selectedCurrencyId = currencyList[index].row.first() - }, - label = stringResource(Res.string.feature_report_currency), - options = currencyList.map { it.row[1] }, - readOnly = true, - ) - Spacer(modifier = Modifier.height(16.dp)) - } - - if (parCalculatorList.isNotEmpty()) { - MifosTextFieldDropdown( - value = selectedParCalculator, - onValueChanged = { - selectedParCalculator = it - }, - onOptionSelected = { index, value -> - selectedParCalculator = value - selectedParCalculatorId = parCalculatorList[index].row.first() - }, - label = stringResource(Res.string.feature_report_par_type), - options = parCalculatorList.map { it.row[1] }, - readOnly = true, - ) - Spacer(modifier = Modifier.height(16.dp)) - } - - if (savingsAccountDepositList.isNotEmpty()) { - MifosTextFieldDropdown( - value = selectedSavingsAccountDeposit, - onValueChanged = { - selectedSavingsAccountDeposit = it - }, - onOptionSelected = { index, value -> - selectedSavingsAccountDeposit = value - selectedSavingsAccountDepositId = savingsAccountDepositList[index].row.first() - }, - label = stringResource(Res.string.feature_report_saving_account), - options = savingsAccountDepositList.map { it.row[1] }, - readOnly = true, - ) - Spacer(modifier = Modifier.height(16.dp)) - } - - if (glAccountList.isNotEmpty()) { - MifosTextFieldDropdown( - value = selectedGlAccount, - onValueChanged = { - selectedGlAccount = it - }, - onOptionSelected = { index, value -> - selectedGlAccount = value - selectedGlAccountId = glAccountList[index].row.first() - }, - label = stringResource(Res.string.feature_report_gl_account), - options = glAccountList.map { it.row[1] }, - readOnly = true, - ) - Spacer(modifier = Modifier.height(16.dp)) - } - - if (obligationDateList.isNotEmpty()) { - MifosTextFieldDropdown( - value = selectedObligationDate, - onValueChanged = { - selectedObligationDate = it - }, - onOptionSelected = { index, value -> - selectedObligationDate = value - selectedObligationDateId = obligationDateList[index].row.first() - }, - label = stringResource(Res.string.feature_report_obligation_date), - options = obligationDateList.map { it.row[1] }, + options =officeList.mapNotNull { it.row.getOrNull(1) }, readOnly = true, ) Spacer(modifier = Modifier.height(16.dp)) } +// +// if (loanPurposeList.isNotEmpty()) { +// MifosTextFieldDropdown( +// value = selectedLoanPurpose, +// onValueChanged = { +// selectedLoanPurpose = it +// }, +// onOptionSelected = { index, value -> +// selectedLoanPurpose = value +// selectedLoanPurposeId = loanPurposeList[index].row.first() +// }, +// label = stringResource(Res.string.feature_report_loan_purpose), +// options = loanPurposeList.map { it.row[1] }, +// readOnly = true, +// ) +// Spacer(modifier = Modifier.height(16.dp)) +// } +// +// if (reportOffices.isNotEmpty()) { +// MifosTextFieldDropdown( +// value = selectedLoanOfficer, +// onValueChanged = { +// selectedLoanOfficer = it +// }, +// onOptionSelected = { index, value -> +// selectedLoanOfficer = value +// selectedLoanOfficerId = reportOffices[index].row.first() +// }, +// label = stringResource(Res.string.feature_report_loan_officer), +// options = reportOffices.map { it.row[1] }, +// readOnly = true, +// ) +// Spacer(modifier = Modifier.height(16.dp)) +// } +// +// if (reportProducts.isNotEmpty()) { +// MifosTextFieldDropdown( +// value = selectedProducts, +// onValueChanged = { +// selectedProducts = it +// }, +// onOptionSelected = { index, value -> +// selectedProducts = value +// selectedProductsId = reportProducts[index].row.first() +// }, +// label = stringResource(Res.string.feature_report_product), +// options = reportProducts.map { it.row[1] }, +// readOnly = true, +// ) +// Spacer(modifier = Modifier.height(16.dp)) +// } +// +// if (fundList.isNotEmpty()) { +// MifosTextFieldDropdown( +// value = selectedFund, +// onValueChanged = { +// selectedFund = it +// }, +// onOptionSelected = { index, value -> +// selectedFund = value +// selectedFundId = fundList[index].row.first() +// }, +// label = stringResource(Res.string.feature_report_fund), +// options = fundList.map { it.row[1] }, +// readOnly = true, +// ) +// Spacer(modifier = Modifier.height(16.dp)) +// } +// +// if (currencyList.isNotEmpty()) { +// MifosTextFieldDropdown( +// value = selectedCurrency, +// onValueChanged = { +// selectedCurrency = it +// }, +// onOptionSelected = { index, value -> +// selectedCurrency = value +// selectedCurrencyId = currencyList[index].row.first() +// }, +// label = stringResource(Res.string.feature_report_currency), +// options = currencyList.map { it.row[1] }, +// readOnly = true, +// ) +// Spacer(modifier = Modifier.height(16.dp)) +// } +// +// if (parCalculatorList.isNotEmpty()) { +// MifosTextFieldDropdown( +// value = selectedParCalculator, +// onValueChanged = { +// selectedParCalculator = it +// }, +// onOptionSelected = { index, value -> +// selectedParCalculator = value +// selectedParCalculatorId = parCalculatorList[index].row.first() +// }, +// label = stringResource(Res.string.feature_report_par_type), +// options = parCalculatorList.map { it.row[1] }, +// readOnly = true, +// ) +// Spacer(modifier = Modifier.height(16.dp)) +// } +// +// if (savingsAccountDepositList.isNotEmpty()) { +// MifosTextFieldDropdown( +// value = selectedSavingsAccountDeposit, +// onValueChanged = { +// selectedSavingsAccountDeposit = it +// }, +// onOptionSelected = { index, value -> +// selectedSavingsAccountDeposit = value +// selectedSavingsAccountDepositId = savingsAccountDepositList[index].row.first() +// }, +// label = stringResource(Res.string.feature_report_saving_account), +// options = savingsAccountDepositList.map { it.row[1] }, +// readOnly = true, +// ) +// Spacer(modifier = Modifier.height(16.dp)) +// } +// +// if (glAccountList.isNotEmpty()) { +// MifosTextFieldDropdown( +// value = selectedGlAccount, +// onValueChanged = { +// selectedGlAccount = it +// }, +// onOptionSelected = { index, value -> +// selectedGlAccount = value +// selectedGlAccountId = glAccountList[index].row.first() +// }, +// label = stringResource(Res.string.feature_report_gl_account), +// options = glAccountList.map { it.row[1] }, +// readOnly = true, +// ) +// Spacer(modifier = Modifier.height(16.dp)) +// } +// +// if (obligationDateList.isNotEmpty()) { +// MifosTextFieldDropdown( +// value = selectedObligationDate, +// onValueChanged = { +// selectedObligationDate = it +// }, +// onOptionSelected = { index, value -> +// selectedObligationDate = value +// selectedObligationDateId = obligationDateList[index].row.first() +// }, +// label = stringResource(Res.string.feature_report_obligation_date), +// options = obligationDateList.map { it.row[1] }, +// readOnly = true, +// ) +// Spacer(modifier = Modifier.height(16.dp)) +// } } } -private class ReportDetailUiStateProvider : PreviewParameterProvider { - - override val values: Sequence - get() = sequenceOf( - ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details), - ReportDetailUiState.Loading, - ReportDetailUiState.ParameterDetailsSuccess, - ) -} - -@Preview -@Composable -private fun ReportDetailScreenPreview( - @PreviewParameter(ReportDetailUiStateProvider::class) state: ReportDetailUiState, -) { - ReportDetailScreen( - reportItem = ClientReportTypeItem(), - state = state, - onBackPressed = {}, - onRetry = {}, - officeList = emptyList(), - loanPurposeList = emptyList(), - fundList = emptyList(), - currencyList = emptyList(), - parCalculatorList = emptyList(), - savingsAccountDepositList = emptyList(), - glAccountList = emptyList(), - obligationDateList = emptyList(), - reportOffices = emptyList(), - reportProducts = emptyList(), - runReport = {}, - ) -} +//private class ReportDetailUiStateProvider : PreviewParameterProvider { +// +// override val values: Sequence +// get() = sequenceOf( +// ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details), +// ReportDetailUiState.Loading, +// ReportDetailUiState.ParameterDetailsSuccess, +// ) +//} +// +//@Preview +//@Composable +//private fun ReportDetailScreenPreview( +// @PreviewParameter(ReportDetailUiStateProvider::class) state: ReportDetailUiState, +//) { +// ReportDetailScreen( +// reportItem = ClientReportTypeItem(), +// state = state, +// onBackPressed = {}, +// onRetry = {}, +// officeList = emptyList(), +// loanPurposeList = emptyList(), +// fundList = emptyList(), +// currencyList = emptyList(), +// parCalculatorList = emptyList(), +// savingsAccountDepositList = emptyList(), +// glAccountList = emptyList(), +// obligationDateList = emptyList(), +// reportOffices = emptyList(), +// reportProducts = emptyList(), +// runReport = {}, +// ) +//} diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt index f730efb0777..2221b01bcf3 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt @@ -14,6 +14,7 @@ import androidclient.feature.report.generated.resources.feature_report_failed_to import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import co.touchlab.kermit.Logger import com.mifos.core.common.utils.Constants import com.mifos.core.common.utils.DataState import com.mifos.core.domain.useCases.GetReportFullParameterListUseCase @@ -63,6 +64,7 @@ class ReportDetailViewModel( val runReport = _runReport.asStateFlow() fun fetchFullParameterList(reportName: String, parameterType: Boolean) = + viewModelScope.launch{ getReportFullParameterListUseCase(reportName, parameterType).collect { result -> when (result) { @@ -82,6 +84,7 @@ class ReportDetailViewModel( fun fetchParameterDetails(parameterName: String, parameterType: Boolean) = viewModelScope.launch{ getReportParameterDetailsUseCase(parameterName, parameterType).collect { result -> + Logger.e("Revanth Result"){result.toString()} when (result) { is DataState.Error -> Unit @@ -98,6 +101,7 @@ class ReportDetailViewModel( fun fetchOffices(parameterName: String, officeId: Int, parameterType: Boolean) = viewModelScope.launch{ getRunReportOfficesUseCase(parameterName, officeId, parameterType).collect { result -> + Logger.e("Revanth Result"){result.toString()} when (result) { is DataState.Error -> _reportDetailUiState.value = @@ -113,36 +117,36 @@ class ReportDetailViewModel( } } - fun fetchProduct(parameterName: String, currencyId: String, parameterType: Boolean) = - viewModelScope.launch{ - getRunReportProductUseCase(parameterName, currencyId, parameterType).collect { result -> - when (result) { - is DataState.Error -> - _reportDetailUiState.value = - ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) - - is DataState.Loading -> Unit - - is DataState.Success -> { - _reportProducts.value = result.data.data - _reportDetailUiState.value = ReportDetailUiState.ParameterDetailsSuccess - } - } - } - } - - fun fetchRunReportWithQuery(reportName: String, options: MutableMap) = - viewModelScope.launch { - getRunReportWithQueryUseCase(reportName, options).collect { result -> - when (result) { - is DataState.Error -> - _reportDetailUiState.value = - ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) - - is DataState.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading - - is DataState.Success -> _runReport.value = result.data - } - } - } +// fun fetchProduct(parameterName: String, currencyId: String, parameterType: Boolean) = +// viewModelScope.launch{ +// getRunReportProductUseCase(parameterName, currencyId, parameterType).collect { result -> +// when (result) { +// is DataState.Error -> +// _reportDetailUiState.value = +// ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) +// +// is DataState.Loading -> Unit +// +// is DataState.Success -> { +// _reportProducts.value = result.data.data +// _reportDetailUiState.value = ReportDetailUiState.ParameterDetailsSuccess +// } +// } +// } +// } +// +// fun fetchRunReportWithQuery(reportName: String, options: MutableMap) = +// viewModelScope.launch { +// getRunReportWithQueryUseCase(reportName, options).collect { result -> +// when (result) { +// is DataState.Error -> +// _reportDetailUiState.value = +// ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) +// +// is DataState.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading +// +// is DataState.Success -> _runReport.value = result.data +// } +// } +// } } \ No newline at end of file From 38f44b9029dcb5a308eb7d8192b221f12f6a9970 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Thu, 19 Jun 2025 17:34:47 +0530 Subject: [PATCH 18/18] updated --- .../report/reportDetail/ReportDetailScreen.kt | 380 +++++++++--------- .../reportDetail/ReportDetailViewModel.kt | 66 +-- 2 files changed, 223 insertions(+), 223 deletions(-) diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt index a2925645fe2..bf0c99a44bd 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailScreen.kt @@ -128,7 +128,7 @@ internal fun ReportDetailScreen( } Constants.LOAN_PRODUCT_ID_SELECT -> { -// viewModel.fetchProduct(reportDetail.second, currencyId, true) + viewModel.fetchProduct(reportDetail.second, currencyId, true) } Constants.LOAN_PURPOSE_ID_SELECT -> { @@ -140,9 +140,9 @@ internal fun ReportDetailScreen( } Constants.CURRENCY_ID_SELECT -> { -// currencyId = reportDetail.first.first().row.first() + currencyId = reportDetail.first.first().row.first()?:"" currencyList = reportDetail.first -// viewModel.fetchProduct(Constants.LOAN_PRODUCT_ID_SELECT, currencyId, true) + viewModel.fetchProduct(Constants.LOAN_PRODUCT_ID_SELECT, currencyId, true) } Constants.OFFICE_ID_SELECT -> { @@ -203,7 +203,7 @@ internal fun ReportDetailScreen( runReport = { mapQuery -> runReportEnable = true reportItem.reportName?.let { -// viewModel.fetchRunReportWithQuery(it, mapQuery) + viewModel.fetchRunReportWithQuery(it, mapQuery) } }, ) @@ -460,192 +460,192 @@ private fun RunReportContent( ) Spacer(modifier = Modifier.height(16.dp)) } -// -// if (loanPurposeList.isNotEmpty()) { -// MifosTextFieldDropdown( -// value = selectedLoanPurpose, -// onValueChanged = { -// selectedLoanPurpose = it -// }, -// onOptionSelected = { index, value -> -// selectedLoanPurpose = value -// selectedLoanPurposeId = loanPurposeList[index].row.first() -// }, -// label = stringResource(Res.string.feature_report_loan_purpose), -// options = loanPurposeList.map { it.row[1] }, -// readOnly = true, -// ) -// Spacer(modifier = Modifier.height(16.dp)) -// } -// -// if (reportOffices.isNotEmpty()) { -// MifosTextFieldDropdown( -// value = selectedLoanOfficer, -// onValueChanged = { -// selectedLoanOfficer = it -// }, -// onOptionSelected = { index, value -> -// selectedLoanOfficer = value -// selectedLoanOfficerId = reportOffices[index].row.first() -// }, -// label = stringResource(Res.string.feature_report_loan_officer), -// options = reportOffices.map { it.row[1] }, -// readOnly = true, -// ) -// Spacer(modifier = Modifier.height(16.dp)) -// } -// -// if (reportProducts.isNotEmpty()) { -// MifosTextFieldDropdown( -// value = selectedProducts, -// onValueChanged = { -// selectedProducts = it -// }, -// onOptionSelected = { index, value -> -// selectedProducts = value -// selectedProductsId = reportProducts[index].row.first() -// }, -// label = stringResource(Res.string.feature_report_product), -// options = reportProducts.map { it.row[1] }, -// readOnly = true, -// ) -// Spacer(modifier = Modifier.height(16.dp)) -// } -// -// if (fundList.isNotEmpty()) { -// MifosTextFieldDropdown( -// value = selectedFund, -// onValueChanged = { -// selectedFund = it -// }, -// onOptionSelected = { index, value -> -// selectedFund = value -// selectedFundId = fundList[index].row.first() -// }, -// label = stringResource(Res.string.feature_report_fund), -// options = fundList.map { it.row[1] }, -// readOnly = true, -// ) -// Spacer(modifier = Modifier.height(16.dp)) -// } -// -// if (currencyList.isNotEmpty()) { -// MifosTextFieldDropdown( -// value = selectedCurrency, -// onValueChanged = { -// selectedCurrency = it -// }, -// onOptionSelected = { index, value -> -// selectedCurrency = value -// selectedCurrencyId = currencyList[index].row.first() -// }, -// label = stringResource(Res.string.feature_report_currency), -// options = currencyList.map { it.row[1] }, -// readOnly = true, -// ) -// Spacer(modifier = Modifier.height(16.dp)) -// } -// -// if (parCalculatorList.isNotEmpty()) { -// MifosTextFieldDropdown( -// value = selectedParCalculator, -// onValueChanged = { -// selectedParCalculator = it -// }, -// onOptionSelected = { index, value -> -// selectedParCalculator = value -// selectedParCalculatorId = parCalculatorList[index].row.first() -// }, -// label = stringResource(Res.string.feature_report_par_type), -// options = parCalculatorList.map { it.row[1] }, -// readOnly = true, -// ) -// Spacer(modifier = Modifier.height(16.dp)) -// } -// -// if (savingsAccountDepositList.isNotEmpty()) { -// MifosTextFieldDropdown( -// value = selectedSavingsAccountDeposit, -// onValueChanged = { -// selectedSavingsAccountDeposit = it -// }, -// onOptionSelected = { index, value -> -// selectedSavingsAccountDeposit = value -// selectedSavingsAccountDepositId = savingsAccountDepositList[index].row.first() -// }, -// label = stringResource(Res.string.feature_report_saving_account), -// options = savingsAccountDepositList.map { it.row[1] }, -// readOnly = true, -// ) -// Spacer(modifier = Modifier.height(16.dp)) -// } -// -// if (glAccountList.isNotEmpty()) { -// MifosTextFieldDropdown( -// value = selectedGlAccount, -// onValueChanged = { -// selectedGlAccount = it -// }, -// onOptionSelected = { index, value -> -// selectedGlAccount = value -// selectedGlAccountId = glAccountList[index].row.first() -// }, -// label = stringResource(Res.string.feature_report_gl_account), -// options = glAccountList.map { it.row[1] }, -// readOnly = true, -// ) -// Spacer(modifier = Modifier.height(16.dp)) -// } -// -// if (obligationDateList.isNotEmpty()) { -// MifosTextFieldDropdown( -// value = selectedObligationDate, -// onValueChanged = { -// selectedObligationDate = it -// }, -// onOptionSelected = { index, value -> -// selectedObligationDate = value -// selectedObligationDateId = obligationDateList[index].row.first() -// }, -// label = stringResource(Res.string.feature_report_obligation_date), -// options = obligationDateList.map { it.row[1] }, -// readOnly = true, -// ) -// Spacer(modifier = Modifier.height(16.dp)) -// } + + if (loanPurposeList.isNotEmpty()) { + MifosTextFieldDropdown( + value = selectedLoanPurpose, + onValueChanged = { + selectedLoanPurpose = it + }, + onOptionSelected = { index, value -> + selectedLoanPurpose = value + selectedLoanPurposeId = loanPurposeList[index].row.first()!! + }, + label = stringResource(Res.string.feature_report_loan_purpose), + options = loanPurposeList.mapNotNull { it.row.getOrNull(1) }, + readOnly = true, + ) + Spacer(modifier = Modifier.height(16.dp)) + } + + if (reportOffices.isNotEmpty() && selectedLoanOfficer!=null) { + MifosTextFieldDropdown( + value = selectedLoanOfficer!!, + onValueChanged = { + selectedLoanOfficer = it + }, + onOptionSelected = { index, value -> + selectedLoanOfficer = value + selectedLoanOfficerId = reportOffices[index].row.first() + }, + label = stringResource(Res.string.feature_report_loan_officer), + options = reportOffices.mapNotNull { it.row.getOrNull(1) }, + readOnly = true, + ) + Spacer(modifier = Modifier.height(16.dp)) + } + + if (reportProducts.isNotEmpty()) { + MifosTextFieldDropdown( + value = selectedProducts, + onValueChanged = { + selectedProducts = it + }, + onOptionSelected = { index, value -> + selectedProducts = value + selectedProductsId = reportProducts[index].row.first()!! + }, + label = stringResource(Res.string.feature_report_product), + options = reportProducts.mapNotNull { it.row.getOrNull(1) }, + readOnly = true, + ) + Spacer(modifier = Modifier.height(16.dp)) + } + + if (fundList.isNotEmpty()) { + MifosTextFieldDropdown( + value = selectedFund, + onValueChanged = { + selectedFund = it + }, + onOptionSelected = { index, value -> + selectedFund = value + selectedFundId = fundList[index].row.first()!! + }, + label = stringResource(Res.string.feature_report_fund), + options = fundList.mapNotNull { it.row.getOrNull(1) }, + readOnly = true, + ) + Spacer(modifier = Modifier.height(16.dp)) + } + + if (currencyList.isNotEmpty()) { + MifosTextFieldDropdown( + value = selectedCurrency, + onValueChanged = { + selectedCurrency = it + }, + onOptionSelected = { index, value -> + selectedCurrency = value + selectedCurrencyId = currencyList[index].row.first()!! + }, + label = stringResource(Res.string.feature_report_currency), + options = currencyList.mapNotNull { it.row.getOrNull(1) }, + readOnly = true, + ) + Spacer(modifier = Modifier.height(16.dp)) + } + + if (parCalculatorList.isNotEmpty()) { + MifosTextFieldDropdown( + value = selectedParCalculator, + onValueChanged = { + selectedParCalculator = it + }, + onOptionSelected = { index, value -> + selectedParCalculator = value + selectedParCalculatorId = parCalculatorList[index].row.first()!! + }, + label = stringResource(Res.string.feature_report_par_type), + options = parCalculatorList.mapNotNull { it.row.getOrNull(1) }, + readOnly = true, + ) + Spacer(modifier = Modifier.height(16.dp)) + } + + if (savingsAccountDepositList.isNotEmpty()) { + MifosTextFieldDropdown( + value = selectedSavingsAccountDeposit, + onValueChanged = { + selectedSavingsAccountDeposit = it + }, + onOptionSelected = { index, value -> + selectedSavingsAccountDeposit = value + selectedSavingsAccountDepositId = savingsAccountDepositList[index].row.first()!! + }, + label = stringResource(Res.string.feature_report_saving_account), + options = savingsAccountDepositList.mapNotNull { it.row.getOrNull(1) }, + readOnly = true, + ) + Spacer(modifier = Modifier.height(16.dp)) + } + + if (glAccountList.isNotEmpty()) { + MifosTextFieldDropdown( + value = selectedGlAccount, + onValueChanged = { + selectedGlAccount = it + }, + onOptionSelected = { index, value -> + selectedGlAccount = value + selectedGlAccountId = glAccountList[index].row.first()!! + }, + label = stringResource(Res.string.feature_report_gl_account), + options = glAccountList.mapNotNull { it.row.getOrNull(1) }, + readOnly = true, + ) + Spacer(modifier = Modifier.height(16.dp)) + } + + if (obligationDateList.isNotEmpty()) { + MifosTextFieldDropdown( + value = selectedObligationDate, + onValueChanged = { + selectedObligationDate = it + }, + onOptionSelected = { index, value -> + selectedObligationDate = value + selectedObligationDateId = obligationDateList[index].row.first()!! + }, + label = stringResource(Res.string.feature_report_obligation_date), + options = obligationDateList.mapNotNull { it.row.getOrNull(1) }, + readOnly = true, + ) + Spacer(modifier = Modifier.height(16.dp)) + } } } -//private class ReportDetailUiStateProvider : PreviewParameterProvider { -// -// override val values: Sequence -// get() = sequenceOf( -// ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details), -// ReportDetailUiState.Loading, -// ReportDetailUiState.ParameterDetailsSuccess, -// ) -//} -// -//@Preview -//@Composable -//private fun ReportDetailScreenPreview( -// @PreviewParameter(ReportDetailUiStateProvider::class) state: ReportDetailUiState, -//) { -// ReportDetailScreen( -// reportItem = ClientReportTypeItem(), -// state = state, -// onBackPressed = {}, -// onRetry = {}, -// officeList = emptyList(), -// loanPurposeList = emptyList(), -// fundList = emptyList(), -// currencyList = emptyList(), -// parCalculatorList = emptyList(), -// savingsAccountDepositList = emptyList(), -// glAccountList = emptyList(), -// obligationDateList = emptyList(), -// reportOffices = emptyList(), -// reportProducts = emptyList(), -// runReport = {}, -// ) -//} +private class ReportDetailUiStateProvider : PreviewParameterProvider { + + override val values: Sequence + get() = sequenceOf( + ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details), + ReportDetailUiState.Loading, + ReportDetailUiState.ParameterDetailsSuccess, + ) +} + +@Preview +@Composable +private fun ReportDetailScreenPreview( + @PreviewParameter(ReportDetailUiStateProvider::class) state: ReportDetailUiState, +) { + ReportDetailScreen( + reportItem = ClientReportTypeItem(), + state = state, + onBackPressed = {}, + onRetry = {}, + officeList = emptyList(), + loanPurposeList = emptyList(), + fundList = emptyList(), + currencyList = emptyList(), + parCalculatorList = emptyList(), + savingsAccountDepositList = emptyList(), + glAccountList = emptyList(), + obligationDateList = emptyList(), + reportOffices = emptyList(), + reportProducts = emptyList(), + runReport = {}, + ) +} diff --git a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt index 2221b01bcf3..11480e1ec62 100644 --- a/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt +++ b/feature/report/src/commonMain/kotlin/com/mifos/feature/report/reportDetail/ReportDetailViewModel.kt @@ -36,7 +36,7 @@ class ReportDetailViewModel( private val getRunReportProductUseCase: GetRunReportProductUseCase, private val getRunReportWithQueryUseCase: GetRunReportWithQueryUseCase, private val getRunReportOfficesUseCase: GetRunReportOfficesUseCase, - private val savedStateHandle: SavedStateHandle, + savedStateHandle: SavedStateHandle, ) : ViewModel() { private val reportName = @@ -117,36 +117,36 @@ class ReportDetailViewModel( } } -// fun fetchProduct(parameterName: String, currencyId: String, parameterType: Boolean) = -// viewModelScope.launch{ -// getRunReportProductUseCase(parameterName, currencyId, parameterType).collect { result -> -// when (result) { -// is DataState.Error -> -// _reportDetailUiState.value = -// ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) -// -// is DataState.Loading -> Unit -// -// is DataState.Success -> { -// _reportProducts.value = result.data.data -// _reportDetailUiState.value = ReportDetailUiState.ParameterDetailsSuccess -// } -// } -// } -// } -// -// fun fetchRunReportWithQuery(reportName: String, options: MutableMap) = -// viewModelScope.launch { -// getRunReportWithQueryUseCase(reportName, options).collect { result -> -// when (result) { -// is DataState.Error -> -// _reportDetailUiState.value = -// ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) -// -// is DataState.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading -// -// is DataState.Success -> _runReport.value = result.data -// } -// } -// } + fun fetchProduct(parameterName: String, currencyId: String, parameterType: Boolean) = + viewModelScope.launch{ + getRunReportProductUseCase(parameterName, currencyId, parameterType).collect { result -> + when (result) { + is DataState.Error -> + _reportDetailUiState.value = + ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) + + is DataState.Loading -> Unit + + is DataState.Success -> { + _reportProducts.value = result.data.data + _reportDetailUiState.value = ReportDetailUiState.ParameterDetailsSuccess + } + } + } + } + + fun fetchRunReportWithQuery(reportName: String, options: MutableMap) = + viewModelScope.launch { + getRunReportWithQueryUseCase(reportName, options).collect { result -> + when (result) { + is DataState.Error -> + _reportDetailUiState.value = + ReportDetailUiState.Error(Res.string.feature_report_failed_to_load_report_details) + + is DataState.Loading -> _reportDetailUiState.value = ReportDetailUiState.Loading + + is DataState.Success -> _runReport.value = result.data + } + } + } } \ No newline at end of file