Skip to content

Commit 6eb1d22

Browse files
feat(savings-account): fetch savings products (#2982)
1 parent ddab8ad commit 6eb1d22

File tree

3 files changed

+68
-24
lines changed

3 files changed

+68
-24
lines changed

feature/savings-account/src/commonMain/composeResources/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@
7575
<string name="feature_savings_update_request_update">Request Update</string>
7676
<string name="feature_savings_new_product_label">New Product</string>
7777

78+
<string name="feature_savings_savings_product_empty">Currently Loan Products are not available</string>
79+
7880
<string name="feature_savings_update_request_successful">Request Submitted Successfully</string>
7981
<string name="feature_savings_update_request_successful_message">Request to update the account details is submitted successfully</string>
8082
<string name="feature_savings_update_request_back_to_home">Back To Home</string>

feature/savings-account/src/commonMain/kotlin/org/mifos/mobile/feature/savingsaccount/savingsAccountUpdate/AccountUpdateScreen.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import androidx.compose.ui.Modifier
2727
import androidx.lifecycle.compose.collectAsStateWithLifecycle
2828
import mifos_mobile.feature.savings_account.generated.resources.Res
2929
import mifos_mobile.feature.savings_account.generated.resources.feature_savings_new_product_label
30+
import mifos_mobile.feature.savings_account.generated.resources.feature_savings_savings_product_empty
3031
import mifos_mobile.feature.savings_account.generated.resources.feature_savings_update_product_label
3132
import mifos_mobile.feature.savings_account.generated.resources.feature_savings_update_topbar_title
3233
import org.jetbrains.compose.resources.stringResource
@@ -126,6 +127,14 @@ internal fun AccountUpdateScreenContent(
126127
},
127128
) {
128129
when (state.uiState) {
130+
ScreenUiState.Empty -> {
131+
MifosErrorComponent(
132+
isRetryEnabled = true,
133+
message = stringResource(Res.string.feature_savings_savings_product_empty),
134+
onRetry = { onAction(AccountUpdateAction.Retry) },
135+
)
136+
}
137+
129138
is ScreenUiState.Error -> {
130139
MifosErrorComponent(
131140
isRetryEnabled = true,

feature/savings-account/src/commonMain/kotlin/org/mifos/mobile/feature/savingsaccount/savingsAccountUpdate/AccountUpdateViewModel.kt

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import kotlinx.coroutines.launch
1818
import kotlinx.serialization.ExperimentalSerializationApi
1919
import kotlinx.serialization.InternalSerializationApi
2020
import mifos_mobile.feature.savings_account.generated.resources.Res
21+
import mifos_mobile.feature.savings_account.generated.resources.feature_generic_error_server
2122
import mifos_mobile.feature.savings_account.generated.resources.feature_savings_update_account_number_label
2223
import mifos_mobile.feature.savings_account.generated.resources.feature_savings_update_client_name_label
2324
import mifos_mobile.feature.savings_account.generated.resources.feature_savings_update_product_label
@@ -74,17 +75,10 @@ internal class AccountUpdateViewModel(
7475
Res.string.feature_savings_update_account_number_label to clientDetails.accountNumber,
7576
Res.string.feature_savings_update_product_label to clientDetails.product,
7677
)
77-
val productOptions = mapOf(
78-
1L to "Wallet",
79-
2L to "FDP",
80-
4L to "1 year Fixed Deposit",
81-
82-
)
8378
AccountUpdateState(
8479
clientId = requireNotNull(userPreferencesRepository.clientId.value),
8580
accountId = requireNotNull(clientDetails.accountId),
8681
details = detailsMap,
87-
productOptions = productOptions,
8882
dialogState = null,
8983
)
9084
},
@@ -95,19 +89,14 @@ internal class AccountUpdateViewModel(
9589
observeAuthResult()
9690
}
9791

98-
// TODO get savings product from server
99-
// init {
100-
// observeSavingsProducts()
101-
// }
102-
103-
// private fun observeSavingsProducts() {
104-
// viewModelScope.launch {
105-
// savingsAccountRepositoryImp.getSavingAccountApplicationTemplate(state.clientId)
106-
// .collect {
107-
// sendAction(AccountUpdateAction.Internal.ReceiveProducts(it))
108-
// }
109-
// }
110-
// }
92+
private fun fetchSavingsProducts() {
93+
viewModelScope.launch {
94+
savingsAccountRepositoryImp.getSavingAccountApplicationTemplate(state.clientId)
95+
.collect {
96+
sendAction(AccountUpdateAction.Internal.ReceiveProducts(it))
97+
}
98+
}
99+
}
111100

112101
/**
113102
* Observes the network connectivity status and updates state accordingly.
@@ -131,13 +120,15 @@ internal class AccountUpdateViewModel(
131120
*
132121
* @param isOnline A boolean indicating the current network status.
133122
*/
123+
@Suppress("ComplexCondition")
134124
private fun handleNetworkStatus(isOnline: Boolean) {
135125
updateState { it.copy(networkStatus = isOnline) }
136126

137127
viewModelScope.launch {
138128
if (!isOnline) {
139129
updateState { current ->
140130
if (current.uiState is ScreenUiState.Loading ||
131+
state.showOverlay ||
141132
current.uiState is ScreenUiState.Error ||
142133
current.uiState is ScreenUiState.Empty ||
143134
current.uiState is ScreenUiState.Network
@@ -148,7 +139,7 @@ internal class AccountUpdateViewModel(
148139
}
149140
}
150141
} else {
151-
// TODO get the products from server
142+
fetchSavingsProducts()
152143
}
153144
}
154145
}
@@ -158,7 +149,7 @@ internal class AccountUpdateViewModel(
158149
if (!state.networkStatus) {
159150
updateState { it.copy(uiState = ScreenUiState.Network) }
160151
} else {
161-
// TODO get the products from server
152+
fetchSavingsProducts()
162153
}
163154
}
164155
}
@@ -201,8 +192,7 @@ internal class AccountUpdateViewModel(
201192

202193
is AccountUpdateAction.Retry -> retry()
203194

204-
// TODO handle received products
205-
is AccountUpdateAction.Internal.ReceiveProducts -> { }
195+
is AccountUpdateAction.Internal.ReceiveProducts -> handleSavingsProduct(action.dataState)
206196

207197
is AccountUpdateAction.Internal.ReceiveUpdateRequestResult -> {
208198
viewModelScope.launch {
@@ -220,6 +210,49 @@ internal class AccountUpdateViewModel(
220210
}
221211
}
222212

213+
/**
214+
* Handles the result of the `fetchSavingsProducts` network call.
215+
* Updates the state with product options on success. If the list of
216+
* options is empty, it sets the `isEmpty` flag to true. On failure,
217+
* it displays an error dialog.
218+
*
219+
* @param template The [DataState] containing the loan template data.
220+
*/
221+
private fun handleSavingsProduct(template: DataState<SavingsAccountTemplate>) {
222+
when (template) {
223+
is DataState.Loading -> updateState { it.copy(uiState = ScreenUiState.Loading) }
224+
is DataState.Success -> {
225+
val loanTemplate = template.data
226+
if (loanTemplate.productOptions.isEmpty()) {
227+
updateState {
228+
it.copy(
229+
uiState = ScreenUiState.Empty,
230+
)
231+
}
232+
return
233+
}
234+
235+
val productOptions = loanTemplate.productOptions.associate {
236+
it.id.toLong() to it.name
237+
}
238+
239+
updateState {
240+
it.copy(
241+
uiState = ScreenUiState.Success,
242+
productOptions = productOptions,
243+
)
244+
}
245+
}
246+
is DataState.Error -> {
247+
updateState {
248+
it.copy(
249+
uiState = ScreenUiState.Error(Res.string.feature_generic_error_server),
250+
)
251+
}
252+
}
253+
}
254+
}
255+
223256
/**
224257
* Updates state based on selected product from dropdown.
225258
*

0 commit comments

Comments
 (0)