TP-72546 | send money, collect request fixes (#11679)
This commit is contained in:
@@ -123,6 +123,9 @@ fun MainScreen(
|
||||
val rewardsNudgeDetailEntity by
|
||||
sendMoneyViewModel.rewardsNudgeDetailEntity.collectAsStateWithLifecycle()
|
||||
val mainCtaState by sendMoneyViewModel.mainCtaState.collectAsStateWithLifecycle()
|
||||
val lastExecutedActionBeforeOnboardingSdkTrigger by
|
||||
sendMoneyViewModel.lastExecutedActionBeforeOnboardingSdkTrigger
|
||||
.collectAsStateWithLifecycle()
|
||||
|
||||
val focusManager = LocalFocusManager.current
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
@@ -139,7 +142,7 @@ fun MainScreen(
|
||||
LaunchedEffect(key1 = Unit) {
|
||||
sendMoneyViewModel.shouldAutoFocusOnAmount.collect {
|
||||
sendMoneyViewModel.clearShouldAutoFocusOnAmountReplayCache()
|
||||
if (it) {
|
||||
if (it && lastExecutedActionBeforeOnboardingSdkTrigger == null) {
|
||||
focusRequester.requestFocus()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,7 +374,7 @@ fun SendMoneyScreen(
|
||||
}
|
||||
|
||||
BackHandler {
|
||||
if (bottomSheetState.isVisible) {
|
||||
if (bottomSheetState.isVisible && bottomSheetStateHolder.showBottomSheet) {
|
||||
sendMoneyViewModel.updateBottomSheetUIState(showBottomSheet = false)
|
||||
} else {
|
||||
onBackClick()
|
||||
|
||||
@@ -145,6 +145,7 @@ import com.navi.pay.utils.LITMUS_EXPERIMENT_NAVIPAY_PPS_TDS
|
||||
import com.navi.pay.utils.MAX_BANK_ACCOUNTS
|
||||
import com.navi.pay.utils.NAVI_AXIS_UPI_HANDLE
|
||||
import com.navi.pay.utils.NAVI_PAY_DEFAULT_MCC
|
||||
import com.navi.pay.utils.NAVI_PAY_PURPLE_CTA_LOADER_LOTTIE
|
||||
import com.navi.pay.utils.NAVI_PAY_UPI_LITE_LOGO_URL
|
||||
import com.navi.pay.utils.NOTES_REGEX
|
||||
import com.navi.pay.utils.NOTE_MAX_LENGTH
|
||||
@@ -174,6 +175,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -465,7 +467,11 @@ constructor(
|
||||
val statusBarColorForLottieTransition = _statusBarColorForLottieTransition.asSharedFlow()
|
||||
|
||||
private var naviPayCustomerStatus: String = ""
|
||||
private var lastExecutedActionBeforeOnboardingSdkTrigger: SendMoneyAction? = null
|
||||
|
||||
private val _lastExecutedActionBeforeOnboardingSdkTrigger =
|
||||
MutableStateFlow<SendMoneyAction?>(null)
|
||||
val lastExecutedActionBeforeOnboardingSdkTrigger =
|
||||
_lastExecutedActionBeforeOnboardingSdkTrigger.asStateFlow()
|
||||
|
||||
private val _onboardingSdkAction = MutableSharedFlow<Boolean>(replay = 1)
|
||||
val onboardingSdkAction = _onboardingSdkAction.asSharedFlow()
|
||||
@@ -506,7 +512,7 @@ constructor(
|
||||
|
||||
// Customer status has changed to LINKED_VPA
|
||||
|
||||
when (lastExecutedActionBeforeOnboardingSdkTrigger) {
|
||||
when (lastExecutedActionBeforeOnboardingSdkTrigger.value) {
|
||||
SendMoneyAction.StartPayment -> {
|
||||
val payButtonSource =
|
||||
when (mainCtaState.value) {
|
||||
@@ -515,13 +521,21 @@ constructor(
|
||||
else -> ""
|
||||
}
|
||||
|
||||
startPayment(payButtonSource = payButtonSource)
|
||||
showRedirectingBottomSheet()
|
||||
startPayment(
|
||||
payButtonSource = payButtonSource,
|
||||
isAutoTriggered = true
|
||||
)
|
||||
}
|
||||
SendMoneyAction.Approve -> {
|
||||
approveCollectRequest()
|
||||
showRedirectingBottomSheet()
|
||||
approveCollectRequest(isAutoTriggered = true)
|
||||
}
|
||||
SendMoneyAction.Decline -> {
|
||||
declineCollectRequest()
|
||||
showRedirectingBottomSheet(
|
||||
titleText = R.string.np_redirecting_decline_request
|
||||
)
|
||||
declineCollectRequest(isAutoTriggered = true)
|
||||
}
|
||||
SendMoneyAction.SetPin -> {
|
||||
// No action required
|
||||
@@ -534,6 +548,22 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun showRedirectingBottomSheet(
|
||||
titleText: Int = R.string.np_redirecting_make_payment
|
||||
) {
|
||||
updateBottomSheetUIState(
|
||||
showBottomSheet = true,
|
||||
bottomSheetStateChange = false,
|
||||
bottomSheetUIState =
|
||||
SendMoneyBottomSheetType.RedirectingBottomSheet(
|
||||
titleText = resourceProvider.getString(titleText),
|
||||
isDescriptionClickable = false,
|
||||
headerLottieFileName = NAVI_PAY_PURPLE_CTA_LOADER_LOTTIE
|
||||
)
|
||||
)
|
||||
delay(2.seconds)
|
||||
}
|
||||
|
||||
private fun updateLinkedAccounts(linkedAccounts: List<LinkedAccountEntity>) {
|
||||
_linkedAccounts.update { linkedAccounts }
|
||||
}
|
||||
@@ -676,7 +706,7 @@ constructor(
|
||||
|
||||
fun handleSetPinClick() {
|
||||
viewModelScope.launch(coroutineDispatcherProvider.io) {
|
||||
lastExecutedActionBeforeOnboardingSdkTrigger = SendMoneyAction.SetPin
|
||||
_lastExecutedActionBeforeOnboardingSdkTrigger.update { SendMoneyAction.SetPin }
|
||||
initiateOnboardingSdk()
|
||||
}
|
||||
}
|
||||
@@ -1184,8 +1214,11 @@ constructor(
|
||||
?: linkedAccounts.last()
|
||||
}
|
||||
|
||||
private fun checkIsInternetAvailableOrShowError(): Boolean {
|
||||
private fun checkIsInternetAvailableOrShowError(isAutoTriggered: Boolean = false): Boolean {
|
||||
if (!naviPayNetworkConnectivity.isInternetConnected()) {
|
||||
if (isAutoTriggered) {
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
}
|
||||
notifyError(getNoInternetErrorConfig())
|
||||
return false
|
||||
}
|
||||
@@ -1216,21 +1249,30 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkIsAirplaneModeOnOrShowError(): Boolean {
|
||||
private fun checkIsAirplaneModeOnOrShowError(isAutoTriggered: Boolean = false): Boolean {
|
||||
if (naviPayNetworkConnectivity.isAirplaneModeOn()) {
|
||||
if (isAutoTriggered) {
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
}
|
||||
notifyError(getAirplaneModeOnErrorConfig())
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private suspend fun validateSimInfoOrShowError(currentSimInfoList: List<SimInfo>): Boolean {
|
||||
private suspend fun validateSimInfoOrShowError(
|
||||
currentSimInfoList: List<SimInfo>,
|
||||
isAutoTriggered: Boolean = false
|
||||
): Boolean {
|
||||
val simInfoValidationResult =
|
||||
NaviPayCommonUtils.validateSimInfo(
|
||||
currentSimInfoList = currentSimInfoList,
|
||||
deviceInfoProvider = deviceInfoProvider
|
||||
)
|
||||
if (!simInfoValidationResult) {
|
||||
if (isAutoTriggered) {
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
}
|
||||
notifyError(getSimFailureErrorConfig(isNoSimPresent = currentSimInfoList.isEmpty()))
|
||||
return false
|
||||
}
|
||||
@@ -1285,10 +1327,12 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun startPayment(payButtonSource: String) {
|
||||
fun startPayment(payButtonSource: String, isAutoTriggered: Boolean = false) {
|
||||
viewModelScope.launch(coroutineDispatcherProvider.io) {
|
||||
if (isUserOnboarded().not()) {
|
||||
lastExecutedActionBeforeOnboardingSdkTrigger = SendMoneyAction.StartPayment
|
||||
_lastExecutedActionBeforeOnboardingSdkTrigger.update {
|
||||
SendMoneyAction.StartPayment
|
||||
}
|
||||
|
||||
// Post onboarding, prefer selecting the original selected account
|
||||
preferredBankAccountUniqueId =
|
||||
@@ -1307,11 +1351,21 @@ constructor(
|
||||
return@launch
|
||||
}
|
||||
|
||||
if (!checkIsInternetAvailableOrShowError()) return@launch
|
||||
if (checkIsAirplaneModeOnOrShowError()) return@launch
|
||||
if (!checkIsInternetAvailableOrShowError(isAutoTriggered = isAutoTriggered)) {
|
||||
return@launch
|
||||
}
|
||||
if (checkIsAirplaneModeOnOrShowError(isAutoTriggered = isAutoTriggered)) {
|
||||
return@launch
|
||||
}
|
||||
|
||||
val currentSimInfoList = naviPayNetworkConnectivity.getCurrentSimInfoList()
|
||||
if (!validateSimInfoOrShowError(currentSimInfoList)) return@launch
|
||||
if (!validateSimInfoOrShowError(currentSimInfoList, isAutoTriggered)) {
|
||||
return@launch
|
||||
}
|
||||
|
||||
if (selectedBankAccount.value == null && isAutoTriggered) {
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
}
|
||||
|
||||
var selectedBankAccount = selectedBankAccount.value ?: return@launch
|
||||
|
||||
@@ -1327,11 +1381,15 @@ constructor(
|
||||
}
|
||||
|
||||
updateSetDefaultStatusBarColor(setDefaultStatusBarColor = true)
|
||||
updateScreenState(
|
||||
screenState =
|
||||
if (isPaymentFromLiteAccount) SendMoneyScreenState.PaymentInProgressPostPinInput
|
||||
else SendMoneyScreenState.PaymentInProgressPrePinInput
|
||||
)
|
||||
|
||||
if (!isAutoTriggered) {
|
||||
updateScreenState(
|
||||
screenState =
|
||||
if (isPaymentFromLiteAccount)
|
||||
SendMoneyScreenState.PaymentInProgressPostPinInput
|
||||
else SendMoneyScreenState.PaymentInProgressPrePinInput
|
||||
)
|
||||
}
|
||||
|
||||
val isExternalUpiRequestIdAvailable =
|
||||
(transactionType == UpiTransactionType.SCAN_PAY ||
|
||||
@@ -1343,6 +1401,9 @@ constructor(
|
||||
else upiRequestIdUseCase.execute()
|
||||
|
||||
if (upiRequestId.isBlank()) {
|
||||
if (isAutoTriggered) {
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
}
|
||||
notifyError(getGenericErrorConfig())
|
||||
return@launch
|
||||
}
|
||||
@@ -1408,6 +1469,9 @@ constructor(
|
||||
) { npciResult ->
|
||||
when (npciResult) {
|
||||
is NpciResult.Success -> {
|
||||
if (isAutoTriggered) {
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
}
|
||||
onClSuccessCallback(
|
||||
isExternalUpiRequestIdAvailable = isExternalUpiRequestIdAvailable,
|
||||
upiRequestId = upiRequestId,
|
||||
@@ -1761,6 +1825,7 @@ constructor(
|
||||
}
|
||||
|
||||
private fun handleNpciError(npciError: NpciResult.Error, upiRequestId: String) {
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
if (source == SendMoneyScreenSource.PMS) {
|
||||
val errorConfig =
|
||||
if (npciError.isUserAborted) NaviPayCommonUtils.getBackPressErrorConfig()
|
||||
@@ -2175,21 +2240,32 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun approveCollectRequest() {
|
||||
fun approveCollectRequest(isAutoTriggered: Boolean = false) {
|
||||
viewModelScope.launch {
|
||||
if (isUserOnboarded().not()) {
|
||||
lastExecutedActionBeforeOnboardingSdkTrigger = SendMoneyAction.Approve
|
||||
_lastExecutedActionBeforeOnboardingSdkTrigger.update { SendMoneyAction.Approve }
|
||||
initiateOnboardingSdk()
|
||||
return@launch
|
||||
}
|
||||
|
||||
if (!checkIsInternetAvailableOrShowError()) return@launch
|
||||
if (checkIsAirplaneModeOnOrShowError()) return@launch
|
||||
if (!checkIsInternetAvailableOrShowError()) {
|
||||
return@launch
|
||||
}
|
||||
if (checkIsAirplaneModeOnOrShowError()) {
|
||||
return@launch
|
||||
}
|
||||
|
||||
val currentSimInfoList = naviPayNetworkConnectivity.getCurrentSimInfoList()
|
||||
if (!validateSimInfoOrShowError(currentSimInfoList)) return@launch
|
||||
if (!validateSimInfoOrShowError(currentSimInfoList)) {
|
||||
return@launch
|
||||
}
|
||||
|
||||
if (source !is SendMoneyScreenSource.CollectRequest) return@launch
|
||||
if (source !is SendMoneyScreenSource.CollectRequest) {
|
||||
if (isAutoTriggered) {
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
|
||||
val updatedBankAccount =
|
||||
if (source.collectType.equals(REQUEST_TYPE_MANDATE, ignoreCase = true)) {
|
||||
@@ -2211,9 +2287,16 @@ constructor(
|
||||
selectedBankAccount.value
|
||||
}
|
||||
|
||||
if (updatedBankAccount == null) return@launch
|
||||
if (updatedBankAccount == null) {
|
||||
if (isAutoTriggered) {
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
|
||||
updateScreenState(screenState = SendMoneyScreenState.PaymentInProgressPrePinInput)
|
||||
if (!isAutoTriggered) {
|
||||
updateScreenState(screenState = SendMoneyScreenState.PaymentInProgressPrePinInput)
|
||||
}
|
||||
|
||||
val upiRequestId = payeeEntity.value.transactionId ?: ""
|
||||
|
||||
@@ -2240,6 +2323,9 @@ constructor(
|
||||
npciRepository.fetchCredentials(npciCredData = npciCredData) { npciResult ->
|
||||
when (npciResult) {
|
||||
is NpciResult.Success -> {
|
||||
if (isAutoTriggered) {
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
}
|
||||
processCollectRequest(
|
||||
collectRequestAction = CollectRequestAction.APPROVE,
|
||||
upiRequestId = upiRequestId,
|
||||
@@ -2258,14 +2344,19 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun declineCollectRequest() {
|
||||
fun declineCollectRequest(isAutoTriggered: Boolean = false) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
if (isUserOnboarded().not()) {
|
||||
lastExecutedActionBeforeOnboardingSdkTrigger = SendMoneyAction.Decline
|
||||
_lastExecutedActionBeforeOnboardingSdkTrigger.update { SendMoneyAction.Decline }
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
initiateOnboardingSdk()
|
||||
return@launch
|
||||
}
|
||||
|
||||
if (selectedBankAccount.value == null && isAutoTriggered) {
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
}
|
||||
|
||||
val selectedBankAccount = selectedBankAccount.value ?: return@launch
|
||||
val upiRequestId = payeeEntity.value.transactionId ?: ""
|
||||
|
||||
@@ -2276,12 +2367,12 @@ constructor(
|
||||
note = getNoteValue()
|
||||
)
|
||||
)
|
||||
|
||||
processCollectRequest(
|
||||
collectRequestAction = CollectRequestAction.DECLINE,
|
||||
upiRequestId = upiRequestId,
|
||||
credBlock = null,
|
||||
selectedBankAccount = selectedBankAccount
|
||||
selectedBankAccount = selectedBankAccount,
|
||||
isAutoTriggered = isAutoTriggered
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2290,27 +2381,29 @@ constructor(
|
||||
collectRequestAction: CollectRequestAction,
|
||||
upiRequestId: String,
|
||||
credBlock: String?,
|
||||
selectedBankAccount: LinkedAccountEntity
|
||||
selectedBankAccount: LinkedAccountEntity,
|
||||
isAutoTriggered: Boolean = false
|
||||
) {
|
||||
if (source !is SendMoneyScreenSource.CollectRequest) return
|
||||
|
||||
viewModelScope.launch(coroutineDispatcherProvider.io) {
|
||||
if (!naviPayNetworkConnectivity.isInternetConnected()) {
|
||||
notifyError(getNoInternetErrorConfig())
|
||||
if (!checkIsInternetAvailableOrShowError(isAutoTriggered = isAutoTriggered)) {
|
||||
return@launch
|
||||
}
|
||||
sharedPreferenceRepository.saveBooleanValue(PENDING_REQUEST_REFRESHED_REQUIRED, true)
|
||||
|
||||
if (collectRequestAction == CollectRequestAction.DECLINE) {
|
||||
updateBottomSheetUIState(
|
||||
showBottomSheet = true,
|
||||
bottomSheetUIState =
|
||||
SendMoneyBottomSheetType.Loading(
|
||||
headerResId = R.string.declining_request,
|
||||
descriptionResId = R.string.loading_bottom_sheet_description
|
||||
),
|
||||
bottomSheetStateChange = false
|
||||
)
|
||||
if (!isAutoTriggered) {
|
||||
updateBottomSheetUIState(
|
||||
showBottomSheet = true,
|
||||
bottomSheetUIState =
|
||||
SendMoneyBottomSheetType.Loading(
|
||||
headerResId = R.string.declining_request,
|
||||
descriptionResId = R.string.loading_bottom_sheet_description
|
||||
),
|
||||
bottomSheetStateChange = false
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// for approve case, showing full screen loader. So hiding bottom sheet.
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
|
||||
@@ -1542,29 +1542,35 @@ constructor(
|
||||
)
|
||||
}
|
||||
|
||||
private fun checkIsInternetAvailableOrShowError(): Boolean {
|
||||
private fun checkIsInternetAvailableOrShowError(isAutoTriggered: Boolean = false): Boolean {
|
||||
if (!naviPayNetworkConnectivity.isInternetConnected()) {
|
||||
if (isAutoTriggered) updateBottomSheetUIState(bottomSheetStateChange = false)
|
||||
notifyError(getNoInternetErrorConfig())
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun checkIsAirplaneModeOnOrShowError(): Boolean {
|
||||
private fun checkIsAirplaneModeOnOrShowError(isAutoTriggered: Boolean = false): Boolean {
|
||||
if (naviPayNetworkConnectivity.isAirplaneModeOn()) {
|
||||
if (isAutoTriggered) updateBottomSheetUIState(bottomSheetStateChange = false)
|
||||
notifyError(getAirplaneModeOnErrorConfig())
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private suspend fun validateSimInfoOrShowError(currentSimInfoList: List<SimInfo>): Boolean {
|
||||
private suspend fun validateSimInfoOrShowError(
|
||||
currentSimInfoList: List<SimInfo>,
|
||||
isAutoTriggered: Boolean = false
|
||||
): Boolean {
|
||||
val simInfoValidationResult =
|
||||
NaviPayCommonUtils.validateSimInfo(
|
||||
currentSimInfoList = currentSimInfoList,
|
||||
deviceInfoProvider = deviceInfoProvider
|
||||
)
|
||||
if (!simInfoValidationResult) {
|
||||
if (isAutoTriggered) updateBottomSheetUIState(bottomSheetStateChange = false)
|
||||
notifyError(getSimFailureErrorConfig(isNoSimPresent = currentSimInfoList.isEmpty()))
|
||||
return false
|
||||
}
|
||||
@@ -1879,11 +1885,13 @@ constructor(
|
||||
shouldAutoInitTopUp: Boolean = false
|
||||
) {
|
||||
viewModelScope.launch(coroutineDispatcherProvider.io) {
|
||||
if (!checkIsInternetAvailableOrShowError()) return@launch
|
||||
if (checkIsAirplaneModeOnOrShowError()) return@launch
|
||||
if (!checkIsInternetAvailableOrShowError(isAutoTriggered = shouldAutoInitTopUp))
|
||||
return@launch
|
||||
if (checkIsAirplaneModeOnOrShowError(isAutoTriggered = shouldAutoInitTopUp))
|
||||
return@launch
|
||||
|
||||
val currentSimInfoList = naviPayNetworkConnectivity.getCurrentSimInfoList()
|
||||
if (!validateSimInfoOrShowError(currentSimInfoList)) return@launch
|
||||
if (!validateSimInfoOrShowError(currentSimInfoList, shouldAutoInitTopUp)) return@launch
|
||||
|
||||
updateEnableButtonLottieState(isLoaderVisible = false)
|
||||
if (loadMoneyType == LoadMoneyType.INITIAL_TOPUP || shouldAutoInitTopUp) {
|
||||
|
||||
@@ -850,4 +850,6 @@
|
||||
<string name="np_bbps_payment_failed">Payment failed</string>
|
||||
<string name="np_bbps_pending_payment_description">We will update the payment status soon.</string>
|
||||
<string name="np_bbps_recharge_pending_message">Your recharge may reflect within 48 hours</string>
|
||||
<string name="np_redirecting_make_payment">Redirecting you to make payment</string>
|
||||
<string name="np_redirecting_decline_request">Declining the payment request</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user