Skip to content

Commit bd78ece

Browse files
refactor(loan): show consistent loan actions for all account statuses (#2952)
1 parent d83c760 commit bd78ece

File tree

5 files changed

+97
-35
lines changed

5 files changed

+97
-35
lines changed

core/model/src/commonMain/kotlin/org/mifos/mobile/core/model/LoanStatus.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ enum class LoanStatus(val status: String) {
1414

1515
CLOSED("Closed"),
1616

17+
CLOSED_OBLIGATIONS_MET("Closed (obligations met)"),
18+
1719
MATURED("Matured"),
1820

1921
APPROVED("Approved"),
@@ -25,4 +27,12 @@ enum class LoanStatus(val status: String) {
2527
REJECTED("Rejected"),
2628

2729
WITHDRAWN("Withdrawn by applicant"),
30+
31+
OVERPAID("Overpaid"),
32+
;
33+
34+
companion object {
35+
fun fromStatus(value: String?): LoanStatus? =
36+
entries.firstOrNull { it.status.equals(value, ignoreCase = true) }
37+
}
2838
}

core/model/src/commonMain/kotlin/org/mifos/mobile/core/model/entity/accounts/loan/Status.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
package org.mifos.mobile.core.model.entity.accounts.loan
1111

1212
import kotlinx.serialization.Serializable
13+
import org.mifos.mobile.core.model.LoanStatus
1314
import org.mifos.mobile.core.model.Parcelable
1415
import org.mifos.mobile.core.model.Parcelize
1516

@@ -40,6 +41,9 @@ data class Status(
4041

4142
) : Parcelable {
4243

44+
val loanStatus: LoanStatus?
45+
get() = LoanStatus.fromStatus(value)
46+
4347
fun isLoanTypeWithdrawn(): Boolean {
4448
return !(
4549
this.active == true || this.closed == true || this.pendingApproval == true ||

feature/loan-account/src/commonMain/kotlin/org/mifos/mobile/feature/loanaccount/loanAccountDetails/LoanAccountDetailsScreen.kt

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import androidx.compose.runtime.remember
2828
import androidx.compose.ui.Modifier
2929
import androidx.compose.ui.unit.dp
3030
import androidx.lifecycle.compose.collectAsStateWithLifecycle
31-
import kotlinx.collections.immutable.ImmutableList
3231
import mifos_mobile.feature.loan_account.generated.resources.Res
3332
import mifos_mobile.feature.loan_account.generated.resources.feature_account_details_action
3433
import mifos_mobile.feature.loan_account.generated.resources.feature_account_details_top_bar_title
@@ -163,14 +162,14 @@ internal fun LoanAccountDetailsContent(
163162
)
164163
}
165164

166-
if (state.isActive) {
167-
SavingsAccountActions(
168-
items = state.items,
169-
onActionClick = {
170-
onAction(LoanAccountDetailsAction.OnNavigateToAction(it))
171-
},
172-
)
173-
}
165+
val visibleActions = state.accountStatus?.allowedActions ?: emptySet()
166+
167+
SavingsAccountActions(
168+
visibleActions = visibleActions,
169+
onActionClick = {
170+
onAction(LoanAccountDetailsAction.OnNavigateToAction(it))
171+
},
172+
)
174173
}
175174
}
176175
}
@@ -222,8 +221,7 @@ internal fun AccountDetailsGrid(
222221

223222
@Composable
224223
internal fun SavingsAccountActions(
225-
items: ImmutableList<LoanActionItems>,
226-
// onAction: (LoanAccountDetailsAction) -> Unit,
224+
visibleActions: Set<LoanActionItems>,
227225
onActionClick: (String) -> Unit,
228226
) {
229227
Column(
@@ -237,16 +235,15 @@ internal fun SavingsAccountActions(
237235
FlowRow(
238236
modifier = Modifier.fillMaxWidth(),
239237
) {
240-
items.forEach { item ->
241-
MifosActionCard(
242-
title = item.title,
243-
subTitle = item.subTitle,
244-
icon = item.icon,
245-
onClick = {
246-
onActionClick(item.route)
247-
},
248-
)
249-
}
238+
visibleActions
239+
.forEach { item ->
240+
MifosActionCard(
241+
title = item.title,
242+
subTitle = item.subTitle,
243+
icon = item.icon,
244+
onClick = { onActionClick(item.route) },
245+
)
246+
}
250247
}
251248
}
252249
}

feature/loan-account/src/commonMain/kotlin/org/mifos/mobile/feature/loanaccount/loanAccountDetails/LoanAccountDetailsViewModel.kt

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ internal class LoanAccountDetailsViewModel(
178178
mutableStateFlow.update {
179179
it.copy(
180180
accountId = loan?.id?.toLong() ?: -1L,
181-
isActive = loan?.status?.value == LoanStatus.ACTIVE.status,
181+
accountStatus = loan?.status?.loanStatus,
182182
accountNumber = loan?.accountNo,
183183
clientName = loan?.clientName,
184184
product = loan?.loanProductName,
@@ -198,7 +198,7 @@ internal class LoanAccountDetailsViewModel(
198198
* @property accountId Unique ID for the loan account.
199199
* @property displayItems List of account metadata to be displayed.
200200
* @property transactionList List of most recent transaction details.
201-
* @property isActive True if the loan is active.
201+
* @property accountStatus True if the loan is active.
202202
* @property items List of quick action items (e.g., Repay, Foreclose).
203203
* @property isUpdatable Whether the loan is editable (e.g., in a pending state).
204204
* @property dialogState State representing UI dialogs like loading or error.
@@ -214,7 +214,7 @@ internal data class LoanAccountDetailsState(
214214
val product: String? = "",
215215
val displayItems: List<LabelValueItem> = emptyList(),
216216
val transactionList: List<LabelValueItem>? = emptyList(),
217-
val isActive: Boolean = false,
217+
val accountStatus: LoanStatus? = LoanStatus.ACTIVE,
218218
val items: ImmutableList<LoanActionItems>,
219219
val isUpdatable: Boolean = false,
220220
val dialogState: DialogState?,
@@ -231,6 +231,57 @@ internal data class LoanAccountDetailsState(
231231
}
232232
}
233233

234+
val LoanStatus.allowedActions: Set<LoanActionItems>
235+
get() = when (this) {
236+
LoanStatus.SUBMIT_AND_PENDING_APPROVAL -> setOf(
237+
LoanActionItems.LoanSummary,
238+
)
239+
240+
LoanStatus.APPROVED -> setOf(
241+
LoanActionItems.LoanSummary,
242+
LoanActionItems.Charges,
243+
)
244+
245+
LoanStatus.DISBURSED,
246+
LoanStatus.ACTIVE,
247+
-> setOf(
248+
LoanActionItems.MakePayment,
249+
LoanActionItems.LoanSummary,
250+
LoanActionItems.RepaymentSchedule,
251+
LoanActionItems.Transactions,
252+
LoanActionItems.Charges,
253+
LoanActionItems.QrCode,
254+
255+
)
256+
257+
LoanStatus.MATURED -> setOf(
258+
LoanActionItems.LoanSummary,
259+
LoanActionItems.RepaymentSchedule,
260+
LoanActionItems.Transactions,
261+
)
262+
263+
LoanStatus.CLOSED -> setOf(
264+
LoanActionItems.LoanSummary,
265+
LoanActionItems.Transactions,
266+
)
267+
268+
LoanStatus.CLOSED_OBLIGATIONS_MET -> setOf(
269+
LoanActionItems.LoanSummary,
270+
LoanActionItems.Transactions,
271+
)
272+
273+
LoanStatus.REJECTED,
274+
LoanStatus.WITHDRAWN,
275+
-> setOf(
276+
LoanActionItems.LoanSummary,
277+
)
278+
279+
LoanStatus.OVERPAID -> setOf(
280+
LoanActionItems.LoanSummary,
281+
LoanActionItems.Transactions,
282+
)
283+
}
284+
234285
/**
235286
* One-time navigation or effect events for the Loan Account Details screen.
236287
*/

feature/loan-account/src/commonMain/kotlin/org/mifos/mobile/feature/loanaccount/loanAccountSummary/AccountSummaryViewModel.kt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -149,23 +149,23 @@ internal class LoanAccountSummaryViewModel(
149149
LabelValueItem(
150150
Res.string.feature_loan_expected_payoff_label,
151151
CurrencyFormatter.format(
152-
loan?.summary?.totalExpectedRepayment,
152+
loan?.summary?.totalExpectedRepayment ?: 0.0,
153153
currencyCode,
154154
maxDigits,
155155
),
156156
),
157157
LabelValueItem(
158158
Res.string.feature_loan_interest_payoff_label,
159159
CurrencyFormatter.format(
160-
loan?.summary?.interestCharged,
160+
loan?.summary?.interestCharged ?: 0.0,
161161
currencyCode,
162162
maxDigits,
163163
),
164164
),
165165
LabelValueItem(
166166
Res.string.feature_loan_principal_label,
167167
CurrencyFormatter.format(
168-
loan?.summary?.principalDisbursed,
168+
loan?.summary?.principalDisbursed ?: 0.0,
169169
currencyCode,
170170
maxDigits,
171171
),
@@ -184,15 +184,15 @@ internal class LoanAccountSummaryViewModel(
184184
LabelValueItem(
185185
Res.string.feature_loan_fees_label,
186186
CurrencyFormatter.format(
187-
loan?.summary?.feeChargesCharged,
187+
loan?.summary?.feeChargesCharged ?: 0.0,
188188
currencyCode,
189189
maxDigits,
190190
),
191191
),
192192
LabelValueItem(
193193
Res.string.feature_loan_penalties_label,
194194
CurrencyFormatter.format(
195-
loan?.summary?.penaltyChargesCharged,
195+
loan?.summary?.penaltyChargesCharged ?: 0.0,
196196
currencyCode,
197197
maxDigits,
198198
),
@@ -203,23 +203,23 @@ internal class LoanAccountSummaryViewModel(
203203
LabelValueItem(
204204
Res.string.feature_loan_interest_waived_label,
205205
CurrencyFormatter.format(
206-
loan?.summary?.interestWaived,
206+
loan?.summary?.interestWaived ?: 0.0,
207207
currencyCode,
208208
maxDigits,
209209
),
210210
),
211211
LabelValueItem(
212212
Res.string.feature_loan_penalty_waived_label,
213213
CurrencyFormatter.format(
214-
loan?.summary?.penaltyChargesWaived,
214+
loan?.summary?.penaltyChargesWaived ?: 0.0,
215215
currencyCode,
216216
maxDigits,
217217
),
218218
),
219219
LabelValueItem(
220220
Res.string.feature_loan_fees_waived_label,
221221
CurrencyFormatter.format(
222-
loan?.summary?.feeChargesWaived,
222+
loan?.summary?.feeChargesWaived ?: 0.0,
223223
currencyCode,
224224
maxDigits,
225225
),
@@ -230,15 +230,15 @@ internal class LoanAccountSummaryViewModel(
230230
LabelValueItem(
231231
Res.string.feature_loan_interest_paid_off_label,
232232
CurrencyFormatter.format(
233-
loan?.summary?.interestPaid,
233+
loan?.summary?.interestPaid ?: 0.0,
234234
currencyCode,
235235
maxDigits,
236236
),
237237
),
238238
LabelValueItem(
239239
Res.string.feature_loan_principal_paid_off_label,
240240
CurrencyFormatter.format(
241-
loan?.summary?.principalPaid,
241+
loan?.summary?.principalPaid ?: 0.0,
242242
currencyCode,
243243
maxDigits,
244244
),
@@ -266,7 +266,7 @@ internal class LoanAccountSummaryViewModel(
266266
LabelValueItem(
267267
Res.string.feature_loan_total_outstanding_label,
268268
CurrencyFormatter.format(
269-
loan?.summary?.totalOutstanding,
269+
loan?.summary?.totalOutstanding ?: 0.0,
270270
currencyCode,
271271
maxDigits,
272272
),

0 commit comments

Comments
 (0)