diff --git a/core/common/src/commonMain/kotlin/com/mifos/core/common/utils/ServerConfig.kt b/core/common/src/commonMain/kotlin/com/mifos/core/common/utils/ServerConfig.kt index 83aa2cf0ad2..b753897ee43 100644 --- a/core/common/src/commonMain/kotlin/com/mifos/core/common/utils/ServerConfig.kt +++ b/core/common/src/commonMain/kotlin/com/mifos/core/common/utils/ServerConfig.kt @@ -31,7 +31,7 @@ data class ServerConfig( endPoint = "tt.mifos.community", apiPath = "/fineract-provider/api/v1/", port = "80", - tenant = "default", + tenant = "dev", ) val LOCALHOST = ServerConfig( diff --git a/core/network/src/commonMain/kotlin/com/mifos/core/network/model/share/ShareTemplate.kt b/core/network/src/commonMain/kotlin/com/mifos/core/network/model/share/ShareTemplate.kt index 902dcfbc9e4..c6bc3d364ac 100644 --- a/core/network/src/commonMain/kotlin/com/mifos/core/network/model/share/ShareTemplate.kt +++ b/core/network/src/commonMain/kotlin/com/mifos/core/network/model/share/ShareTemplate.kt @@ -9,6 +9,10 @@ */ package com.mifos.core.network.model.share +import com.mifos.core.model.objects.template.client.ChargeAppliesTo +import com.mifos.core.model.objects.template.client.ChargeCalculationType +import com.mifos.core.model.objects.template.client.ChargePaymentMode +import com.mifos.core.model.objects.template.client.ChargeTimeType import com.mifos.core.model.objects.template.client.Currency import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -25,6 +29,8 @@ data class ShareTemplate( val productOptions: List = emptyList(), + val chargeOptions: List = emptyList(), + @SerialName("clientSavingsAccounts") val savingsAccountOptions: List? = emptyList(), @@ -52,3 +58,17 @@ data class FrequencyTypeOption( val value: String, ) + +@Serializable +data class ChargeOptions( + val id: Int? = null, + val name: String? = null, + val active: Boolean? = null, + val penalty: Boolean? = null, + val currency: Currency? = null, + val amount: Double? = null, + val chargeTimeType: ChargeTimeType? = null, + val chargeAppliesTo: ChargeAppliesTo? = null, + val chargeCalculationType: ChargeCalculationType? = null, + val chargePaymentMode: ChargePaymentMode? = null, +) diff --git a/core/ui/src/commonMain/kotlin/com/mifos/core/ui/components/AddChargeDialog.kt b/core/ui/src/commonMain/kotlin/com/mifos/core/ui/components/AddChargeDialog.kt index 04c563aea06..5617edc5cdf 100644 --- a/core/ui/src/commonMain/kotlin/com/mifos/core/ui/components/AddChargeDialog.kt +++ b/core/ui/src/commonMain/kotlin/com/mifos/core/ui/components/AddChargeDialog.kt @@ -50,9 +50,9 @@ fun AddChargeBottomSheet( title: String, confirmText: String, dismissText: String, - showDatePicker: Boolean, + showDatePicker: Boolean = false, selectedChargeName: String, - selectedDate: String, + selectedDate: String? = null, chargeAmount: String, chargeType: String, chargeCollectedOn: String, @@ -109,13 +109,15 @@ fun AddChargeBottomSheet( label = stringResource(Res.string.name), ) - MifosDatePickerTextField( - value = selectedDate, - label = stringResource(Res.string.date), - openDatePicker = { onDatePick(true) }, - ) + if (selectedDate != null) { + MifosDatePickerTextField( + value = selectedDate, + label = stringResource(Res.string.date), + openDatePicker = { onDatePick(true) }, + ) - Spacer(Modifier.height(DesignToken.padding.large)) + Spacer(Modifier.height(DesignToken.padding.large)) + } MifosOutlinedTextField( value = chargeAmount, @@ -161,7 +163,7 @@ fun AddChargeBottomSheet( secondBtnText = confirmText, onFirstBtnClick = onDismiss, onSecondBtnClick = onConfirm, - isSecondButtonEnabled = chargeAmount.isNotEmpty() && chargeType.isNotEmpty() && amountError.isNullOrEmpty(), + isSecondButtonEnabled = chargeAmount.isNotEmpty() && amountError.isNullOrEmpty(), ) } }, diff --git a/core/ui/src/commonMain/kotlin/com/mifos/core/ui/components/MifosActionsListingCardComponent.kt b/core/ui/src/commonMain/kotlin/com/mifos/core/ui/components/MifosActionsListingCardComponent.kt index 52b379c1bbd..668c34d9ba5 100644 --- a/core/ui/src/commonMain/kotlin/com/mifos/core/ui/components/MifosActionsListingCardComponent.kt +++ b/core/ui/src/commonMain/kotlin/com/mifos/core/ui/components/MifosActionsListingCardComponent.kt @@ -599,7 +599,7 @@ fun MifosActionsShareListingComponent( fun MifosActionsChargeListingComponent( chargeTitle: String, type: String, - date: String, + date: String? = null, collectedOn: String, amount: String, menuList: List = listOf( @@ -642,11 +642,15 @@ fun MifosActionsChargeListingComponent( text = type, ), ) - PrintTextUtil( - TextUtil( - text = date, - ), - ) + if ( + date != null + ) { + PrintTextUtil( + TextUtil( + text = date, + ), + ) + } } Row( verticalAlignment = Alignment.CenterVertically, diff --git a/feature/client/src/commonMain/composeResources/values/strings.xml b/feature/client/src/commonMain/composeResources/values/strings.xml index c50f5cab4a4..fa6cdbf282a 100644 --- a/feature/client/src/commonMain/composeResources/values/strings.xml +++ b/feature/client/src/commonMain/composeResources/values/strings.xml @@ -569,6 +569,19 @@ Type Lock-in Period + Charge + Add New + View + Active Charge + Add New Charge + Date + Type + Collected On + View Charges + Edit Charge + Add + Add + This field cannot be empty diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/CreateShareAccountScreen.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/CreateShareAccountScreen.kt index 7bc5ba55b3f..f5524136a69 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/CreateShareAccountScreen.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/CreateShareAccountScreen.kt @@ -10,25 +10,44 @@ package com.mifos.feature.client.createShareAccount import androidclient.feature.client.generated.resources.Res +import androidclient.feature.client.generated.resources.feature_share_account_back +import androidclient.feature.client.generated.resources.feature_share_account_charge_add +import androidclient.feature.client.generated.resources.feature_share_account_charge_add_new_charge +import androidclient.feature.client.generated.resources.feature_share_account_charge_btn_add_new +import androidclient.feature.client.generated.resources.feature_share_account_charge_edit_charge +import androidclient.feature.client.generated.resources.feature_share_account_charge_view_charges import androidclient.feature.client.generated.resources.feature_share_account_charges import androidclient.feature.client.generated.resources.feature_share_account_details import androidclient.feature.client.generated.resources.feature_share_account_preview import androidclient.feature.client.generated.resources.feature_share_account_terms +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavController +import com.mifos.core.designsystem.component.MifosBottomSheet import com.mifos.core.designsystem.component.MifosScaffold import com.mifos.core.designsystem.component.MifosSweetError +import com.mifos.core.designsystem.theme.DesignToken +import com.mifos.core.designsystem.theme.MifosTypography +import com.mifos.core.ui.components.Actions +import com.mifos.core.ui.components.AddChargeBottomSheet +import com.mifos.core.ui.components.MifosActionsChargeListingComponent import com.mifos.core.ui.components.MifosBreadcrumbNavBar import com.mifos.core.ui.components.MifosProgressIndicator +import com.mifos.core.ui.components.MifosProgressIndicatorOverlay import com.mifos.core.ui.components.MifosStepper +import com.mifos.core.ui.components.MifosTwoButtonRow import com.mifos.core.ui.components.Step import com.mifos.core.ui.util.EventsEffect import com.mifos.feature.client.createShareAccount.pages.ChargesPage @@ -50,8 +69,8 @@ internal fun CreateShareAccountScreen( EventsEffect(viewModel.eventFlow) { event -> when (event) { - ShareAccountEvent.NavigateBack -> onNavigateBack() - ShareAccountEvent.Finish -> onFinish() + CreateShareAccountEvent.NavigateBack -> onNavigateBack() + CreateShareAccountEvent.Finish -> onFinish() } } @@ -61,13 +80,44 @@ internal fun CreateShareAccountScreen( onAction = { viewModel.trySendAction(it) }, navController = navController, ) + + CreateShareAccountDialog( + state = state, + onAction = { viewModel.trySendAction(it) }, + ) +} + +@Composable +fun CreateShareAccountDialog( + state: CreateShareAccountState, + onAction: (CreateShareAccountAction) -> Unit, +) { + when (state.dialogState) { + is CreateShareAccountState.DialogState.AddNewCharge -> { + AddNewChargeDialog( + isEdit = state.dialogState.edit, + index = state.dialogState.index, + state = state, + onAction = onAction, + ) + } + + CreateShareAccountState.DialogState.ShowCharges -> { + ShowChargesDialog( + state = state, + onAction = onAction, + ) + } + + null -> Unit + } } @Composable private fun CreateShareAccountContent( - state: ShareAccountState, + state: CreateShareAccountState, modifier: Modifier = Modifier, - onAction: (ShareAccountAction) -> Unit, + onAction: (CreateShareAccountAction) -> Unit, navController: NavController, ) { val steps = listOf( @@ -85,12 +135,13 @@ private fun CreateShareAccountContent( }, Step(name = stringResource(Res.string.feature_share_account_charges)) { ChargesPage( - onNext = { onAction(ShareAccountAction.NextStep) }, + state = state, + onAction = onAction, ) }, Step(name = stringResource(Res.string.feature_share_account_preview)) { PreviewPage( - onNext = { onAction(ShareAccountAction.Finish) }, + onNext = { onAction(CreateShareAccountAction.Finish) }, ) }, ) @@ -99,8 +150,8 @@ private fun CreateShareAccountContent( modifier = modifier, ) { paddingValues -> when (state.screenState) { - is ShareAccountState.ScreenState.Loading -> MifosProgressIndicator() - is ShareAccountState.ScreenState.Success -> { + is CreateShareAccountState.ScreenState.Loading -> MifosProgressIndicator() + is CreateShareAccountState.ScreenState.Success -> { Column( Modifier.fillMaxSize().padding(paddingValues), ) { @@ -111,7 +162,7 @@ private fun CreateShareAccountContent( steps = steps, currentIndex = state.currentStep, onStepChange = { newIndex -> - onAction(ShareAccountAction.OnStepChange(newIndex)) + onAction(CreateShareAccountAction.OnStepChange(newIndex)) }, modifier = Modifier .fillMaxWidth().align(Alignment.CenterHorizontally), @@ -119,12 +170,140 @@ private fun CreateShareAccountContent( } } - is ShareAccountState.ScreenState.Error -> { + is CreateShareAccountState.ScreenState.Error -> { MifosSweetError( message = state.screenState.message, - onclick = { onAction(ShareAccountAction.Retry) }, + onclick = { onAction(CreateShareAccountAction.Retry) }, ) } } + + if (state.isOverLayLoadingActive) { + MifosProgressIndicatorOverlay() + } } } + +@Composable +private fun AddNewChargeDialog( + isEdit: Boolean, + index: Int = -1, + state: CreateShareAccountState, + onAction: (CreateShareAccountAction) -> Unit, +) { + AddChargeBottomSheet( + title = if (isEdit) { + stringResource(Res.string.feature_share_account_charge_edit_charge) + } else { + stringResource(Res.string.feature_share_account_charge_add_new_charge) + }, + confirmText = if (isEdit) { + stringResource(Res.string.feature_share_account_charge_edit_charge) + } else { + stringResource(Res.string.feature_share_account_charge_add) + }, + dismissText = stringResource(Res.string.feature_share_account_back), + selectedChargeName = if (state.chooseChargeIndex == null) { + "" + } else { + state.chargeOptions[state.chooseChargeIndex].name ?: "" + }, + chargeAmount = state.chargeAmount, + chargeType = if (state.chooseChargeIndex == null) { + "" + } else { + state.chargeOptions[state.chooseChargeIndex].chargeCalculationType?.value + ?: "" + }, + chargeCollectedOn = if (state.chooseChargeIndex == null) { + "" + } else { + state.chargeOptions[state.chooseChargeIndex].chargeTimeType?.value + ?: "" + }, + chargeOptions = state.chargeOptions.map { it.name ?: "" }, + onConfirm = { + if (isEdit) { + onAction(CreateShareAccountAction.EditCharge(index)) + } else { + onAction(CreateShareAccountAction.AddChargeToList) + } + }, + onDismiss = { onAction(CreateShareAccountAction.OnDismissDialog) }, + onChargeSelected = { index, _ -> + onAction(CreateShareAccountAction.OnChooseChargeIndexChange(index)) + }, + onDatePick = {}, + onDateChange = {}, + onAmountChange = { amount -> + onAction(CreateShareAccountAction.OnChargeAmountChange(amount)) + }, + ) +} + +@Composable +private fun ShowChargesDialog( + state: CreateShareAccountState, + onAction: (CreateShareAccountAction) -> Unit, +) { + var expandedIndex: Int? by rememberSaveable { mutableStateOf(-1) } + + MifosBottomSheet( + onDismiss = { + onAction(CreateShareAccountAction.OnDismissDialog) + }, + content = { + Column( + modifier = Modifier.fillMaxWidth().padding(DesignToken.padding.large), + verticalArrangement = Arrangement.spacedBy(DesignToken.padding.largeIncreased), + ) { + Text( + text = stringResource(Res.string.feature_share_account_charge_view_charges), + style = MifosTypography.titleMediumEmphasized, + ) + state.addedCharges.forEachIndexed { index, charge -> + val chargesValue = state.chargeOptions + .firstOrNull { it.id == charge.chargeId } + MifosActionsChargeListingComponent( + chargeTitle = chargesValue?.name ?: "", + type = chargesValue?.chargeCalculationType?.value ?: "", + collectedOn = chargesValue?.chargeTimeType?.value ?: "", + amount = charge.amount.toString(), + onActionClicked = { action -> + when (action) { + is Actions.Delete -> { + onAction( + CreateShareAccountAction.DeleteChargeFromSelectedCharges( + index, + ), + ) + } + + is Actions.Edit -> { + onAction(CreateShareAccountAction.EditChargeDialog(index)) + } + + else -> {} + } + }, + isExpanded = expandedIndex == index, + onExpandToggle = { + expandedIndex = if (expandedIndex == index) -1 else index + }, + ) + } + } + + MifosTwoButtonRow( + firstBtnText = stringResource(Res.string.feature_share_account_back), + secondBtnText = stringResource(Res.string.feature_share_account_charge_btn_add_new), + onFirstBtnClick = { + onAction(CreateShareAccountAction.OnDismissDialog) + }, + onSecondBtnClick = { + onAction(CreateShareAccountAction.ShowAddChargeDialog) + }, + ) + }, + ) +} diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/CreateShareAccountViewModel.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/CreateShareAccountViewModel.kt index a9251042d8f..0a2c64a088c 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/CreateShareAccountViewModel.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/CreateShareAccountViewModel.kt @@ -18,11 +18,13 @@ import com.mifos.core.common.utils.DataState import com.mifos.core.common.utils.DateHelper import com.mifos.core.data.repository.ShareAccountRepository import com.mifos.core.data.util.NetworkMonitor +import com.mifos.core.network.model.share.ChargeOptions import com.mifos.core.network.model.share.FrequencyTypeOption import com.mifos.core.network.model.share.ProductOption import com.mifos.core.network.model.share.SavingsAccountOption import com.mifos.core.ui.util.BaseViewModel import com.mifos.core.ui.util.TextFieldsValidator +import com.mifos.feature.loan.newLoanAccount.NewLoanAccountState.DialogState import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @@ -36,8 +38,8 @@ class CreateShareAccountViewModel( private val networkMonitor: NetworkMonitor, val savedStateHandle: SavedStateHandle, -) : BaseViewModel - (ShareAccountState()) { +) : BaseViewModel + (CreateShareAccountState()) { val route = savedStateHandle.toRoute() @@ -45,7 +47,7 @@ class CreateShareAccountViewModel( loadShareTemplate(route.clientId) } - private fun loadShareTemplateFromProduct(client: Int, productId: Int) { + private fun loadShareTemplateFromProduct(client: Int, productId: Int?) { viewModelScope.launch { val online = networkMonitor.isOnline.first() if (online) { @@ -54,7 +56,10 @@ class CreateShareAccountViewModel( is DataState.Error -> { mutableStateFlow.update { it.copy( - screenState = ShareAccountState.ScreenState.Error(dataState.message), + screenState = CreateShareAccountState.ScreenState.Error( + dataState.message, + ), + isOverLayLoadingActive = false, ) } } @@ -62,7 +67,7 @@ class CreateShareAccountViewModel( DataState.Loading -> { mutableStateFlow.update { it.copy( - screenState = ShareAccountState.ScreenState.Loading, + isOverLayLoadingActive = true, ) } } @@ -70,12 +75,13 @@ class CreateShareAccountViewModel( is DataState.Success -> { mutableStateFlow.update { it.copy( - screenState = ShareAccountState.ScreenState.Success, + screenState = CreateShareAccountState.ScreenState.Success, currency = dataState.data.currency?.name, currentPrice = dataState.data.currentMarketPrice?.toString(), savingsAccountOptions = dataState.data.savingsAccountOptions.orEmpty(), lockInPeriodFrequencyTypeOptions = dataState.data.lockinPeriodFrequencyTypeOptions.orEmpty(), minimumActivePeriodFrequencyTypeOptions = dataState.data.minimumActivePeriodFrequencyTypeOptions.orEmpty(), + isOverLayLoadingActive = false, ) } } @@ -84,7 +90,7 @@ class CreateShareAccountViewModel( } else { mutableStateFlow.update { it.copy( - screenState = ShareAccountState.ScreenState.Error(getString(Res.string.feature_client_error_network_not_available)), + screenState = CreateShareAccountState.ScreenState.Error(getString(Res.string.feature_client_error_network_not_available)), ) } } @@ -100,7 +106,9 @@ class CreateShareAccountViewModel( is DataState.Error -> { mutableStateFlow.update { it.copy( - screenState = ShareAccountState.ScreenState.Error(dataState.message), + screenState = CreateShareAccountState.ScreenState.Error( + dataState.message, + ), ) } } @@ -108,7 +116,7 @@ class CreateShareAccountViewModel( DataState.Loading -> { mutableStateFlow.update { it.copy( - screenState = ShareAccountState.ScreenState.Loading, + screenState = CreateShareAccountState.ScreenState.Loading, ) } } @@ -116,8 +124,9 @@ class CreateShareAccountViewModel( is DataState.Success -> { mutableStateFlow.update { it.copy( - screenState = ShareAccountState.ScreenState.Success, + screenState = CreateShareAccountState.ScreenState.Success, productOption = dataState.data.productOptions, + chargeOptions = dataState.data.chargeOptions, ) } } @@ -126,7 +135,7 @@ class CreateShareAccountViewModel( } else { mutableStateFlow.update { it.copy( - screenState = ShareAccountState.ScreenState.Error(getString(Res.string.feature_client_error_network_not_available)), + screenState = CreateShareAccountState.ScreenState.Error(getString(Res.string.feature_client_error_network_not_available)), ) } } @@ -161,9 +170,8 @@ class CreateShareAccountViewModel( ) } } else { - state.selectedProduct?.id?.let { productId -> - loadShareTemplateFromProduct(client = route.clientId, productId = productId) - } + loadShareTemplateFromProduct(client = route.clientId, productId = state.productId) + moveToNextStep() } } @@ -190,7 +198,9 @@ class CreateShareAccountViewModel( hasError = true } if (state.minActivePeriodFreqTypeIdx == null) { - newState = newState.copy(minActivePeriodFreqTypeError = TextFieldsValidator.stringValidator("")) + newState = newState.copy( + minActivePeriodFreqTypeError = TextFieldsValidator.stringValidator(""), + ) hasError = true } } @@ -202,7 +212,8 @@ class CreateShareAccountViewModel( hasError = true } if (state.lockInPeriodFreqTypeIdx == null) { - newState = newState.copy(lockInPeriodFreqTypeError = TextFieldsValidator.stringValidator("")) + newState = + newState.copy(lockInPeriodFreqTypeError = TextFieldsValidator.stringValidator("")) hasError = true } } @@ -214,25 +225,25 @@ class CreateShareAccountViewModel( } } - override fun handleAction(action: ShareAccountAction) { + override fun handleAction(action: CreateShareAccountAction) { when (action) { - ShareAccountAction.NextStep -> { + CreateShareAccountAction.NextStep -> { moveToNextStep() } - is ShareAccountAction.OnStepChange -> { + is CreateShareAccountAction.OnStepChange -> { mutableStateFlow.update { it.copy(currentStep = action.index) } } - ShareAccountAction.NavigateBack -> { - sendEvent(ShareAccountEvent.NavigateBack) + CreateShareAccountAction.NavigateBack -> { + sendEvent(CreateShareAccountEvent.NavigateBack) } - ShareAccountAction.Finish -> { - sendEvent(ShareAccountEvent.Finish) + CreateShareAccountAction.Finish -> { + sendEvent(CreateShareAccountEvent.Finish) } - is ShareAccountAction.OnSubmissionDateChange -> { + is CreateShareAccountAction.OnSubmissionDateChange -> { mutableStateFlow.update { it.copy( submissionDate = action.date, @@ -240,7 +251,7 @@ class CreateShareAccountViewModel( } } - is ShareAccountAction.OnApplicationDateChange -> { + is CreateShareAccountAction.OnApplicationDateChange -> { mutableStateFlow.update { it.copy( applicationDate = action.date, @@ -249,7 +260,7 @@ class CreateShareAccountViewModel( } } - is ShareAccountAction.OnOpenSubmissionDatePicker -> { + is CreateShareAccountAction.OnOpenSubmissionDatePicker -> { mutableStateFlow.update { it.copy( showSubmissionDatePicker = action.state, @@ -257,7 +268,7 @@ class CreateShareAccountViewModel( } } - is ShareAccountAction.OnOpenApplicationDatePicker -> { + is CreateShareAccountAction.OnOpenApplicationDatePicker -> { mutableStateFlow.update { it.copy( showApplicationDatePicker = action.state, @@ -265,16 +276,17 @@ class CreateShareAccountViewModel( } } - is ShareAccountAction.OnShareProductChange -> { + is CreateShareAccountAction.OnShareProductChange -> { mutableStateFlow.update { it.copy( shareProductIndex = action.index, shareProductError = null, + productId = state.productOption[action.index].id, ) } } - is ShareAccountAction.OnSavingsAccountChange -> { + is CreateShareAccountAction.OnSavingsAccountChange -> { mutableStateFlow.update { it.copy( savingsAccountIdx = action.index, @@ -283,7 +295,7 @@ class CreateShareAccountViewModel( } } - is ShareAccountAction.OnMinActiveFreqTypeChange -> { + is CreateShareAccountAction.OnMinActiveFreqTypeChange -> { mutableStateFlow.update { it.copy( minActivePeriodFreqTypeIdx = action.index, @@ -292,7 +304,7 @@ class CreateShareAccountViewModel( } } - is ShareAccountAction.OnLockInFreqTypeChange -> { + is CreateShareAccountAction.OnLockInFreqTypeChange -> { mutableStateFlow.update { it.copy( lockInPeriodFreqTypeIdx = action.index, @@ -301,7 +313,7 @@ class CreateShareAccountViewModel( } } - is ShareAccountAction.OnExternalIdChange -> { + is CreateShareAccountAction.OnExternalIdChange -> { mutableStateFlow.update { it.copy( externalId = action.value, @@ -309,7 +321,7 @@ class CreateShareAccountViewModel( } } - is ShareAccountAction.OnTotalSharesChange -> { + is CreateShareAccountAction.OnTotalSharesChange -> { mutableStateFlow.update { it.copy( totalShares = action.value, @@ -318,7 +330,7 @@ class CreateShareAccountViewModel( } } - is ShareAccountAction.OnMinActiveFreqChange -> { + is CreateShareAccountAction.OnMinActiveFreqChange -> { mutableStateFlow.update { it.copy( minActivePeriodFreq = action.value, @@ -327,7 +339,7 @@ class CreateShareAccountViewModel( } } - is ShareAccountAction.OnLockInFreqChange -> { + is CreateShareAccountAction.OnLockInFreqChange -> { mutableStateFlow.update { it.copy( lockInPeriodFreq = action.value, @@ -336,7 +348,7 @@ class CreateShareAccountViewModel( } } - is ShareAccountAction.OnIsDividendAllowedClicked -> { + is CreateShareAccountAction.OnIsDividendAllowedClicked -> { mutableStateFlow.update { it.copy( isDividendAllowed = !it.isDividendAllowed, @@ -344,32 +356,136 @@ class CreateShareAccountViewModel( } } - ShareAccountAction.Retry -> { + CreateShareAccountAction.Retry -> { loadShareTemplate(route.clientId) } - ShareAccountAction.OnDetailNext -> { + CreateShareAccountAction.OnDetailNext -> { handleOnDetailNext() } - ShareAccountAction.OnTermsNext -> { + CreateShareAccountAction.OnTermsNext -> { handleOnTermsNext() } - ShareAccountAction.PreviousStep -> { + CreateShareAccountAction.PreviousStep -> { moveToPreviousStep() } + + is CreateShareAccountAction.OnChargeAmountChange -> { + mutableStateFlow.update { + it.copy( + chargeAmount = action.amount, + ) + } + } + + is CreateShareAccountAction.AddChargeToList -> { + val createdData = CreatedCharges( + chargeId = state.chargeOptions[state.chooseChargeIndex!!].id, + amount = state.chargeAmount.toDoubleOrNull(), + ) + + mutableStateFlow.update { + it.copy( + addedCharges = it.addedCharges + createdData, + chooseChargeIndex = null, + dialogState = null, + chargeAmount = "", + ) + } + } + + is CreateShareAccountAction.EditCharge -> { + val createdData = CreatedCharges( + chargeId = state.chargeOptions[action.index].id, + amount = state.chargeAmount.toDoubleOrNull(), + ) + + val currentAddedCharges = state.addedCharges.toMutableList() + currentAddedCharges[action.index] = createdData + mutableStateFlow.update { + it.copy( + addedCharges = currentAddedCharges, + chooseChargeIndex = null, + dialogState = CreateShareAccountState.DialogState.ShowCharges, + chargeAmount = "", + ) + } + } + + is CreateShareAccountAction.OnChooseChargeIndexChange -> { + mutableStateFlow.update { + it.copy( + chooseChargeIndex = action.index, + ) + } + } + + CreateShareAccountAction.OnDismissDialog -> { + mutableStateFlow.update { + it.copy( + dialogState = null, + ) + } + } + + is CreateShareAccountAction.DeleteChargeFromSelectedCharges -> { + val newCharges = state.addedCharges.toMutableList().apply { + removeAt(action.index) + } + mutableStateFlow.update { + it.copy(addedCharges = newCharges) + } + } + + is CreateShareAccountAction.EditChargeDialog -> { + val selectedEditCharge = state.addedCharges[action.index] + val chooseChargeIndex = state.chargeOptions + .indexOfFirst { it.id == selectedEditCharge.chargeId } + + mutableStateFlow.update { + it.copy( + chargeAmount = selectedEditCharge.amount.toString(), + chooseChargeIndex = chooseChargeIndex, + dialogState = CreateShareAccountState.DialogState.AddNewCharge( + true, + action.index, + ), + ) + } + } + + CreateShareAccountAction.ShowAddChargeDialog -> { + mutableStateFlow.update { + it.copy( + dialogState = CreateShareAccountState.DialogState.AddNewCharge(false), + ) + } + } + + CreateShareAccountAction.ShowListOfChargesDialog -> { + mutableStateFlow.update { + it.copy( + dialogState = CreateShareAccountState.DialogState.ShowCharges, + ) + } + } } } } -data class ShareAccountState +data class CreateShareAccountState @OptIn(ExperimentalTime::class) constructor( val currentStep: Int = 0, val totalSteps: Int = 4, - val dialogState: Any? = null, + val dialogState: DialogState? = null, + val chargeOptions: List = emptyList(), + val chooseChargeIndex: Int? = null, + val chargeAmount: String = "", val externalId: String? = null, + val productId: Int? = null, val shareProductIndex: Int? = null, val shareProductError: StringResource? = null, val submissionDate: String = DateHelper.getDateAsStringFromLong( @@ -401,41 +517,61 @@ constructor( val lockInPeriodFreqTypeIdx: Int? = null, val lockInPeriodFreqTypeError: StringResource? = null, val screenState: ScreenState = ScreenState.Loading, + val isOverLayLoadingActive: Boolean = false, + val addedCharges: List = emptyList(), ) { - val selectedProduct: ProductOption? get() = shareProductIndex?.let { productOption.getOrNull(it) } interface ScreenState { object Loading : ScreenState object Success : ScreenState data class Error(val message: String) : ScreenState } + + sealed interface DialogState { + data class AddNewCharge(val edit: Boolean, val index: Int = -1) : DialogState + data object ShowCharges : DialogState + } } -sealed interface ShareAccountAction { - object NextStep : ShareAccountAction - data object PreviousStep : ShareAccountAction - data class OnStepChange(val index: Int) : ShareAccountAction - object NavigateBack : ShareAccountAction - object Finish : ShareAccountAction - data class OnShareProductChange(val index: Int) : ShareAccountAction - data class OnSavingsAccountChange(val index: Int) : ShareAccountAction - data class OnSubmissionDateChange(val date: String) : ShareAccountAction - data class OnApplicationDateChange(val date: String) : ShareAccountAction - data class OnOpenSubmissionDatePicker(val state: Boolean) : ShareAccountAction - data class OnOpenApplicationDatePicker(val state: Boolean) : ShareAccountAction - data class OnExternalIdChange(val value: String?) : ShareAccountAction - data class OnTotalSharesChange(val value: String) : ShareAccountAction - data class OnMinActiveFreqChange(val value: String) : ShareAccountAction - data class OnMinActiveFreqTypeChange(val index: Int?) : ShareAccountAction - data class OnLockInFreqChange(val value: String) : ShareAccountAction - data class OnLockInFreqTypeChange(val index: Int?) : ShareAccountAction - data object OnIsDividendAllowedClicked : ShareAccountAction - object OnDetailNext : ShareAccountAction - object OnTermsNext : ShareAccountAction - object Retry : ShareAccountAction +sealed interface CreateShareAccountAction { + object NextStep : CreateShareAccountAction + data object PreviousStep : CreateShareAccountAction + data class OnStepChange(val index: Int) : CreateShareAccountAction + object NavigateBack : CreateShareAccountAction + object Finish : CreateShareAccountAction + data class OnShareProductChange(val index: Int) : CreateShareAccountAction + data class OnSavingsAccountChange(val index: Int) : CreateShareAccountAction + data class OnSubmissionDateChange(val date: String) : CreateShareAccountAction + data class OnApplicationDateChange(val date: String) : CreateShareAccountAction + data class OnOpenSubmissionDatePicker(val state: Boolean) : CreateShareAccountAction + data class OnOpenApplicationDatePicker(val state: Boolean) : CreateShareAccountAction + data class OnExternalIdChange(val value: String?) : CreateShareAccountAction + data class OnTotalSharesChange(val value: String) : CreateShareAccountAction + data class OnMinActiveFreqChange(val value: String) : CreateShareAccountAction + data class OnMinActiveFreqTypeChange(val index: Int?) : CreateShareAccountAction + data class OnLockInFreqChange(val value: String) : CreateShareAccountAction + data class OnLockInFreqTypeChange(val index: Int?) : CreateShareAccountAction + data object OnIsDividendAllowedClicked : CreateShareAccountAction + object OnDetailNext : CreateShareAccountAction + object OnTermsNext : CreateShareAccountAction + object Retry : CreateShareAccountAction + data object AddChargeToList : CreateShareAccountAction + object OnDismissDialog : CreateShareAccountAction + object ShowAddChargeDialog : CreateShareAccountAction + object ShowListOfChargesDialog : CreateShareAccountAction + data class EditCharge(val index: Int) : CreateShareAccountAction + data class OnChooseChargeIndexChange(val index: Int) : CreateShareAccountAction + data class OnChargeAmountChange(val amount: String) : CreateShareAccountAction + data class DeleteChargeFromSelectedCharges(val index: Int) : CreateShareAccountAction + data class EditChargeDialog(val index: Int) : CreateShareAccountAction } -sealed interface ShareAccountEvent { - object NavigateBack : ShareAccountEvent - object Finish : ShareAccountEvent +sealed interface CreateShareAccountEvent { + object NavigateBack : CreateShareAccountEvent + object Finish : CreateShareAccountEvent } + +data class CreatedCharges( + val chargeId: Int? = null, + val amount: Double? = null, +) diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/pages/ChargesPage.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/pages/ChargesPage.kt index c041a5689de..eb7943a22d7 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/pages/ChargesPage.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/pages/ChargesPage.kt @@ -9,23 +9,106 @@ */ package com.mifos.feature.client.createShareAccount.pages +import androidclient.feature.client.generated.resources.Res +import androidclient.feature.client.generated.resources.feature_share_account_back +import androidclient.feature.client.generated.resources.feature_share_account_charge +import androidclient.feature.client.generated.resources.feature_share_account_charge_active_charge +import androidclient.feature.client.generated.resources.feature_share_account_charge_add_new +import androidclient.feature.client.generated.resources.feature_share_account_charge_view +import androidclient.feature.client.generated.resources.feature_share_account_next +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.material3.Button +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp +import com.mifos.core.designsystem.icon.MifosIcons +import com.mifos.core.designsystem.theme.DesignToken +import com.mifos.core.designsystem.theme.MifosTypography +import com.mifos.core.ui.components.MifosRowWithTextAndButton +import com.mifos.core.ui.components.MifosTwoButtonRow +import com.mifos.feature.client.createShareAccount.CreateShareAccountAction +import com.mifos.feature.client.createShareAccount.CreateShareAccountState +import org.jetbrains.compose.resources.stringResource @Composable -fun ChargesPage(onNext: () -> Unit) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Text("Charges Page") - Spacer(Modifier.height(8.dp)) - Button(onClick = onNext) { - Text("Next Button") +fun ChargesPage( + state: CreateShareAccountState, + modifier: Modifier = Modifier, + onAction: (CreateShareAccountAction) -> Unit, +) { + Column(modifier = Modifier.fillMaxSize()) { + Column( + modifier = modifier.weight(1f).verticalScroll(rememberScrollState()), + ) { + Text( + stringResource(Res.string.feature_share_account_charge), + style = MifosTypography.labelLargeEmphasized, + ) + Spacer(Modifier.height(DesignToken.padding.large)) + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.End, + ) { + Row( + modifier = Modifier.clickable { + onAction( + CreateShareAccountAction.ShowAddChargeDialog, + ) + }, + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + imageVector = MifosIcons.Add, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.size(DesignToken.sizes.iconSmall), + ) + + Text( + text = stringResource(Res.string.feature_share_account_charge_add_new), + color = MaterialTheme.colorScheme.primary, + style = MifosTypography.labelLargeEmphasized, + ) + } + } + + Spacer(Modifier.height(DesignToken.padding.large)) + + MifosRowWithTextAndButton( + onBtnClick = { + onAction( + CreateShareAccountAction.ShowListOfChargesDialog, + ) + }, + btnText = stringResource(Res.string.feature_share_account_charge_view), + text = state.addedCharges.size.toString() + " " + stringResource(Res.string.feature_share_account_charge_active_charge), + btnEnabled = state.addedCharges.isNotEmpty(), + ) } + MifosTwoButtonRow( + firstBtnText = stringResource(Res.string.feature_share_account_back), + secondBtnText = stringResource(Res.string.feature_share_account_next), + onFirstBtnClick = { + onAction(CreateShareAccountAction.PreviousStep) + }, + onSecondBtnClick = { + onAction(CreateShareAccountAction.NextStep) + }, + modifier = Modifier.padding(top = DesignToken.padding.small), + ) } } diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/pages/DetailsPage.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/pages/DetailsPage.kt index 4eecc67a8df..751dde2f6e3 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/pages/DetailsPage.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/pages/DetailsPage.kt @@ -41,8 +41,8 @@ import com.mifos.core.designsystem.component.MifosTextFieldDropdown import com.mifos.core.designsystem.theme.DesignToken import com.mifos.core.designsystem.theme.MifosTypography import com.mifos.core.ui.components.MifosTwoButtonRow -import com.mifos.feature.client.createShareAccount.ShareAccountAction -import com.mifos.feature.client.createShareAccount.ShareAccountState +import com.mifos.feature.client.createShareAccount.CreateShareAccountAction +import com.mifos.feature.client.createShareAccount.CreateShareAccountState import org.jetbrains.compose.resources.stringResource import kotlin.time.Clock import kotlin.time.ExperimentalTime @@ -50,8 +50,8 @@ import kotlin.time.ExperimentalTime @OptIn(ExperimentalMaterial3Api::class, ExperimentalTime::class) @Composable fun DetailsPage( - state: ShareAccountState, - onAction: (ShareAccountAction) -> Unit, + state: CreateShareAccountState, + onAction: (CreateShareAccountAction) -> Unit, modifier: Modifier = Modifier, ) { val submissionDatePickerState = rememberDatePickerState( @@ -66,15 +66,15 @@ fun DetailsPage( if (state.showSubmissionDatePicker) { DatePickerDialog( onDismissRequest = { - onAction(ShareAccountAction.OnOpenSubmissionDatePicker(state = false)) + onAction(CreateShareAccountAction.OnOpenSubmissionDatePicker(state = false)) }, confirmButton = { TextButton( onClick = { - onAction(ShareAccountAction.OnOpenSubmissionDatePicker(state = false)) + onAction(CreateShareAccountAction.OnOpenSubmissionDatePicker(state = false)) submissionDatePickerState.selectedDateMillis?.let { onAction( - ShareAccountAction.OnSubmissionDateChange( + CreateShareAccountAction.OnSubmissionDateChange( DateHelper.getDateAsStringFromLong(it), ), ) @@ -85,7 +85,7 @@ fun DetailsPage( dismissButton = { TextButton( onClick = { - onAction(ShareAccountAction.OnOpenSubmissionDatePicker(state = false)) + onAction(CreateShareAccountAction.OnOpenSubmissionDatePicker(state = false)) }, ) { Text(stringResource(Res.string.feature_share_account_detail_date_cancel)) } }, @@ -112,7 +112,7 @@ fun DetailsPage( }, onValueChanged = {}, onOptionSelected = { index, value -> - onAction(ShareAccountAction.OnShareProductChange(index)) + onAction(CreateShareAccountAction.OnShareProductChange(index)) }, options = state.productOption.map { it.name @@ -124,14 +124,14 @@ fun DetailsPage( value = state.submissionDate, label = stringResource(Res.string.feature_share_account_detail_submission_date), openDatePicker = { - onAction(ShareAccountAction.OnOpenSubmissionDatePicker(true)) + onAction(CreateShareAccountAction.OnOpenSubmissionDatePicker(true)) }, ) Spacer(Modifier.height(DesignToken.padding.large)) MifosOutlinedTextField( value = state.externalId ?: "", onValueChange = { - onAction(ShareAccountAction.OnExternalIdChange(it)) + onAction(CreateShareAccountAction.OnExternalIdChange(it)) }, label = stringResource(Res.string.feature_share_account_detail_external_id), ) @@ -141,10 +141,10 @@ fun DetailsPage( firstBtnText = stringResource(Res.string.feature_share_account_back), secondBtnText = stringResource(Res.string.feature_share_account_next), onFirstBtnClick = { - onAction(ShareAccountAction.NavigateBack) + onAction(CreateShareAccountAction.NavigateBack) }, onSecondBtnClick = { - onAction(ShareAccountAction.OnDetailNext) + onAction(CreateShareAccountAction.OnDetailNext) }, modifier = Modifier.padding(top = DesignToken.padding.small), ) diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/pages/TermsPage.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/pages/TermsPage.kt index d5bad2e53d5..56f15e93744 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/pages/TermsPage.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createShareAccount/pages/TermsPage.kt @@ -52,8 +52,8 @@ import com.mifos.core.designsystem.theme.DesignToken import com.mifos.core.designsystem.theme.MifosTypography import com.mifos.core.ui.components.MifosCheckBox import com.mifos.core.ui.components.MifosTwoButtonRow -import com.mifos.feature.client.createShareAccount.ShareAccountAction -import com.mifos.feature.client.createShareAccount.ShareAccountState +import com.mifos.feature.client.createShareAccount.CreateShareAccountAction +import com.mifos.feature.client.createShareAccount.CreateShareAccountState import org.jetbrains.compose.resources.stringResource import kotlin.time.Clock import kotlin.time.ExperimentalTime @@ -61,8 +61,8 @@ import kotlin.time.ExperimentalTime @OptIn(ExperimentalMaterial3Api::class, ExperimentalTime::class) @Composable fun TermsPage( - state: ShareAccountState, - onAction: (ShareAccountAction) -> Unit, + state: CreateShareAccountState, + onAction: (CreateShareAccountAction) -> Unit, modifier: Modifier = Modifier, ) { val applicationDatePickerState = rememberDatePickerState( @@ -77,15 +77,15 @@ fun TermsPage( if (state.showApplicationDatePicker) { DatePickerDialog( onDismissRequest = { - onAction(ShareAccountAction.OnOpenApplicationDatePicker(state = false)) + onAction(CreateShareAccountAction.OnOpenApplicationDatePicker(state = false)) }, confirmButton = { TextButton( onClick = { - onAction(ShareAccountAction.OnOpenApplicationDatePicker(state = false)) + onAction(CreateShareAccountAction.OnOpenApplicationDatePicker(state = false)) applicationDatePickerState.selectedDateMillis?.let { onAction( - ShareAccountAction.OnApplicationDateChange( + CreateShareAccountAction.OnApplicationDateChange( DateHelper.getDateAsStringFromLong(it), ), ) @@ -96,7 +96,7 @@ fun TermsPage( dismissButton = { TextButton( onClick = { - onAction(ShareAccountAction.OnOpenApplicationDatePicker(state = false)) + onAction(CreateShareAccountAction.OnOpenApplicationDatePicker(state = false)) }, ) { Text(stringResource(Res.string.feature_share_account_detail_date_cancel)) } }, @@ -136,7 +136,7 @@ fun TermsPage( MifosOutlinedTextField( value = state.totalShares, onValueChange = { - onAction(ShareAccountAction.OnTotalSharesChange(it)) + onAction(CreateShareAccountAction.OnTotalSharesChange(it)) }, label = stringResource(Res.string.feature_share_account_terms_total_shares), config = MifosTextFieldConfig( @@ -157,7 +157,7 @@ fun TermsPage( }, onValueChanged = {}, onOptionSelected = { index, value -> - onAction(ShareAccountAction.OnSavingsAccountChange(index)) + onAction(CreateShareAccountAction.OnSavingsAccountChange(index)) }, options = state.savingsAccountOptions.map { it.accountNo + (it.savingsProductName?.let { name -> " - $name" }.orEmpty()) @@ -170,7 +170,7 @@ fun TermsPage( value = state.applicationDate, label = stringResource(Res.string.feature_share_account_terms_application_date), openDatePicker = { - onAction(ShareAccountAction.OnOpenApplicationDatePicker(true)) + onAction(CreateShareAccountAction.OnOpenApplicationDatePicker(true)) }, errorMessage = state.applicationDateError?.let { stringResource(it) }, ) @@ -179,7 +179,7 @@ fun TermsPage( text = stringResource(Res.string.feature_share_account_terms_allow_dividends), checked = state.isDividendAllowed, onCheckChanged = { - onAction(ShareAccountAction.OnIsDividendAllowedClicked) + onAction(CreateShareAccountAction.OnIsDividendAllowedClicked) }, ) Spacer(Modifier.height(DesignToken.padding.large)) @@ -193,7 +193,7 @@ fun TermsPage( MifosOutlinedTextField( value = state.minActivePeriodFreq, onValueChange = { - onAction(ShareAccountAction.OnMinActiveFreqChange(it)) + onAction(CreateShareAccountAction.OnMinActiveFreqChange(it)) }, label = stringResource(Res.string.feature_share_account_terms_frequency), config = MifosTextFieldConfig( @@ -214,7 +214,7 @@ fun TermsPage( }, onValueChanged = {}, onOptionSelected = { index, value -> - onAction(ShareAccountAction.OnMinActiveFreqTypeChange(index)) + onAction(CreateShareAccountAction.OnMinActiveFreqTypeChange(index)) }, options = state.minimumActivePeriodFrequencyTypeOptions.map { it.value @@ -233,7 +233,7 @@ fun TermsPage( MifosOutlinedTextField( value = state.lockInPeriodFreq, onValueChange = { - onAction(ShareAccountAction.OnLockInFreqChange(it)) + onAction(CreateShareAccountAction.OnLockInFreqChange(it)) }, label = stringResource(Res.string.feature_share_account_terms_frequency), config = MifosTextFieldConfig( @@ -254,7 +254,7 @@ fun TermsPage( }, onValueChanged = {}, onOptionSelected = { index, value -> - onAction(ShareAccountAction.OnLockInFreqTypeChange(index)) + onAction(CreateShareAccountAction.OnLockInFreqTypeChange(index)) }, options = state.lockInPeriodFrequencyTypeOptions.map { it.value @@ -268,10 +268,10 @@ fun TermsPage( firstBtnText = stringResource(Res.string.feature_share_account_back), secondBtnText = stringResource(Res.string.feature_share_account_next), onFirstBtnClick = { - onAction(ShareAccountAction.PreviousStep) + onAction(CreateShareAccountAction.PreviousStep) }, onSecondBtnClick = { - onAction(ShareAccountAction.OnTermsNext) + onAction(CreateShareAccountAction.OnTermsNext) }, modifier = Modifier.padding(top = DesignToken.padding.small), ) diff --git a/feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/newLoanAccount/NewLoanAccountScreen.kt b/feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/newLoanAccount/NewLoanAccountScreen.kt index f485fd651eb..28e7cdafaac 100644 --- a/feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/newLoanAccount/NewLoanAccountScreen.kt +++ b/feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/newLoanAccount/NewLoanAccountScreen.kt @@ -474,9 +474,9 @@ private fun ShowChargesDialog( collectedOn = it.chargeTimeType?.value.toString(), amount = it.amount.toString(), onActionClicked = {}, - isExpanded = expandedIndex == it.id, + isExpanded = expandedIndex == index, onExpandToggle = { - expandedIndex = if (expandedIndex == it.id) -1 else it.id + expandedIndex = if (expandedIndex == index) -1 else index }, ) } @@ -505,9 +505,9 @@ private fun ShowChargesDialog( else -> {} } }, - isExpanded = expandedIndex == it.id, + isExpanded = expandedIndex == index, onExpandToggle = { - expandedIndex = if (expandedIndex == it.id) -1 else it.id + expandedIndex = if (expandedIndex == index) -1 else index }, ) } diff --git a/feature/savings/src/commonMain/kotlin/com/mifos/feature/savings/savingsAccountv2/SavingsAccountViewModel.kt b/feature/savings/src/commonMain/kotlin/com/mifos/feature/savings/savingsAccountv2/SavingsAccountViewModel.kt index 727ed9268f8..e354549d13f 100644 --- a/feature/savings/src/commonMain/kotlin/com/mifos/feature/savings/savingsAccountv2/SavingsAccountViewModel.kt +++ b/feature/savings/src/commonMain/kotlin/com/mifos/feature/savings/savingsAccountv2/SavingsAccountViewModel.kt @@ -256,20 +256,17 @@ internal class SavingsAccountViewModel( val msg = getString(Res.string.field_empty_msg) val isSavingProductInvalid = state.savingsProductSelected == -1 - val isFieldOfficerInvalid = state.fieldOfficerIndex == -1 - if (isSavingProductInvalid || isFieldOfficerInvalid) { + if (isSavingProductInvalid) { mutableStateFlow.update { it.copy( - savingProductError = if (isSavingProductInvalid) msg else null, - fieldOfficerError = if (isFieldOfficerInvalid) msg else null, + savingProductError = msg, ) } } else { mutableStateFlow.update { it.copy( savingProductError = null, - fieldOfficerError = null, ) } moveToNextStep() @@ -515,7 +512,6 @@ internal class SavingsAccountViewModel( mutableStateFlow.update { it.copy( fieldOfficerIndex = action.index, - fieldOfficerError = null, ) } } @@ -677,7 +673,6 @@ constructor( val launchEffectKey: Int? = null, val savingProductError: String? = null, - val fieldOfficerError: String? = null, ) { sealed interface DialogState { data object ShowCharges : DialogState diff --git a/feature/savings/src/commonMain/kotlin/com/mifos/feature/savings/savingsAccountv2/pages/DetailsPage.kt b/feature/savings/src/commonMain/kotlin/com/mifos/feature/savings/savingsAccountv2/pages/DetailsPage.kt index 836eeebfa05..b2196b77fa9 100644 --- a/feature/savings/src/commonMain/kotlin/com/mifos/feature/savings/savingsAccountv2/pages/DetailsPage.kt +++ b/feature/savings/src/commonMain/kotlin/com/mifos/feature/savings/savingsAccountv2/pages/DetailsPage.kt @@ -147,7 +147,6 @@ fun DetailsPage( it.displayName }, label = stringResource(Res.string.feature_savings_field_officer), - errorMessage = state.fieldOfficerError, ) MifosOutlinedTextField(