Skip to content

Commit bfdf4c6

Browse files
authored
Merge branch 'dev' into feature/loan-account-action
2 parents 2ba5fb0 + e7d68c5 commit bfdf4c6

7 files changed

Lines changed: 159 additions & 109 deletions

File tree

core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/theme/Color.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,13 @@ object AppColors {
256256

257257
val loanActiveStatus = Color(0xFF5CB85C)
258258
val loanPendingStatus = Color(0xFFFFA500)
259-
val loanOverpaidStatus = Color(0xFF800080)
259+
val loanApprovedStatus = Color(0xFFFFA500)
260+
val loanClosedOverpaidStatus = Color(0xFF800080)
261+
val loanClosedObligationsMetStatus = Color(0xFF5CB85C)
262+
val loanClosedRescheduled = Color(0xFF000AAD)
263+
val loanClosedWrittenOffStatus = Color(0xFF990000)
264+
val loanRejectedStatus = Color(0xFF990000)
265+
val loanWithdrawnByApplicantStatus = Color(0xFF990000)
266+
260267
val loanUnknownStatus = Color(0xFF9E9E9E)
261268
}

feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientLoanAccounts/ClientLoanAccountsScreen.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ import com.mifos.core.ui.components.MifosEmptyCard
7575
import com.mifos.core.ui.components.MifosProgressIndicator
7676
import com.mifos.core.ui.components.MifosSearchBar
7777
import com.mifos.core.ui.util.EventsEffect
78+
import com.mifos.feature.loan.utils.getLoanStatus
7879
import com.mifos.room.entities.accounts.loans.LoanAccountEntity
7980
import org.jetbrains.compose.resources.painterResource
8081
import org.jetbrains.compose.resources.stringResource
@@ -252,7 +253,7 @@ private fun LoanAccountItem(
252253

253254
type = loan.loanType?.value ?: notAvailable,
254255

255-
status = loan.status?.value ?: notAvailable,
256+
status = loan.status?.let { stringResource(it.getLoanStatus().label) } ?: notAvailable,
256257

257258
menuList = buildLoanActions(loan),
258259

feature/loan/src/commonMain/composeResources/values/strings.xml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,6 @@
165165
<string name="feature_loan_profile_item_notes_subtitle">Additional internal comments</string>
166166
<string name="feature_loan_profile_item_standing_instructions_title">Standing Instructions</string>
167167
<string name="feature_loan_profile_item_standing_instructions_subtitle">Automated payment settings</string>
168-
<string name="feature_loan_profile_status_active">Active</string>
169-
<string name="feature_loan_profile_status_pending">Pending</string>
170-
<string name="feature_loan_profile_status_overpaid">Overpaid</string>
171-
<string name="feature_loan_profile_status_unknown">Unknown</string>
172168
<string name="feature_loan_profile_action_approve">Approve Account</string>
173169
<string name="feature_loan_profile_action_repayment">Make Repayment</string>
174170
<string name="feature_loan_profile_action_transfer">Transfer Funds</string>
@@ -587,4 +583,16 @@
587583
<string name="feature_loan_reschedule_fetch_failed">Failed to load reschedule history.</string>
588584
<string name="feature_loan_reschedule_approve_failed">Failed to approve reschedule.</string>
589585
<string name="feature_loan_reschedule_delete_failed">Failed to delete reschedule.</string>
586+
587+
588+
<string name="feature_loan_pending_approval">Pending Approval</string>
589+
<string name="feature_loan_approved">Approved</string>
590+
<string name="feature_loan_withdrawn_by_applicant">Withdrawn by Applicant</string>
591+
<string name="feature_loan_active">Active</string>
592+
<string name="feature_loan_closed_overpaid">Closed (Overpaid)</string>
593+
<string name="feature_loan_closed_obligations_met">Closed (Obligations Met)</string>
594+
<string name="feature_loan_closed_written_off">Closed (Written Off)</string>
595+
<string name="feature_loan_closed_rescheduled">Closed (Rescheduled)</string>
596+
<string name="feature_loan_rejected">Rejected</string>
597+
<string name="feature_loan_unknown">Unknown</string>">
590598
</resources>

feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import androidclient.feature.loan.generated.resources.feature_loan_profile_label
2020
import androidclient.feature.loan.generated.resources.feature_loan_profile_open_actions
2121
import androidclient.feature.loan.generated.resources.feature_loan_profile_section_account_overview
2222
import androidclient.feature.loan.generated.resources.feature_loan_profile_section_actions_details
23-
import androidclient.feature.loan.generated.resources.feature_loan_profile_status_active
2423
import androidx.compose.foundation.background
2524
import androidx.compose.foundation.clickable
2625
import androidx.compose.foundation.layout.Arrangement
@@ -64,6 +63,7 @@ import com.mifos.core.ui.util.EventsEffect
6463
import com.mifos.core.ui.util.TextUtil
6564
import com.mifos.feature.loan.loanAccountProfile.components.LoanAccountProfileActionItem
6665
import com.mifos.feature.loan.loanAccountProfile.components.loanProfileActionItems
66+
import com.mifos.feature.loan.utils.getLoanStatus
6767
import com.mifos.room.entities.accounts.loans.LoanStatusEntity
6868
import com.mifos.room.entities.accounts.loans.LoanWithAssociationsEntity
6969
import com.mifos.room.entities.accounts.loans.LoansAccountSummaryEntity
@@ -111,19 +111,24 @@ internal fun LoanAccountProfileScreen(
111111
}
112112
}
113113
}
114+
114115
is LoanAccountEvent.NavigateToDetail -> {
115116
val loanId = state.loanAccount?.id ?: -1
116117

117118
when (event.detailItem) {
118-
LoanAccountProfileActionItem.RepaymentSchedule -> navigateToRepaymentSchedule(loanId)
119+
LoanAccountProfileActionItem.RepaymentSchedule -> navigateToRepaymentSchedule(
120+
loanId,
121+
)
122+
119123
LoanAccountProfileActionItem.Transactions -> navigateToTransactions(loanId)
120124
LoanAccountProfileActionItem.Charges -> navigateToCharges(loanId)
121125
LoanAccountProfileActionItem.Documents -> navigateToDocuments(loanId)
122126
LoanAccountProfileActionItem.Reschedules -> navigateToReschedules(loanId)
123127
LoanAccountProfileActionItem.Notes -> navigateToNotes(loanId)
124-
else -> { }
128+
else -> {}
125129
}
126130
}
131+
127132
LoanAccountEvent.NavigateToAccountDetails -> {}
128133
LoanAccountEvent.NavigateToLoanAction -> {
129134
val loanId = state.loanAccount?.id ?: -1
@@ -176,7 +181,6 @@ private fun LoanAccountContent(
176181

177182
LoanAccountTopCard(
178183
loanAccount = loanAccount,
179-
statusUi = state.statusUiModel,
180184
onClick = { onAction(LoanAccountAction.OnAccountClick) },
181185
onArrowClick = { onAction(LoanAccountAction.OnArrowClick) },
182186
)
@@ -228,16 +232,17 @@ private fun LoanAccountContent(
228232
@Composable
229233
private fun LoanAccountTopCard(
230234
loanAccount: LoanWithAssociationsEntity,
231-
statusUi: LoanStatusUiModel?,
232235
onClick: () -> Unit,
233236
onArrowClick: () -> Unit,
234237
modifier: Modifier = Modifier,
235238
) {
236239
val currencyCode = loanAccount.currency?.code
237240
val decimalPlaces = loanAccount.currency?.decimalPlaces
238241

239-
val balance = CurrencyFormatter.format(loanAccount.summary.totalOutstanding, currencyCode, decimalPlaces)
240-
val arrears = CurrencyFormatter.format(loanAccount.summary.totalOverdue, currencyCode, decimalPlaces)
242+
val balance =
243+
CurrencyFormatter.format(loanAccount.summary.totalOutstanding, currencyCode, decimalPlaces)
244+
val arrears =
245+
CurrencyFormatter.format(loanAccount.summary.totalOverdue, currencyCode, decimalPlaces)
241246
val overpaid = CurrencyFormatter.format(loanAccount.totalOverpaid, currencyCode, decimalPlaces)
242247

243248
MifosCard(
@@ -262,15 +267,18 @@ private fun LoanAccountTopCard(
262267
) {
263268
Column(modifier = Modifier.weight(1f)) {
264269
Text(
265-
text = "${loanAccount.loanProductName?.uppercase().orEmpty()} ${loanAccount.accountNo}".trim(),
270+
text = "${
271+
loanAccount.loanProductName?.uppercase().orEmpty()
272+
} ${loanAccount.accountNo}".trim(),
266273
style = MifosTypography.titleMediumEmphasized,
267274
color = KptTheme.colorScheme.onPrimary,
268275
)
269276

270277
Spacer(Modifier.height(KptTheme.spacing.xs))
271278

272279
Text(
273-
text = loanAccount.clientName ?: stringResource(Res.string.feature_loan_profile_label_client_name_placeholder),
280+
text = loanAccount.clientName
281+
?: stringResource(Res.string.feature_loan_profile_label_client_name_placeholder),
274282
style = MifosTypography.bodyMedium,
275283
color = KptTheme.colorScheme.onPrimary.copy(alpha = 0.8f),
276284
)
@@ -287,21 +295,22 @@ private fun LoanAccountTopCard(
287295

288296
Spacer(Modifier.height(DesignToken.padding.medium))
289297

290-
statusUi?.let { ui ->
291-
Box(
292-
modifier = Modifier
293-
.clip(KptTheme.shapes.large)
294-
.background(ui.color)
295-
.padding(horizontal = DesignToken.padding.medium, vertical = KptTheme.spacing.xs),
296-
contentAlignment = Alignment.Center,
297-
) {
298-
Text(
299-
text = stringResource(ui.labelRes).uppercase(),
300-
color = KptTheme.colorScheme.onPrimary,
301-
style = MifosTypography.labelSmallEmphasized,
302-
fontWeight = FontWeight.Bold,
303-
)
304-
}
298+
Box(
299+
modifier = Modifier
300+
.clip(KptTheme.shapes.large)
301+
.background(loanAccount.status.getLoanStatus().color)
302+
.padding(
303+
horizontal = DesignToken.padding.medium,
304+
vertical = KptTheme.spacing.xs,
305+
),
306+
contentAlignment = Alignment.Center,
307+
) {
308+
Text(
309+
text = stringResource(loanAccount.status.getLoanStatus().label).uppercase(),
310+
color = KptTheme.colorScheme.onPrimary,
311+
style = MifosTypography.labelSmallEmphasized,
312+
fontWeight = FontWeight.Bold,
313+
)
305314
}
306315

307316
Spacer(Modifier.height(KptTheme.spacing.md))
@@ -374,6 +383,7 @@ private fun LoanAccountDialogs(
374383
onRetry = onRetry,
375384
)
376385
}
386+
377387
null -> Unit
378388
}
379389
}
@@ -403,10 +413,6 @@ private class LoanAccountPreviewProvider : PreviewParameterProvider<LoanAccountS
403413
value = "Active",
404414
),
405415
),
406-
statusUiModel = LoanStatusUiModel(
407-
labelRes = Res.string.feature_loan_profile_status_active,
408-
color = AppColors.loanActiveStatus,
409-
),
410416
nextActionButtonRes = Res.string.feature_loan_profile_action_repayment,
411417
dialogState = null,
412418
),

feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileViewModel.kt

Lines changed: 13 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,18 @@ import androidclient.feature.loan.generated.resources.feature_loan_profile_actio
1717
import androidclient.feature.loan.generated.resources.feature_loan_profile_error_details_not_found
1818
import androidclient.feature.loan.generated.resources.feature_loan_profile_error_network_not_available
1919
import androidclient.feature.loan.generated.resources.feature_loan_profile_failed_to_load_loan
20-
import androidclient.feature.loan.generated.resources.feature_loan_profile_status_active
21-
import androidclient.feature.loan.generated.resources.feature_loan_profile_status_overpaid
22-
import androidclient.feature.loan.generated.resources.feature_loan_profile_status_pending
23-
import androidclient.feature.loan.generated.resources.feature_loan_profile_status_unknown
24-
import androidx.compose.ui.graphics.Color
2520
import androidx.lifecycle.SavedStateHandle
2621
import androidx.lifecycle.viewModelScope
2722
import androidx.navigation.toRoute
2823
import com.mifos.core.common.utils.DataState
2924
import com.mifos.core.data.repository.LoanAccountSummaryRepository
3025
import com.mifos.core.data.util.NetworkMonitor
31-
import com.mifos.core.designsystem.theme.AppColors
3226
import com.mifos.core.ui.util.BaseViewModel
3327
import com.mifos.feature.loan.loanAccountProfile.LoanAccountEvent.NavigateToDetail
3428
import com.mifos.feature.loan.loanAccountProfile.LoanAccountState.DialogState.Error
3529
import com.mifos.feature.loan.loanAccountProfile.components.LoanAccountProfileActionItem
36-
import com.mifos.room.entities.accounts.loans.LoanStatusEntity
30+
import com.mifos.feature.loan.utils.LoanStatus
31+
import com.mifos.feature.loan.utils.getLoanStatus
3732
import com.mifos.room.entities.accounts.loans.LoanWithAssociationsEntity
3833
import kotlinx.coroutines.Job
3934
import kotlinx.coroutines.flow.update
@@ -87,13 +82,12 @@ internal class LoanAccountProfileViewModel(
8782
}
8883
return@collect
8984
}
90-
val currentStatus = loan.status.toProfileStatus()
85+
val currentStatus = loan.status.getLoanStatus()
9186

9287
mutableStateFlow.update {
9388
it.copy(
9489
loanAccount = loan,
9590
dialogState = null,
96-
statusUiModel = calculateStatusUi(currentStatus),
9791
nextActionButtonRes = calculateNextActionResource(currentStatus),
9892
)
9993
}
@@ -113,21 +107,12 @@ internal class LoanAccountProfileViewModel(
113107
}
114108
}
115109

116-
private fun calculateNextActionResource(status: LoanProfileStatus): StringResource {
110+
private fun calculateNextActionResource(status: LoanStatus): StringResource {
117111
return when (status) {
118-
LoanProfileStatus.PENDING -> Res.string.feature_loan_profile_action_approve
119-
LoanProfileStatus.OVERPAID -> Res.string.feature_loan_profile_action_transfer
120-
LoanProfileStatus.ACTIVE -> Res.string.feature_loan_profile_action_repayment
121-
LoanProfileStatus.UNKNOWN -> Res.string.feature_loan_profile_action_view
122-
}
123-
}
124-
125-
private fun calculateStatusUi(status: LoanProfileStatus): LoanStatusUiModel {
126-
return when (status) {
127-
LoanProfileStatus.ACTIVE -> LoanStatusUiModel(Res.string.feature_loan_profile_status_active, AppColors.loanActiveStatus)
128-
LoanProfileStatus.PENDING -> LoanStatusUiModel(Res.string.feature_loan_profile_status_pending, AppColors.loanPendingStatus)
129-
LoanProfileStatus.OVERPAID -> LoanStatusUiModel(Res.string.feature_loan_profile_status_overpaid, AppColors.loanOverpaidStatus)
130-
LoanProfileStatus.UNKNOWN -> LoanStatusUiModel(Res.string.feature_loan_profile_status_unknown, AppColors.loanUnknownStatus)
112+
LoanStatus.PENDING_APPROVAL -> Res.string.feature_loan_profile_action_approve
113+
LoanStatus.CLOSED_OVERPAID -> Res.string.feature_loan_profile_action_transfer
114+
LoanStatus.ACTIVE -> Res.string.feature_loan_profile_action_repayment
115+
else -> Res.string.feature_loan_profile_action_view
131116
}
132117
}
133118

@@ -151,37 +136,19 @@ internal class LoanAccountProfileViewModel(
151136
private fun handleNextAction() {
152137
val account = mutableStateFlow.value.loanAccount ?: return
153138

154-
when (account.status.toProfileStatus()) {
155-
LoanProfileStatus.PENDING -> sendEvent(LoanAccountEvent.NavigateToAction(LoanProfileAction.Approve))
156-
LoanProfileStatus.OVERPAID -> sendEvent(LoanAccountEvent.NavigateToAction(LoanProfileAction.Transfer))
157-
LoanProfileStatus.ACTIVE -> sendEvent(LoanAccountEvent.NavigateToAction(LoanProfileAction.Repayment))
158-
LoanProfileStatus.UNKNOWN -> sendEvent(LoanAccountEvent.NavigateToAccountDetails)
159-
}
160-
}
161-
162-
private fun LoanStatusEntity?.toProfileStatus(): LoanProfileStatus {
163-
if (this == null) return LoanProfileStatus.UNKNOWN
164-
return when {
165-
this.pendingApproval == true -> LoanProfileStatus.PENDING
166-
this.overpaid == true -> LoanProfileStatus.OVERPAID
167-
this.active == true -> LoanProfileStatus.ACTIVE
168-
else -> LoanProfileStatus.UNKNOWN
139+
when (account.status.getLoanStatus()) {
140+
LoanStatus.PENDING_APPROVAL -> sendEvent(LoanAccountEvent.NavigateToAction(LoanProfileAction.Approve))
141+
LoanStatus.CLOSED_OVERPAID -> sendEvent(LoanAccountEvent.NavigateToAction(LoanProfileAction.Transfer))
142+
LoanStatus.ACTIVE -> sendEvent(LoanAccountEvent.NavigateToAction(LoanProfileAction.Repayment))
143+
else -> sendEvent(LoanAccountEvent.NavigateToAccountDetails)
169144
}
170145
}
171146
}
172147

173-
enum class LoanProfileStatus {
174-
ACTIVE,
175-
PENDING,
176-
OVERPAID,
177-
UNKNOWN,
178-
}
179-
180148
data class LoanAccountState(
181149
val loanAccount: LoanWithAssociationsEntity? = null,
182150
val dialogState: DialogState? = null,
183151
val networkConnection: Boolean = false,
184-
val statusUiModel: LoanStatusUiModel? = null,
185152
val nextActionButtonRes: StringResource = Res.string.feature_loan_profile_action_view,
186153
) {
187154
sealed interface DialogState {
@@ -190,11 +157,6 @@ data class LoanAccountState(
190157
}
191158
}
192159

193-
data class LoanStatusUiModel(
194-
val labelRes: StringResource,
195-
val color: Color,
196-
)
197-
198160
sealed interface LoanProfileAction {
199161
data object Approve : LoanProfileAction
200162
data object Repayment : LoanProfileAction

feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountSummary/LoanAccountSummaryScreen.kt

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,13 @@ import com.mifos.core.designsystem.component.MifosMenuDropDownItem
8888
import com.mifos.core.designsystem.component.MifosScaffold
8989
import com.mifos.core.designsystem.component.MifosSweetError
9090
import com.mifos.core.designsystem.icon.MifosIcons
91-
import com.mifos.core.designsystem.theme.AppColors
9291
import com.mifos.core.designsystem.theme.DesignToken
9392
import com.mifos.core.designsystem.theme.MifosTheme
9493
import com.mifos.core.designsystem.theme.MifosTypography
9594
import com.mifos.core.ui.components.MifosBreadcrumbNavBar
9695
import com.mifos.core.ui.components.MifosProgressIndicator
9796
import com.mifos.core.ui.util.EventsEffect
97+
import com.mifos.feature.loan.utils.getLoanStatus
9898
import com.mifos.room.entities.accounts.loans.LoanStatusEntity
9999
import com.mifos.room.entities.accounts.loans.LoanWithAssociationsEntity
100100
import com.mifos.room.entities.accounts.loans.LoansAccountSummaryEntity
@@ -270,12 +270,7 @@ private fun LoanAccountSummaryContent(
270270
modifier = Modifier.fillMaxWidth(),
271271
verticalAlignment = Alignment.CenterVertically,
272272
) {
273-
val statusDescription = when {
274-
loanWithAssociations.status.active == true -> "Active"
275-
loanWithAssociations.status.pendingApproval == true -> "Pending Approval"
276-
loanWithAssociations.status.waitingForDisbursal == true -> "Waiting for Disbursal"
277-
else -> "Closed"
278-
}
273+
val statusDescription = stringResource(loanWithAssociations.status.getLoanStatus().label)
279274
Canvas(
280275
modifier = Modifier
281276
.size(DesignToken.sizes.iconMedium)
@@ -284,23 +279,7 @@ private fun LoanAccountSummaryContent(
284279
},
285280
onDraw = {
286281
drawCircle(
287-
color = when {
288-
loanWithAssociations.status.active == true -> {
289-
AppColors.loanIndicatorActive
290-
}
291-
292-
loanWithAssociations.status.pendingApproval == true -> {
293-
AppColors.loanIndicatorPending
294-
}
295-
296-
loanWithAssociations.status.waitingForDisbursal == true -> {
297-
AppColors.loanIndicatorWaitingForDisbursal
298-
}
299-
300-
else -> {
301-
AppColors.loanIndicatorOther
302-
}
303-
},
282+
color = loanWithAssociations.status.getLoanStatus().color,
304283
)
305284
},
306285
)

0 commit comments

Comments
 (0)