diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 6aa58f3f3c8..9cb6f973927 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -146,7 +146,7 @@ complexity: ignoreOverloaded: false CyclomaticComplexMethod: active: true - threshold: 25 + threshold: 30 ignoreSingleWhenExpression: false ignoreSimpleWhenEntries: false ignoreNestingFunctions: false @@ -168,7 +168,7 @@ complexity: threshold: 600 LongMethod: active: true - threshold: 360 #180 #60 + threshold: 400 #360 #180 #60 LongParameterList: active: true # Updating Common values based on current scenario diff --git a/feature/loan/build.gradle.kts b/feature/loan/build.gradle.kts index c7dbac3bc99..45257472f2c 100644 --- a/feature/loan/build.gradle.kts +++ b/feature/loan/build.gradle.kts @@ -1,3 +1,12 @@ +/* + * 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 + */ plugins { alias(libs.plugins.mifos.android.feature) alias(libs.plugins.mifos.android.library.compose) diff --git a/feature/loan/src/androidTest/java/com/mifos/feature/loan/ExampleInstrumentedTest.kt b/feature/loan/src/androidTest/java/com/mifos/feature/loan/ExampleInstrumentedTest.kt index 80841bc46e4..ff08d064ca0 100644 --- a/feature/loan/src/androidTest/java/com/mifos/feature/loan/ExampleInstrumentedTest.kt +++ b/feature/loan/src/androidTest/java/com/mifos/feature/loan/ExampleInstrumentedTest.kt @@ -1,13 +1,20 @@ +/* + * 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.loan -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * @@ -21,4 +28,4 @@ class ExampleInstrumentedTest { val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.mifos.feature.loan.test", appContext.packageName) } -} \ No newline at end of file +} diff --git a/feature/loan/src/main/AndroidManifest.xml b/feature/loan/src/main/AndroidManifest.xml index a5918e68abc..1dc76da0f7e 100644 --- a/feature/loan/src/main/AndroidManifest.xml +++ b/feature/loan/src/main/AndroidManifest.xml @@ -1,4 +1,13 @@ + \ No newline at end of file diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/group_loan_account/GroupLoanAccountScreen.kt b/feature/loan/src/main/java/com/mifos/feature/loan/groupLoanAccount/GroupLoanAccountScreen.kt similarity index 92% rename from feature/loan/src/main/java/com/mifos/feature/loan/group_loan_account/GroupLoanAccountScreen.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/groupLoanAccount/GroupLoanAccountScreen.kt index 3b9218e5f69..128e676fe0d 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/group_loan_account/GroupLoanAccountScreen.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/groupLoanAccount/GroupLoanAccountScreen.kt @@ -1,6 +1,15 @@ +/* + * 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 + */ @file:OptIn(ExperimentalMaterial3Api::class) -package com.mifos.feature.loan.group_loan_account +package com.mifos.feature.loan.groupLoanAccount import android.widget.Toast import androidx.compose.foundation.isSystemInDarkTheme @@ -66,10 +75,10 @@ import java.text.SimpleDateFormat import java.util.Locale @Composable -fun GroupLoanAccountScreen( - onBackPressed: () -> Unit +internal fun GroupLoanAccountScreen( + onBackPressed: () -> Unit, + viewModel: GroupLoanAccountViewModel = hiltViewModel(), ) { - val viewModel: GroupLoanAccountViewModel = hiltViewModel() val state by viewModel.groupLoanAccountUiState.collectAsStateWithLifecycle() val loanProducts by viewModel.loanProducts.collectAsStateWithLifecycle() val groupId by viewModel.groupId.collectAsStateWithLifecycle() @@ -97,32 +106,31 @@ fun GroupLoanAccountScreen( }, createLoanAccount = { loansPayload -> viewModel.createGroupLoanAccount(loansPayload) - } + }, ) } @Composable -fun GroupLoanAccountScreen( +internal fun GroupLoanAccountScreen( groupId: Int, state: GroupLoanAccountUiState, loanProducts: List, onBackPressed: () -> Unit, onRetry: () -> Unit, onLoanProductSelected: (Int) -> Unit, - createLoanAccount: (GroupLoanPayload) -> Unit + createLoanAccount: (GroupLoanPayload) -> Unit, ) { - val snackbarHostState = remember { SnackbarHostState() } MifosScaffold( icon = MifosIcons.arrowBack, title = stringResource(id = R.string.feature_loan_application), onBackPressed = onBackPressed, - snackbarHostState = snackbarHostState + snackbarHostState = snackbarHostState, ) { paddingValues -> Column( modifier = Modifier - .padding(paddingValues) + .padding(paddingValues), ) { when (state) { is GroupLoanAccountUiState.GroupLoanAccountTemplate -> { @@ -142,7 +150,7 @@ fun GroupLoanAccountScreen( is GroupLoanAccountUiState.Loading -> { Column( modifier = Modifier.fillMaxSize(), - verticalArrangement = Arrangement.Center + verticalArrangement = Arrangement.Center, ) { MifosCircularProgress() } @@ -152,7 +160,7 @@ fun GroupLoanAccountScreen( Toast.makeText( LocalContext.current, stringResource(id = R.string.feature_loan_account_created_successfully), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() onBackPressed() } @@ -162,12 +170,12 @@ fun GroupLoanAccountScreen( } @Composable -fun GroupLoanAccountContent( +private fun GroupLoanAccountContent( groupId: Int, productLoans: List, loanTemplate: GroupLoanTemplate, onLoanProductSelected: (Int) -> Unit, - createLoanAccount: (GroupLoanPayload) -> Unit + createLoanAccount: (GroupLoanPayload) -> Unit, ) { var selectedLoanProduct by rememberSaveable { mutableStateOf("") } var selectedLoanProductId by rememberSaveable { mutableIntStateOf(0) } @@ -186,7 +194,7 @@ fun GroupLoanAccountContent( override fun isSelectableDate(utcTimeMillis: Long): Boolean { return utcTimeMillis >= System.currentTimeMillis() } - } + }, ) var showDisbursementDatePicker by rememberSaveable { mutableStateOf(false) } @@ -197,7 +205,7 @@ fun GroupLoanAccountContent( override fun isSelectableDate(utcTimeMillis: Long): Boolean { return utcTimeMillis >= System.currentTimeMillis() } - } + }, ) var externalId by rememberSaveable { mutableStateOf("") } @@ -233,18 +241,17 @@ fun GroupLoanAccountContent( submissionDatePickerState.selectedDateMillis?.let { submissionDate = it } - } + }, ) { Text(stringResource(id = R.string.feature_loan_select)) } }, dismissButton = { TextButton( onClick = { showSubmissionDatePicker = false - } + }, ) { Text(stringResource(id = R.string.feature_loan_cancel)) } - } - ) - { + }, + ) { DatePicker(state = submissionDatePickerState) } } @@ -261,24 +268,22 @@ fun GroupLoanAccountContent( disbursementDatePickerState.selectedDateMillis?.let { disbursementDate = it } - } + }, ) { Text(stringResource(id = R.string.feature_loan_select)) } }, dismissButton = { TextButton( onClick = { showSubmissionDatePicker = false - } + }, ) { Text(stringResource(id = R.string.feature_loan_cancel)) } - } - ) - { + }, + ) { DatePicker(state = disbursementDatePickerState) } } Column(modifier = Modifier.verticalScroll(rememberScrollState())) { - MifosTextFieldDropdown( value = selectedLoanProduct, onValueChanged = { selectedLoanProduct = it }, @@ -291,7 +296,7 @@ fun GroupLoanAccountContent( }, label = R.string.feature_loan_product, options = productLoans.map { it.name.toString() }, - readOnly = true + readOnly = true, ) loanTemplate.loanPurposeOptions?.let { loanPurposeOptions -> @@ -306,7 +311,7 @@ fun GroupLoanAccountContent( }, label = R.string.feature_loan_purpose, options = loanPurposeOptions.map { it.name.toString() }, - readOnly = true + readOnly = true, ) } @@ -322,7 +327,7 @@ fun GroupLoanAccountContent( }, label = R.string.feature_loan_officer, options = loanOfficerOptions.map { it.displayName.toString() }, - readOnly = true + readOnly = true, ) } @@ -338,28 +343,28 @@ fun GroupLoanAccountContent( }, label = R.string.feature_loan_fund, options = fundOptions.map { it.name.toString() }, - readOnly = true + readOnly = true, ) } MifosDatePickerTextField( value = SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()).format( - submissionDate + submissionDate, ), label = R.string.feature_loan_submission_date, openDatePicker = { showSubmissionDatePicker = true - } + }, ) MifosDatePickerTextField( value = SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()).format( - disbursementDate + disbursementDate, ), label = R.string.feature_loan_disbursed_date, openDatePicker = { showDisbursementDatePicker = true - } + }, ) MifosOutlinedTextField( @@ -369,7 +374,7 @@ fun GroupLoanAccountContent( externalId = it }, error = null, - keyboardType = KeyboardType.Text + keyboardType = KeyboardType.Text, ) MifosOutlinedTextField( @@ -379,7 +384,7 @@ fun GroupLoanAccountContent( principalAmount = it }, error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) MifosOutlinedTextField( @@ -389,7 +394,7 @@ fun GroupLoanAccountContent( numberOfRepayment = it }, error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) Row(verticalAlignment = Alignment.CenterVertically) { @@ -403,11 +408,11 @@ fun GroupLoanAccountContent( nominal = it }, error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) Text( modifier = Modifier.padding(16.dp), - text = stringResource(id = R.string.feature_loan_per_month) + text = stringResource(id = R.string.feature_loan_per_month), ) } @@ -422,7 +427,7 @@ fun GroupLoanAccountContent( repaidEvery = it }, error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) loanTemplate.repaymentFrequencyDaysOfWeekTypeOptions?.let { repaymentFrequencyDaysOfWeekTypeOptions -> @@ -440,7 +445,7 @@ fun GroupLoanAccountContent( }, label = R.string.feature_loan_term, options = repaymentFrequencyDaysOfWeekTypeOptions.map { it.value.toString() }, - readOnly = true + readOnly = true, ) } } @@ -455,7 +460,7 @@ fun GroupLoanAccountContent( loanTerms = it }, error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) loanTemplate.termFrequencyTypeOptions?.let { termFrequencyTypeOptions -> @@ -473,7 +478,7 @@ fun GroupLoanAccountContent( }, label = R.string.feature_loan_term, options = termFrequencyTypeOptions.map { it.value.toString() }, - readOnly = true + readOnly = true, ) } } @@ -490,7 +495,7 @@ fun GroupLoanAccountContent( }, label = R.string.feature_loan_amortization, options = amortizationTypeOptions.map { it.value.toString() }, - readOnly = true + readOnly = true, ) } @@ -506,7 +511,7 @@ fun GroupLoanAccountContent( }, label = R.string.feature_loan_interest_calculation_period, options = interestCalculationPeriodTypeOptions.map { it.value.toString() }, - readOnly = true + readOnly = true, ) } @@ -522,7 +527,7 @@ fun GroupLoanAccountContent( }, label = R.string.feature_loan_repayment_strategy, options = transactionProcessingStrategyOptions.map { it.name.toString() }, - readOnly = true + readOnly = true, ) } @@ -531,7 +536,8 @@ fun GroupLoanAccountContent( checked = selectedCalculateExactDaysIn, onCheckedChange = { selectedCalculateExactDaysIn = selectedCalculateExactDaysIn.not() - }) + }, + ) Text(text = stringResource(id = R.string.feature_loan_calculate_interest_for_exact_days_in)) } @@ -547,11 +553,10 @@ fun GroupLoanAccountContent( }, label = R.string.feature_loan_interest_type_method, options = interestTypeOptions.map { it.value.toString() }, - readOnly = true + readOnly = true, ) } - Spacer(modifier = Modifier.height(16.dp)) Button( @@ -563,7 +568,7 @@ fun GroupLoanAccountContent( dateFormat = "dd MMMM yyyy" expectedDisbursementDate = SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()).format( - disbursementDate + disbursementDate, ) interestCalculationPeriodType = selectedInterestCalculationPeriodId loanType = "individual" @@ -585,7 +590,6 @@ fun GroupLoanAccountContent( interestRatePerPeriod = nominal.toDouble() } createLoanAccount(loadPayload) - }, modifier = Modifier .fillMaxWidth() @@ -593,8 +597,8 @@ fun GroupLoanAccountContent( .padding(start = 16.dp, end = 16.dp), contentPadding = PaddingValues(), colors = ButtonDefaults.buttonColors( - containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary - ) + containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary, + ), ) { Text(text = stringResource(id = R.string.feature_loan_submit), fontSize = 16.sp) } @@ -603,21 +607,20 @@ fun GroupLoanAccountContent( } } -class GroupLoanAccountUiStateProvider : PreviewParameterProvider { +private class GroupLoanAccountUiStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( GroupLoanAccountUiState.Error(R.string.feature_loan_failed_to_create_loan_account), GroupLoanAccountUiState.Loading, - GroupLoanAccountUiState.GroupLoanAccountCreatedSuccessfully + GroupLoanAccountUiState.GroupLoanAccountCreatedSuccessfully, ) - } @Preview(showBackground = true) @Composable private fun GroupLoanAccountScreenPreview( - @PreviewParameter(GroupLoanAccountUiStateProvider::class) state: GroupLoanAccountUiState + @PreviewParameter(GroupLoanAccountUiStateProvider::class) state: GroupLoanAccountUiState, ) { GroupLoanAccountScreen( groupId = 0, @@ -626,10 +629,6 @@ private fun GroupLoanAccountScreenPreview( onBackPressed = {}, onRetry = {}, onLoanProductSelected = {}, - createLoanAccount = {} + createLoanAccount = {}, ) } - -val sampleLoanProducts = List(10) { - LoanProducts(name = "mifos $it") -} \ No newline at end of file diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/group_loan_account/LoanAccountUiState.kt b/feature/loan/src/main/java/com/mifos/feature/loan/groupLoanAccount/GroupLoanAccountUiState.kt similarity index 56% rename from feature/loan/src/main/java/com/mifos/feature/loan/group_loan_account/LoanAccountUiState.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/groupLoanAccount/GroupLoanAccountUiState.kt index 2d8ed2ca197..24380ed5ad1 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/group_loan_account/LoanAccountUiState.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/groupLoanAccount/GroupLoanAccountUiState.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.group_loan_account +/* + * 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.loan.groupLoanAccount import com.mifos.core.objects.templates.loans.GroupLoanTemplate @@ -15,4 +24,4 @@ sealed class GroupLoanAccountUiState { data class GroupLoanAccountTemplate(val groupLoanTemplate: GroupLoanTemplate) : GroupLoanAccountUiState() -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/group_loan_account/GroupLoanAccountViewModel.kt b/feature/loan/src/main/java/com/mifos/feature/loan/groupLoanAccount/GroupLoanAccountViewModel.kt similarity index 60% rename from feature/loan/src/main/java/com/mifos/feature/loan/group_loan_account/GroupLoanAccountViewModel.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/groupLoanAccount/GroupLoanAccountViewModel.kt index c24c0316a68..f42b8bdcc00 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/group_loan_account/GroupLoanAccountViewModel.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/groupLoanAccount/GroupLoanAccountViewModel.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.group_loan_account +/* + * 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.loan.groupLoanAccount import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel @@ -24,7 +33,7 @@ class GroupLoanAccountViewModel @Inject constructor( private val getAllLoanUseCase: GetAllLoanUseCase, private val getGroupLoansAccountTemplateUseCase: GetGroupLoansAccountTemplateUseCase, private val createGroupLoansAccountUseCase: CreateGroupLoansAccountUseCase, - savedStateHandle: SavedStateHandle + savedStateHandle: SavedStateHandle, ) : ViewModel() { val groupId = savedStateHandle.getStateFlow(key = Constants.GROUP_ID, initialValue = 0) @@ -39,11 +48,13 @@ class GroupLoanAccountViewModel @Inject constructor( fun loadAllLoans() = viewModelScope.launch(Dispatchers.IO) { getAllLoanUseCase().collect { result -> when (result) { - is Resource.Error -> _groupLoanAccountUiState.value = - GroupLoanAccountUiState.Error(R.string.feature_loan_failed_to_load_loan) + is Resource.Error -> + _groupLoanAccountUiState.value = + GroupLoanAccountUiState.Error(R.string.feature_loan_failed_to_load_loan) - is Resource.Loading -> _groupLoanAccountUiState.value = - GroupLoanAccountUiState.Loading + is Resource.Loading -> + _groupLoanAccountUiState.value = + GroupLoanAccountUiState.Loading is Resource.Success -> _loanProducts.value = result.data ?: emptyList() } @@ -54,17 +65,18 @@ class GroupLoanAccountViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { getGroupLoansAccountTemplateUseCase(groupId, productId).collect { result -> when (result) { - is Resource.Error -> _groupLoanAccountUiState.value = - GroupLoanAccountUiState.Error(R.string.feature_loan_failed_to_load_template) + is Resource.Error -> + _groupLoanAccountUiState.value = + GroupLoanAccountUiState.Error(R.string.feature_loan_failed_to_load_template) is Resource.Loading -> Unit - is Resource.Success -> _groupLoanAccountUiState.value = - GroupLoanAccountUiState.GroupLoanAccountTemplate( - result.data ?: GroupLoanTemplate() - ) + is Resource.Success -> + _groupLoanAccountUiState.value = + GroupLoanAccountUiState.GroupLoanAccountTemplate( + result.data ?: GroupLoanTemplate(), + ) } - } } @@ -72,15 +84,18 @@ class GroupLoanAccountViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { createGroupLoansAccountUseCase(loansPayload).collect { result -> when (result) { - is Resource.Error -> _groupLoanAccountUiState.value = - GroupLoanAccountUiState.Error(R.string.feature_loan_failed_to_create_loan_account) + is Resource.Error -> + _groupLoanAccountUiState.value = + GroupLoanAccountUiState.Error(R.string.feature_loan_failed_to_create_loan_account) - is Resource.Loading -> _groupLoanAccountUiState.value = - GroupLoanAccountUiState.Loading + is Resource.Loading -> + _groupLoanAccountUiState.value = + GroupLoanAccountUiState.Loading - is Resource.Success -> _groupLoanAccountUiState.value = - GroupLoanAccountUiState.GroupLoanAccountCreatedSuccessfully + is Resource.Success -> + _groupLoanAccountUiState.value = + GroupLoanAccountUiState.GroupLoanAccountCreatedSuccessfully } } } -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_account/LoanAccountScreen.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanAccount/LoanAccountScreen.kt similarity index 91% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_account/LoanAccountScreen.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanAccount/LoanAccountScreen.kt index dfd0045c500..6884f14c0e7 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_account/LoanAccountScreen.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanAccount/LoanAccountScreen.kt @@ -1,6 +1,15 @@ +/* + * 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 + */ @file:OptIn(ExperimentalMaterial3Api::class) -package com.mifos.feature.loan.loan_account +package com.mifos.feature.loan.loanAccount import android.widget.Toast import androidx.compose.foundation.isSystemInDarkTheme @@ -69,9 +78,9 @@ import java.util.Locale @Composable fun LoanAccountScreen( onBackPressed: () -> Unit, - dataTable: (List, LoansPayload) -> Unit + dataTable: (List, LoansPayload) -> Unit, + viewModel: LoanAccountViewModel = hiltViewModel(), ) { - val viewModel: LoanAccountViewModel = hiltViewModel() val state by viewModel.loanAccountUiState.collectAsStateWithLifecycle() val loanAccountTemplateState by viewModel.loanAccountTemplateUiState.collectAsStateWithLifecycle() val clientId by viewModel.clientId.collectAsStateWithLifecycle() @@ -97,7 +106,7 @@ fun LoanAccountScreen( dataTable = dataTable, fetchTemplate = { productId -> viewModel.loadLoanAccountTemplate(clientId, productId) - } + }, ) } @@ -111,7 +120,8 @@ fun LoanAccountScreen( onLoanProductSelected: (Int) -> Unit, createLoanAccount: (LoansPayload) -> Unit, dataTable: (List, LoansPayload) -> Unit, - fetchTemplate: (Int) -> Unit + fetchTemplate: (Int) -> Unit, + modifier: Modifier = Modifier, ) { val snackbarHostState = remember { SnackbarHostState() } @@ -119,11 +129,12 @@ fun LoanAccountScreen( icon = MifosIcons.arrowBack, title = stringResource(id = R.string.feature_loan_application), onBackPressed = onBackPressed, - snackbarHostState = snackbarHostState + snackbarHostState = snackbarHostState, + modifier = modifier, ) { paddingValues -> Column( modifier = Modifier - .padding(paddingValues) + .padding(paddingValues), ) { when (state) { is LoanAccountUiState.AllLoan -> { @@ -133,7 +144,7 @@ fun LoanAccountScreen( loanTemplate = loanAccountTemplateState, onLoanProductSelected = onLoanProductSelected, createLoanAccount = createLoanAccount, - dataTable = dataTable + dataTable = dataTable, ) state.productLoans[0].id?.let { fetchTemplate(it) } } @@ -145,7 +156,7 @@ fun LoanAccountScreen( is LoanAccountUiState.Loading -> { Column( modifier = Modifier.fillMaxSize(), - verticalArrangement = Arrangement.Center + verticalArrangement = Arrangement.Center, ) { MifosCircularProgress() } @@ -155,7 +166,7 @@ fun LoanAccountScreen( Toast.makeText( LocalContext.current, stringResource(id = R.string.feature_loan_account_created_successfully), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() onBackPressed() } @@ -165,15 +176,14 @@ fun LoanAccountScreen( } @Composable -fun LoanAccountContent( +private fun LoanAccountContent( clientsId: Int, productLoans: List, loanTemplate: LoanTemplate, onLoanProductSelected: (Int) -> Unit, createLoanAccount: (LoansPayload) -> Unit, - dataTable: (List, LoansPayload) -> Unit + dataTable: (List, LoansPayload) -> Unit, ) { - var selectedLoanProduct by rememberSaveable { mutableStateOf("") } var selectedLoanProductId by rememberSaveable { mutableIntStateOf(0) } var selectedLoanPurpose by rememberSaveable { mutableStateOf("") } @@ -191,7 +201,7 @@ fun LoanAccountContent( override fun isSelectableDate(utcTimeMillis: Long): Boolean { return utcTimeMillis >= System.currentTimeMillis() } - } + }, ) var showDisbursementDatePicker by rememberSaveable { mutableStateOf(false) } @@ -202,7 +212,7 @@ fun LoanAccountContent( override fun isSelectableDate(utcTimeMillis: Long): Boolean { return utcTimeMillis >= System.currentTimeMillis() } - } + }, ) var externalId by rememberSaveable { mutableStateOf("") } @@ -240,27 +250,24 @@ fun LoanAccountContent( submissionDatePickerState.selectedDateMillis?.let { submissionDate = it } - } + }, ) { Text(stringResource(id = R.string.feature_loan_select)) } }, dismissButton = { TextButton( onClick = { showSubmissionDatePicker = false - } + }, ) { Text(stringResource(id = R.string.feature_loan_cancel)) } - } - ) - { + }, + ) { DatePicker(state = submissionDatePickerState) } } if (showDisbursementDatePicker) { DatePickerDialog( - onDismissRequest = { - showDisbursementDatePicker = false - }, + onDismissRequest = { showDisbursementDatePicker = false }, confirmButton = { TextButton( onClick = { @@ -268,24 +275,22 @@ fun LoanAccountContent( disbursementDatePickerState.selectedDateMillis?.let { disbursementDate = it } - } + }, ) { Text(stringResource(id = R.string.feature_loan_select)) } }, dismissButton = { TextButton( onClick = { showSubmissionDatePicker = false - } + }, ) { Text(stringResource(id = R.string.feature_loan_cancel)) } - } - ) - { + }, + ) { DatePicker(state = disbursementDatePickerState) } } Column(modifier = Modifier.verticalScroll(rememberScrollState())) { - MifosTextFieldDropdown( value = selectedLoanProduct, onValueChanged = { selectedLoanProduct = it }, @@ -298,7 +303,7 @@ fun LoanAccountContent( }, label = R.string.feature_loan_product, options = productLoans.map { it.name.toString() }, - readOnly = true + readOnly = true, ) MifosTextFieldDropdown( @@ -306,13 +311,11 @@ fun LoanAccountContent( onValueChanged = { selectedLoanPurpose = it }, onOptionSelected = { index, value -> selectedLoanPurpose = value - loanTemplate.loanPurposeOptions[index].id?.let { - selectedLoanPurposeId = it - } + loanTemplate.loanPurposeOptions[index].id?.let { selectedLoanPurposeId = it } }, label = R.string.feature_loan_purpose, options = loanTemplate.loanPurposeOptions.map { it.name.toString() }, - readOnly = true + readOnly = true, ) MifosTextFieldDropdown( @@ -326,7 +329,7 @@ fun LoanAccountContent( }, label = R.string.feature_loan_officer, options = loanTemplate.loanOfficerOptions.map { it.displayName.toString() }, - readOnly = true + readOnly = true, ) MifosTextFieldDropdown( @@ -340,27 +343,27 @@ fun LoanAccountContent( }, label = R.string.feature_loan_fund, options = loanTemplate.fundOptions.map { it.name.toString() }, - readOnly = true + readOnly = true, ) MifosDatePickerTextField( value = SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()).format( - submissionDate + submissionDate, ), label = R.string.feature_loan_submission_date, openDatePicker = { showSubmissionDatePicker = true - } + }, ) MifosDatePickerTextField( value = SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()).format( - disbursementDate + disbursementDate, ), label = R.string.feature_loan_disbursed_date, openDatePicker = { showDisbursementDatePicker = true - } + }, ) MifosOutlinedTextField( @@ -370,7 +373,7 @@ fun LoanAccountContent( externalId = it }, error = null, - keyboardType = KeyboardType.Text + keyboardType = KeyboardType.Text, ) MifosTextFieldDropdown( @@ -384,7 +387,7 @@ fun LoanAccountContent( }, label = R.string.feature_loan_link_savings, options = loanTemplate.accountLinkingOptions.map { it.productName.toString() }, - readOnly = true + readOnly = true, ) MifosOutlinedTextField( @@ -394,7 +397,7 @@ fun LoanAccountContent( principalAmount = it }, error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) MifosOutlinedTextField( @@ -404,7 +407,7 @@ fun LoanAccountContent( numberOfRepayment = it }, error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) Row(verticalAlignment = Alignment.CenterVertically) { @@ -418,11 +421,11 @@ fun LoanAccountContent( nominal = it }, error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) Text( modifier = Modifier.padding(16.dp), - text = stringResource(id = R.string.feature_loan_per_month) + text = stringResource(id = R.string.feature_loan_per_month), ) } @@ -437,7 +440,7 @@ fun LoanAccountContent( repaidEvery = it }, error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) MifosTextFieldDropdown( modifier = Modifier @@ -453,7 +456,7 @@ fun LoanAccountContent( }, label = R.string.feature_loan_term, options = loanTemplate.repaymentFrequencyDaysOfWeekTypeOptions.map { it.value.toString() }, - readOnly = true + readOnly = true, ) } Row(verticalAlignment = Alignment.CenterVertically) { @@ -467,7 +470,7 @@ fun LoanAccountContent( loanTerms = it }, error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) MifosTextFieldDropdown( modifier = Modifier @@ -483,7 +486,7 @@ fun LoanAccountContent( }, label = R.string.feature_loan_term, options = loanTemplate.termFrequencyTypeOptions.map { it.value.toString() }, - readOnly = true + readOnly = true, ) } @@ -498,7 +501,7 @@ fun LoanAccountContent( }, label = R.string.feature_loan_amortization, options = loanTemplate.amortizationTypeOptions.map { it.value.toString() }, - readOnly = true + readOnly = true, ) MifosTextFieldDropdown( @@ -512,7 +515,7 @@ fun LoanAccountContent( }, label = R.string.feature_loan_interest_calculation_period, options = loanTemplate.interestCalculationPeriodTypeOptions.map { it.value.toString() }, - readOnly = true + readOnly = true, ) MifosTextFieldDropdown( @@ -526,7 +529,7 @@ fun LoanAccountContent( }, label = R.string.feature_loan_repayment_strategy, options = loanTemplate.transactionProcessingStrategyOptions.map { it.name.toString() }, - readOnly = true + readOnly = true, ) Row(verticalAlignment = Alignment.CenterVertically) { @@ -534,7 +537,8 @@ fun LoanAccountContent( checked = selectedCalculateExactDaysIn, onCheckedChange = { selectedCalculateExactDaysIn = selectedCalculateExactDaysIn.not() - }) + }, + ) Text(text = stringResource(id = R.string.feature_loan_calculate_interest_for_exact_days_in)) } @@ -549,7 +553,7 @@ fun LoanAccountContent( }, label = R.string.feature_loan_interest_type_method, options = loanTemplate.interestTypeOptions.map { it.value.toString() }, - readOnly = true + readOnly = true, ) Spacer(modifier = Modifier.height(16.dp)) @@ -563,7 +567,7 @@ fun LoanAccountContent( dateFormat = "dd MMMM yyyy" expectedDisbursementDate = SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()).format( - disbursementDate + disbursementDate, ) interestCalculationPeriodType = selectedInterestCalculationPeriodId loanType = "individual" @@ -599,8 +603,8 @@ fun LoanAccountContent( .padding(start = 16.dp, end = 16.dp), contentPadding = PaddingValues(), colors = ButtonDefaults.buttonColors( - containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary - ) + containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary, + ), ) { Text(text = stringResource(id = R.string.feature_loan_submit), fontSize = 16.sp) } @@ -609,22 +613,21 @@ fun LoanAccountContent( } } -class LoanAccountUiStateProvider : PreviewParameterProvider { +private class LoanAccountUiStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( LoanAccountUiState.AllLoan(sampleLoanList), LoanAccountUiState.Error(R.string.feature_loan_application), LoanAccountUiState.Loading, - LoanAccountUiState.LoanAccountCreatedSuccessfully + LoanAccountUiState.LoanAccountCreatedSuccessfully, ) - } @Preview(showBackground = true) @Composable private fun LoanAccountScreenPreview( - @PreviewParameter(LoanAccountUiStateProvider::class) state: LoanAccountUiState + @PreviewParameter(LoanAccountUiStateProvider::class) state: LoanAccountUiState, ) { LoanAccountScreen( clientId = 1, @@ -635,10 +638,10 @@ private fun LoanAccountScreenPreview( onLoanProductSelected = {}, createLoanAccount = {}, dataTable = { _, _ -> }, - fetchTemplate = {} + fetchTemplate = {}, ) } val sampleLoanList = List(10) { LoanProducts(name = "Loan $it", id = it) -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_account/LoanAccountUiState.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanAccount/LoanAccountUiState.kt similarity index 52% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_account/LoanAccountUiState.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanAccount/LoanAccountUiState.kt index 6437dc42206..a17ca96a075 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_account/LoanAccountUiState.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanAccount/LoanAccountUiState.kt @@ -1,8 +1,15 @@ -package com.mifos.feature.loan.loan_account +/* + * 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.loan.loanAccount -import com.mifos.core.objects.accounts.loan.Loans import com.mifos.core.objects.organisation.LoanProducts -import com.mifos.core.objects.templates.loans.LoanTemplate /** * Created by Aditya Gupta on 08/08/23. @@ -16,4 +23,4 @@ sealed class LoanAccountUiState { data class Error(val message: Int) : LoanAccountUiState() data object LoanAccountCreatedSuccessfully : LoanAccountUiState() -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_account/LoanAccountViewModel.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanAccount/LoanAccountViewModel.kt similarity index 63% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_account/LoanAccountViewModel.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanAccount/LoanAccountViewModel.kt index f272444ed01..54d83da81af 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_account/LoanAccountViewModel.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanAccount/LoanAccountViewModel.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_account +/* + * 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.loan.loanAccount import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel @@ -23,7 +32,7 @@ class LoanAccountViewModel @Inject constructor( private val getAllLoanUseCase: GetAllLoanUseCase, private val getLoansAccountTemplateUseCase: GetLoansAccountTemplateUseCase, private val createLoanAccountUseCase: CreateLoanAccountUseCase, - savedStateHandle: SavedStateHandle + savedStateHandle: SavedStateHandle, ) : ViewModel() { val clientId = savedStateHandle.getStateFlow(key = Constants.CLIENT_ID, initialValue = 0) @@ -38,13 +47,15 @@ class LoanAccountViewModel @Inject constructor( fun loadAllLoans() = viewModelScope.launch(Dispatchers.IO) { getAllLoanUseCase().collect { result -> when (result) { - is Resource.Error -> _loanAccountUiState.value = - LoanAccountUiState.Error(R.string.feature_loan_failed_to_load_loan) + is Resource.Error -> + _loanAccountUiState.value = + LoanAccountUiState.Error(R.string.feature_loan_failed_to_load_loan) is Resource.Loading -> _loanAccountUiState.value = LoanAccountUiState.Loading - is Resource.Success -> _loanAccountUiState.value = - LoanAccountUiState.AllLoan(result.data ?: emptyList()) + is Resource.Success -> + _loanAccountUiState.value = + LoanAccountUiState.AllLoan(result.data ?: emptyList()) } } } @@ -53,13 +64,15 @@ class LoanAccountViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { getLoansAccountTemplateUseCase(clientId, productId).collect { result -> when (result) { - is Resource.Error -> _loanAccountUiState.value = - LoanAccountUiState.Error(R.string.feature_loan_failed_to_load_template) + is Resource.Error -> + _loanAccountUiState.value = + LoanAccountUiState.Error(R.string.feature_loan_failed_to_load_template) is Resource.Loading -> Unit - is Resource.Success -> _loanAccountTemplateUiState.value = - result.data ?: LoanTemplate() + is Resource.Success -> + _loanAccountTemplateUiState.value = + result.data ?: LoanTemplate() } } } @@ -67,14 +80,16 @@ class LoanAccountViewModel @Inject constructor( fun createLoansAccount(loansPayload: LoansPayload) = viewModelScope.launch(Dispatchers.IO) { createLoanAccountUseCase(loansPayload).collect { result -> when (result) { - is Resource.Error -> _loanAccountUiState.value = - LoanAccountUiState.Error(R.string.feature_loan_failed_to_create_loan_account) + is Resource.Error -> + _loanAccountUiState.value = + LoanAccountUiState.Error(R.string.feature_loan_failed_to_create_loan_account) is Resource.Loading -> _loanAccountUiState.value = LoanAccountUiState.Loading - is Resource.Success -> _loanAccountUiState.value = - LoanAccountUiState.LoanAccountCreatedSuccessfully + is Resource.Success -> + _loanAccountUiState.value = + LoanAccountUiState.LoanAccountCreatedSuccessfully } } } -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_account_summary/LoanAccountSummaryScreen.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanAccountSummary/LoanAccountSummaryScreen.kt similarity index 75% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_account_summary/LoanAccountSummaryScreen.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanAccountSummary/LoanAccountSummaryScreen.kt index 2fd8551ea51..fcc44817dc1 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_account_summary/LoanAccountSummaryScreen.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanAccountSummary/LoanAccountSummaryScreen.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_account_summary +/* + * 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.loan.loanAccountSummary import android.content.Context import android.util.Log @@ -67,18 +76,18 @@ import com.mifos.feature.loan.R * Created by Pronay Sarker on 01/07/2024 (5:50 AM) */ @Composable -fun LoanAccountSummaryScreen( +internal fun LoanAccountSummaryScreen( navigateBack: () -> Unit, - onMoreInfoClicked: (String, loanId : Int) -> Unit, + onMoreInfoClicked: (String, loanId: Int) -> Unit, onTransactionsClicked: (loadId: Int) -> Unit, onRepaymentScheduleClicked: (loanId: Int) -> Unit, - onDocumentsClicked: (loanId : Int) -> Unit, - onChargesClicked: (loanId : Int) -> Unit, - approveLoan: (loadId : Int, loanWithAssociations: LoanWithAssociations) -> Unit, - disburseLoan: (loanId : Int) -> Unit, - onRepaymentClick: (loanWithAssociations: LoanWithAssociations) -> Unit + onDocumentsClicked: (loanId: Int) -> Unit, + onChargesClicked: (loanId: Int) -> Unit, + approveLoan: (loadId: Int, loanWithAssociations: LoanWithAssociations) -> Unit, + disburseLoan: (loanId: Int) -> Unit, + onRepaymentClick: (loanWithAssociations: LoanWithAssociations) -> Unit, + viewModel: LoanAccountSummaryViewModel = hiltViewModel(), ) { - val viewModel: LoanAccountSummaryViewModel = hiltViewModel() val uiState by viewModel.loanAccountSummaryUiState.collectAsStateWithLifecycle() val loanAccountNumber by viewModel.loanAccountNumber.collectAsStateWithLifecycle() @@ -90,19 +99,19 @@ fun LoanAccountSummaryScreen( uiState = uiState, navigateBack = navigateBack, onRetry = { viewModel.loadLoanById(loanAccountNumber) }, - onMoreInfoClicked = { onMoreInfoClicked.invoke( Constants.DATA_TABLE_NAME_LOANS, loanAccountNumber) }, + onMoreInfoClicked = { onMoreInfoClicked.invoke(Constants.DATA_TABLE_NAME_LOANS, loanAccountNumber) }, onTransactionsClicked = { onTransactionsClicked.invoke(loanAccountNumber) }, onRepaymentScheduleClicked = { onRepaymentScheduleClicked.invoke(loanAccountNumber) }, onDocumentsClicked = { onDocumentsClicked(loanAccountNumber) }, onChargesClicked = { onChargesClicked(loanAccountNumber) }, - approveLoan = { approveLoan(loanAccountNumber, it )}, + approveLoan = { approveLoan(loanAccountNumber, it) }, disburseLoan = { disburseLoan(loanAccountNumber) }, - makeRepayment = onRepaymentClick + makeRepayment = onRepaymentClick, ) } @Composable -fun LoanAccountSummaryScreen( +internal fun LoanAccountSummaryScreen( uiState: LoanAccountSummaryUiState, navigateBack: () -> Unit, onRetry: () -> Unit, @@ -113,7 +122,7 @@ fun LoanAccountSummaryScreen( onChargesClicked: () -> Unit, approveLoan: (loanWithAssociations: LoanWithAssociations) -> Unit, disburseLoan: () -> Unit, - makeRepayment: (loanWithAssociations: LoanWithAssociations) -> Unit + makeRepayment: (loanWithAssociations: LoanWithAssociations) -> Unit, ) { val snackbarHostState = remember { androidx.compose.material3.SnackbarHostState() @@ -122,68 +131,72 @@ fun LoanAccountSummaryScreen( mutableStateOf(false) } - MifosScaffold(icon = MifosIcons.arrowBack, + MifosScaffold( + icon = MifosIcons.arrowBack, title = stringResource(id = R.string.feature_loan_loan_account_summary), onBackPressed = navigateBack, snackbarHostState = snackbarHostState, actions = { IconButton(onClick = { openDropdown = !openDropdown }) { Icon( - imageVector = MifosIcons.moreVert, contentDescription = null + imageVector = MifosIcons.moreVert, + contentDescription = null, ) } if (openDropdown) { DropdownMenu( expanded = openDropdown, - onDismissRequest = { openDropdown = false } + onDismissRequest = { openDropdown = false }, ) { MifosMenuDropDownItem( option = Constants.DATA_TABLE_LOAN_NAME, onClick = { openDropdown = false onMoreInfoClicked.invoke() - } + }, ) MifosMenuDropDownItem( option = stringResource(id = R.string.feature_loan_transactions), onClick = { openDropdown = false onTransactionsClicked.invoke() - } + }, ) MifosMenuDropDownItem( option = stringResource(id = R.string.feature_loan_repayment_schedule), onClick = { openDropdown = false onRepaymentScheduleClicked.invoke() - } + }, ) MifosMenuDropDownItem( option = stringResource(id = R.string.feature_loan_documents), onClick = { openDropdown = false onDocumentsClicked.invoke() - } + }, ) MifosMenuDropDownItem( option = stringResource(id = R.string.feature_loan_loan_charges), onClick = { openDropdown = false onChargesClicked.invoke() - } + }, ) } } - }) { + }, + ) { Box( modifier = Modifier .fillMaxSize() - .padding(it) + .padding(it), ) { when (uiState) { is LoanAccountSummaryUiState.ShowFetchingError -> { MifosSweetError( - message = uiState.message, onclick = onRetry + message = uiState.message, + onclick = onRetry, ) } @@ -193,7 +206,7 @@ fun LoanAccountSummaryScreen( loanWithAssociations = loanWithAssociations, makeRepayment = { makeRepayment.invoke(loanWithAssociations) }, approveLoan = { approveLoan.invoke(loanWithAssociations) }, - disburseLoan = disburseLoan + disburseLoan = disburseLoan, ) } @@ -206,7 +219,7 @@ fun LoanAccountSummaryScreen( } @Composable -fun LoanAccountSummaryContent( +private fun LoanAccountSummaryContent( loanWithAssociations: LoanWithAssociations, makeRepayment: () -> Unit, approveLoan: () -> Unit, @@ -225,7 +238,7 @@ fun LoanAccountSummaryContent( Toast.makeText( context, context.resources.getString(R.string.feature_loan_loan_rejected_message), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() return "" } @@ -235,7 +248,7 @@ fun LoanAccountSummaryContent( modifier = Modifier .fillMaxSize() .padding(horizontal = 24.dp) - .verticalScroll(scrollState) + .verticalScroll(scrollState), ) { Text( modifier = Modifier @@ -249,11 +262,12 @@ fun LoanAccountSummaryContent( Row( modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { - Canvas(modifier = Modifier - .size(22.dp) - .padding(top = 4.dp, end = 4.dp), + Canvas( + modifier = Modifier + .size(22.dp) + .padding(top = 4.dp, end = 4.dp), contentDescription = "", onDraw = { drawRect( @@ -273,49 +287,58 @@ fun LoanAccountSummaryContent( else -> { Color.Black } - } + }, ) - }) + }, + ) LoanSummaryFarApartTextItem( title = loanWithAssociations.loanProductName, - value = "#" + loanWithAssociations.accountNo + value = "#" + loanWithAssociations.accountNo, ) } HorizontalDivider( modifier = Modifier .fillMaxWidth() - .padding(top = 2.dp) + .padding(top = 2.dp), ) LoanSummaryFarApartTextItem( title = stringResource(id = R.string.feature_loan_loan_amount_disbursed), - value = if (inflateLoanSummary) loanWithAssociations.summary.principalDisbursed?.toString() - ?: "" else "" + value = if (inflateLoanSummary) { + loanWithAssociations.summary.principalDisbursed?.toString() + ?: "" + } else { + "" + }, ) LoanSummaryFarApartTextItem( title = stringResource(id = R.string.feature_loan_disbursed_date), - value = if (inflateLoanSummary) getActualDisbursementDateInStringFormat() else "" + value = if (inflateLoanSummary) getActualDisbursementDateInStringFormat() else "", ) LoanSummaryFarApartTextItem( title = stringResource(id = R.string.feature_loan_loan_in_arrears), - value = if (inflateLoanSummary) loanWithAssociations.summary.totalOverdue?.toString() - ?: "" else "" + value = if (inflateLoanSummary) { + loanWithAssociations.summary.totalOverdue?.toString() + ?: "" + } else { + "" + }, ) LoanSummaryFarApartTextItem( title = stringResource(id = R.string.feature_loan_staff), - value = loanWithAssociations.loanOfficerName + value = loanWithAssociations.loanOfficerName, ) Spacer(modifier = Modifier.height(8.dp)) LoanSummaryDataTable( loanSummary = loanWithAssociations.summary, - inflateLoanSummary = inflateLoanSummary + inflateLoanSummary = inflateLoanSummary, ) Spacer(modifier = Modifier.height(4.dp)) @@ -349,75 +372,76 @@ fun LoanAccountSummaryContent( else -> { { Log.d("LoanAccountSummary", "TRANSACTION ACTION NOT SET") } } - } + }, ) { Text( color = MaterialTheme.colorScheme.background, - text = getButtonText(context, loanWithAssociations.status) + text = getButtonText(context, loanWithAssociations.status), ) } } } @Composable -fun LoanSummaryDataTable(loanSummary: Summary, inflateLoanSummary: Boolean) { +private fun LoanSummaryDataTable(loanSummary: Summary, inflateLoanSummary: Boolean) { // dataTable should be empty if [inflateLoanSummary] is false val summary = if (inflateLoanSummary) loanSummary else null + Column { + DataTableRow( + summaryColumnTitle = stringResource(id = R.string.feature_loan_summary), + loanColumnValue = stringResource(id = R.string.feature_loan), + amountColumnValue = stringResource(id = R.string.feature_loan_amount_paid), + balanceColumnValue = stringResource(id = R.string.feature_loan_balance), + isHeader = true, + color = BluePrimary.copy(alpha = .3f), + ) - DataTableRow( - summaryColumnTitle = stringResource(id = R.string.feature_loan_summary), - loanColumnValue = stringResource(id = R.string.feature_loan), - amountColumnValue = stringResource(id = R.string.feature_loan_amount_paid), - balanceColumnValue = stringResource(id = R.string.feature_loan_balance), - isHeader = true, - color = BluePrimary.copy(alpha = .3f) - ) - - DataTableRow( - summaryColumnTitle = stringResource(id = R.string.feature_loan_loan_principal), - loanColumnValue = summary?.principalDisbursed?.toString() ?: "", - amountColumnValue = summary?.principalPaid?.toString() ?: "", - balanceColumnValue = summary?.principalOutstanding?.toString() ?: "" - ) + DataTableRow( + summaryColumnTitle = stringResource(id = R.string.feature_loan_loan_principal), + loanColumnValue = summary?.principalDisbursed?.toString() ?: "", + amountColumnValue = summary?.principalPaid?.toString() ?: "", + balanceColumnValue = summary?.principalOutstanding?.toString() ?: "", + ) - DataTableRow( - summaryColumnTitle = stringResource(id = R.string.feature_loan_loan_interest), - loanColumnValue = summary?.interestCharged?.toString() ?: "", - amountColumnValue = summary?.interestPaid?.toString() ?: "", - balanceColumnValue = summary?.interestOutstanding?.toString() ?: "", - color = BluePrimary.copy(alpha = .1f) - ) + DataTableRow( + summaryColumnTitle = stringResource(id = R.string.feature_loan_loan_interest), + loanColumnValue = summary?.interestCharged?.toString() ?: "", + amountColumnValue = summary?.interestPaid?.toString() ?: "", + balanceColumnValue = summary?.interestOutstanding?.toString() ?: "", + color = BluePrimary.copy(alpha = .1f), + ) - DataTableRow( - summaryColumnTitle = stringResource(id = R.string.feature_loan_loan_fees), - loanColumnValue = summary?.feeChargesCharged?.toString() ?: "", - amountColumnValue = summary?.feeChargesPaid?.toString() ?: "", - balanceColumnValue = summary?.feeChargesOutstanding?.toString() ?: "" - ) + DataTableRow( + summaryColumnTitle = stringResource(id = R.string.feature_loan_loan_fees), + loanColumnValue = summary?.feeChargesCharged?.toString() ?: "", + amountColumnValue = summary?.feeChargesPaid?.toString() ?: "", + balanceColumnValue = summary?.feeChargesOutstanding?.toString() ?: "", + ) - DataTableRow( - summaryColumnTitle = stringResource(id = R.string.feature_loan_loan_penalty), - loanColumnValue = summary?.penaltyChargesCharged?.toString() ?: "", - amountColumnValue = summary?.penaltyChargesPaid?.toString() ?: "", - balanceColumnValue = summary?.penaltyChargesOutstanding?.toString() ?: "", - color = BluePrimary.copy(alpha = .1f) - ) + DataTableRow( + summaryColumnTitle = stringResource(id = R.string.feature_loan_loan_penalty), + loanColumnValue = summary?.penaltyChargesCharged?.toString() ?: "", + amountColumnValue = summary?.penaltyChargesPaid?.toString() ?: "", + balanceColumnValue = summary?.penaltyChargesOutstanding?.toString() ?: "", + color = BluePrimary.copy(alpha = .1f), + ) - DataTableRow( - summaryColumnTitle = stringResource(id = R.string.feature_loan_total), - loanColumnValue = summary?.totalExpectedRepayment?.toString() ?: "", - amountColumnValue = summary?.totalRepayment?.toString() ?: "", - balanceColumnValue = summary?.totalOutstanding?.toString() ?: "" - ) + DataTableRow( + summaryColumnTitle = stringResource(id = R.string.feature_loan_total), + loanColumnValue = summary?.totalExpectedRepayment?.toString() ?: "", + amountColumnValue = summary?.totalRepayment?.toString() ?: "", + balanceColumnValue = summary?.totalOutstanding?.toString() ?: "", + ) + } } @Composable -fun LoanSummaryFarApartTextItem(title: String, value: String) { +private fun LoanSummaryFarApartTextItem(title: String, value: String) { Row( modifier = Modifier .fillMaxWidth() .padding(top = 6.dp), - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Text( style = MaterialTheme.typography.bodyLarge, @@ -440,7 +464,7 @@ private fun DataTableRow( amountColumnValue: String, balanceColumnValue: String, isHeader: Boolean = false, - color: Color = White + color: Color = White, ) { Row( modifier = Modifier @@ -485,7 +509,7 @@ private fun DataTableRow( .padding(end = 2.dp), style = MaterialTheme.typography.bodyLarge, fontWeight = if (isHeader) FontWeight.Bold else FontWeight.Normal, - textAlign = TextAlign.End + textAlign = TextAlign.End, ) } } @@ -523,7 +547,7 @@ private fun getButtonActiveStatus(status: Status): Boolean { } @Composable -fun getInflateLoanSummaryValue(status: Status): Boolean { +private fun getInflateLoanSummaryValue(status: Status): Boolean { return when { status.active == true || status.closedObligationsMet == true -> { true @@ -539,7 +563,7 @@ fun getInflateLoanSummaryValue(status: Status): Boolean { } } -class LoanAccountSummaryPreviewProvider : PreviewParameterProvider { +private class LoanAccountSummaryPreviewProvider : PreviewParameterProvider { private val demoSummary = Summary( loanId = 12345, principalDisbursed = 10000.0, @@ -570,7 +594,7 @@ class LoanAccountSummaryPreviewProvider : PreviewParameterProvider @@ -581,21 +605,21 @@ class LoanAccountSummaryPreviewProvider : PreviewParameterProvider get() = _loanAccountSummaryUiState - fun loadLoanById(loanAccountNumber: Int) { _loanAccountSummaryUiState.value = LoanAccountSummaryUiState.ShowProgressbar repository.getLoanById(loanAccountNumber) @@ -47,10 +54,10 @@ class LoanAccountSummaryViewModel @Inject constructor( override fun onNext(loanWithAssociations: LoanWithAssociations?) { _loanAccountSummaryUiState.value = loanWithAssociations?.let { LoanAccountSummaryUiState.ShowLoanById( - it + it, ) }!! } }) } -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_approval/LoanAccountApprovalScreen.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanApproval/LoanAccountApprovalScreen.kt similarity index 83% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_approval/LoanAccountApprovalScreen.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanApproval/LoanAccountApprovalScreen.kt index 89cb5baacbb..3484fca6832 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_approval/LoanAccountApprovalScreen.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanApproval/LoanAccountApprovalScreen.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_approval +/* + * 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.loan.loanApproval import android.content.Context import android.widget.Toast @@ -62,10 +71,10 @@ import java.util.Locale */ @Composable -fun LoanAccountApprovalScreen( +internal fun LoanAccountApprovalScreen( navigateBack: () -> Unit, + viewModel: LoanAccountApprovalViewModel = hiltViewModel(), ) { - val viewModel: LoanAccountApprovalViewModel = hiltViewModel() val uiState by viewModel.loanAccountApprovalUiState.collectAsStateWithLifecycle() LoanAccountApprovalScreen( @@ -74,16 +83,16 @@ fun LoanAccountApprovalScreen( navigateBack = navigateBack, onLoanApprove = { viewModel.approveLoan(it) - } + }, ) } @Composable -fun LoanAccountApprovalScreen( +internal fun LoanAccountApprovalScreen( uiState: LoanAccountApprovalUiState, loanWithAssociations: LoanWithAssociations?, navigateBack: () -> Unit, - onLoanApprove: (loanApproval: LoanApproval) -> Unit + onLoanApprove: (loanApproval: LoanApproval) -> Unit, ) { val snackBarHostState = remember { SnackbarHostState() @@ -94,16 +103,16 @@ fun LoanAccountApprovalScreen( snackbarHostState = snackBarHostState, title = stringResource(id = R.string.feature_loan_approve_loan), icon = MifosIcons.arrowBack, - onBackPressed = navigateBack + onBackPressed = navigateBack, ) { Box( modifier = Modifier .fillMaxSize() - .padding(it) + .padding(it), ) { LoanAccountApprovalContent( loanWithAssociations = loanWithAssociations, - onLoanApprove = onLoanApprove + onLoanApprove = onLoanApprove, ) when (uiState) { @@ -117,7 +126,7 @@ fun LoanAccountApprovalScreen( Toast.makeText( context, stringResource(id = R.string.feature_loan_loan_approved), - Toast.LENGTH_LONG + Toast.LENGTH_LONG, ).show() navigateBack.invoke() } @@ -128,11 +137,10 @@ fun LoanAccountApprovalScreen( .fillMaxSize() .background( color = MaterialTheme.colorScheme.background.copy( - alpha = .7f - ) - ) - ) - { + alpha = .7f, + ), + ), + ) { MifosCircularProgress() } } @@ -141,12 +149,11 @@ fun LoanAccountApprovalScreen( } } - @OptIn(ExperimentalMaterial3Api::class) @Composable -fun LoanAccountApprovalContent( +private fun LoanAccountApprovalContent( loanWithAssociations: LoanWithAssociations?, - onLoanApprove: (loanApproval: LoanApproval) -> Unit + onLoanApprove: (loanApproval: LoanApproval) -> Unit, ) { var approvedAmount by rememberSaveable { mutableStateOf(loanWithAssociations?.approvedPrincipal.toString()) @@ -178,7 +185,7 @@ fun LoanAccountApprovalContent( override fun isSelectableDate(utcTimeMillis: Long): Boolean { return utcTimeMillis >= System.currentTimeMillis() } - } + }, ) val disburseDatePickerState = rememberDatePickerState( initialSelectedDateMillis = currentDisburseDate, @@ -186,16 +193,16 @@ fun LoanAccountApprovalContent( override fun isSelectableDate(utcTimeMillis: Long): Boolean { return utcTimeMillis >= System.currentTimeMillis() } - } + }, ) var disbursementDate by rememberSaveable { mutableStateOf( loanWithAssociations ?.timeline!!.expectedDisbursementDate?.let { - DateHelper.getDateAsString( - it - ) - } + DateHelper.getDateAsString( + it, + ) + }, ) } @@ -208,22 +215,23 @@ fun LoanAccountApprovalContent( confirmButton = { TextButton( onClick = { - if (pickApproveDate) approveDatePickerState.selectedDateMillis?.let { - approveDate = it - } - else { + if (pickApproveDate) { + approveDatePickerState.selectedDateMillis?.let { + approveDate = it + } + } else { disburseDatePickerState.selectedDateMillis?.let { disbursementDate = SimpleDateFormat( "dd MMMM yyyy", - Locale.getDefault() + Locale.getDefault(), ).format( - it + it, ) } } pickApproveDate = false pickDisbursementDate = false - } + }, ) { Text(stringResource(id = R.string.feature_loan_select_date)) } }, dismissButton = { @@ -231,11 +239,10 @@ fun LoanAccountApprovalContent( onClick = { pickApproveDate = false pickDisbursementDate = false - } + }, ) { Text(stringResource(id = R.string.feature_loan_cancel)) } - } - ) - { + }, + ) { DatePicker(state = if (pickApproveDate) approveDatePickerState else disburseDatePickerState) } } @@ -243,18 +250,18 @@ fun LoanAccountApprovalContent( Column( modifier = Modifier .fillMaxSize() - .verticalScroll(scrollState) + .verticalScroll(scrollState), ) { Spacer(modifier = Modifier.height(16.dp)) MifosDatePickerTextField( value = SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()).format( - approveDate + approveDate, ), label = R.string.feature_loan_approved_on, openDatePicker = { pickApproveDate = true - } + }, ) Spacer(modifier = Modifier.height(16.dp)) @@ -264,7 +271,7 @@ fun LoanAccountApprovalContent( label = R.string.feature_loan_expected_disbursement_on, openDatePicker = { pickDisbursementDate = true - } + }, ) Spacer(modifier = Modifier.height(16.dp)) @@ -274,7 +281,7 @@ fun LoanAccountApprovalContent( onValueChange = { approvedAmount = it }, label = stringResource(id = R.string.feature_loan_approved_amount), keyboardType = KeyboardType.Number, - error = null + error = null, ) Spacer(modifier = Modifier.height(16.dp)) @@ -284,7 +291,7 @@ fun LoanAccountApprovalContent( onValueChange = { transactionAmount = it }, label = stringResource(id = R.string.feature_loan_transaction_amount), keyboardType = KeyboardType.Number, - error = null + error = null, ) Spacer(modifier = Modifier.height(16.dp)) @@ -294,7 +301,7 @@ fun LoanAccountApprovalContent( onValueChange = { note = it }, label = stringResource(id = R.string.feature_loan_approval_note), keyboardType = KeyboardType.Text, - error = null + error = null, ) Spacer(modifier = Modifier.height(16.dp)) @@ -305,7 +312,7 @@ fun LoanAccountApprovalContent( .padding(horizontal = 16.dp) .heightIn(46.dp), colors = ButtonDefaults.buttonColors( - containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary + containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary, ), onClick = { if (isFieldValid(amount = approvedAmount, context = context) && @@ -314,9 +321,9 @@ fun LoanAccountApprovalContent( if (com.mifos.core.common.utils.Network.isOnline(context)) { val approvedOnDate = SimpleDateFormat( "dd MMMM yyyy", - Locale.getDefault() + Locale.getDefault(), ).format( - approveDate + approveDate, ) onLoanApprove.invoke( @@ -324,30 +331,31 @@ fun LoanAccountApprovalContent( note = note, approvedOnDate = approvedOnDate, approvedLoanAmount = approvedAmount, - expectedDisbursementDate = disbursementDate - ) + expectedDisbursementDate = disbursementDate, + ), ) } else { Toast.makeText( context, context.resources.getString(R.string.feature_loan_error_not_connected_internet), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() } } - }) { + }, + ) { Text(text = stringResource(id = R.string.feature_loan_submit)) } } } -fun isFieldValid(amount: String, context: Context): Boolean { +private fun isFieldValid(amount: String, context: Context): Boolean { return when { amount.isEmpty() -> { Toast.makeText( context, context.resources.getString(R.string.feature_loan_approval_amount_can_not_be_empty), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() false @@ -357,7 +365,7 @@ fun isFieldValid(amount: String, context: Context): Boolean { Toast.makeText( context, context.resources.getString(R.string.feature_loan_error_invalid_amount), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() false @@ -369,30 +377,30 @@ fun isFieldValid(amount: String, context: Context): Boolean { } } -fun isAmountValid(amount: String): Boolean { +private fun isAmountValid(amount: String): Boolean { return amount.toDoubleOrNull() != null } -class LoanAccountApprovalScreenPreviewProvider : +private class LoanAccountApprovalScreenPreviewProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( LoanAccountApprovalUiState.Initial, LoanAccountApprovalUiState.ShowProgressbar, LoanAccountApprovalUiState.ShowLoanApproveSuccessfully(GenericResponse()), - LoanAccountApprovalUiState.ShowLoanApproveFailed("Loan approve failed") + LoanAccountApprovalUiState.ShowLoanApproveFailed("Loan approve failed"), ) } @Composable @Preview(showSystemUi = true) -fun PreviewLoanAccountApprovalScreen( - @PreviewParameter(LoanAccountApprovalScreenPreviewProvider::class) loanAccountApprovalUiState: LoanAccountApprovalUiState +private fun PreviewLoanAccountApprovalScreen( + @PreviewParameter(LoanAccountApprovalScreenPreviewProvider::class) loanAccountApprovalUiState: LoanAccountApprovalUiState, ) { LoanAccountApprovalScreen( uiState = loanAccountApprovalUiState, loanWithAssociations = LoanWithAssociations(), - navigateBack = { }) { + navigateBack = { }, + ) { } } - diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_approval/LoanAccountApprovalUiState.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanApproval/LoanAccountApprovalUiState.kt similarity index 56% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_approval/LoanAccountApprovalUiState.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanApproval/LoanAccountApprovalUiState.kt index bd907560d43..db0bd6b5536 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_approval/LoanAccountApprovalUiState.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanApproval/LoanAccountApprovalUiState.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_approval +/* + * 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.loan.loanApproval import com.mifos.core.network.GenericResponse @@ -15,4 +24,4 @@ sealed class LoanAccountApprovalUiState { data class ShowLoanApproveSuccessfully(val genericResponse: GenericResponse) : LoanAccountApprovalUiState() -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_approval/LoanAccountApprovalViewModel.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanApproval/LoanAccountApprovalViewModel.kt similarity index 86% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_approval/LoanAccountApprovalViewModel.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanApproval/LoanAccountApprovalViewModel.kt index 07dbda689a4..b0891abd9c5 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_approval/LoanAccountApprovalViewModel.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanApproval/LoanAccountApprovalViewModel.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_approval +/* + * 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.loan.loanApproval import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel @@ -7,8 +16,6 @@ import com.mifos.core.data.repository.LoanAccountApprovalRepository import com.mifos.core.network.GenericResponse import com.mifos.core.objects.accounts.loan.LoanApproval import com.mifos.core.objects.accounts.loan.LoanApprovalData -import com.mifos.core.objects.accounts.loan.LoanWithAssociations -import com.mifos.core.objects.accounts.savings.SavingsSummaryData import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -25,7 +32,7 @@ import javax.inject.Inject @HiltViewModel class LoanAccountApprovalViewModel @Inject constructor( private val repository: LoanAccountApprovalRepository, - savedStateHandle: SavedStateHandle + savedStateHandle: SavedStateHandle, ) : ViewModel() { private val arg = savedStateHandle.getStateFlow(key = "arg", initialValue = "") @@ -52,7 +59,7 @@ class LoanAccountApprovalViewModel @Inject constructor( ?.string() _loanAccountApprovalUiState.value = LoanAccountApprovalUiState.ShowLoanApproveFailed( - errorMessage ?: "Something went wrong" + errorMessage ?: "Something went wrong", ) } } catch (throwable: Throwable) { @@ -63,10 +70,10 @@ class LoanAccountApprovalViewModel @Inject constructor( override fun onNext(genericResponse: GenericResponse?) { _loanAccountApprovalUiState.value = genericResponse?.let { LoanAccountApprovalUiState.ShowLoanApproveSuccessfully( - it + it, ) }!! } }) } -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_charge/LoanChargeScreen.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanCharge/LoanChargeScreen.kt similarity index 83% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_charge/LoanChargeScreen.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanCharge/LoanChargeScreen.kt index 859cfabbde3..8964eb2ac60 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_charge/LoanChargeScreen.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanCharge/LoanChargeScreen.kt @@ -1,6 +1,15 @@ +/* + * 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 + */ @file:OptIn(ExperimentalMaterialApi::class) -package com.mifos.feature.loan.loan_charge +package com.mifos.feature.loan.loanCharge import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -53,12 +62,13 @@ import com.mifos.core.designsystem.theme.DarkGray import com.mifos.core.objects.client.Charges import com.mifos.core.ui.components.MifosEmptyUi import com.mifos.feature.loan.R -import com.mifos.feature.loan.loan_charge_dialog.LoanChargeDialogScreen +import com.mifos.feature.loan.loanChargeDialog.LoanChargeDialogScreen @Composable -fun LoanChargeScreen(onBackPressed: () -> Unit) { - - val viewModel: LoanChargeViewModel = hiltViewModel() +internal fun LoanChargeScreen( + onBackPressed: () -> Unit, + viewModel: LoanChargeViewModel = hiltViewModel(), +) { val state by viewModel.loanChargeUiState.collectAsStateWithLifecycle() val refreshState by viewModel.isRefreshing.collectAsStateWithLifecycle() val loanAccountNumber by viewModel.loanAccountNumber.collectAsStateWithLifecycle() @@ -80,13 +90,12 @@ fun LoanChargeScreen(onBackPressed: () -> Unit) { refreshState = refreshState, onRefresh = { viewModel.refreshLoanChargeList(loanAccountNumber) - } + }, ) - } @Composable -fun LoanChargeScreen( +internal fun LoanChargeScreen( loanAccountNumber: Int, state: LoanChargeUiState, onBackPressed: () -> Unit, @@ -98,7 +107,7 @@ fun LoanChargeScreen( val snackbarHostState by remember { mutableStateOf(SnackbarHostState()) } val pullRefreshState = rememberPullRefreshState( refreshing = refreshState, - onRefresh = onRefresh + onRefresh = onRefresh, ) var showLoanChargeDialog by rememberSaveable { mutableStateOf(false) } @@ -109,7 +118,7 @@ fun LoanChargeScreen( onChargeCreated() showLoanChargeDialog = false }, - onDismiss = { showLoanChargeDialog = false } + onDismiss = { showLoanChargeDialog = false }, ) } @@ -124,7 +133,7 @@ fun LoanChargeScreen( Icon(imageVector = MifosIcons.Add, contentDescription = null) } }, - snackbarHostState = snackbarHostState + snackbarHostState = snackbarHostState, ) { paddingValues -> Column(modifier = Modifier.padding(paddingValues)) { Box(modifier = Modifier.pullRefresh(pullRefreshState)) { @@ -139,7 +148,7 @@ fun LoanChargeScreen( if (state.loanCharges.isEmpty()) { MifosEmptyUi( text = stringResource(id = R.string.feature_loan_no_loan_charges), - icon = MifosIcons.fileTask + icon = MifosIcons.fileTask, ) } else { LoanChargesContent(loanCharges = state.loanCharges) @@ -150,7 +159,7 @@ fun LoanChargeScreen( PullRefreshIndicator( refreshing = refreshState, state = pullRefreshState, - modifier = Modifier.align(Alignment.TopCenter) + modifier = Modifier.align(Alignment.TopCenter), ) } } @@ -158,21 +167,21 @@ fun LoanChargeScreen( } @Composable -fun LoanChargesContent( - loanCharges: List +private fun LoanChargesContent( + loanCharges: List, ) { LazyColumn { items(loanCharges) { charges -> LoanChargeItem( - charges = charges + charges = charges, ) } } } @Composable -fun LoanChargeItem( - charges: Charges +private fun LoanChargeItem( + charges: Charges, ) { Card( modifier = Modifier @@ -181,36 +190,36 @@ fun LoanChargeItem( shape = RoundedCornerShape(0.dp), elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), colors = CardDefaults.cardColors( - containerColor = BlueSecondary - ) + containerColor = BlueSecondary, + ), ) { Spacer(modifier = Modifier.height(8.dp)) MifosLoanChargeDetailsText( stringResource(id = R.string.feature_loan_client_id), - charges.chargeId.toString() + charges.chargeId.toString(), ) MifosLoanChargeDetailsText( stringResource(id = R.string.feature_loan_charge_name), - charges.name ?: "" + charges.name ?: "", ) MifosLoanChargeDetailsText( stringResource(id = R.string.feature_loan_charge_amount), - charges.amount.toString() + charges.amount.toString(), ) MifosLoanChargeDetailsText( stringResource(id = R.string.feature_loan_charge_due_date), - charges.formattedDueDate + charges.formattedDueDate, ) Spacer(modifier = Modifier.height(8.dp)) } } @Composable -fun MifosLoanChargeDetailsText(field: String, value: String) { +private fun MifosLoanChargeDetailsText(field: String, value: String) { Row( modifier = Modifier .fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Text( modifier = Modifier @@ -220,10 +229,10 @@ fun MifosLoanChargeDetailsText(field: String, value: String) { style = TextStyle( fontSize = 16.sp, fontWeight = FontWeight.Normal, - fontStyle = FontStyle.Normal + fontStyle = FontStyle.Normal, ), color = Black, - textAlign = TextAlign.Start + textAlign = TextAlign.Start, ) Text( modifier = Modifier.weight(1f), @@ -231,29 +240,28 @@ fun MifosLoanChargeDetailsText(field: String, value: String) { style = TextStyle( fontSize = 16.sp, fontWeight = FontWeight.Normal, - fontStyle = FontStyle.Normal + fontStyle = FontStyle.Normal, ), color = DarkGray, - textAlign = TextAlign.Start + textAlign = TextAlign.Start, ) } } -class LoanChargeUiStateProvider : PreviewParameterProvider { +private class LoanChargeUiStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( LoanChargeUiState.Loading, LoanChargeUiState.Error(R.string.feature_loan_failed_to_load_loan_charges), - LoanChargeUiState.LoanChargesList(sampleLoanChargeList) + LoanChargeUiState.LoanChargesList(sampleLoanChargeList), ) } - @Preview(showBackground = true) @Composable private fun LoanChargeScreenPreview( - @PreviewParameter(LoanChargeUiStateProvider::class) state: LoanChargeUiState + @PreviewParameter(LoanChargeUiStateProvider::class) state: LoanChargeUiState, ) { LoanChargeScreen( loanAccountNumber = 1, @@ -262,10 +270,10 @@ private fun LoanChargeScreenPreview( onBackPressed = {}, onRetry = {}, refreshState = false, - onRefresh = {} + onRefresh = {}, ) } val sampleLoanChargeList = List(10) { Charges(name = "name $it", chargeId = it, amount = it.toDouble()) -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loanCharge/LoanChargeUiState.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanCharge/LoanChargeUiState.kt new file mode 100644 index 00000000000..ccdc2a1f38d --- /dev/null +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanCharge/LoanChargeUiState.kt @@ -0,0 +1,24 @@ +/* + * 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.loan.loanCharge + +import com.mifos.core.objects.client.Charges + +/** + * Created by Aditya Gupta on 10/08/23. + */ +sealed class LoanChargeUiState { + + data object Loading : LoanChargeUiState() + + data class Error(val message: Int) : LoanChargeUiState() + + data class LoanChargesList(val loanCharges: List) : LoanChargeUiState() +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_charge/LoanChargeViewModel.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanCharge/LoanChargeViewModel.kt similarity index 67% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_charge/LoanChargeViewModel.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanCharge/LoanChargeViewModel.kt index c2d37225e0f..d96bbc850a4 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_charge/LoanChargeViewModel.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanCharge/LoanChargeViewModel.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_charge +/* + * 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.loan.loanCharge import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel @@ -17,7 +26,7 @@ import javax.inject.Inject @HiltViewModel class LoanChargeViewModel @Inject constructor( private val getListOfLoanChargesUseCase: GetListOfLoanChargesUseCase, - savedStateHandle: SavedStateHandle + savedStateHandle: SavedStateHandle, ) : ViewModel() { val loanAccountNumber = savedStateHandle.getStateFlow(key = Constants.LOAN_ACCOUNT_NUMBER, initialValue = 0) @@ -34,18 +43,19 @@ class LoanChargeViewModel @Inject constructor( _isRefreshing.value = false } - fun loadLoanChargesList(loanAccountNumber: Int) = viewModelScope.launch(Dispatchers.IO) { getListOfLoanChargesUseCase(loanAccountNumber).collect { result -> when (result) { - is Resource.Error -> _loanChargeUiState.value = - LoanChargeUiState.Error(R.string.feature_loan_failed_to_load_loan_charges) + is Resource.Error -> + _loanChargeUiState.value = + LoanChargeUiState.Error(R.string.feature_loan_failed_to_load_loan_charges) is Resource.Loading -> _loanChargeUiState.value = LoanChargeUiState.Loading - is Resource.Success -> _loanChargeUiState.value = - LoanChargeUiState.LoanChargesList(result.data ?: emptyList()) + is Resource.Success -> + _loanChargeUiState.value = + LoanChargeUiState.LoanChargesList(result.data ?: emptyList()) } } } -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_charge_dialog/LoanChargeDialogScreen.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanChargeDialog/LoanChargeDialogScreen.kt similarity index 88% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_charge_dialog/LoanChargeDialogScreen.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanChargeDialog/LoanChargeDialogScreen.kt index 5c43cad02e3..a2d9501c229 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_charge_dialog/LoanChargeDialogScreen.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanChargeDialog/LoanChargeDialogScreen.kt @@ -1,6 +1,15 @@ +/* + * 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 + */ @file:OptIn(ExperimentalMaterial3Api::class) -package com.mifos.feature.loan.loan_charge_dialog +package com.mifos.feature.loan.loanChargeDialog import android.widget.Toast import androidx.compose.foundation.layout.Arrangement @@ -64,13 +73,12 @@ import java.text.SimpleDateFormat import java.util.Locale @Composable -fun LoanChargeDialogScreen( +internal fun LoanChargeDialogScreen( loanId: Int, onSuccess: () -> Unit, - onDismiss: () -> Unit + onDismiss: () -> Unit, + viewModel: LoanChargeDialogViewModel = hiltViewModel(), ) { - - val viewModel: LoanChargeDialogViewModel = hiltViewModel() val state by viewModel.loanChargeDialogUiState.collectAsStateWithLifecycle() LaunchedEffect(Unit) { @@ -83,18 +91,17 @@ fun LoanChargeDialogScreen( viewModel.createLoanCharges(loanId, it) }, onSuccess = onSuccess, - onDismiss = onDismiss + onDismiss = onDismiss, ) } @Composable -fun LoanChargeDialogScreen( +internal fun LoanChargeDialogScreen( state: LoanChargeDialogUiState, onCreate: (ChargesPayload) -> Unit, onSuccess: () -> Unit, - onDismiss: () -> Unit + onDismiss: () -> Unit, ) { - var amount by rememberSaveable { mutableStateOf("") } var amountError by rememberSaveable { mutableStateOf(false) } val locale by rememberSaveable { mutableStateOf("en") } @@ -105,11 +112,10 @@ fun LoanChargeDialogScreen( override fun isSelectableDate(utcTimeMillis: Long): Boolean { return utcTimeMillis >= System.currentTimeMillis() } - } + }, ) var showDatePicker by rememberSaveable { mutableStateOf(false) } - fun validateInput(): Boolean { if (amount.isEmpty()) { amountError = true @@ -118,7 +124,6 @@ fun LoanChargeDialogScreen( return true } - if (showDatePicker) { DatePickerDialog( onDismissRequest = { @@ -131,38 +136,37 @@ fun LoanChargeDialogScreen( dueDatePickerState.selectedDateMillis?.let { dueDate = it } - } + }, ) { Text(stringResource(id = R.string.feature_loan_charge_select)) } }, dismissButton = { TextButton( onClick = { showDatePicker = false - } + }, ) { Text(stringResource(id = R.string.feature_loan_charge_cancel)) } - } - ) - { + }, + ) { DatePicker(state = dueDatePickerState) } } - - Dialog(onDismissRequest = { onDismiss() } + Dialog( + onDismissRequest = { onDismiss() }, ) { Surface( shape = RoundedCornerShape(16.dp), - color = Color.White + color = Color.White, ) { Box( - contentAlignment = Alignment.Center + contentAlignment = Alignment.Center, ) { when (state) { is LoanChargeDialogUiState.AllChargesV3 -> { var name by rememberSaveable { mutableStateOf(state.list[0].name) } var chargeId by rememberSaveable { mutableIntStateOf( - state.list[0].id ?: 0 + state.list[0].id ?: 0, ) } @@ -172,12 +176,12 @@ fun LoanChargeDialogScreen( .fillMaxWidth() .padding(bottom = 16.dp), horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Text( text = stringResource(id = R.string.feature_loan_charge_dialog), fontSize = MaterialTheme.typography.titleLarge.fontSize, - color = BluePrimary + color = BluePrimary, ) IconButton(onClick = { onDismiss() }) { Icon( @@ -186,7 +190,7 @@ fun LoanChargeDialogScreen( tint = colorResource(android.R.color.darker_gray), modifier = Modifier .width(30.dp) - .height(30.dp) + .height(30.dp), ) } } @@ -206,7 +210,7 @@ fun LoanChargeDialogScreen( } name = value }, - options = state.list.map { it.name.toString() } + options = state.list.map { it.name.toString() }, ) } @@ -222,23 +226,23 @@ fun LoanChargeDialogScreen( if (amountError) { Icon( imageVector = MifosIcons.error, - contentDescription = null + contentDescription = null, ) } - } + }, ) MifosDatePickerTextField( value = SimpleDateFormat( "dd MMMM yyyy", - Locale.getDefault() + Locale.getDefault(), ).format( - dueDate + dueDate, ), label = R.string.feature_loan_charge_due_date, openDatePicker = { showDatePicker = true - } + }, ) MifosOutlinedTextField( @@ -246,7 +250,7 @@ fun LoanChargeDialogScreen( onValueChange = {}, label = stringResource(id = R.string.feature_loan_locale), error = null, - readOnly = true + readOnly = true, ) Spacer(modifier = Modifier.height(16.dp)) @@ -261,9 +265,9 @@ fun LoanChargeDialogScreen( this.chargeId = chargeId this.dueDate = SimpleDateFormat( "dd MMMM yyyy", - Locale.getDefault() + Locale.getDefault(), ).format( - dueDate + dueDate, ) } onCreate(payload) @@ -276,35 +280,33 @@ fun LoanChargeDialogScreen( containerColor = BluePrimary, contentColor = White, disabledContainerColor = BluePrimary, - disabledContentColor = Gray - ) + disabledContentColor = Gray, + ), ) { Text(text = stringResource(id = R.string.feature_loan_charge_submit)) } } - } is LoanChargeDialogUiState.Error -> MifosSweetError( modifier = Modifier .fillMaxWidth() .height(300.dp), - message = stringResource(id = state.message) + message = stringResource(id = state.message), ) { - } is LoanChargeDialogUiState.Loading -> MifosCircularProgress( modifier = Modifier .fillMaxWidth() - .heightIn(300.dp) + .heightIn(300.dp), ) is LoanChargeDialogUiState.LoanChargesCreatedSuccessfully -> { Toast.makeText( LocalContext.current, stringResource(id = R.string.feature_loan_charge_created_successfully), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() onSuccess() } @@ -314,26 +316,25 @@ fun LoanChargeDialogScreen( } } -class LoanChargeDialogUiStateProvider : PreviewParameterProvider { +private class LoanChargeDialogUiStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( LoanChargeDialogUiState.AllChargesV3(sampleChargeList), LoanChargeDialogUiState.Error(R.string.feature_loan_failed_to_load_loan_charges), LoanChargeDialogUiState.Loading, - LoanChargeDialogUiState.LoanChargesCreatedSuccessfully + LoanChargeDialogUiState.LoanChargesCreatedSuccessfully, ) - } @Preview(showBackground = true) @Composable private fun LoanChargeDialogScreenPreview( - @PreviewParameter(LoanChargeDialogUiStateProvider::class) state: LoanChargeDialogUiState + @PreviewParameter(LoanChargeDialogUiStateProvider::class) state: LoanChargeDialogUiState, ) { LoanChargeDialogScreen(state = state, onCreate = {}, onSuccess = { }, onDismiss = {}) } val sampleChargeList = List(10) { Charges(name = "name $it") -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_charge_dialog/LoanChargeDialogUiState.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanChargeDialog/LoanChargeDialogUiState.kt similarity index 53% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_charge_dialog/LoanChargeDialogUiState.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanChargeDialog/LoanChargeDialogUiState.kt index 56d35898e53..30a10c4493b 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_charge_dialog/LoanChargeDialogUiState.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanChargeDialog/LoanChargeDialogUiState.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_charge_dialog +/* + * 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.loan.loanChargeDialog import com.mifos.core.objects.client.Charges diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_charge_dialog/LoanChargeDialogViewModel.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanChargeDialog/LoanChargeDialogViewModel.kt similarity index 74% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_charge_dialog/LoanChargeDialogViewModel.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanChargeDialog/LoanChargeDialogViewModel.kt index 8dd620c475b..b941069e344 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_charge_dialog/LoanChargeDialogViewModel.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanChargeDialog/LoanChargeDialogViewModel.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_charge_dialog +/* + * 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.loan.loanChargeDialog import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -22,7 +31,7 @@ import javax.inject.Inject @HiltViewModel class LoanChargeDialogViewModel @Inject constructor( private val getAllChargesV3UseCase: GetAllChargesV3UseCase, - private val createLoanChargesUseCase: CreateLoanChargesUseCase + private val createLoanChargesUseCase: CreateLoanChargesUseCase, ) : ViewModel() { private val _loanChargeDialogUiState = @@ -32,11 +41,13 @@ class LoanChargeDialogViewModel @Inject constructor( fun loanAllChargesV3(loanId: Int) = viewModelScope.launch(Dispatchers.IO) { getAllChargesV3UseCase(loanId).collect { result -> when (result) { - is Resource.Error -> _loanChargeDialogUiState.value = - LoanChargeDialogUiState.Error(R.string.feature_loan_charge_failed_to_load_charge) + is Resource.Error -> + _loanChargeDialogUiState.value = + LoanChargeDialogUiState.Error(R.string.feature_loan_charge_failed_to_load_charge) - is Resource.Loading -> _loanChargeDialogUiState.value = - LoanChargeDialogUiState.Loading + is Resource.Loading -> + _loanChargeDialogUiState.value = + LoanChargeDialogUiState.Loading is Resource.Success -> { // result.data?.let { @@ -53,21 +64,22 @@ class LoanChargeDialogViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { createLoanChargesUseCase(loanId, chargesPayload).collect { result -> when (result) { - is Resource.Error -> _loanChargeDialogUiState.value = - LoanChargeDialogUiState.Error(R.string.feature_loan_failed_to_create_loan_charge) + is Resource.Error -> + _loanChargeDialogUiState.value = + LoanChargeDialogUiState.Error(R.string.feature_loan_failed_to_create_loan_charge) - is Resource.Loading -> _loanChargeDialogUiState.value = - LoanChargeDialogUiState.Loading + is Resource.Loading -> + _loanChargeDialogUiState.value = + LoanChargeDialogUiState.Loading - is Resource.Success -> _loanChargeDialogUiState.value = - LoanChargeDialogUiState.LoanChargesCreatedSuccessfully + is Resource.Success -> + _loanChargeDialogUiState.value = + LoanChargeDialogUiState.LoanChargesCreatedSuccessfully } } } - private fun mapResourceBodyToChargeList(result: ResponseBody) { - val charges: MutableList = ArrayList() var reader: BufferedReader? = null val sb = StringBuilder() @@ -94,4 +106,4 @@ class LoanChargeDialogViewModel @Inject constructor( LoanChargeDialogUiState.Error(R.string.feature_loan_charge_failed_to_load_charge) } } -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_disbursement/LoanAccountDisbursementScreen.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanDisbursement/LoanAccountDisbursementScreen.kt similarity index 86% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_disbursement/LoanAccountDisbursementScreen.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanDisbursement/LoanAccountDisbursementScreen.kt index 497d5801456..87236bb9190 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_disbursement/LoanAccountDisbursementScreen.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanDisbursement/LoanAccountDisbursementScreen.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_disbursement +/* + * 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.loan.loanDisbursement import android.content.Context import android.widget.Toast @@ -64,10 +73,10 @@ import java.util.Locale */ @Composable -fun LoanAccountDisbursementScreen( +internal fun LoanAccountDisbursementScreen( navigateBack: () -> Unit, + viewmodel: LoanAccountDisbursementViewModel = hiltViewModel(), ) { - val viewmodel: LoanAccountDisbursementViewModel = hiltViewModel() val uiState by viewmodel.loanAccountDisbursementUiState.collectAsStateWithLifecycle() val loanId by viewmodel.loadId.collectAsStateWithLifecycle() @@ -81,38 +90,38 @@ fun LoanAccountDisbursementScreen( onRetry = { viewmodel.loadLoanTemplate(loanId) }, onDisburseLoan = { viewmodel.disburseLoan(loanId, it) - } + }, ) } @Composable -fun LoanAccountDisbursementScreen( +internal fun LoanAccountDisbursementScreen( uiState: LoanAccountDisbursementUiState, navigateBack: () -> Unit, onRetry: () -> Unit, - onDisburseLoan: (loanDisbursement: LoanDisbursement) -> Unit + onDisburseLoan: (loanDisbursement: LoanDisbursement) -> Unit, ) { - val SnackbarHostState = remember { + val snackbarHostState = remember { SnackbarHostState() } val context = LocalContext.current MifosScaffold( - snackbarHostState = SnackbarHostState, + snackbarHostState = snackbarHostState, title = stringResource(id = R.string.feature_loan_disburse_loan), icon = MifosIcons.arrowBack, - onBackPressed = navigateBack + onBackPressed = navigateBack, ) { Box( modifier = Modifier - .padding(it) + .padding(it), ) { when (uiState) { is LoanAccountDisbursementUiState.ShowDisburseLoanSuccessfully -> { Toast.makeText( context, stringResource(id = R.string.feature_loan_loan_disburse_successfully), - Toast.LENGTH_LONG + Toast.LENGTH_LONG, ).show() navigateBack.invoke() } @@ -120,7 +129,7 @@ fun LoanAccountDisbursementScreen( is LoanAccountDisbursementUiState.ShowError -> { MifosSweetError( message = uiState.message, - onclick = onRetry + onclick = onRetry, ) } @@ -128,7 +137,7 @@ fun LoanAccountDisbursementScreen( LoanAccountDisbursementContent( initialAmount = uiState.loanTransactionTemplate.amount.toString(), paymentTypeOptions = uiState.loanTransactionTemplate.paymentTypeOptions, - onDisburseLoan = onDisburseLoan + onDisburseLoan = onDisburseLoan, ) } @@ -140,10 +149,10 @@ fun LoanAccountDisbursementScreen( @OptIn(ExperimentalMaterial3Api::class) @Composable -fun LoanAccountDisbursementContent( +private fun LoanAccountDisbursementContent( initialAmount: String, paymentTypeOptions: List, - onDisburseLoan: (loanDisbursement: LoanDisbursement) -> Unit + onDisburseLoan: (loanDisbursement: LoanDisbursement) -> Unit, ) { var disbursementDate by rememberSaveable { mutableLongStateOf(System.currentTimeMillis()) @@ -170,7 +179,7 @@ fun LoanAccountDisbursementContent( override fun isSelectableDate(utcTimeMillis: Long): Boolean { return utcTimeMillis >= System.currentTimeMillis() } - } + }, ) val scrollState = rememberScrollState() @@ -186,18 +195,17 @@ fun LoanAccountDisbursementContent( disbursementDate = it } showDatePickerDialog = false - } + }, ) { Text(stringResource(id = R.string.feature_loan_select_date)) } }, dismissButton = { TextButton( onClick = { showDatePickerDialog = false - } + }, ) { Text(stringResource(id = R.string.feature_loan_cancel)) } - } - ) - { + }, + ) { DatePicker(state = datePickerState) } } @@ -205,18 +213,18 @@ fun LoanAccountDisbursementContent( Column( modifier = Modifier .fillMaxSize() - .verticalScroll(scrollState) + .verticalScroll(scrollState), ) { Spacer(modifier = Modifier.height(16.dp)) MifosDatePickerTextField( value = SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()).format( - disbursementDate + disbursementDate, ), label = R.string.feature_loan_approval_disbursement_date, openDatePicker = { showDatePickerDialog = true - } + }, ) Spacer(modifier = Modifier.height(16.dp)) @@ -226,7 +234,7 @@ fun LoanAccountDisbursementContent( onValueChange = { amount = it }, label = stringResource(id = R.string.feature_loan_loan_amount_disbursed), error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) Spacer(modifier = Modifier.height(16.dp)) @@ -240,7 +248,7 @@ fun LoanAccountDisbursementContent( }, label = R.string.feature_loan_payment_type, options = paymentTypeOptions.map { it.name }, - readOnly = true + readOnly = true, ) Spacer(modifier = Modifier.height(16.dp)) @@ -260,22 +268,22 @@ fun LoanAccountDisbursementContent( .padding(horizontal = 16.dp) .heightIn(44.dp), colors = ButtonDefaults.buttonColors( - containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary + containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary, ), onClick = { if (Network.isOnline(context)) { if (isFieldValid(amount = amount, context = context)) { val date = SimpleDateFormat( "dd MMMM yyyy", - Locale.getDefault() + Locale.getDefault(), ).format( - disbursementDate + disbursementDate, ) val loanDisbursement = LoanDisbursement( note = note, paymentId = paymentTypeId, actualDisbursementDate = date, - transactionAmount = amount.toDouble() + transactionAmount = amount.toDouble(), ) onDisburseLoan.invoke(loanDisbursement) @@ -284,22 +292,23 @@ fun LoanAccountDisbursementContent( Toast.makeText( context, context.resources.getString(R.string.feature_loan_error_network_not_available), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() } - }) { + }, + ) { Text(text = stringResource(id = R.string.feature_loan_submit)) } } } -fun isFieldValid(amount: String, context: Context): Boolean { +private fun isFieldValid(amount: String, context: Context): Boolean { return when { amount.isEmpty() -> { Toast.makeText( context, context.resources.getString(R.string.feature_loan_error_amount_can_not_be_empty), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() false @@ -309,7 +318,7 @@ fun isFieldValid(amount: String, context: Context): Boolean { Toast.makeText( context, context.resources.getString(R.string.feature_loan_error_invalid_amount), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() false @@ -321,30 +330,30 @@ fun isFieldValid(amount: String, context: Context): Boolean { } } -fun isAmountValid(amount: String): Boolean { +private fun isAmountValid(amount: String): Boolean { return amount.toDoubleOrNull() != null } -class LoanAccountDisbursementScreenPreviewProvider : +private class LoanAccountDisbursementScreenPreviewProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( LoanAccountDisbursementUiState.ShowProgressbar, LoanAccountDisbursementUiState.ShowError("An error occurred"), LoanAccountDisbursementUiState.ShowDisburseLoanSuccessfully(null), - LoanAccountDisbursementUiState.ShowLoanTransactionTemplate(LoanTransactionTemplate()) + LoanAccountDisbursementUiState.ShowLoanTransactionTemplate(LoanTransactionTemplate()), ) } @Composable @Preview(showSystemUi = true) -fun PreviewLoanAccountDisbursementScreen( - @PreviewParameter(LoanAccountDisbursementScreenPreviewProvider::class) loanAccountDisbursementUiState: LoanAccountDisbursementUiState +private fun PreviewLoanAccountDisbursementScreen( + @PreviewParameter(LoanAccountDisbursementScreenPreviewProvider::class) loanAccountDisbursementUiState: LoanAccountDisbursementUiState, ) { LoanAccountDisbursementScreen( uiState = loanAccountDisbursementUiState, navigateBack = { }, onRetry = { }, - onDisburseLoan = { } + onDisburseLoan = { }, ) -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_disbursement/LoanAccountDisbursementUiState.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanDisbursement/LoanAccountDisbursementUiState.kt similarity index 63% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_disbursement/LoanAccountDisbursementUiState.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanDisbursement/LoanAccountDisbursementUiState.kt index 2cb0b33d309..2b1fe3eb545 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_disbursement/LoanAccountDisbursementUiState.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanDisbursement/LoanAccountDisbursementUiState.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_disbursement +/* + * 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.loan.loanDisbursement import com.mifos.core.network.GenericResponse import com.mifos.core.objects.templates.loans.LoanTransactionTemplate diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_disbursement/LoanAccountDisbursementViewModel.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanDisbursement/LoanAccountDisbursementViewModel.kt similarity index 83% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_disbursement/LoanAccountDisbursementViewModel.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanDisbursement/LoanAccountDisbursementViewModel.kt index 9f309ee1219..3d413ab3b95 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_disbursement/LoanAccountDisbursementViewModel.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanDisbursement/LoanAccountDisbursementViewModel.kt @@ -1,8 +1,14 @@ -package com.mifos.feature.loan.loan_disbursement +/* + * 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.loan.loanDisbursement -import androidx.compose.ui.res.stringArrayResource -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import com.mifos.core.common.utils.Constants @@ -25,7 +31,7 @@ import javax.inject.Inject @HiltViewModel class LoanAccountDisbursementViewModel @Inject constructor( private val repository: LoanAccountDisbursementRepository, - savedStateHandle: SavedStateHandle + savedStateHandle: SavedStateHandle, ) : ViewModel() { val loadId = savedStateHandle.getStateFlow(key = Constants.LOAN_ACCOUNT_NUMBER, initialValue = 0) @@ -35,7 +41,7 @@ class LoanAccountDisbursementViewModel @Inject constructor( val loanAccountDisbursementUiState: StateFlow get() = _loanAccountDisbursementUiState - fun loadLoanTemplate(loanId : Int) { + fun loadLoanTemplate(loanId: Int) { _loanAccountDisbursementUiState.value = LoanAccountDisbursementUiState.ShowProgressbar repository.getLoanTransactionTemplate(loanId, APIEndPoint.DISBURSE) .observeOn(AndroidSchedulers.mainThread()) @@ -50,13 +56,13 @@ class LoanAccountDisbursementViewModel @Inject constructor( override fun onNext(loanTransactionTemplate: LoanTransactionTemplate) { _loanAccountDisbursementUiState.value = LoanAccountDisbursementUiState.ShowLoanTransactionTemplate( - loanTransactionTemplate + loanTransactionTemplate, ) } }) } - fun disburseLoan(loanId : Int, loanDisbursement: LoanDisbursement?) { + fun disburseLoan(loanId: Int, loanDisbursement: LoanDisbursement?) { _loanAccountDisbursementUiState.value = LoanAccountDisbursementUiState.ShowProgressbar repository.disburseLoan(loanId, loanDisbursement) .observeOn(AndroidSchedulers.mainThread()) @@ -74,5 +80,4 @@ class LoanAccountDisbursementViewModel @Inject constructor( } }) } - -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment/LoanRepaymentScreen.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanRepayment/LoanRepaymentScreen.kt similarity index 86% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment/LoanRepaymentScreen.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanRepayment/LoanRepaymentScreen.kt index 133b8aadd35..d413b6a2827 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment/LoanRepaymentScreen.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanRepayment/LoanRepaymentScreen.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_repayment +/* + * 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.loan.loanRepayment import android.content.Context import android.util.Log @@ -63,7 +72,6 @@ import com.mifos.core.designsystem.theme.DarkGray import com.mifos.core.objects.PaymentTypeOption import com.mifos.core.objects.accounts.loan.LoanRepaymentRequest import com.mifos.core.objects.accounts.loan.LoanRepaymentResponse -import com.mifos.core.objects.accounts.loan.LoanWithAssociations_Table.loanProductName import com.mifos.core.objects.templates.loans.LoanRepaymentTemplate import com.mifos.feature.loan.R import java.text.SimpleDateFormat @@ -73,10 +81,10 @@ import java.util.Locale * Created by Pronay Sarker on 16/07/2024 (2:14 PM) */ @Composable -fun LoanRepaymentScreen( - navigateBack: () -> Unit +internal fun LoanRepaymentScreen( + navigateBack: () -> Unit, + viewmodel: LoanRepaymentViewModel = hiltViewModel(), ) { - val viewmodel: LoanRepaymentViewModel = hiltViewModel() val uiState by viewmodel.loanRepaymentUiState.collectAsStateWithLifecycle() LaunchedEffect(key1 = Unit) { @@ -98,12 +106,12 @@ fun LoanRepaymentScreen( }, onLoanRepaymentDoesNotExistInDatabase = { viewmodel.loanLoanRepaymentTemplate() - } + }, ) } @Composable -fun LoanRepaymentScreen( +internal fun LoanRepaymentScreen( loanId: Int, clientName: String, loanProductName: String, @@ -113,7 +121,7 @@ fun LoanRepaymentScreen( navigateBack: () -> Unit, onRetry: () -> Unit, submitPayment: (request: LoanRepaymentRequest) -> Unit, - onLoanRepaymentDoesNotExistInDatabase: () -> Unit + onLoanRepaymentDoesNotExistInDatabase: () -> Unit, ) { val context = LocalContext.current val snackbarHostState = remember { @@ -127,7 +135,7 @@ fun LoanRepaymentScreen( icon = MifosIcons.arrowBack, ) { Box( - modifier = Modifier.padding(it) + modifier = Modifier.padding(it), ) { when (uiState) { is LoanRepaymentUiState.ShowError -> { @@ -145,7 +153,7 @@ fun LoanRepaymentScreen( amountInArrears = amountInArrears, loanRepaymentTemplate = uiState.loanRepaymentTemplate, navigateBack = navigateBack, - submitPayment = submitPayment + submitPayment = submitPayment, ) } @@ -154,18 +162,21 @@ fun LoanRepaymentScreen( } LoanRepaymentUiState.ShowLoanRepaymentExistInDatabase -> { - AlertDialog(onDismissRequest = { }, confirmButton = { - TextButton(onClick = { navigateBack.invoke() }) { - Text(text = stringResource(id = R.string.feature_loan_dialog_action_ok)) - } - }, + AlertDialog( + onDismissRequest = { }, + confirmButton = { + TextButton(onClick = { navigateBack.invoke() }) { + Text(text = stringResource(id = R.string.feature_loan_dialog_action_ok)) + } + }, title = { Text( text = stringResource(id = R.string.feature_loan_sync_previous_transaction), - style = MaterialTheme.typography.titleLarge + style = MaterialTheme.typography.titleLarge, ) }, - text = { Text(text = stringResource(id = R.string.feature_loan_dialog_message_sync_transaction)) }) + text = { Text(text = stringResource(id = R.string.feature_loan_dialog_message_sync_transaction)) }, + ) } is LoanRepaymentUiState.ShowPaymentSubmittedSuccessfully -> { @@ -173,7 +184,7 @@ fun LoanRepaymentScreen( Toast.makeText( context, "Payment Successful, Transaction ID = " + uiState.loanRepaymentResponse.resourceId, - Toast.LENGTH_LONG + Toast.LENGTH_LONG, ).show() } @@ -190,7 +201,7 @@ fun LoanRepaymentScreen( @OptIn(ExperimentalMaterial3Api::class) @Composable -fun LoanRepaymentContent( +private fun LoanRepaymentContent( loanId: Int, clientName: String, loanProductName: String, @@ -198,7 +209,7 @@ fun LoanRepaymentContent( loanAccountNumber: String, loanRepaymentTemplate: LoanRepaymentTemplate, navigateBack: () -> Unit, - submitPayment: (request: LoanRepaymentRequest) -> Unit + submitPayment: (request: LoanRepaymentRequest) -> Unit, ) { var paymentType by rememberSaveable { mutableStateOf("") } var amount by rememberSaveable { mutableStateOf("") } @@ -214,7 +225,7 @@ fun LoanRepaymentContent( override fun isSelectableDate(utcTimeMillis: Long): Boolean { return utcTimeMillis >= System.currentTimeMillis() } - } + }, ) val scrollState = rememberScrollState() val context = LocalContext.current @@ -235,7 +246,7 @@ fun LoanRepaymentContent( total = calculateTotal( fees = fees, amount = amount, - additionalPayment = additionalPayment + additionalPayment = additionalPayment, ).toString(), context = context, submitPayment = submitPayment, @@ -258,18 +269,17 @@ fun LoanRepaymentContent( repaymentDate = it } showDatePickerDialog = false - } + }, ) { Text(stringResource(id = R.string.feature_loan_select_date)) } }, dismissButton = { TextButton( onClick = { showDatePickerDialog = false - } + }, ) { Text(stringResource(id = R.string.feature_loan_cancel)) } - } - ) - { + }, + ) { DatePicker(state = datePickerState) } } @@ -278,14 +288,14 @@ fun LoanRepaymentContent( modifier = Modifier .fillMaxSize() .padding(horizontal = 16.dp) - .verticalScroll(scrollState) + .verticalScroll(scrollState), ) { Spacer(modifier = Modifier.height(16.dp)) Text( style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onBackground, - text = clientName + text = clientName, ) HorizontalDivider(modifier = Modifier.padding(top = 10.dp)) @@ -293,11 +303,11 @@ fun LoanRepaymentContent( FarApartTextItem(title = loanProductName, value = loanId.toString()) FarApartTextItem( title = stringResource(id = R.string.feature_loan_loan_in_arrears), - value = amountInArrears?.toString() ?: "" + value = amountInArrears?.toString() ?: "", ) FarApartTextItem( title = stringResource(id = R.string.feature_loan_loan_amount_due), - value = loanRepaymentTemplate.amount?.toString() ?: "" + value = loanRepaymentTemplate.amount?.toString() ?: "", ) HorizontalDivider(modifier = Modifier.padding(vertical = 10.dp)) @@ -306,10 +316,11 @@ fun LoanRepaymentContent( modifier = Modifier.fillMaxWidth(), value = SimpleDateFormat( "dd MMMM yyyy", - Locale.getDefault() + Locale.getDefault(), ).format( - repaymentDate - ), label = R.string.feature_loan_repayment_date + repaymentDate, + ), + label = R.string.feature_loan_repayment_date, ) { showDatePickerDialog = true } @@ -326,7 +337,7 @@ fun LoanRepaymentContent( }, label = R.string.feature_loan_payment_type, options = if (loanRepaymentTemplate.paymentTypeOptions != null) loanRepaymentTemplate.paymentTypeOptions!!.map { it.name } else listOf(), - readOnly = true + readOnly = true, ) Spacer(modifier = Modifier.height(16.dp)) @@ -339,7 +350,7 @@ fun LoanRepaymentContent( }, label = stringResource(id = R.string.feature_loan_amount), error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) Spacer(modifier = Modifier.height(16.dp)) @@ -352,7 +363,7 @@ fun LoanRepaymentContent( }, label = stringResource(id = R.string.feature_loan_additional_payment), error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) Spacer(modifier = Modifier.height(16.dp)) @@ -365,7 +376,7 @@ fun LoanRepaymentContent( }, label = stringResource(id = R.string.feature_loan_loan_fees), error = null, - keyboardType = KeyboardType.Number + keyboardType = KeyboardType.Number, ) Spacer(modifier = Modifier.height(16.dp)) @@ -375,27 +386,28 @@ fun LoanRepaymentContent( value = calculateTotal( fees = fees, amount = amount, - additionalPayment = additionalPayment + additionalPayment = additionalPayment, ).toString(), onValueChange = { }, label = stringResource(id = R.string.feature_loan_total), error = null, - readOnly = true + readOnly = true, ) Spacer(modifier = Modifier.height(16.dp)) Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Button( modifier = Modifier .heightIn(46.dp), colors = ButtonDefaults.buttonColors( - containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary + containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary, ), - onClick = { navigateBack.invoke() }) { + onClick = { navigateBack.invoke() }, + ) { Text(text = stringResource(id = R.string.feature_loan_cancel)) } @@ -403,7 +415,7 @@ fun LoanRepaymentContent( modifier = Modifier .heightIn(46.dp), colors = ButtonDefaults.buttonColors( - containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary + containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary, ), onClick = { if (isAllFieldsValid( @@ -411,12 +423,12 @@ fun LoanRepaymentContent( additionalPayment = additionalPayment, fees = fees, paymentType = paymentType, - context = context + context = context, ) ) { showConfirmationDialog = true } - } + }, ) { Text(text = stringResource(id = R.string.feature_loan_review_payment)) } @@ -430,7 +442,7 @@ private fun FarApartTextItem(title: String, value: String) { modifier = Modifier .fillMaxWidth() .padding(top = 10.dp), - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Text( style = MaterialTheme.typography.bodyLarge, @@ -447,7 +459,7 @@ private fun FarApartTextItem(title: String, value: String) { } @Composable -fun ShowLoanRepaymentConfirmationDialog( +private fun ShowLoanRepaymentConfirmationDialog( onDismiss: () -> Unit, loanAccountNumber: String, paymentTypeId: String, @@ -458,7 +470,7 @@ fun ShowLoanRepaymentConfirmationDialog( fees: String, total: String, context: Context, - submitPayment: (request: LoanRepaymentRequest) -> Unit + submitPayment: (request: LoanRepaymentRequest) -> Unit, ) { AlertDialog( onDismissRequest = { onDismiss() }, @@ -476,9 +488,9 @@ fun ShowLoanRepaymentConfirmationDialog( request.transactionAmount = total request.transactionDate = SimpleDateFormat( "dd MMMM yyyy", - Locale.getDefault() + Locale.getDefault(), ).format( - repaymentDate + repaymentDate, ) submitPayment.invoke(request) @@ -486,23 +498,25 @@ fun ShowLoanRepaymentConfirmationDialog( Toast.makeText( context, context.resources.getString(R.string.feature_loan_error_not_connected_internet), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() } - }) { + }, + ) { Text(text = stringResource(id = R.string.feature_loan_dialog_action_pay_now)) } }, dismissButton = { TextButton( - onClick = { onDismiss() }) { + onClick = { onDismiss() }, + ) { Text(text = stringResource(id = R.string.feature_loan_cancel)) } }, title = { Text( text = stringResource(id = R.string.feature_loan_review_payment), - style = MaterialTheme.typography.titleLarge + style = MaterialTheme.typography.titleLarge, ) }, text = { @@ -511,8 +525,8 @@ fun ShowLoanRepaymentConfirmationDialog( Text( text = stringResource(id = R.string.feature_loan_repayment_date) + " : " + SimpleDateFormat( "dd MMMM yyyy", - Locale.getDefault() - ).format(repaymentDate) + Locale.getDefault(), + ).format(repaymentDate), ) Text(text = stringResource(id = R.string.feature_loan_payment_type) + " : " + paymentType) Text(text = stringResource(id = R.string.feature_loan_amount) + " : " + amount) @@ -520,7 +534,7 @@ fun ShowLoanRepaymentConfirmationDialog( Text(text = stringResource(id = R.string.feature_loan_loan_fees) + " : " + fees) Text(text = stringResource(id = R.string.feature_loan_total) + " : " + total) } - } + }, ) } @@ -528,10 +542,10 @@ fun ShowLoanRepaymentConfirmationDialog( * Calculating the Total of the Amount, Additional Payment and Fee * @return Total of the Amount + Additional Payment + Fees */ -fun calculateTotal( +private fun calculateTotal( fees: String, amount: String, - additionalPayment: String + additionalPayment: String, ): Double { fun setValue(value: String): Double { if (value.isEmpty()) { @@ -551,12 +565,12 @@ fun calculateTotal( return feesValue + amountValue + additionalPaymentValue } -fun isAllFieldsValid( +private fun isAllFieldsValid( amount: String, additionalPayment: String, fees: String, paymentType: String, - context: Context + context: Context, ): Boolean { return when { amount.isNotEmpty() && additionalPayment.isNotEmpty() && fees.isNotEmpty() && paymentType.isNotEmpty() -> { @@ -567,7 +581,7 @@ fun isAllFieldsValid( Toast.makeText( context, context.resources.getString(R.string.feature_loan_repayment_make_sure_every_field_has_a_value), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() false @@ -575,7 +589,7 @@ fun isAllFieldsValid( } } -class LoanRepaymentScreenPreviewProvider : +private class LoanRepaymentScreenPreviewProvider : PreviewParameterProvider { private val samplePaymentTypeOptions = mutableListOf( @@ -584,8 +598,8 @@ class LoanRepaymentScreenPreviewProvider : name = "Cash", description = "Cash payment", isCashPayment = true, - position = 1 - ) + position = 1, + ), ) private val sampleLoanRepaymentTemplate = LoanRepaymentTemplate( @@ -596,7 +610,7 @@ class LoanRepaymentScreenPreviewProvider : interestPortion = 150.0, feeChargesPortion = 30.0, penaltyChargesPortion = 20.0, - paymentTypeOptions = samplePaymentTypeOptions + paymentTypeOptions = samplePaymentTypeOptions, ) override val values: Sequence @@ -612,8 +626,8 @@ class LoanRepaymentScreenPreviewProvider : @Composable @Preview(showSystemUi = true) -fun PreviewLoanRepaymentScreen( - @PreviewParameter(LoanRepaymentScreenPreviewProvider::class) loanRepaymentUiState: LoanRepaymentUiState +private fun PreviewLoanRepaymentScreen( + @PreviewParameter(LoanRepaymentScreenPreviewProvider::class) loanRepaymentUiState: LoanRepaymentUiState, ) { LoanRepaymentScreen( loanId = 2, @@ -625,6 +639,6 @@ fun PreviewLoanRepaymentScreen( navigateBack = {}, onRetry = {}, submitPayment = {}, - onLoanRepaymentDoesNotExistInDatabase = {} + onLoanRepaymentDoesNotExistInDatabase = {}, ) } diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment/LoanRepaymentUiState.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanRepayment/LoanRepaymentUiState.kt similarity index 67% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment/LoanRepaymentUiState.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanRepayment/LoanRepaymentUiState.kt index 5dccf89f57e..dfe009e22f0 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment/LoanRepaymentUiState.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanRepayment/LoanRepaymentUiState.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_repayment +/* + * 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.loan.loanRepayment import com.mifos.core.objects.accounts.loan.LoanRepaymentResponse import com.mifos.core.objects.templates.loans.LoanRepaymentTemplate @@ -21,4 +30,4 @@ sealed class LoanRepaymentUiState { data object ShowLoanRepaymentExistInDatabase : LoanRepaymentUiState() data object ShowLoanRepaymentDoesNotExistInDatabase : LoanRepaymentUiState() -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment/LoanRepaymentViewModel.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanRepayment/LoanRepaymentViewModel.kt similarity index 91% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment/LoanRepaymentViewModel.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanRepayment/LoanRepaymentViewModel.kt index 783ea279b5d..ed53a406351 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment/LoanRepaymentViewModel.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanRepayment/LoanRepaymentViewModel.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_repayment +/* + * 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.loan.loanRepayment import android.util.Log import androidx.lifecycle.SavedStateHandle @@ -6,7 +15,6 @@ import androidx.lifecycle.ViewModel import com.google.gson.Gson import com.mifos.core.common.utils.Constants import com.mifos.core.data.repository.LoanRepaymentRepository -import com.mifos.core.objects.accounts.loan.LoanApprovalData import com.mifos.core.objects.accounts.loan.LoanRepaymentRequest import com.mifos.core.objects.accounts.loan.LoanRepaymentResponse import com.mifos.core.objects.accounts.loan.LoanWithAssociations @@ -26,7 +34,7 @@ import javax.inject.Inject @HiltViewModel class LoanRepaymentViewModel @Inject constructor( private val repository: LoanRepaymentRepository, - savedStateHandle: SavedStateHandle + savedStateHandle: SavedStateHandle, ) : ViewModel() { val arg = savedStateHandle.getStateFlow(key = Constants.LOAN_WITH_ASSOCIATIONS, initialValue = "") @@ -60,7 +68,7 @@ class LoanRepaymentViewModel @Inject constructor( override fun onNext(loanRepaymentTemplate: LoanRepaymentTemplate?) { _loanRepaymentUiState.value = LoanRepaymentUiState.ShowLoanRepayTemplate( - loanRepaymentTemplate ?: LoanRepaymentTemplate() + loanRepaymentTemplate ?: LoanRepaymentTemplate(), ) } }) @@ -114,5 +122,3 @@ class LoanRepaymentViewModel @Inject constructor( }) } } - - diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment_schedule/LoanRepaymentScheduleScreen.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanRepaymentSchedule/LoanRepaymentScheduleScreen.kt similarity index 79% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment_schedule/LoanRepaymentScheduleScreen.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanRepaymentSchedule/LoanRepaymentScheduleScreen.kt index fb5e87a0070..e7fbd3632f2 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment_schedule/LoanRepaymentScheduleScreen.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanRepaymentSchedule/LoanRepaymentScheduleScreen.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_repayment_schedule +/* + * 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.loan.loanRepaymentSchedule import androidx.compose.foundation.Canvas import androidx.compose.foundation.background @@ -46,9 +55,9 @@ import com.mifos.feature.loan.R */ @Composable -fun LoanRepaymentScheduleScreen( +internal fun LoanRepaymentScheduleScreen( viewModel: LoanRepaymentScheduleViewModel = hiltViewModel(), - navigateBack: () -> Unit + navigateBack: () -> Unit, ) { val uiState by viewModel.loanRepaymentScheduleUiState.collectAsStateWithLifecycle() val loanId by viewModel.loanId.collectAsStateWithLifecycle() @@ -60,15 +69,15 @@ fun LoanRepaymentScheduleScreen( LoanRepaymentScheduleScreen( uiState = uiState, navigateBack = navigateBack, - onRetry = { viewModel.loadLoanRepaySchedule(loanId) } + onRetry = { viewModel.loadLoanRepaySchedule(loanId) }, ) } @Composable -fun LoanRepaymentScheduleScreen( +internal fun LoanRepaymentScheduleScreen( uiState: LoanRepaymentScheduleUiState, navigateBack: () -> Unit, - onRetry: () -> Unit + onRetry: () -> Unit, ) { val snackbarHostState = remember { SnackbarHostState() @@ -78,20 +87,20 @@ fun LoanRepaymentScheduleScreen( title = stringResource(R.string.feature_loan_loan_repayment_schedule), snackbarHostState = snackbarHostState, icon = MifosIcons.arrowBack, - onBackPressed = navigateBack + onBackPressed = navigateBack, ) { Box(modifier = Modifier.padding(it)) { when (uiState) { is LoanRepaymentScheduleUiState.ShowFetchingError -> { MifosSweetError( message = uiState.message, - onclick = onRetry + onclick = onRetry, ) } is LoanRepaymentScheduleUiState.ShowLoanRepaySchedule -> { LoanRepaymentScheduleContent( - uiState.loanWithAssociations.repaymentSchedule.getlistOfActualPeriods() + uiState.loanWithAssociations.repaymentSchedule.getlistOfActualPeriods(), ) } @@ -104,17 +113,17 @@ fun LoanRepaymentScheduleScreen( } @Composable -fun LoanRepaymentScheduleContent( - periods: List +private fun LoanRepaymentScheduleContent( + periods: List, ) { Column( - modifier = Modifier.fillMaxSize() + modifier = Modifier.fillMaxSize(), ) { HeaderLoanRepaymentSchedule() Box { LazyColumn( - modifier = Modifier.fillMaxSize() + modifier = Modifier.fillMaxSize(), ) { items(periods) { period -> LoanRepaymentRowItem( @@ -128,11 +137,10 @@ fun LoanRepaymentScheduleContent( } else -> Color.Blue.copy(alpha = .7f) - }, date = period.dueDate?.let { DateHelper.getDateAsString(it) }, amountDue = period.totalDueForPeriod.toString(), - amountPaid = period.totalPaidForPeriod.toString() + amountPaid = period.totalPaidForPeriod.toString(), ) } } @@ -144,44 +152,46 @@ fun LoanRepaymentScheduleContent( .toString(), modifier = Modifier .align(Alignment.BottomStart) - .background(color = Color.LightGray) + .background(color = Color.LightGray), ) } } } - @Composable -fun LoanRepaymentRowItem( +private fun LoanRepaymentRowItem( color: Color, date: String?, amountDue: String, - amountPaid: String + amountPaid: String, ) { Column( modifier = Modifier - .fillMaxWidth() + .fillMaxWidth(), ) { Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { - Canvas(modifier = Modifier - .size(20.dp) - .padding(2.dp), onDraw = { - drawRect( - color = color - ) - }) + Canvas( + modifier = Modifier + .size(20.dp) + .padding(2.dp), + onDraw = { + drawRect( + color = color, + ) + }, + ) Text( modifier = Modifier.weight(3f), text = date ?: "", style = MaterialTheme.typography.bodyLarge, color = Color.Black, - textAlign = TextAlign.End + textAlign = TextAlign.End, ) Text( @@ -189,7 +199,7 @@ fun LoanRepaymentRowItem( text = amountDue, style = MaterialTheme.typography.bodyLarge, color = Color.Black, - textAlign = TextAlign.End + textAlign = TextAlign.End, ) Text( @@ -197,7 +207,7 @@ fun LoanRepaymentRowItem( text = amountPaid, style = MaterialTheme.typography.bodyLarge, color = Color.Black, - textAlign = TextAlign.End + textAlign = TextAlign.End, ) } @@ -206,24 +216,24 @@ fun LoanRepaymentRowItem( } @Composable -fun HeaderLoanRepaymentSchedule() { +private fun HeaderLoanRepaymentSchedule() { Box( modifier = Modifier .background(Color.Red.copy(alpha = .5f)) - .fillMaxWidth() + .fillMaxWidth(), ) { Row( modifier = Modifier .fillMaxWidth() .padding(horizontal = 4.dp, vertical = 4.dp), - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Text( modifier = Modifier.weight(2f), text = stringResource(id = R.string.feature_loan_status), style = MaterialTheme.typography.bodyLarge, color = Color.Black, - textAlign = TextAlign.Start + textAlign = TextAlign.Start, ) Text( @@ -231,7 +241,7 @@ fun HeaderLoanRepaymentSchedule() { text = stringResource(id = R.string.feature_loan_date), style = MaterialTheme.typography.bodyLarge, color = Color.Black, - textAlign = TextAlign.Center + textAlign = TextAlign.Center, ) Text( @@ -239,7 +249,7 @@ fun HeaderLoanRepaymentSchedule() { text = stringResource(id = R.string.feature_loan_loan_amount_due), style = MaterialTheme.typography.bodyLarge, color = Color.Black, - textAlign = TextAlign.Center + textAlign = TextAlign.Center, ) Text( @@ -247,32 +257,32 @@ fun HeaderLoanRepaymentSchedule() { text = stringResource(id = R.string.feature_loan_amount_paid), style = MaterialTheme.typography.bodyLarge, color = Color.Black, - textAlign = TextAlign.End + textAlign = TextAlign.End, ) } } } @Composable -fun BottomBarLoanRepaymentSchedule( +private fun BottomBarLoanRepaymentSchedule( totalPaid: String, totalOverdue: String, tvTotalUpcoming: String, - modifier: Modifier + modifier: Modifier = Modifier, ) { Box(modifier = modifier) { Row( modifier = Modifier .fillMaxWidth() .padding(horizontal = 8.dp, vertical = 8.dp), - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Text( modifier = Modifier.weight(3.4f), text = stringResource(id = R.string.feature_loan_complete) + " : " + totalPaid, style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.Start + textAlign = TextAlign.Start, ) Text( @@ -280,7 +290,7 @@ fun BottomBarLoanRepaymentSchedule( text = stringResource(id = R.string.feature_loan_pending) + " : " + tvTotalUpcoming, style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.Center + textAlign = TextAlign.Center, ) Text( @@ -288,13 +298,13 @@ fun BottomBarLoanRepaymentSchedule( text = stringResource(id = R.string.feature_loan_overdue) + " : " + totalOverdue, style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.End + textAlign = TextAlign.End, ) } } } -class LoanRepaymentSchedulePreviewProvider : +private class LoanRepaymentSchedulePreviewProvider : PreviewParameterProvider { val loanWithAssociations = LoanWithAssociations( @@ -304,52 +314,52 @@ class LoanRepaymentSchedulePreviewProvider : complete = true, totalDueForPeriod = 123.232, totalPaidForPeriod = 34343.3434, - dueDate = listOf(2024, 6, 1) + dueDate = listOf(2024, 6, 1), ), Period( complete = true, totalDueForPeriod = 123.232, totalPaidForPeriod = 34343.3434, - dueDate = listOf(2024, 6, 1) + dueDate = listOf(2024, 6, 1), ), Period( complete = true, totalDueForPeriod = 123.232, totalPaidForPeriod = 34343.3434, - dueDate = listOf(2024, 6, 1) + dueDate = listOf(2024, 6, 1), ), Period( complete = true, totalDueForPeriod = 123.232, totalPaidForPeriod = 34343.3434, - dueDate = listOf(2024, 6, 1) + dueDate = listOf(2024, 6, 1), ), Period( complete = true, totalDueForPeriod = 123.232, totalPaidForPeriod = 34343.3434, - dueDate = listOf(2024, 6, 1) - ) - ) - ) + dueDate = listOf(2024, 6, 1), + ), + ), + ), ) override val values: Sequence get() = sequenceOf( LoanRepaymentScheduleUiState.ShowFetchingError("Error fetching loan repayment schedule"), LoanRepaymentScheduleUiState.ShowProgressbar, - LoanRepaymentScheduleUiState.ShowLoanRepaySchedule(loanWithAssociations) + LoanRepaymentScheduleUiState.ShowLoanRepaySchedule(loanWithAssociations), ) } @Composable @Preview(showSystemUi = true) -fun PreviewLoanRepaymentSchedule( - @PreviewParameter(LoanRepaymentSchedulePreviewProvider::class) loanRepaymentScheduleUiState: LoanRepaymentScheduleUiState +private fun PreviewLoanRepaymentSchedule( + @PreviewParameter(LoanRepaymentSchedulePreviewProvider::class) loanRepaymentScheduleUiState: LoanRepaymentScheduleUiState, ) { LoanRepaymentScheduleScreen( uiState = loanRepaymentScheduleUiState, navigateBack = { }, - onRetry = {} + onRetry = {}, ) -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment_schedule/LoanRepaymentScheduleUiState.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanRepaymentSchedule/LoanRepaymentScheduleUiState.kt similarity index 54% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment_schedule/LoanRepaymentScheduleUiState.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanRepaymentSchedule/LoanRepaymentScheduleUiState.kt index 460c2dcdd56..da3799937ed 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment_schedule/LoanRepaymentScheduleUiState.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanRepaymentSchedule/LoanRepaymentScheduleUiState.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_repayment_schedule +/* + * 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.loan.loanRepaymentSchedule import com.mifos.core.objects.accounts.loan.LoanWithAssociations diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment_schedule/LoanRepaymentScheduleViewModel.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanRepaymentSchedule/LoanRepaymentScheduleViewModel.kt similarity index 80% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment_schedule/LoanRepaymentScheduleViewModel.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanRepaymentSchedule/LoanRepaymentScheduleViewModel.kt index 4aca5ed2203..3fbd33d4bad 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_repayment_schedule/LoanRepaymentScheduleViewModel.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanRepaymentSchedule/LoanRepaymentScheduleViewModel.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_repayment_schedule +/* + * 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.loan.loanRepaymentSchedule import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel @@ -19,7 +28,7 @@ import javax.inject.Inject @HiltViewModel class LoanRepaymentScheduleViewModel @Inject constructor( private val repository: LoanRepaymentScheduleRepository, - savedStateHandle: SavedStateHandle + savedStateHandle: SavedStateHandle, ) : ViewModel() { val loanId = savedStateHandle.getStateFlow(key = Constants.LOAN_ACCOUNT_NUMBER, initialValue = 0) @@ -28,7 +37,7 @@ class LoanRepaymentScheduleViewModel @Inject constructor( MutableStateFlow(LoanRepaymentScheduleUiState.ShowProgressbar) val loanRepaymentScheduleUiState: StateFlow get() = _loanRepaymentScheduleUiState - fun loadLoanRepaySchedule(loanId : Int) { + fun loadLoanRepaySchedule(loanId: Int) { _loanRepaymentScheduleUiState.value = LoanRepaymentScheduleUiState.ShowProgressbar repository.getLoanRepaySchedule(loanId) .observeOn(AndroidSchedulers.mainThread()) @@ -48,5 +57,4 @@ class LoanRepaymentScheduleViewModel @Inject constructor( } }) } - -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_transaction/LoanTransactionsScreen.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loanTransaction/LoanTransactionsScreen.kt similarity index 70% rename from feature/loan/src/main/java/com/mifos/feature/loan/loan_transaction/LoanTransactionsScreen.kt rename to feature/loan/src/main/java/com/mifos/feature/loan/loanTransaction/LoanTransactionsScreen.kt index 9ab043b8791..02e45a2c9c0 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_transaction/LoanTransactionsScreen.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/loanTransaction/LoanTransactionsScreen.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.loan.loan_transaction +/* + * 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.loan.loanTransaction import android.util.Log import androidx.compose.animation.AnimatedVisibility @@ -66,10 +75,10 @@ import com.mifos.feature.loan.R */ @Composable -fun LoanTransactionsScreen( - navigateBack: () -> Unit +internal fun LoanTransactionsScreen( + navigateBack: () -> Unit, + viewModel: LoanTransactionsViewModel = hiltViewModel(), ) { - val viewModel: LoanTransactionsViewModel = hiltViewModel() val uiState by viewModel.loanTransactionsUiState.collectAsStateWithLifecycle() val loanId by viewModel.loanId.collectAsStateWithLifecycle() @@ -81,15 +90,15 @@ fun LoanTransactionsScreen( LoanTransactionsScreen( uiState = uiState, navigateBack = navigateBack, - onRetry = { viewModel.loadLoanTransaction(loanId) } + onRetry = { viewModel.loadLoanTransaction(loanId) }, ) } @Composable -fun LoanTransactionsScreen( +internal fun LoanTransactionsScreen( uiState: LoanTransactionsUiState, navigateBack: () -> Unit, - onRetry: () -> Unit + onRetry: () -> Unit, ) { val snackbarHostState = remember { SnackbarHostState() @@ -98,26 +107,27 @@ fun LoanTransactionsScreen( snackbarHostState = snackbarHostState, title = stringResource(id = R.string.feature_loan_loan_transactions), icon = MifosIcons.arrowBack, - onBackPressed = navigateBack + onBackPressed = navigateBack, ) { Box( modifier = Modifier .fillMaxSize() - .padding(it) + .padding(it), ) { when (uiState) { is LoanTransactionsUiState.ShowFetchingError -> { MifosSweetError( message = uiState.message, - onclick = onRetry + onclick = onRetry, ) } is LoanTransactionsUiState.ShowLoanTransaction -> { if (uiState.loanWithAssociations.transactions.isEmpty()) { MifosEmptyUi(text = stringResource(id = R.string.feature_loan_no_transactions)) - } else LoanTransactionsContent(uiState.loanWithAssociations.transactions) - + } else { + LoanTransactionsContent(uiState.loanWithAssociations.transactions) + } } LoanTransactionsUiState.ShowProgressBar -> { @@ -129,8 +139,8 @@ fun LoanTransactionsScreen( } @Composable -fun LoanTransactionsContent( - transactions: List +private fun LoanTransactionsContent( + transactions: List, ) { LazyColumn { items(transactions) { transaction -> @@ -140,151 +150,150 @@ fun LoanTransactionsContent( } @Composable -fun LoanTransactionsItemRow(transaction: Transaction) { - +private fun LoanTransactionsItemRow(transaction: Transaction) { val density = LocalDensity.current var showDetails by rememberSaveable { mutableStateOf(false) } - - Card( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp), - shape = RoundedCornerShape(0.dp), - onClick = { showDetails = !showDetails }, - colors = CardDefaults.cardColors( - containerColor = White - ) - ) { - Column( + Column { + Card( modifier = Modifier - .padding(horizontal = 8.dp, vertical = 10.dp) - .fillMaxWidth(), - verticalArrangement = Arrangement.Center + .fillMaxWidth() + .padding(horizontal = 16.dp), + shape = RoundedCornerShape(0.dp), + onClick = { showDetails = !showDetails }, + colors = CardDefaults.cardColors( + containerColor = White, + ), ) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically + Column( + modifier = Modifier + .padding(horizontal = 8.dp, vertical = 10.dp) + .fillMaxWidth(), + verticalArrangement = Arrangement.Center, ) { - Icon( - imageVector = if (!showDetails) MifosIcons.arrowDown else MifosIcons.arrowUp, - contentDescription = "" - ) + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + imageVector = if (!showDetails) MifosIcons.arrowDown else MifosIcons.arrowUp, + contentDescription = "", + ) - Text( - modifier = Modifier - .weight(3f) - .padding(start = 8.dp), - text = DateHelper.getDateAsString(transaction.date), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.Center - ) + Text( + modifier = Modifier + .weight(3f) + .padding(start = 8.dp), + text = DateHelper.getDateAsString(transaction.date), + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onBackground, + textAlign = TextAlign.Center, + ) - Text( - modifier = Modifier - .weight(3.3f) - .padding(start = 8.dp), - text = transaction.type?.value.toString(), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.Center - ) + Text( + modifier = Modifier + .weight(3.3f) + .padding(start = 8.dp), + text = transaction.type?.value.toString(), + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onBackground, + textAlign = TextAlign.Center, + ) - Text( - modifier = Modifier - .weight(2.7f) - .padding(start = 8.dp), - text = transaction.amount.toString(), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.End - ) + Text( + modifier = Modifier + .weight(2.7f) + .padding(start = 8.dp), + text = transaction.amount.toString(), + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onBackground, + textAlign = TextAlign.End, + ) + } } } - } - AnimatedVisibility( - visible = showDetails, - enter = slideInVertically { - with(density) { -40.dp.roundToPx() } - } + expandVertically( - expandFrom = Alignment.Top - ) + fadeIn( - initialAlpha = 0.3f - ), - exit = slideOutVertically() + shrinkVertically() + fadeOut() - ) { - LoanTransactionsItemDetailsCard(transaction = transaction) + AnimatedVisibility( + visible = showDetails, + enter = slideInVertically { + with(density) { -40.dp.roundToPx() } + } + expandVertically( + expandFrom = Alignment.Top, + ) + fadeIn( + initialAlpha = 0.3f, + ), + exit = slideOutVertically() + shrinkVertically() + fadeOut(), + ) { + LoanTransactionsItemDetailsCard(transaction = transaction) + } + HorizontalDivider(modifier = Modifier.padding(horizontal = 16.dp)) } - - HorizontalDivider(modifier = Modifier.padding(horizontal = 16.dp)) } @Composable -fun LoanTransactionsItemDetailsCard( - transaction: Transaction +private fun LoanTransactionsItemDetailsCard( + transaction: Transaction, ) { Card( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp), colors = CardDefaults.cardColors( - containerColor = Color(0xFFe7eb9a) + containerColor = Color(0xFFe7eb9a), ), elevation = CardDefaults.cardElevation(2.dp), - shape = RoundedCornerShape(0.dp) + shape = RoundedCornerShape(0.dp), ) { Column( modifier = Modifier .fillMaxWidth() - .padding(8.dp) + .padding(8.dp), ) { Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Text( text = stringResource(id = R.string.feature_loan_id), style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onBackground + color = MaterialTheme.colorScheme.onBackground, ) Text( text = transaction.id.toString(), style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onBackground + color = MaterialTheme.colorScheme.onBackground, ) } Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Text( text = stringResource(id = R.string.feature_loan_office), style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onBackground + color = MaterialTheme.colorScheme.onBackground, ) Text( text = transaction.officeName.toString(), style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onBackground + color = MaterialTheme.colorScheme.onBackground, ) } Box( modifier = Modifier .fillMaxWidth() - .padding(top = 12.dp, bottom = 8.dp) + .padding(top = 12.dp, bottom = 8.dp), ) { Text( modifier = Modifier.align(Alignment.Center), text = stringResource(id = R.string.feature_loan_break_down), style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onBackground + color = MaterialTheme.colorScheme.onBackground, ) } @@ -294,12 +303,12 @@ fun LoanTransactionsItemDetailsCard( Box( modifier = Modifier - .background(Color(0xFFdea164)) + .background(Color(0xFFdea164)), ) { Row( modifier = Modifier .fillMaxWidth() - .padding(4.dp) + .padding(4.dp), ) { Text( modifier = Modifier.weight(2.5f), @@ -307,7 +316,7 @@ fun LoanTransactionsItemDetailsCard( style = MaterialTheme.typography.bodyLarge, fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.Start + textAlign = TextAlign.Start, ) Text( @@ -316,7 +325,7 @@ fun LoanTransactionsItemDetailsCard( style = MaterialTheme.typography.bodyLarge, fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.Center + textAlign = TextAlign.Center, ) Text( @@ -325,7 +334,7 @@ fun LoanTransactionsItemDetailsCard( style = MaterialTheme.typography.bodyLarge, fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.Center + textAlign = TextAlign.Center, ) Text( @@ -334,7 +343,7 @@ fun LoanTransactionsItemDetailsCard( style = MaterialTheme.typography.bodyLarge, fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.End + textAlign = TextAlign.End, ) } } @@ -342,14 +351,14 @@ fun LoanTransactionsItemDetailsCard( Row( modifier = Modifier .fillMaxWidth() - .padding(4.dp) + .padding(4.dp), ) { Text( modifier = Modifier.weight(2.5f), text = transaction.principalPortion.toString(), style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.Start + textAlign = TextAlign.Start, ) Text( @@ -359,7 +368,7 @@ fun LoanTransactionsItemDetailsCard( text = transaction.interestPortion.toString(), style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.Center + textAlign = TextAlign.Center, ) Text( @@ -367,7 +376,7 @@ fun LoanTransactionsItemDetailsCard( text = transaction.feeChargesPortion.toString(), style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.Center + textAlign = TextAlign.Center, ) Text( @@ -377,14 +386,14 @@ fun LoanTransactionsItemDetailsCard( text = transaction.penaltyChargesPortion.toString(), style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.End + textAlign = TextAlign.End, ) } } } } -class LoanTransactionsPreviewProvider : PreviewParameterProvider { +private class LoanTransactionsPreviewProvider : PreviewParameterProvider { val transaction = Transaction( id = 23, @@ -396,8 +405,8 @@ class LoanTransactionsPreviewProvider : PreviewParameterProvider @@ -417,21 +426,20 @@ class LoanTransactionsPreviewProvider : PreviewParameterProvider(LoanTransactionsUiState.ShowProgressBar) val loanTransactionsUiState: StateFlow get() = _loanTransactionsUiState - fun loadLoanTransaction(loanId : Int) { + fun loadLoanTransaction(loanId: Int) { _loanTransactionsUiState.value = LoanTransactionsUiState.ShowProgressBar repository.getLoanTransactions(loanId) .observeOn(AndroidSchedulers.mainThread()) @@ -46,4 +55,4 @@ class LoanTransactionsViewModel @Inject constructor( } }) } -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/loan_charge/LoanChargeUiState.kt b/feature/loan/src/main/java/com/mifos/feature/loan/loan_charge/LoanChargeUiState.kt deleted file mode 100644 index 139166ad67d..00000000000 --- a/feature/loan/src/main/java/com/mifos/feature/loan/loan_charge/LoanChargeUiState.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.mifos.feature.loan.loan_charge - -import com.mifos.core.objects.client.Charges - -/** - * Created by Aditya Gupta on 10/08/23. - */ -sealed class LoanChargeUiState { - - data object Loading : LoanChargeUiState() - - data class Error(val message: Int) : LoanChargeUiState() - - data class LoanChargesList(val loanCharges: List) : LoanChargeUiState() -} \ No newline at end of file diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/navigation/LoanNavigation.kt b/feature/loan/src/main/java/com/mifos/feature/loan/navigation/LoanNavigation.kt index 76fbab3b893..57076b21da6 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/navigation/LoanNavigation.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/navigation/LoanNavigation.kt @@ -1,3 +1,12 @@ +/* + * 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.loan.navigation import androidx.navigation.NavController @@ -10,15 +19,15 @@ import com.mifos.core.common.utils.Constants import com.mifos.core.data.LoansPayload import com.mifos.core.objects.accounts.loan.LoanWithAssociations import com.mifos.core.objects.noncore.DataTable -import com.mifos.feature.loan.group_loan_account.GroupLoanAccountScreen -import com.mifos.feature.loan.loan_account.LoanAccountScreen -import com.mifos.feature.loan.loan_account_summary.LoanAccountSummaryScreen -import com.mifos.feature.loan.loan_approval.LoanAccountApprovalScreen -import com.mifos.feature.loan.loan_charge.LoanChargeScreen -import com.mifos.feature.loan.loan_disbursement.LoanAccountDisbursementScreen -import com.mifos.feature.loan.loan_repayment.LoanRepaymentScreen -import com.mifos.feature.loan.loan_repayment_schedule.LoanRepaymentScheduleScreen -import com.mifos.feature.loan.loan_transaction.LoanTransactionsScreen +import com.mifos.feature.loan.groupLoanAccount.GroupLoanAccountScreen +import com.mifos.feature.loan.loanAccount.LoanAccountScreen +import com.mifos.feature.loan.loanAccountSummary.LoanAccountSummaryScreen +import com.mifos.feature.loan.loanApproval.LoanAccountApprovalScreen +import com.mifos.feature.loan.loanCharge.LoanChargeScreen +import com.mifos.feature.loan.loanDisbursement.LoanAccountDisbursementScreen +import com.mifos.feature.loan.loanRepayment.LoanRepaymentScreen +import com.mifos.feature.loan.loanRepaymentSchedule.LoanRepaymentScheduleScreen +import com.mifos.feature.loan.loanTransaction.LoanTransactionsScreen /** * Created by Pronay Sarker on 16/08/2024 (2:24 AM) @@ -27,11 +36,11 @@ import com.mifos.feature.loan.loan_transaction.LoanTransactionsScreen fun NavGraphBuilder.loanNavGraph( navController: NavController, onDocumentsClicked: (Int, String) -> Unit, - onMoreInfoClicked: (String, Int) -> Unit + onMoreInfoClicked: (String, Int) -> Unit, ) { navigation( startDestination = LoanScreens.LoanAccountSummaryScreen.route, - route = "loan_route" + route = "loan_route", ) { loanAccountSummary( onBackPressed = navController::popBackStack, @@ -42,7 +51,7 @@ fun NavGraphBuilder.loanNavGraph( onChargesClicked = navController::navigateToLoanChargesScreen, approveLoan = navController::navigateToLoanApprovalScreen, disburseLoan = navController::navigateToLoanDisbursementScreen, - onRepaymentClick = navController::navigateToLoanRepaymentScreen + onRepaymentClick = navController::navigateToLoanRepaymentScreen, ) loanDisbursementScreen { @@ -60,20 +69,20 @@ fun NavGraphBuilder.loanNavGraph( loanChargeScreen { navController.popBackStack() } - loanRepaymentScreen{ + loanRepaymentScreen { navController.popBackStack() } } } fun NavGraphBuilder.groupLoanScreen( - onBackPressed: () -> Unit + onBackPressed: () -> Unit, ) { composable( route = LoanScreens.GroupLoanScreen.route, arguments = listOf( - navArgument(name = Constants.GROUP_ID, builder = { type = NavType.IntType }) - ) + navArgument(name = Constants.GROUP_ID, builder = { type = NavType.IntType }), + ), ) { GroupLoanAccountScreen( onBackPressed = onBackPressed, @@ -83,17 +92,17 @@ fun NavGraphBuilder.groupLoanScreen( fun NavGraphBuilder.addLoanAccountScreen( onBackPressed: () -> Unit, - dataTable: (List, LoansPayload) -> Unit + dataTable: (List, LoansPayload) -> Unit, ) { composable( route = LoanScreens.LoanAccountScreen.route, arguments = listOf( - navArgument(name = Constants.CLIENT_ID, builder = { type = NavType.IntType }) - ) + navArgument(name = Constants.CLIENT_ID, builder = { type = NavType.IntType }), + ), ) { LoanAccountScreen( onBackPressed = onBackPressed, - dataTable = dataTable + dataTable = dataTable, ) } } @@ -107,13 +116,13 @@ fun NavGraphBuilder.loanAccountSummary( onChargesClicked: (Int) -> Unit, approveLoan: (loadId: Int, loanWithAssociations: LoanWithAssociations) -> Unit, disburseLoan: (Int) -> Unit, - onRepaymentClick: (LoanWithAssociations) -> Unit + onRepaymentClick: (LoanWithAssociations) -> Unit, ) { composable( route = LoanScreens.LoanAccountSummaryScreen.route, arguments = listOf( - navArgument(name = Constants.LOAN_ACCOUNT_NUMBER, builder = { type = NavType.IntType }) - ) + navArgument(name = Constants.LOAN_ACCOUNT_NUMBER, builder = { type = NavType.IntType }), + ), ) { LoanAccountSummaryScreen( navigateBack = onBackPressed, @@ -124,98 +133,98 @@ fun NavGraphBuilder.loanAccountSummary( onChargesClicked = onChargesClicked, approveLoan = approveLoan, disburseLoan = disburseLoan, - onRepaymentClick = onRepaymentClick + onRepaymentClick = onRepaymentClick, ) } } fun NavGraphBuilder.loanApprovalScreen( - onBackPressed: () -> Unit + onBackPressed: () -> Unit, ) { composable( route = LoanScreens.LoanApprovalScreen.route, arguments = listOf( - navArgument(name = "arg", builder = { type = NavType.StringType }) - ) + navArgument(name = "arg", builder = { type = NavType.StringType }), + ), ) { LoanAccountApprovalScreen( - navigateBack = onBackPressed + navigateBack = onBackPressed, ) } } fun NavGraphBuilder.loanChargeScreen( - onBackPressed: () -> Unit + onBackPressed: () -> Unit, ) { composable( route = LoanScreens.LoanChargeScreen.route, arguments = listOf( - navArgument(name = Constants.LOAN_ACCOUNT_NUMBER, builder = { type = NavType.IntType }) - ) + navArgument(name = Constants.LOAN_ACCOUNT_NUMBER, builder = { type = NavType.IntType }), + ), ) { LoanChargeScreen( - onBackPressed = onBackPressed + onBackPressed = onBackPressed, ) } } fun NavGraphBuilder.loanDisbursementScreen( - onBackPressed: () -> Unit + onBackPressed: () -> Unit, ) { composable( route = LoanScreens.LoanDisbursementScreen.route, arguments = listOf( - navArgument(name = Constants.LOAN_ACCOUNT_NUMBER, builder = { type = NavType.IntType }) - ) + navArgument(name = Constants.LOAN_ACCOUNT_NUMBER, builder = { type = NavType.IntType }), + ), ) { LoanAccountDisbursementScreen( - navigateBack = onBackPressed + navigateBack = onBackPressed, ) } } fun NavGraphBuilder.loanRepaymentScreen( - onBackPressed: () -> Unit + onBackPressed: () -> Unit, ) { composable( route = LoanScreens.LoanRepaymentScreen.route, arguments = listOf( - navArgument(name = Constants.LOAN_WITH_ASSOCIATIONS , builder = { type = NavType.StringType }) - ) + navArgument(name = Constants.LOAN_WITH_ASSOCIATIONS, builder = { type = NavType.StringType }), + ), ) { LoanRepaymentScreen( - navigateBack = onBackPressed + navigateBack = onBackPressed, ) } } fun NavGraphBuilder.loanRepaymentSchedule( - onBackPressed: () -> Unit + onBackPressed: () -> Unit, ) { composable( route = LoanScreens.LoanRepaymentSchedule.route, arguments = listOf( - navArgument(name = Constants.LOAN_ACCOUNT_NUMBER, builder = { type = NavType.IntType }) - ) + navArgument(name = Constants.LOAN_ACCOUNT_NUMBER, builder = { type = NavType.IntType }), + ), ) { LoanRepaymentScheduleScreen( - navigateBack = onBackPressed + navigateBack = onBackPressed, ) } } fun NavGraphBuilder.loanTransactionScreen( - onBackPressed: () -> Unit + onBackPressed: () -> Unit, ) { composable( route = LoanScreens.LoanTransactionScreen.route, arguments = listOf( - navArgument(name = Constants.LOAN_ACCOUNT_NUMBER, builder = { type = NavType.IntType }) - ) + navArgument(name = Constants.LOAN_ACCOUNT_NUMBER, builder = { type = NavType.IntType }), + ), ) { LoanTransactionsScreen( - navigateBack = onBackPressed + navigateBack = onBackPressed, ) } } @@ -246,7 +255,7 @@ fun NavController.navigateToLoanChargesScreen(loanAccountNumber: Int) { fun NavController.navigateToLoanApprovalScreen( loanId: Int, - loanWithAssociations: LoanWithAssociations + loanWithAssociations: LoanWithAssociations, ) { navigate(LoanScreens.LoanApprovalScreen.argument(loanId, loanWithAssociations)) } @@ -255,6 +264,6 @@ fun NavController.navigateToLoanRepaymentScreen(loanWithAssociations: LoanWithAs navigate(LoanScreens.LoanRepaymentScreen.argument(loanWithAssociations)) } -fun NavController.navigateToGroupLoanScreen(groupId : Int){ +fun NavController.navigateToGroupLoanScreen(groupId: Int) { navigate(LoanScreens.GroupLoanScreen.argument(groupId)) -} \ No newline at end of file +} diff --git a/feature/loan/src/main/java/com/mifos/feature/loan/navigation/LoanScreens.kt b/feature/loan/src/main/java/com/mifos/feature/loan/navigation/LoanScreens.kt index bc4418a217b..8773d45fe5a 100644 --- a/feature/loan/src/main/java/com/mifos/feature/loan/navigation/LoanScreens.kt +++ b/feature/loan/src/main/java/com/mifos/feature/loan/navigation/LoanScreens.kt @@ -1,3 +1,12 @@ +/* + * 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.loan.navigation import com.google.gson.Gson @@ -10,16 +19,16 @@ import com.mifos.core.objects.accounts.loan.LoanWithAssociations */ sealed class LoanScreens(val route: String) { - data object LoanAccountScreen : LoanScreens("loan_account_screen/{${Constants.CLIENT_ID}}"){ - fun argument(clientId : Int) = "loan_account_screen/$clientId" + data object LoanAccountScreen : LoanScreens("loan_account_screen/{${Constants.CLIENT_ID}}") { + fun argument(clientId: Int) = "loan_account_screen/$clientId" } - data object LoanAccountSummaryScreen : LoanScreens("loan_account_summary_screen/{${Constants.LOAN_ACCOUNT_NUMBER}}"){ - fun argument(loanAccountNumber : Int) = "loan_account_summary_screen/$loanAccountNumber" + data object LoanAccountSummaryScreen : LoanScreens("loan_account_summary_screen/{${Constants.LOAN_ACCOUNT_NUMBER}}") { + fun argument(loanAccountNumber: Int) = "loan_account_summary_screen/$loanAccountNumber" } - data object LoanApprovalScreen : LoanScreens("loan_approval_screen/{arg}"){ - fun argument(loanAccountNumber: Int, loanWithAssociations: LoanWithAssociations) : String{ + data object LoanApprovalScreen : LoanScreens("loan_approval_screen/{arg}") { + fun argument(loanAccountNumber: Int, loanWithAssociations: LoanWithAssociations): String { val gson = Gson() val arg = LoanApprovalData(loanAccountNumber, loanWithAssociations) val loanApprovalDataInJson = gson.toJson(arg) @@ -28,16 +37,16 @@ sealed class LoanScreens(val route: String) { } } - data object LoanChargeScreen : LoanScreens("loan_charge_screen/{${Constants.LOAN_ACCOUNT_NUMBER}}"){ - fun argument(loanAccountNumber : Int) = "loan_charge_screen/$loanAccountNumber" + data object LoanChargeScreen : LoanScreens("loan_charge_screen/{${Constants.LOAN_ACCOUNT_NUMBER}}") { + fun argument(loanAccountNumber: Int) = "loan_charge_screen/$loanAccountNumber" } - data object LoanDisbursementScreen : LoanScreens("loan_disbursement_screen/{${Constants.LOAN_ACCOUNT_NUMBER}}"){ - fun argument(loanAccountNumber : Int) = "loan_disbursement_screen/$loanAccountNumber" + data object LoanDisbursementScreen : LoanScreens("loan_disbursement_screen/{${Constants.LOAN_ACCOUNT_NUMBER}}") { + fun argument(loanAccountNumber: Int) = "loan_disbursement_screen/$loanAccountNumber" } - data object LoanRepaymentScreen : LoanScreens("loan_repayment_screen/{${Constants.LOAN_WITH_ASSOCIATIONS}}"){ - fun argument(loanWithAssociations: LoanWithAssociations) : String { + data object LoanRepaymentScreen : LoanScreens("loan_repayment_screen/{${Constants.LOAN_WITH_ASSOCIATIONS}}") { + fun argument(loanWithAssociations: LoanWithAssociations): String { val gson = Gson() val loanWithAssociationsInJson = gson.toJson(loanWithAssociations) @@ -45,15 +54,15 @@ sealed class LoanScreens(val route: String) { } } - data object LoanRepaymentSchedule : LoanScreens("loan_repayment_schedule/{${Constants.LOAN_ACCOUNT_NUMBER}}"){ - fun argument(loanAccountNumber : Int) = "loan_repayment_schedule/$loanAccountNumber" + data object LoanRepaymentSchedule : LoanScreens("loan_repayment_schedule/{${Constants.LOAN_ACCOUNT_NUMBER}}") { + fun argument(loanAccountNumber: Int) = "loan_repayment_schedule/$loanAccountNumber" } - data object LoanTransactionScreen : LoanScreens("loan_transaction_screen/{${Constants.LOAN_ACCOUNT_NUMBER}}"){ - fun argument(loanAccountNumber : Int) = "loan_transaction_screen/$loanAccountNumber" + data object LoanTransactionScreen : LoanScreens("loan_transaction_screen/{${Constants.LOAN_ACCOUNT_NUMBER}}") { + fun argument(loanAccountNumber: Int) = "loan_transaction_screen/$loanAccountNumber" } - data object GroupLoanScreen : LoanScreens("group_loan_screen/{${Constants.GROUP_ID}}"){ - fun argument(groupId : Int) = "group_loan_screen/$groupId" + data object GroupLoanScreen : LoanScreens("group_loan_screen/{${Constants.GROUP_ID}}") { + fun argument(groupId: Int) = "group_loan_screen/$groupId" } -} \ No newline at end of file +} diff --git a/feature/loan/src/main/res/values/strings.xml b/feature/loan/src/main/res/values/strings.xml index c6a7cc4b50e..6b24d1f1e61 100644 --- a/feature/loan/src/main/res/values/strings.xml +++ b/feature/loan/src/main/res/values/strings.xml @@ -1,4 +1,13 @@ + Loan Application Loan account created successfully diff --git a/feature/loan/src/test/java/com/mifos/feature/loan/ExampleUnitTest.kt b/feature/loan/src/test/java/com/mifos/feature/loan/ExampleUnitTest.kt index c189c45bb94..da1e691eb1e 100644 --- a/feature/loan/src/test/java/com/mifos/feature/loan/ExampleUnitTest.kt +++ b/feature/loan/src/test/java/com/mifos/feature/loan/ExampleUnitTest.kt @@ -1,9 +1,17 @@ +/* + * 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.loan +import org.junit.Assert.assertEquals import org.junit.Test -import org.junit.Assert.* - /** * Example local unit test, which will execute on the development machine (host). * @@ -14,4 +22,4 @@ class ExampleUnitTest { fun addition_isCorrect() { assertEquals(4, 2 + 2) } -} \ No newline at end of file +} diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/loanaccount/LoanAccountFragment.kt b/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/loanaccount/LoanAccountFragment.kt index 3089b3a7286..dab99e2d06b 100644 --- a/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/loanaccount/LoanAccountFragment.kt +++ b/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/loanaccount/LoanAccountFragment.kt @@ -12,13 +12,9 @@ import androidx.appcompat.app.AppCompatActivity import androidx.compose.ui.platform.ComposeView import androidx.fragment.app.Fragment import androidx.navigation.findNavController -import androidx.navigation.fragment.navArgs -import com.mifos.core.common.utils.Constants import com.mifos.core.data.LoansPayload import com.mifos.core.objects.noncore.DataTable -import com.mifos.feature.loan.loan_account.LoanAccountScreen -import com.mifos.mifosxdroid.R -import com.mifos.utils.FragmentConstants +import com.mifos.feature.loan.loanAccount.LoanAccountScreen import dagger.hilt.android.AndroidEntryPoint /**