Skip to content

Commit b3cd263

Browse files
committed
fix(loan): align reject flow error and network handling conventions
1 parent 5556719 commit b3cd263

2 files changed

Lines changed: 50 additions & 8 deletions

File tree

core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanAccountRejectRepositoryImp.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import com.mifos.core.data.repository.LoanAccountRejectRepository
1414
import com.mifos.core.model.objects.account.loan.RejectLoanResponse
1515
import com.mifos.core.model.objects.payloads.RejectLoanPayload
1616
import com.mifos.core.network.datamanager.DataManagerLoan
17+
import kotlinx.coroutines.CancellationException
1718
import kotlinx.coroutines.CoroutineDispatcher
1819
import kotlinx.coroutines.withContext
1920

@@ -33,8 +34,9 @@ class LoanAccountRejectRepositoryImp(
3334
try {
3435
val response = dataManagerLoan.rejectLoan(loanId, rejectLoanPayload)
3536
DataState.Success(response)
36-
} catch (e: Exception) {
37-
DataState.Error(e)
37+
} catch (throwable: Throwable) {
38+
if (throwable is CancellationException) throw throwable
39+
DataState.Error(throwable)
3840
}
3941
}
4042
}

feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanReject/RejectLoanViewModel.kt

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,21 @@
1010
package com.mifos.feature.loan.loanReject
1111

1212
import androidclient.feature.loan.generated.resources.Res
13+
import androidclient.feature.loan.generated.resources.feature_loan_error_network_not_available
1314
import androidclient.feature.loan.generated.resources.feature_loan_reject_date_error_future
15+
import androidclient.feature.loan.generated.resources.feature_loan_unknown_error_occured
1416
import androidx.compose.runtime.Immutable
1517
import androidx.lifecycle.SavedStateHandle
1618
import androidx.lifecycle.viewModelScope
1719
import androidx.navigation.toRoute
1820
import com.mifos.core.common.utils.ApiDateFormatter
1921
import com.mifos.core.common.utils.DataState
2022
import com.mifos.core.data.repository.LoanAccountRejectRepository
23+
import com.mifos.core.data.util.NetworkMonitor
2124
import com.mifos.core.model.objects.payloads.RejectLoanPayload
2225
import com.mifos.core.model.utils.DateConstants
2326
import com.mifos.core.ui.util.BaseViewModel
27+
import kotlinx.coroutines.flow.distinctUntilChanged
2428
import kotlinx.coroutines.flow.update
2529
import kotlinx.coroutines.launch
2630
import kotlinx.datetime.LocalDate
@@ -33,6 +37,7 @@ import kotlin.time.ExperimentalTime
3337
@OptIn(ExperimentalTime::class)
3438
internal class RejectLoanViewModel(
3539
private val repository: LoanAccountRejectRepository,
40+
private val networkMonitor: NetworkMonitor,
3641
savedStateHandle: SavedStateHandle,
3742
) : BaseViewModel<RejectLoanState, RejectLoanEvent, RejectLoanAction>(
3843
initialState = RejectLoanState(
@@ -44,6 +49,10 @@ internal class RejectLoanViewModel(
4449

4550
private val initialDate = state.rejectedOnDate
4651

52+
init {
53+
observeNetworkStatus()
54+
}
55+
4756
override fun handleAction(action: RejectLoanAction) {
4857
when (action) {
4958
is RejectLoanAction.RejectedOnDateChanged -> {
@@ -103,7 +112,18 @@ internal class RejectLoanViewModel(
103112

104113
if (validatedState.rejectedOnDateError != null) return@launch
105114

106-
mutableStateFlow.update { it.copy(isLoading = true) }
115+
if (!validatedState.networkConnection) {
116+
mutableStateFlow.update {
117+
it.copy(
118+
dialogState = RejectLoanState.DialogState.Error(
119+
getString(Res.string.feature_loan_error_network_not_available),
120+
),
121+
)
122+
}
123+
return@launch
124+
}
125+
126+
mutableStateFlow.update { it.copy(isLoading = true, dialogState = null) }
107127

108128
val payload = RejectLoanPayload(
109129
rejectedOnDate = ApiDateFormatter.formatForApi(validatedState.rejectedOnDate),
@@ -112,26 +132,45 @@ internal class RejectLoanViewModel(
112132
dateFormat = DateConstants.DATE_FORMAT,
113133
)
114134

115-
when (val result = repository.rejectLoan(loanId, payload)) {
116-
DataState.Loading -> Unit
117-
is DataState.Success -> mutableStateFlow.update {
135+
val result = repository.rejectLoan(loanId, payload)
136+
137+
when {
138+
result is DataState.Success -> mutableStateFlow.update {
118139
it.copy(
119140
isLoading = false,
120141
dialogState = RejectLoanState.DialogState.Success,
121142
)
122143
}
123-
is DataState.Error -> mutableStateFlow.update {
144+
result is DataState.Error -> mutableStateFlow.update {
124145
it.copy(
125146
isLoading = false,
126147
dialogState = RejectLoanState.DialogState.Error(
127-
result.message.ifBlank { "An error occurred" },
148+
result.message.ifBlank { getString(Res.string.feature_loan_unknown_error_occured) },
149+
),
150+
)
151+
}
152+
else -> mutableStateFlow.update {
153+
it.copy(
154+
isLoading = false,
155+
dialogState = RejectLoanState.DialogState.Error(
156+
getString(Res.string.feature_loan_unknown_error_occured),
128157
),
129158
)
130159
}
131160
}
132161
}
133162
}
134163

164+
private fun observeNetworkStatus() {
165+
viewModelScope.launch {
166+
networkMonitor.isOnline
167+
.distinctUntilChanged()
168+
.collect { isOnline ->
169+
mutableStateFlow.update { it.copy(networkConnection = isOnline) }
170+
}
171+
}
172+
}
173+
135174
private suspend fun validate(state: RejectLoanState): RejectLoanState {
136175
return if (state.rejectedOnDate > Clock.System.now().toLocalDateTime(TimeZone.UTC).date) {
137176
state.copy(
@@ -151,6 +190,7 @@ internal class RejectLoanViewModel(
151190
internal data class RejectLoanState(
152191
val rejectedOnDate: LocalDate = Clock.System.now().toLocalDateTime(TimeZone.UTC).date,
153192
val note: String = "",
193+
val networkConnection: Boolean = false,
154194
val isLoading: Boolean = false,
155195
val rejectedOnDateError: String? = null,
156196
val showDiscardDialog: Boolean = false,

0 commit comments

Comments
 (0)