From dc2eec89b953dc7dbb8968324f25897fbcb052fd Mon Sep 17 00:00:00 2001 From: Pratyush Singh Date: Sun, 22 Oct 2023 19:03:11 +0530 Subject: [PATCH] refactor #2415: savings viewmodels to stateflow --- .../java/org/mifos/mobile/api/DataManager.kt | 12 +-- .../api/services/SavingAccountsListService.kt | 13 ++- .../repositories/SavingsAccountRepository.kt | 14 +-- .../SavingsAccountRepositoryImp.kt | 39 +++++--- .../fragments/SavingAccountsDetailFragment.kt | 89 +++++++++++-------- .../SavingAccountsTransactionFragment.kt | 66 ++++++++------ .../mobile/utils/SavingsAccountUiState.kt | 1 + .../SavingAccountsDetailViewModel.kt | 27 +++--- .../SavingAccountsTransactionViewModel.kt | 29 +++--- .../SavingsAccountApplicationViewModel.kt | 78 ++++++---------- .../SavingsAccountWithdrawViewModel.kt | 33 +++---- .../SavingsMakeTransferViewModel.kt | 21 +++-- 12 files changed, 214 insertions(+), 208 deletions(-) diff --git a/app/src/main/java/org/mifos/mobile/api/DataManager.kt b/app/src/main/java/org/mifos/mobile/api/DataManager.kt index ba403f265..a9f9dfa4e 100644 --- a/app/src/main/java/org/mifos/mobile/api/DataManager.kt +++ b/app/src/main/java/org/mifos/mobile/api/DataManager.kt @@ -96,33 +96,33 @@ class DataManager @Inject constructor( suspend fun getSavingsWithAssociations( accountId: Long?, associationType: String?, - ): Response? { + ): SavingsWithAssociations { return baseApiManager .savingAccountsListApi.getSavingsWithAssociations(accountId, associationType) } - suspend fun accountTransferTemplate(): Response? = + suspend fun accountTransferTemplate(): AccountOptionsTemplate = baseApiManager.savingAccountsListApi.accountTransferTemplate() suspend fun makeTransfer(transferPayload: TransferPayload?): Response? { return baseApiManager.savingAccountsListApi.makeTransfer(transferPayload) } - suspend fun getSavingAccountApplicationTemplate(client: Long?): Response? { + suspend fun getSavingAccountApplicationTemplate(client: Long?): SavingsAccountTemplate { return baseApiManager.savingAccountsListApi .getSavingsAccountApplicationTemplate(client) } suspend fun submitSavingAccountApplication( payload: SavingsAccountApplicationPayload?, - ): Response? { + ): ResponseBody { return baseApiManager.savingAccountsListApi.submitSavingAccountApplication(payload) } suspend fun updateSavingsAccount( accountId: Long?, payload: SavingsAccountUpdatePayload?, - ): Response? { + ): ResponseBody { return baseApiManager.savingAccountsListApi .updateSavingsAccountUpdate(accountId, payload) } @@ -130,7 +130,7 @@ class DataManager @Inject constructor( suspend fun submitWithdrawSavingsAccount( accountId: String?, payload: SavingsAccountWithdrawPayload?, - ): Response? { + ): ResponseBody { return baseApiManager.savingAccountsListApi .submitWithdrawSavingsAccount(accountId, payload) } diff --git a/app/src/main/java/org/mifos/mobile/api/services/SavingAccountsListService.kt b/app/src/main/java/org/mifos/mobile/api/services/SavingAccountsListService.kt index 570370d5f..441a5d18f 100644 --- a/app/src/main/java/org/mifos/mobile/api/services/SavingAccountsListService.kt +++ b/app/src/main/java/org/mifos/mobile/api/services/SavingAccountsListService.kt @@ -1,6 +1,5 @@ package org.mifos.mobile.api.services -import io.reactivex.Observable import okhttp3.ResponseBody import org.mifos.mobile.api.ApiEndPoints import org.mifos.mobile.models.accounts.savings.SavingsAccountApplicationPayload @@ -22,10 +21,10 @@ interface SavingAccountsListService { suspend fun getSavingsWithAssociations( @Path("accountId") accountId: Long?, @Query("associations") associationType: String?, - ): Response? + ): SavingsWithAssociations @GET(ApiEndPoints.ACCOUNT_TRANSFER + "/template") - suspend fun accountTransferTemplate(): Response? + suspend fun accountTransferTemplate(): AccountOptionsTemplate @POST(ApiEndPoints.ACCOUNT_TRANSFER) suspend fun makeTransfer(@Body transferPayload: TransferPayload?): Response? @@ -33,22 +32,22 @@ interface SavingAccountsListService { @GET(ApiEndPoints.SAVINGS_ACCOUNTS + "/template") suspend fun getSavingsAccountApplicationTemplate( @Query("clientId") clientId: Long?, - ): Response? + ): SavingsAccountTemplate @POST(ApiEndPoints.SAVINGS_ACCOUNTS) suspend fun submitSavingAccountApplication( @Body payload: SavingsAccountApplicationPayload?, - ): Response? + ): ResponseBody @PUT(ApiEndPoints.SAVINGS_ACCOUNTS + "/{accountsId}") suspend fun updateSavingsAccountUpdate( @Path("accountsId") accountsId: Long?, @Body payload: SavingsAccountUpdatePayload?, - ): Response? + ): ResponseBody @POST(ApiEndPoints.SAVINGS_ACCOUNTS + "/{savingsId}?command=withdrawnByApplicant") suspend fun submitWithdrawSavingsAccount( @Path("savingsId") savingsId: String?, @Body payload: SavingsAccountWithdrawPayload?, - ): Response? + ): ResponseBody } diff --git a/app/src/main/java/org/mifos/mobile/repositories/SavingsAccountRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/SavingsAccountRepository.kt index d5860de90..4de370639 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/SavingsAccountRepository.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/SavingsAccountRepository.kt @@ -1,5 +1,6 @@ package org.mifos.mobile.repositories +import kotlinx.coroutines.flow.Flow import okhttp3.ResponseBody import org.mifos.mobile.models.accounts.savings.SavingsAccountApplicationPayload import org.mifos.mobile.models.accounts.savings.SavingsAccountUpdatePayload @@ -7,28 +8,27 @@ import org.mifos.mobile.models.accounts.savings.SavingsAccountWithdrawPayload import org.mifos.mobile.models.accounts.savings.SavingsWithAssociations import org.mifos.mobile.models.templates.account.AccountOptionsTemplate import org.mifos.mobile.models.templates.savings.SavingsAccountTemplate -import retrofit2.Response interface SavingsAccountRepository { suspend fun getSavingsWithAssociations( accountId: Long?, associationType: String?, - ): Response? + ): Flow - suspend fun getSavingAccountApplicationTemplate(clientId: Long?): Response? + suspend fun getSavingAccountApplicationTemplate(clientId: Long?): Flow - suspend fun submitSavingAccountApplication(payload: SavingsAccountApplicationPayload?): Response? + suspend fun submitSavingAccountApplication(payload: SavingsAccountApplicationPayload?): Flow suspend fun updateSavingsAccount( accountId: Long?, payload: SavingsAccountUpdatePayload? - ): Response? + ): Flow suspend fun submitWithdrawSavingsAccount( accountId: String?, payload: SavingsAccountWithdrawPayload? - ): Response? + ): Flow - suspend fun loanAccountTransferTemplate(): Response? + suspend fun loanAccountTransferTemplate(): Flow } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/SavingsAccountRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/SavingsAccountRepositoryImp.kt index 866a56aa4..daaf3a236 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/SavingsAccountRepositoryImp.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/SavingsAccountRepositoryImp.kt @@ -1,5 +1,7 @@ package org.mifos.mobile.repositories +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow import okhttp3.ResponseBody import org.mifos.mobile.api.DataManager import org.mifos.mobile.models.accounts.savings.SavingsAccountApplicationPayload @@ -8,7 +10,6 @@ import org.mifos.mobile.models.accounts.savings.SavingsAccountWithdrawPayload import org.mifos.mobile.models.accounts.savings.SavingsWithAssociations import org.mifos.mobile.models.templates.account.AccountOptionsTemplate import org.mifos.mobile.models.templates.savings.SavingsAccountTemplate -import retrofit2.Response import javax.inject.Inject class SavingsAccountRepositoryImp @Inject constructor(private val dataManager: DataManager) : @@ -17,33 +18,45 @@ class SavingsAccountRepositoryImp @Inject constructor(private val dataManager: D override suspend fun getSavingsWithAssociations( accountId: Long?, associationType: String? - ): Response? { - return dataManager.getSavingsWithAssociations(accountId, associationType) + ): Flow { + return flow { + emit(dataManager.getSavingsWithAssociations(accountId, associationType)) + } } - override suspend fun getSavingAccountApplicationTemplate(clientId: Long?): Response? { - return dataManager.getSavingAccountApplicationTemplate(clientId) + override suspend fun getSavingAccountApplicationTemplate(clientId: Long?): Flow { + return flow { + emit(dataManager.getSavingAccountApplicationTemplate(clientId)) + } } - override suspend fun submitSavingAccountApplication(payload: SavingsAccountApplicationPayload?): Response? { - return dataManager.submitSavingAccountApplication(payload) + override suspend fun submitSavingAccountApplication(payload: SavingsAccountApplicationPayload?): Flow { + return flow { + emit(dataManager.submitSavingAccountApplication(payload)) + } } override suspend fun updateSavingsAccount( accountId: Long?, payload: SavingsAccountUpdatePayload? - ): Response? { - return dataManager.updateSavingsAccount(accountId, payload) + ): Flow { + return flow { + emit(dataManager.updateSavingsAccount(accountId, payload)) + } } override suspend fun submitWithdrawSavingsAccount( accountId: String?, payload: SavingsAccountWithdrawPayload? - ): Response? { - return dataManager.submitWithdrawSavingsAccount(accountId, payload) + ): Flow { + return flow { + emit(dataManager.submitWithdrawSavingsAccount(accountId, payload)) + } } - override suspend fun loanAccountTransferTemplate(): Response? { - return dataManager.accountTransferTemplate() + override suspend fun loanAccountTransferTemplate(): Flow { + return flow { + emit(dataManager.accountTransferTemplate()) + } } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt index 180a8fba3..9a78a5e2c 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt @@ -11,9 +11,13 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.widget.Toast -import androidx.lifecycle.ViewModelProvider +import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch import org.mifos.mobile.R import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.databinding.FragmentSavingAccountDetailsBinding @@ -35,7 +39,6 @@ import org.mifos.mobile.utils.SymbolsUtils import org.mifos.mobile.utils.Toaster import org.mifos.mobile.utils.Utils import org.mifos.mobile.viewModels.SavingAccountsDetailViewModel -import java.lang.IllegalStateException import javax.inject.Inject /** @@ -51,7 +54,7 @@ class SavingAccountsDetailFragment : BaseFragment() { @JvmField @Inject var preferencesHelper: PreferencesHelper? = null - private lateinit var viewModel: SavingAccountsDetailViewModel + private val viewModel: SavingAccountsDetailViewModel by viewModels() private var savingsId: Long? = 0 private var status: Status? = null private var savingsWithAssociations: SavingsWithAssociations? = null @@ -71,7 +74,6 @@ class SavingAccountsDetailFragment : BaseFragment() { ): View { _binding = FragmentSavingAccountDetailsBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.saving_account_details)) - viewModel = ViewModelProvider(this)[SavingAccountsDetailViewModel::class.java] sweetUIErrorHandler = SweetUIErrorHandler(context, binding.root) if (savedInstanceState == null && this.savingsWithAssociations == null) { viewModel.loadSavingsWithAssociations(savingsId) @@ -84,52 +86,63 @@ class SavingAccountsDetailFragment : BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - binding.tvHelpLineNumber.setOnClickListener { - dialHelpLineNumber() - } - binding.tvDeposit.setOnClickListener { - deposit() - } + with(binding) { + tvHelpLineNumber.setOnClickListener { + dialHelpLineNumber() + } - binding.tvMakeATransfer.setOnClickListener { - transfer() - } - binding.layoutError.btnTryAgain.setOnClickListener { - onRetry() - } + tvDeposit.setOnClickListener { + deposit() + } - binding.llSavingsTransactions.setOnClickListener { - transactionsClicked() - } + tvMakeATransfer.setOnClickListener { + transfer() + } - binding.llSavingsCharges.setOnClickListener { - chargeClicked() - } + layoutError.btnTryAgain.setOnClickListener { + onRetry() + } - binding.llSavingsQrCode.setOnClickListener { - qrCodeClicked() + llSavingsTransactions.setOnClickListener { + transactionsClicked() + } + + llSavingsCharges.setOnClickListener { + chargeClicked() + } + + llSavingsQrCode.setOnClickListener { + qrCodeClicked() + } } - viewModel.savingAccountsDetailUiState.observe(viewLifecycleOwner) { state -> - when (state) { - SavingsAccountUiState.Loading -> showProgress() + viewLifecycleOwner.lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.savingAccountsDetailUiState.collect { state -> + when (state) { + SavingsAccountUiState.Loading -> showProgress() - SavingsAccountUiState.Error -> { - hideProgress() - showErrorFetchingSavingAccountsDetail( - context?.getString(R.string.error_saving_account_details_loading), - ) - } + SavingsAccountUiState.Error -> { + hideProgress() + showErrorFetchingSavingAccountsDetail( + context?.getString(R.string.error_saving_account_details_loading), + ) + } - is SavingsAccountUiState.SuccessLoadingSavingsWithAssociations -> { - hideProgress() - showSavingAccountsDetail(state.savingAccount) - } + is SavingsAccountUiState.SuccessLoadingSavingsWithAssociations -> { + hideProgress() + showSavingAccountsDetail(state.savingAccount) + } + + is SavingsAccountUiState.Initial -> {} - else -> throw IllegalStateException("Unexpected State: $state") + else -> throw IllegalStateException("Unexpected State: $state") + } + } } } + } override fun onSaveInstanceState(outState: Bundle) { diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt index 80eadb92d..a14ce55ad 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt @@ -15,12 +15,16 @@ import android.widget.RadioButton import android.widget.RadioGroup import android.widget.Toast import androidx.appcompat.widget.AppCompatCheckBox -import androidx.lifecycle.ViewModelProvider +import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentSavingAccountTransactionsBinding import org.mifos.mobile.models.CheckboxStatus @@ -52,7 +56,7 @@ class SavingAccountsTransactionFragment : BaseFragment() { private var _binding: FragmentSavingAccountTransactionsBinding? = null private val binding get() = _binding!! - private lateinit var viewModel: SavingAccountsTransactionViewModel + private val viewModel: SavingAccountsTransactionViewModel by viewModels() @JvmField @Inject @@ -87,7 +91,6 @@ class SavingAccountsTransactionFragment : BaseFragment() { savedInstanceState: Bundle?, ): View { _binding = FragmentSavingAccountTransactionsBinding.inflate(inflater, container, false) - viewModel = ViewModelProvider(this)[SavingAccountsTransactionViewModel::class.java] sweetUIErrorHandler = SweetUIErrorHandler(context, binding.root) showUserInterface() if (savedInstanceState == null) { @@ -99,32 +102,41 @@ class SavingAccountsTransactionFragment : BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - binding.tvHelpLineNumber.setOnClickListener { - dialHelpLineNumber() - } - binding.layoutError.btnTryAgain.setOnClickListener { - retryClicked() + + with(binding) { + tvHelpLineNumber.setOnClickListener { + dialHelpLineNumber() + } + layoutError.btnTryAgain.setOnClickListener { + retryClicked() + } } - viewModel.savingAccountsTransactionUiState.observe(viewLifecycleOwner) { state -> - when (state) { - SavingsAccountUiState.Loading -> showProgress() + viewLifecycleOwner.lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.savingAccountsTransactionUiState.collect { state -> + when (state) { + SavingsAccountUiState.Loading -> showProgress() - SavingsAccountUiState.Error -> { - hideProgress() - showErrorFetchingSavingAccountsDetail(context?.getString(R.string.saving_account_details)) - } + SavingsAccountUiState.Error -> { + hideProgress() + showErrorFetchingSavingAccountsDetail(context?.getString(R.string.saving_account_details)) + } - is SavingsAccountUiState.SuccessLoadingSavingsWithAssociations -> { - hideProgress() - showSavingAccountsDetail(state.savingAccount) - } + is SavingsAccountUiState.SuccessLoadingSavingsWithAssociations -> { + hideProgress() + showSavingAccountsDetail(state.savingAccount) + } - is SavingsAccountUiState.ShowFilteredTransactionsList -> { - showFilteredList(state.savingAccountsTransactionList) - } + is SavingsAccountUiState.ShowFilteredTransactionsList -> { + showFilteredList(state.savingAccountsTransactionList) + } + + is SavingsAccountUiState.Initial -> {} - else -> throw IllegalStateException("Unexpected State : $state") + else -> throw IllegalStateException("Unexpected State : $state") + } + } } } } @@ -176,7 +188,7 @@ class SavingAccountsTransactionFragment : BaseFragment() { * * @param savingsWithAssociations Contains [Transactions] for given Savings account. */ - fun showSavingAccountsDetail(savingsWithAssociations: SavingsWithAssociations?) { + private fun showSavingAccountsDetail(savingsWithAssociations: SavingsWithAssociations?) { binding.llAccount.visibility = View.VISIBLE this.savingsWithAssociations = savingsWithAssociations transactionsList = savingsWithAssociations?.transactions @@ -193,7 +205,7 @@ class SavingAccountsTransactionFragment : BaseFragment() { * * @param message Error message that tells the user about the problem. */ - fun showErrorFetchingSavingAccountsDetail(message: String?) { + private fun showErrorFetchingSavingAccountsDetail(message: String?) { if (!Network.isConnected(activity)) { sweetUIErrorHandler?.showSweetNoInternetUI( binding.rvSavingAccountsTransaction, @@ -227,7 +239,7 @@ class SavingAccountsTransactionFragment : BaseFragment() { /** * Provides with a filtered list according to the constraints used in `filter()` function */ - fun showFilteredList(list: List?) { + private fun showFilteredList(list: List?) { if (!list.isNullOrEmpty()) { Toaster.show(binding.root, getString(R.string.filtered)) transactionListAdapter?.setSavingAccountsTransactionList(list) @@ -236,7 +248,7 @@ class SavingAccountsTransactionFragment : BaseFragment() { } } - fun showEmptyTransactions() { + private fun showEmptyTransactions() { sweetUIErrorHandler?.showSweetEmptyUI( getString(R.string.transactions), R.drawable.ic_compare_arrows_black_24dp, diff --git a/app/src/main/java/org/mifos/mobile/utils/SavingsAccountUiState.kt b/app/src/main/java/org/mifos/mobile/utils/SavingsAccountUiState.kt index 5ec6e7d00..7ba8c719a 100644 --- a/app/src/main/java/org/mifos/mobile/utils/SavingsAccountUiState.kt +++ b/app/src/main/java/org/mifos/mobile/utils/SavingsAccountUiState.kt @@ -6,6 +6,7 @@ import org.mifos.mobile.models.templates.account.AccountOptionsTemplate import org.mifos.mobile.models.templates.savings.SavingsAccountTemplate sealed class SavingsAccountUiState { + object Initial : SavingsAccountUiState() object Loading : SavingsAccountUiState() object Error : SavingsAccountUiState() data class SuccessLoadingSavingsWithAssociations(val savingAccount: SavingsWithAssociations) : diff --git a/app/src/main/java/org/mifos/mobile/viewModels/SavingAccountsDetailViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/SavingAccountsDetailViewModel.kt index d7aa6a3b8..765df430d 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/SavingAccountsDetailViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/SavingAccountsDetailViewModel.kt @@ -1,10 +1,11 @@ package org.mifos.mobile.viewModels -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.launch import org.mifos.mobile.repositories.SavingsAccountRepository import org.mifos.mobile.utils.Constants @@ -15,8 +16,9 @@ import javax.inject.Inject class SavingAccountsDetailViewModel @Inject constructor(private val savingsAccountRepositoryImp: SavingsAccountRepository) : ViewModel() { - private val _savingAccountsDetailUiState = MutableLiveData() - val savingAccountsDetailUiState: LiveData get() = _savingAccountsDetailUiState + private val _savingAccountsDetailUiState = + MutableStateFlow(SavingsAccountUiState.Initial) + val savingAccountsDetailUiState: StateFlow get() = _savingAccountsDetailUiState /** * Load details of a particular saving account from the server and notify the view @@ -28,17 +30,14 @@ class SavingAccountsDetailViewModel @Inject constructor(private val savingsAccou fun loadSavingsWithAssociations(accountId: Long?) { viewModelScope.launch { _savingAccountsDetailUiState.value = SavingsAccountUiState.Loading - try { - val response = savingsAccountRepositoryImp.getSavingsWithAssociations( - accountId, - Constants.TRANSACTIONS, - ) - if (response?.isSuccessful == true) { - _savingAccountsDetailUiState.value = response.body() - ?.let { SavingsAccountUiState.SuccessLoadingSavingsWithAssociations(it) } - } - } catch (e: Throwable) { + savingsAccountRepositoryImp.getSavingsWithAssociations( + accountId, + Constants.TRANSACTIONS, + ).catch { _savingAccountsDetailUiState.value = SavingsAccountUiState.Error + }.collect { + _savingAccountsDetailUiState.value = + SavingsAccountUiState.SuccessLoadingSavingsWithAssociations(it) } } } diff --git a/app/src/main/java/org/mifos/mobile/viewModels/SavingAccountsTransactionViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/SavingAccountsTransactionViewModel.kt index 8733d9c38..58c6fb597 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/SavingAccountsTransactionViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/SavingAccountsTransactionViewModel.kt @@ -1,12 +1,13 @@ package org.mifos.mobile.viewModels -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import io.reactivex.Observable import io.reactivex.functions.Predicate +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.launch import org.mifos.mobile.models.CheckboxStatus import org.mifos.mobile.models.accounts.savings.Transactions @@ -21,8 +22,9 @@ import javax.inject.Inject class SavingAccountsTransactionViewModel @Inject constructor(private val savingsAccountRepositoryImp: SavingsAccountRepository) : ViewModel() { - private val _savingAccountsTransactionUiState = MutableLiveData() - val savingAccountsTransactionUiState: LiveData get() = _savingAccountsTransactionUiState + private val _savingAccountsTransactionUiState = + MutableStateFlow(SavingsAccountUiState.Initial) + val savingAccountsTransactionUiState: StateFlow get() = _savingAccountsTransactionUiState /** * Filters [List] of [CheckboxStatus] @@ -45,18 +47,14 @@ class SavingAccountsTransactionViewModel @Inject constructor(private val savings fun loadSavingsWithAssociations(accountId: Long) { viewModelScope.launch { _savingAccountsTransactionUiState.value = SavingsAccountUiState.Loading - try { - val response = savingsAccountRepositoryImp.getSavingsWithAssociations( - accountId, - Constants.TRANSACTIONS, - ) - if (response?.isSuccessful == true) { - _savingAccountsTransactionUiState.value = - response.body() - ?.let { SavingsAccountUiState.SuccessLoadingSavingsWithAssociations(it) } - } - } catch (e: Throwable) { + savingsAccountRepositoryImp.getSavingsWithAssociations( + accountId, + Constants.TRANSACTIONS, + ).catch { _savingAccountsTransactionUiState.value = SavingsAccountUiState.Error + }.collect { + _savingAccountsTransactionUiState.value = + SavingsAccountUiState.SuccessLoadingSavingsWithAssociations(it) } } } @@ -82,6 +80,7 @@ class SavingAccountsTransactionViewModel @Inject constructor(private val savings } .toList().blockingGet() } + else -> null } _savingAccountsTransactionUiState.value = diff --git a/app/src/main/java/org/mifos/mobile/viewModels/SavingsAccountApplicationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/SavingsAccountApplicationViewModel.kt index cdb611db9..261bd74fb 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/SavingsAccountApplicationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/SavingsAccountApplicationViewModel.kt @@ -1,25 +1,27 @@ package org.mifos.mobile.viewModels -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.launch import org.mifos.mobile.models.accounts.savings.SavingsAccountApplicationPayload import org.mifos.mobile.models.accounts.savings.SavingsAccountUpdatePayload import org.mifos.mobile.repositories.SavingsAccountRepository import org.mifos.mobile.ui.enums.SavingsAccountState import org.mifos.mobile.utils.SavingsAccountUiState -import retrofit2.HttpException import javax.inject.Inject @HiltViewModel class SavingsAccountApplicationViewModel @Inject constructor(private val savingsAccountRepositoryImp: SavingsAccountRepository) : ViewModel() { - private val _savingsAccountApplicationUiState = MutableLiveData() - val savingsAccountApplicationUiState: LiveData get() = _savingsAccountApplicationUiState + private val _savingsAccountApplicationUiState = + MutableStateFlow(SavingsAccountUiState.Initial) + val savingsAccountApplicationUiState: StateFlow get() = _savingsAccountApplicationUiState fun loadSavingsAccountApplicationTemplate( clientId: Long?, @@ -27,21 +29,17 @@ class SavingsAccountApplicationViewModel @Inject constructor(private val savings ) { viewModelScope.launch { _savingsAccountApplicationUiState.value = SavingsAccountUiState.Loading - try { - val response = - savingsAccountRepositoryImp.getSavingAccountApplicationTemplate(clientId) - if (response?.isSuccessful == true) { - if (state === SavingsAccountState.CREATE) { - _savingsAccountApplicationUiState.value = response.body()?.let { - SavingsAccountUiState.ShowUserInterfaceSavingAccountApplication(it) - } - } else { - _savingsAccountApplicationUiState.value = response.body() - ?.let { SavingsAccountUiState.ShowUserInterfaceSavingAccountUpdate(it) } - } - } - } catch (e: Throwable) { + savingsAccountRepositoryImp.getSavingAccountApplicationTemplate(clientId).catch { e -> _savingsAccountApplicationUiState.value = SavingsAccountUiState.ErrorMessage(e) + }.collect { + if (state === SavingsAccountState.CREATE) { + _savingsAccountApplicationUiState.value = + SavingsAccountUiState.ShowUserInterfaceSavingAccountApplication(it) + + } else { + _savingsAccountApplicationUiState.value = + SavingsAccountUiState.ShowUserInterfaceSavingAccountUpdate(it) + } } } } @@ -49,22 +47,13 @@ class SavingsAccountApplicationViewModel @Inject constructor(private val savings fun submitSavingsAccountApplication(payload: SavingsAccountApplicationPayload?) { viewModelScope.launch { _savingsAccountApplicationUiState.value = SavingsAccountUiState.Loading - try { - val response = savingsAccountRepositoryImp.submitSavingAccountApplication(payload) - if (response?.isSuccessful == true) { - _savingsAccountApplicationUiState.value = SavingsAccountUiState.HideProgress - _savingsAccountApplicationUiState.value = - SavingsAccountUiState.SavingsAccountApplicationSuccess - } else { - _savingsAccountApplicationUiState.value = - response?.let { HttpException(it) }?.let { - SavingsAccountUiState.ErrorMessage( - it - ) - } - } - } catch (e: Throwable) { + savingsAccountRepositoryImp.submitSavingAccountApplication(payload).catch { e -> _savingsAccountApplicationUiState.value = SavingsAccountUiState.ErrorMessage(e) + }.onCompletion { + _savingsAccountApplicationUiState.value = + SavingsAccountUiState.SavingsAccountApplicationSuccess + }.collect { + _savingsAccountApplicationUiState.value = SavingsAccountUiState.HideProgress } } } @@ -72,22 +61,13 @@ class SavingsAccountApplicationViewModel @Inject constructor(private val savings fun updateSavingsAccount(accountId: Long?, payload: SavingsAccountUpdatePayload?) { viewModelScope.launch { _savingsAccountApplicationUiState.value = SavingsAccountUiState.Loading - try { - val response = savingsAccountRepositoryImp.updateSavingsAccount(accountId, payload) - if (response?.isSuccessful == true) { - _savingsAccountApplicationUiState.value = SavingsAccountUiState.HideProgress - _savingsAccountApplicationUiState.value = - SavingsAccountUiState.SavingsAccountUpdateSuccess - } else { - _savingsAccountApplicationUiState.value = - response?.let { HttpException(it) }?.let { - SavingsAccountUiState.ErrorMessage( - it - ) - } - } - } catch (e: Throwable) { + savingsAccountRepositoryImp.updateSavingsAccount(accountId, payload).catch { e -> _savingsAccountApplicationUiState.value = SavingsAccountUiState.ErrorMessage(e) + }.onCompletion { + _savingsAccountApplicationUiState.value = + SavingsAccountUiState.SavingsAccountUpdateSuccess + }.collect { + _savingsAccountApplicationUiState.value = SavingsAccountUiState.HideProgress } } } diff --git a/app/src/main/java/org/mifos/mobile/viewModels/SavingsAccountWithdrawViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/SavingsAccountWithdrawViewModel.kt index 2172b83f4..a95ddeacb 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/SavingsAccountWithdrawViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/SavingsAccountWithdrawViewModel.kt @@ -1,24 +1,24 @@ package org.mifos.mobile.viewModels -import android.util.Log -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.launch import org.mifos.mobile.models.accounts.savings.SavingsAccountWithdrawPayload import org.mifos.mobile.repositories.SavingsAccountRepository import org.mifos.mobile.utils.SavingsAccountUiState -import retrofit2.HttpException import javax.inject.Inject @HiltViewModel class SavingsAccountWithdrawViewModel @Inject constructor(private val savingsAccountRepositoryImp: SavingsAccountRepository) : ViewModel() { - private val _savingsAccountWithdrawUiState = MutableLiveData() - val savingsAccountWithdrawUiState: LiveData get() = _savingsAccountWithdrawUiState + private val _savingsAccountWithdrawUiState = + MutableStateFlow(SavingsAccountUiState.Initial) + val savingsAccountWithdrawUiState: StateFlow get() = _savingsAccountWithdrawUiState fun submitWithdrawSavingsAccount( accountId: String?, @@ -26,21 +26,12 @@ class SavingsAccountWithdrawViewModel @Inject constructor(private val savingsAcc ) { viewModelScope.launch { _savingsAccountWithdrawUiState.value = SavingsAccountUiState.Loading - try { - val response = - savingsAccountRepositoryImp.submitWithdrawSavingsAccount(accountId, payload) - if (response?.isSuccessful == true) { - _savingsAccountWithdrawUiState.value = - SavingsAccountUiState.SavingsAccountWithdrawSuccess - } else { - _savingsAccountWithdrawUiState.value = response?.let { HttpException(it) }?.let { - SavingsAccountUiState.ErrorMessage( - it - ) - } - } - } catch (e: Throwable) { - _savingsAccountWithdrawUiState.value = SavingsAccountUiState.ErrorMessage(e) + savingsAccountRepositoryImp.submitWithdrawSavingsAccount(accountId, payload) + .catch { e -> + _savingsAccountWithdrawUiState.value = SavingsAccountUiState.ErrorMessage(e) + }.collect { + _savingsAccountWithdrawUiState.value = + SavingsAccountUiState.SavingsAccountWithdrawSuccess } } } diff --git a/app/src/main/java/org/mifos/mobile/viewModels/SavingsMakeTransferViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/SavingsMakeTransferViewModel.kt index 4b3302c05..7b7b01c1e 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/SavingsMakeTransferViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/SavingsMakeTransferViewModel.kt @@ -1,11 +1,12 @@ package org.mifos.mobile.viewModels -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import io.reactivex.Observable +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.launch import org.mifos.mobile.models.payload.AccountDetail import org.mifos.mobile.models.templates.account.AccountOption @@ -18,8 +19,9 @@ import javax.inject.Inject class SavingsMakeTransferViewModel @Inject constructor(private val savingsAccountRepositoryImp: SavingsAccountRepository) : ViewModel() { - private val _savingsMakeTransferUiState = MutableLiveData() - val savingsMakeTransferUiState: LiveData get() = _savingsMakeTransferUiState + private val _savingsMakeTransferUiState = + MutableStateFlow(SavingsAccountUiState.Initial) + val savingsMakeTransferUiState: StateFlow get() = _savingsMakeTransferUiState /** * Fetches [AccountOptionsTemplate] from server and notifies the view to display it. And @@ -28,14 +30,11 @@ class SavingsMakeTransferViewModel @Inject constructor(private val savingsAccoun fun loanAccountTransferTemplate() { viewModelScope.launch { _savingsMakeTransferUiState.value = SavingsAccountUiState.Loading - try { - val response = savingsAccountRepositoryImp.loanAccountTransferTemplate() - if (response?.isSuccessful == true) { - _savingsMakeTransferUiState.value = response.body() - ?.let { SavingsAccountUiState.ShowSavingsAccountTemplate(it) } - } - } catch (e: Throwable) { + savingsAccountRepositoryImp.loanAccountTransferTemplate().catch { e -> _savingsMakeTransferUiState.value = SavingsAccountUiState.ErrorMessage(e) + }.collect { + _savingsMakeTransferUiState.value = + SavingsAccountUiState.ShowSavingsAccountTemplate(it) } } }