mirror of
https://github.com/openMF/mifos-mobile.git
synced 2026-02-06 11:26:51 +00:00
refactor(loan): show consistent loan actions for all account statuses (#2952)
This commit is contained in:
parent
d83c760eeb
commit
bd78ecefc1
@ -14,6 +14,8 @@ enum class LoanStatus(val status: String) {
|
||||
|
||||
CLOSED("Closed"),
|
||||
|
||||
CLOSED_OBLIGATIONS_MET("Closed (obligations met)"),
|
||||
|
||||
MATURED("Matured"),
|
||||
|
||||
APPROVED("Approved"),
|
||||
@ -25,4 +27,12 @@ enum class LoanStatus(val status: String) {
|
||||
REJECTED("Rejected"),
|
||||
|
||||
WITHDRAWN("Withdrawn by applicant"),
|
||||
|
||||
OVERPAID("Overpaid"),
|
||||
;
|
||||
|
||||
companion object {
|
||||
fun fromStatus(value: String?): LoanStatus? =
|
||||
entries.firstOrNull { it.status.equals(value, ignoreCase = true) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
package org.mifos.mobile.core.model.entity.accounts.loan
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import org.mifos.mobile.core.model.LoanStatus
|
||||
import org.mifos.mobile.core.model.Parcelable
|
||||
import org.mifos.mobile.core.model.Parcelize
|
||||
|
||||
@ -40,6 +41,9 @@ data class Status(
|
||||
|
||||
) : Parcelable {
|
||||
|
||||
val loanStatus: LoanStatus?
|
||||
get() = LoanStatus.fromStatus(value)
|
||||
|
||||
fun isLoanTypeWithdrawn(): Boolean {
|
||||
return !(
|
||||
this.active == true || this.closed == true || this.pendingApproval == true ||
|
||||
|
||||
@ -28,7 +28,6 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import mifos_mobile.feature.loan_account.generated.resources.Res
|
||||
import mifos_mobile.feature.loan_account.generated.resources.feature_account_details_action
|
||||
import mifos_mobile.feature.loan_account.generated.resources.feature_account_details_top_bar_title
|
||||
@ -163,14 +162,14 @@ internal fun LoanAccountDetailsContent(
|
||||
)
|
||||
}
|
||||
|
||||
if (state.isActive) {
|
||||
SavingsAccountActions(
|
||||
items = state.items,
|
||||
onActionClick = {
|
||||
onAction(LoanAccountDetailsAction.OnNavigateToAction(it))
|
||||
},
|
||||
)
|
||||
}
|
||||
val visibleActions = state.accountStatus?.allowedActions ?: emptySet()
|
||||
|
||||
SavingsAccountActions(
|
||||
visibleActions = visibleActions,
|
||||
onActionClick = {
|
||||
onAction(LoanAccountDetailsAction.OnNavigateToAction(it))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -222,8 +221,7 @@ internal fun AccountDetailsGrid(
|
||||
|
||||
@Composable
|
||||
internal fun SavingsAccountActions(
|
||||
items: ImmutableList<LoanActionItems>,
|
||||
// onAction: (LoanAccountDetailsAction) -> Unit,
|
||||
visibleActions: Set<LoanActionItems>,
|
||||
onActionClick: (String) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
@ -237,16 +235,15 @@ internal fun SavingsAccountActions(
|
||||
FlowRow(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
items.forEach { item ->
|
||||
MifosActionCard(
|
||||
title = item.title,
|
||||
subTitle = item.subTitle,
|
||||
icon = item.icon,
|
||||
onClick = {
|
||||
onActionClick(item.route)
|
||||
},
|
||||
)
|
||||
}
|
||||
visibleActions
|
||||
.forEach { item ->
|
||||
MifosActionCard(
|
||||
title = item.title,
|
||||
subTitle = item.subTitle,
|
||||
icon = item.icon,
|
||||
onClick = { onActionClick(item.route) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,7 +178,7 @@ internal class LoanAccountDetailsViewModel(
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
accountId = loan?.id?.toLong() ?: -1L,
|
||||
isActive = loan?.status?.value == LoanStatus.ACTIVE.status,
|
||||
accountStatus = loan?.status?.loanStatus,
|
||||
accountNumber = loan?.accountNo,
|
||||
clientName = loan?.clientName,
|
||||
product = loan?.loanProductName,
|
||||
@ -198,7 +198,7 @@ internal class LoanAccountDetailsViewModel(
|
||||
* @property accountId Unique ID for the loan account.
|
||||
* @property displayItems List of account metadata to be displayed.
|
||||
* @property transactionList List of most recent transaction details.
|
||||
* @property isActive True if the loan is active.
|
||||
* @property accountStatus True if the loan is active.
|
||||
* @property items List of quick action items (e.g., Repay, Foreclose).
|
||||
* @property isUpdatable Whether the loan is editable (e.g., in a pending state).
|
||||
* @property dialogState State representing UI dialogs like loading or error.
|
||||
@ -214,7 +214,7 @@ internal data class LoanAccountDetailsState(
|
||||
val product: String? = "",
|
||||
val displayItems: List<LabelValueItem> = emptyList(),
|
||||
val transactionList: List<LabelValueItem>? = emptyList(),
|
||||
val isActive: Boolean = false,
|
||||
val accountStatus: LoanStatus? = LoanStatus.ACTIVE,
|
||||
val items: ImmutableList<LoanActionItems>,
|
||||
val isUpdatable: Boolean = false,
|
||||
val dialogState: DialogState?,
|
||||
@ -231,6 +231,57 @@ internal data class LoanAccountDetailsState(
|
||||
}
|
||||
}
|
||||
|
||||
val LoanStatus.allowedActions: Set<LoanActionItems>
|
||||
get() = when (this) {
|
||||
LoanStatus.SUBMIT_AND_PENDING_APPROVAL -> setOf(
|
||||
LoanActionItems.LoanSummary,
|
||||
)
|
||||
|
||||
LoanStatus.APPROVED -> setOf(
|
||||
LoanActionItems.LoanSummary,
|
||||
LoanActionItems.Charges,
|
||||
)
|
||||
|
||||
LoanStatus.DISBURSED,
|
||||
LoanStatus.ACTIVE,
|
||||
-> setOf(
|
||||
LoanActionItems.MakePayment,
|
||||
LoanActionItems.LoanSummary,
|
||||
LoanActionItems.RepaymentSchedule,
|
||||
LoanActionItems.Transactions,
|
||||
LoanActionItems.Charges,
|
||||
LoanActionItems.QrCode,
|
||||
|
||||
)
|
||||
|
||||
LoanStatus.MATURED -> setOf(
|
||||
LoanActionItems.LoanSummary,
|
||||
LoanActionItems.RepaymentSchedule,
|
||||
LoanActionItems.Transactions,
|
||||
)
|
||||
|
||||
LoanStatus.CLOSED -> setOf(
|
||||
LoanActionItems.LoanSummary,
|
||||
LoanActionItems.Transactions,
|
||||
)
|
||||
|
||||
LoanStatus.CLOSED_OBLIGATIONS_MET -> setOf(
|
||||
LoanActionItems.LoanSummary,
|
||||
LoanActionItems.Transactions,
|
||||
)
|
||||
|
||||
LoanStatus.REJECTED,
|
||||
LoanStatus.WITHDRAWN,
|
||||
-> setOf(
|
||||
LoanActionItems.LoanSummary,
|
||||
)
|
||||
|
||||
LoanStatus.OVERPAID -> setOf(
|
||||
LoanActionItems.LoanSummary,
|
||||
LoanActionItems.Transactions,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* One-time navigation or effect events for the Loan Account Details screen.
|
||||
*/
|
||||
|
||||
@ -149,7 +149,7 @@ internal class LoanAccountSummaryViewModel(
|
||||
LabelValueItem(
|
||||
Res.string.feature_loan_expected_payoff_label,
|
||||
CurrencyFormatter.format(
|
||||
loan?.summary?.totalExpectedRepayment,
|
||||
loan?.summary?.totalExpectedRepayment ?: 0.0,
|
||||
currencyCode,
|
||||
maxDigits,
|
||||
),
|
||||
@ -157,7 +157,7 @@ internal class LoanAccountSummaryViewModel(
|
||||
LabelValueItem(
|
||||
Res.string.feature_loan_interest_payoff_label,
|
||||
CurrencyFormatter.format(
|
||||
loan?.summary?.interestCharged,
|
||||
loan?.summary?.interestCharged ?: 0.0,
|
||||
currencyCode,
|
||||
maxDigits,
|
||||
),
|
||||
@ -165,7 +165,7 @@ internal class LoanAccountSummaryViewModel(
|
||||
LabelValueItem(
|
||||
Res.string.feature_loan_principal_label,
|
||||
CurrencyFormatter.format(
|
||||
loan?.summary?.principalDisbursed,
|
||||
loan?.summary?.principalDisbursed ?: 0.0,
|
||||
currencyCode,
|
||||
maxDigits,
|
||||
),
|
||||
@ -184,7 +184,7 @@ internal class LoanAccountSummaryViewModel(
|
||||
LabelValueItem(
|
||||
Res.string.feature_loan_fees_label,
|
||||
CurrencyFormatter.format(
|
||||
loan?.summary?.feeChargesCharged,
|
||||
loan?.summary?.feeChargesCharged ?: 0.0,
|
||||
currencyCode,
|
||||
maxDigits,
|
||||
),
|
||||
@ -192,7 +192,7 @@ internal class LoanAccountSummaryViewModel(
|
||||
LabelValueItem(
|
||||
Res.string.feature_loan_penalties_label,
|
||||
CurrencyFormatter.format(
|
||||
loan?.summary?.penaltyChargesCharged,
|
||||
loan?.summary?.penaltyChargesCharged ?: 0.0,
|
||||
currencyCode,
|
||||
maxDigits,
|
||||
),
|
||||
@ -203,7 +203,7 @@ internal class LoanAccountSummaryViewModel(
|
||||
LabelValueItem(
|
||||
Res.string.feature_loan_interest_waived_label,
|
||||
CurrencyFormatter.format(
|
||||
loan?.summary?.interestWaived,
|
||||
loan?.summary?.interestWaived ?: 0.0,
|
||||
currencyCode,
|
||||
maxDigits,
|
||||
),
|
||||
@ -211,7 +211,7 @@ internal class LoanAccountSummaryViewModel(
|
||||
LabelValueItem(
|
||||
Res.string.feature_loan_penalty_waived_label,
|
||||
CurrencyFormatter.format(
|
||||
loan?.summary?.penaltyChargesWaived,
|
||||
loan?.summary?.penaltyChargesWaived ?: 0.0,
|
||||
currencyCode,
|
||||
maxDigits,
|
||||
),
|
||||
@ -219,7 +219,7 @@ internal class LoanAccountSummaryViewModel(
|
||||
LabelValueItem(
|
||||
Res.string.feature_loan_fees_waived_label,
|
||||
CurrencyFormatter.format(
|
||||
loan?.summary?.feeChargesWaived,
|
||||
loan?.summary?.feeChargesWaived ?: 0.0,
|
||||
currencyCode,
|
||||
maxDigits,
|
||||
),
|
||||
@ -230,7 +230,7 @@ internal class LoanAccountSummaryViewModel(
|
||||
LabelValueItem(
|
||||
Res.string.feature_loan_interest_paid_off_label,
|
||||
CurrencyFormatter.format(
|
||||
loan?.summary?.interestPaid,
|
||||
loan?.summary?.interestPaid ?: 0.0,
|
||||
currencyCode,
|
||||
maxDigits,
|
||||
),
|
||||
@ -238,7 +238,7 @@ internal class LoanAccountSummaryViewModel(
|
||||
LabelValueItem(
|
||||
Res.string.feature_loan_principal_paid_off_label,
|
||||
CurrencyFormatter.format(
|
||||
loan?.summary?.principalPaid,
|
||||
loan?.summary?.principalPaid ?: 0.0,
|
||||
currencyCode,
|
||||
maxDigits,
|
||||
),
|
||||
@ -266,7 +266,7 @@ internal class LoanAccountSummaryViewModel(
|
||||
LabelValueItem(
|
||||
Res.string.feature_loan_total_outstanding_label,
|
||||
CurrencyFormatter.format(
|
||||
loan?.summary?.totalOutstanding,
|
||||
loan?.summary?.totalOutstanding ?: 0.0,
|
||||
currencyCode,
|
||||
maxDigits,
|
||||
),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user