Skip to content

Commit a07a625

Browse files
authored
Order Savings Accounts by Active State Etc (#2986)
1 parent 70c39c6 commit a07a625

File tree

2 files changed

+55
-63
lines changed

2 files changed

+55
-63
lines changed

feature/savings-account/src/commonMain/kotlin/org/mifos/mobile/feature/savingsaccount/savingsAccount/SavingsAccountScreen.kt

Lines changed: 28 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import mifos_mobile.feature.savings_account.generated.resources.feature_account_
4040
import mifos_mobile.feature.savings_account.generated.resources.feature_savings_account
4141
import mifos_mobile.feature.savings_account.generated.resources.feature_savings_account_dashboard
4242
import mifos_mobile.feature.savings_account.generated.resources.feature_savings_account_items
43+
import mifos_mobile.feature.savings_account.generated.resources.feature_savings_filter_pending_account
4344
import mifos_mobile.feature.savings_account.generated.resources.feature_savings_no_accounts_found
4445
import org.jetbrains.compose.resources.StringResource
4546
import org.jetbrains.compose.resources.stringResource
@@ -52,15 +53,14 @@ import org.mifos.mobile.core.designsystem.theme.AppColors
5253
import org.mifos.mobile.core.designsystem.theme.DesignToken
5354
import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme
5455
import org.mifos.mobile.core.designsystem.theme.MifosTypography
55-
import org.mifos.mobile.core.model.LoanStatus
56+
import org.mifos.mobile.core.model.SavingStatus
5657
import org.mifos.mobile.core.ui.component.EmptyDataView
5758
import org.mifos.mobile.core.ui.component.MifosAccountCard
5859
import org.mifos.mobile.core.ui.component.MifosDashboardCard
5960
import org.mifos.mobile.core.ui.component.MifosErrorComponent
6061
import org.mifos.mobile.core.ui.component.MifosProgressIndicator
6162
import org.mifos.mobile.core.ui.utils.EventsEffect
6263
import org.mifos.mobile.core.ui.utils.ScreenUiState
63-
import kotlin.collections.orEmpty
6464

6565
@Composable
6666
fun SavingsAccountScreen(
@@ -91,29 +91,21 @@ fun SavingsAccountScreen(
9191
EventsEffect(viewModel.eventFlow) { event ->
9292
when (event) {
9393
is SavingsAccountsEvent.NavigateBack -> navigateBack.invoke()
94-
9594
is SavingsAccountsEvent.AccountClicked -> {
9695
onAccountClicked(Constants.SAVINGS_ACCOUNT, event.accountId)
9796
}
98-
99-
is SavingsAccountsEvent.LoadingCompleted -> {
100-
onLoadingCompleted.invoke()
101-
}
97+
is SavingsAccountsEvent.LoadingCompleted -> onLoadingCompleted.invoke()
10298
}
10399
}
104100

105101
SavingsAccountDialog(
106102
dialogState = state.dialogState,
107-
onAction = remember(viewModel) {
108-
{ viewModel.trySendAction(it) }
109-
},
103+
onAction = remember(viewModel) { { viewModel.trySendAction(it) } },
110104
)
111105

112106
SavingsAccountContent(
113107
state = state,
114-
onAction = remember(viewModel) {
115-
{ viewModel.trySendAction(it) }
116-
},
108+
onAction = remember(viewModel) { { viewModel.trySendAction(it) } },
117109
filtersClicked = filtersClicked,
118110
)
119111
}
@@ -131,7 +123,6 @@ internal fun SavingsAccountDialog(
131123
isRetryEnabled = true,
132124
)
133125
}
134-
135126
null -> Unit
136127
}
137128
}
@@ -210,19 +201,7 @@ internal fun SavingsAccountContent(
210201
)
211202
}
212203

213-
Row(
214-
horizontalArrangement = Arrangement.spacedBy(DesignToken.spacing.largeIncreased),
215-
) {
216-
// TODO : un-implemented feature,
217-
// commenting because user won't feels its good ,uncomment and implement it
218-
// Icon(
219-
// modifier = Modifier
220-
// .clickable {}
221-
// .size(20.dp),
222-
// imageVector = MifosIcons.SearchNew,
223-
// contentDescription =
224-
// stringResource(Res.string.content_description_search),
225-
// )
204+
Row(horizontalArrangement = Arrangement.spacedBy(DesignToken.spacing.largeIncreased)) {
226205
Icon(
227206
modifier = Modifier
228207
.clickable { filtersClicked() }
@@ -254,38 +233,41 @@ internal fun SavingsAccountContent(
254233
)
255234
}
256235
} else {
236+
val accounts = state.savingsAccount.orEmpty()
257237
LazyColumn(
258238
modifier = Modifier
259239
.fillMaxSize()
260240
.weight(1f),
261241
) {
262-
item {
263-
Spacer(modifier = Modifier.height(DesignToken.spacing.small))
264-
}
265-
items(state.savingsAccount.orEmpty()) { account ->
242+
item { Spacer(modifier = Modifier.height(DesignToken.spacing.small)) }
243+
244+
items(accounts) { account ->
266245
val color = when (account.status?.value) {
267-
LoanStatus.ACTIVE.status -> AppColors.customEnable
268-
LoanStatus.SUBMIT_AND_PENDING_APPROVAL.status -> AppColors.customYellow
269-
LoanStatus.WITHDRAWN.status, LoanStatus.MATURED.status ->
270-
MaterialTheme.colorScheme.error
246+
SavingStatus.ACTIVE.status -> AppColors.customEnable
247+
SavingStatus.SUBMIT_AND_PENDING_APPROVAL.status -> AppColors.customYellow
248+
SavingStatus.INACTIVE.status -> MaterialTheme.colorScheme.error
271249
else -> MaterialTheme.colorScheme.onSurface
272250
}
273251

252+
val accountStatus = if (account.status?.active == true) {
253+
CurrencyFormatter.format(
254+
account.accountBalance,
255+
account.currency?.code,
256+
account.currency?.decimalPlaces,
257+
)
258+
} else {
259+
if (account.status?.value == SavingStatus.SUBMIT_AND_PENDING_APPROVAL.status) {
260+
stringResource(Res.string.feature_savings_filter_pending_account)
261+
} else {
262+
account.status?.value ?: ""
263+
}
264+
}
265+
274266
MifosAccountCard(
275267
accountId = account.id,
276268
accountNumber = account.accountNo,
277269
accountType = account.productName,
278-
accountStatus = (
279-
if (account.status?.active == true) {
280-
CurrencyFormatter.format(
281-
account.accountBalance,
282-
account.currency?.code,
283-
account.currency?.decimalPlaces,
284-
)
285-
} else {
286-
account.status?.value ?: ""
287-
}
288-
),
270+
accountStatus = accountStatus,
289271
accountStatusColor = color,
290272
onAccountClick = {
291273
onAction(

feature/savings-account/src/commonMain/kotlin/org/mifos/mobile/feature/savingsaccount/savingsAccount/SavingsAccountViewmodel.kt

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ import org.mifos.mobile.core.common.DataState
2323
import org.mifos.mobile.core.data.repository.AccountsRepository
2424
import org.mifos.mobile.core.data.util.NetworkMonitor
2525
import org.mifos.mobile.core.datastore.UserPreferencesRepository
26+
import org.mifos.mobile.core.model.SavingStatus
2627
import org.mifos.mobile.core.model.entity.accounts.savings.SavingAccount
2728
import org.mifos.mobile.core.model.entity.client.ClientAccounts
2829
import org.mifos.mobile.core.ui.utils.BaseViewModel
2930
import org.mifos.mobile.core.ui.utils.ScreenUiState
30-
import org.mifos.mobile.core.ui.utils.ScreenUiState.Network
3131
import org.mifos.mobile.feature.savingsaccount.utils.FilterUtil
3232
import kotlin.collections.orEmpty
3333

@@ -55,9 +55,7 @@ class SavingsAccountViewmodel(
5555
observeNetwork()
5656
}
5757

58-
/**
59-
* Observes the network connectivity status and updates state accordingly.
60-
*/
58+
/** Observes the network connectivity status and updates state accordingly. */
6159
private fun observeNetwork() {
6260
viewModelScope.launch {
6361
networkMonitor.isOnline
@@ -140,9 +138,9 @@ class SavingsAccountViewmodel(
140138
}
141139

142140
/**
143-
* Retries the data fetching process. If the network is unavailable, it shows
144-
* a network error dialog. Otherwise, it triggers the `loadAccounts` `fetchClient`,
145-
* `fetchLonPurpose` function.
141+
* A helper function to update the mutable state flow.
142+
*
143+
* @param update A lambda function that takes the current state and returns a new state.
146144
*/
147145
private fun retry() {
148146
viewModelScope.launch {
@@ -155,17 +153,15 @@ class SavingsAccountViewmodel(
155153
}
156154

157155
/**
158-
* Toggles visibility of the total savings amount in UI.
159-
*/
156+
* Toggles visibility of total savings amount in UI.
157+
* */
160158
private fun handleAmountVisible() {
161159
mutableStateFlow.update {
162160
it.copy(isAmountVisible = !state.isAmountVisible)
163161
}
164162
}
165163

166-
/**
167-
* Dismisses any active dialog in the UI.
168-
*/
164+
/** Dismisses any active dialog. */
169165
private fun handleDismissDialog() {
170166
mutableStateFlow.update {
171167
it.copy(dialogState = null)
@@ -230,9 +226,11 @@ class SavingsAccountViewmodel(
230226
is DataState.Success -> {
231227
val allSavings = dataState.data.savingsAccounts.orEmpty()
232228
val filtered = filterAccounts(selectedFilters, allSavings)
229+
val sortedAccounts = sortAccountsByStatus(filtered)
233230
updateState {
234231
it.copy(
235-
decimals = filtered.firstOrNull()?.currency?.decimalPlaces ?: 2,
232+
decimals = sortedAccounts.firstOrNull()?.currency?.decimalPlaces
233+
?: allSavings.firstOrNull()?.currency?.decimalPlaces ?: 2,
236234
)
237235
}
238236

@@ -242,12 +240,12 @@ class SavingsAccountViewmodel(
242240

243241
updateState {
244242
val isEmptyAccounts = allSavings.isEmpty()
245-
val isFilteredEmpty = filtered.isEmpty()
243+
val isFilteredEmpty = sortedAccounts.isEmpty()
246244

247245
it.copy(
248-
items = filtered.size,
246+
items = sortedAccounts.size,
249247
isFilteredEmpty = isFilteredEmpty,
250-
savingsAccount = filtered,
248+
savingsAccount = sortedAccounts,
251249
originalAccounts = allSavings,
252250
selectedFilters = selectedFilters,
253251
currency = allSavings.firstOrNull()?.currency?.displaySymbol,
@@ -280,7 +278,6 @@ class SavingsAccountViewmodel(
280278
} else {
281279
accounts
282280
}
283-
284281
return filteredByStatus.distinct()
285282
}
286283

@@ -289,6 +286,11 @@ class SavingsAccountViewmodel(
289286
*
290287
* @param accounts List of [SavingAccount] to compute totals from.
291288
*/
289+
private fun sortAccountsByStatus(accounts: List<SavingAccount>): List<SavingAccount> {
290+
return accounts.sortedWith(compareBy { state.statusOrder.indexOf(it.status?.value) })
291+
}
292+
293+
/** Calculates total savings balance and updates state. */
292294
private fun getTotalSavingAmount(accounts: List<SavingAccount>?) {
293295
var amount = 0.0
294296
var items = 0
@@ -352,6 +354,14 @@ data class SavingsAccountState(
352354
val uiState: ScreenUiState? = ScreenUiState.Loading,
353355

354356
val networkStatus: Boolean = false,
357+
358+
/** Order of statuses for consistent sorting */
359+
val statusOrder: List<String> = listOf(
360+
SavingStatus.ACTIVE.status,
361+
SavingStatus.SUBMIT_AND_PENDING_APPROVAL.status,
362+
SavingStatus.CLOSED.status,
363+
SavingStatus.INACTIVE.status,
364+
),
355365
) {
356366

357367
/**

0 commit comments

Comments
 (0)