From 68e53127806c6e3359a4834869cb5f864ee069d1 Mon Sep 17 00:00:00 2001 From: Aditya Narayan Malik Date: Tue, 1 Jul 2025 19:19:14 +0530 Subject: [PATCH] NTP-63094 | DataInitAndSyncUseCase for UPI (#16790) --- .../navi/pay/analytics/NaviPayAnalytics.kt | 50 ++-- .../common/settingscreen/ui/UPISettingSDK.kt | 5 +- .../viewmodel/SettingSDKViewmodel.kt | 11 + .../common/usecase/BankUptimePollerUseCase.kt | 14 +- .../usecase/NaviPayDataSetupAndSyncUseCase.kt | 223 ++++++++++++++++++ .../com/navi/pay/entry/NaviPayViewModel.kt | 216 +---------------- 6 files changed, 275 insertions(+), 244 deletions(-) create mode 100644 android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/NaviPayDataSetupAndSyncUseCase.kt diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/analytics/NaviPayAnalytics.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/analytics/NaviPayAnalytics.kt index 77b9322988..a70de2f994 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/analytics/NaviPayAnalytics.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/analytics/NaviPayAnalytics.kt @@ -6248,6 +6248,32 @@ class NaviPayAnalytics private constructor() { NaviTrackEvent.trackEventOnClickStream("NaviPay_ViewModel_Init") } + fun onBlockedVpaBottomSheetDescriptionClicked() { + NaviTrackEvent.trackEventOnClickStream( + "NaviPay_BlockedVpaBottomSheetDescriptionClicked" + ) + } + + fun onBlockedVpaBottomSheetLanded() { + NaviTrackEvent.trackEventOnClickStream("NaviPay_BlockedVpaBottomSheetLanded") + } + } + + inner class NaviPayDataInitAndSyncUseCase { + fun onCustomerDataFetchSuccess(phoneNumber: String, customerData: DocumentSnapshot?) { + NaviTrackEvent.trackEventOnClickStream( + "NaviPay_Dev_ViewModel_CustomerDataFetchSuccess", + mapOf("phoneNumber" to phoneNumber, "customerData" to customerData.toString()), + ) + } + + fun onCustomerDataFetchFailed(phoneNumber: String, exception: Exception) { + NaviTrackEvent.trackEventOnClickStream( + "NaviPay_Dev_ViewModel_CustomerDataFetchFailed", + mapOf("phoneNumber" to phoneNumber, "exception" to exception.toString()), + ) + } + fun onErrorOccurredInGetQuerySnapshot(exception: Exception) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_ViewModel_ErrorOccurredInGetQuerySnapshot", @@ -6267,30 +6293,6 @@ class NaviPayAnalytics private constructor() { ), ) } - - fun onCustomerDataFetchSuccess(phoneNumber: String, customerData: DocumentSnapshot?) { - NaviTrackEvent.trackEventOnClickStream( - "NaviPay_Dev_ViewModel_CustomerDataFetchSuccess", - mapOf("phoneNumber" to phoneNumber, "customerData" to customerData.toString()), - ) - } - - fun onCustomerDataFetchFailed(phoneNumber: String, exception: Exception) { - NaviTrackEvent.trackEventOnClickStream( - "NaviPay_Dev_ViewModel_CustomerDataFetchFailed", - mapOf("phoneNumber" to phoneNumber, "exception" to exception.toString()), - ) - } - - fun onBlockedVpaBottomSheetDescriptionClicked() { - NaviTrackEvent.trackEventOnClickStream( - "NaviPay_BlockedVpaBottomSheetDescriptionClicked" - ) - } - - fun onBlockedVpaBottomSheetLanded() { - NaviTrackEvent.trackEventOnClickStream("NaviPay_BlockedVpaBottomSheetLanded") - } } inner class NaviPayActivateVpa { diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/ui/UPISettingSDK.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/ui/UPISettingSDK.kt index 7b60096fe1..f8e77a89a9 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/ui/UPISettingSDK.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/ui/UPISettingSDK.kt @@ -115,7 +115,10 @@ fun UPISettingSDK( val naviSettingSDKAnalytics: NaviPayAnalytics.NaviSettingSDK = remember { NaviPayAnalytics.INSTANCE.NaviSettingSDK() } - LaunchedEffect(Unit) { naviSettingSDKAnalytics.onUPISettingSDKLand() } + LaunchedEffect(Unit) { + naviSettingSDKAnalytics.onUPISettingSDKLand() + settingSDKViewmodel.performInitialDataSetupAndSync() + } LaunchedEffect(Unit) { settingSDKViewmodel.navigateToCtaUrl.collect { actionData -> diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/viewmodel/SettingSDKViewmodel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/viewmodel/SettingSDKViewmodel.kt index 98b0ef9600..f33961b341 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/viewmodel/SettingSDKViewmodel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/viewmodel/SettingSDKViewmodel.kt @@ -36,6 +36,7 @@ import com.navi.pay.common.settingscreen.viewmodel.RccRewardStripType.Companion. import com.navi.pay.common.setup.NaviPayCustomerStatusHandler import com.navi.pay.common.setup.NaviPayManager import com.navi.pay.common.usecase.LinkedAccountsUseCase +import com.navi.pay.common.usecase.NaviPayDataSetupAndSyncUseCase import com.navi.pay.common.utils.NaviPayNotificationHandler import com.navi.pay.common.utils.NaviPayOnboardingNavigator import com.navi.pay.common.utils.getMetricInfo @@ -94,6 +95,7 @@ constructor( @NaviPayGsonBuilder private val gson: Gson, private val settingSDKRepository: SettingSDKRepository, private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, + private val naviPayDataSetupAndSyncUseCase: NaviPayDataSetupAndSyncUseCase, ) : NaviPayBaseVM() { private val _upiSettingDetails = MutableStateFlow(UpiSettingDetails()) @@ -174,6 +176,15 @@ constructor( fetchRccRewardInfo() } + fun performInitialDataSetupAndSync() { + viewModelScope.launch(Dispatchers.IO) { + naviPayDataSetupAndSyncUseCase.execute( + screenName = screenName, + numberOfPollerIterations = 1, + ) + } + } + private fun fetchRccRewardInfo() { viewModelScope.launch(Dispatchers.IO) { val rccRewardsExperimentData = diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/BankUptimePollerUseCase.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/BankUptimePollerUseCase.kt index c4720e7426..79c434c6a3 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/BankUptimePollerUseCase.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/BankUptimePollerUseCase.kt @@ -25,13 +25,15 @@ constructor( private val bankUptimeRepository: BankUptimeRepository, ) { private val BANK_UPTIME_POLLING_INTERVAL = 10.minutes - private val bankUptimePoller by lazy { - NaviApiPoller(repeatInterval = BANK_UPTIME_POLLING_INTERVAL, numberOfIterations = 3) - } - private val naviPayAnalytics: NaviPayAnalytics.NaviPayViewModel = - NaviPayAnalytics.INSTANCE.NaviPayViewModel() + private val naviPayAnalytics: NaviPayAnalytics.NaviPayDataInitAndSyncUseCase = + NaviPayAnalytics.INSTANCE.NaviPayDataInitAndSyncUseCase() - suspend fun executePollerForBankUptime() { + suspend fun executePollerForBankUptime(numberOfIterations: Int = 3) { + val bankUptimePoller = + NaviApiPoller( + repeatInterval = BANK_UPTIME_POLLING_INTERVAL, + numberOfIterations = numberOfIterations, + ) bankUptimePoller .startPolling { try { diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/NaviPayDataSetupAndSyncUseCase.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/NaviPayDataSetupAndSyncUseCase.kt new file mode 100644 index 0000000000..f5726649b6 --- /dev/null +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/NaviPayDataSetupAndSyncUseCase.kt @@ -0,0 +1,223 @@ +/* + * + * * Copyright © 2025 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.pay.common.usecase + +import com.google.firebase.firestore.DocumentSnapshot +import com.google.firebase.firestore.QuerySnapshot +import com.google.gson.Gson +import com.navi.base.cache.model.NaviCacheEntity +import com.navi.base.cache.repository.NaviCacheRepository +import com.navi.base.utils.BaseUtils.getPhoneNumberWithNinetyOneCode +import com.navi.base.utils.FirestoreDataProvider +import com.navi.base.utils.toBooleanWithSafe +import com.navi.common.usecase.SyncLitmusExperimentUseCase +import com.navi.common.utils.NaviApiPoller +import com.navi.pay.BuildConfig +import com.navi.pay.analytics.NaviPayAnalytics +import com.navi.pay.common.batman.DarkKnightScheduler +import com.navi.pay.common.model.view.PspType +import com.navi.pay.common.usecase.lite.LiteAccountSyncUseCase +import com.navi.pay.common.utils.generateSHA256Hash +import com.navi.pay.management.upinumber.list.model.view.toUpiNumberEntity +import com.navi.pay.management.upinumber.list.repository.UpiNumberRepository +import com.navi.pay.network.di.NaviPayGsonBuilder +import com.navi.pay.tstore.list.usecase.SyncOrderHistoryUseCase +import com.navi.pay.utils.FIRESTORE_CUSTOMER_DATA_COLLECTION_PATH +import com.navi.pay.utils.FIRESTORE_PSP_ROUTING_BUCKETS_COLLECTION_PATH +import com.navi.pay.utils.IS_TRANSACTION_HISTORY_SYNCED_ONCE +import com.navi.pay.utils.NAVI_PAY_LITMUS_EXPERIMENTS +import com.navi.pay.utils.NAVI_PAY_PSP_ROUTING_BUCKETS_KEY +import com.navi.payments.shared.feature.arc.usecase.ArcNudgeSyncUseCase +import javax.inject.Inject +import kotlin.time.Duration.Companion.seconds +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class NaviPayDataSetupAndSyncUseCase +@Inject +constructor( + private val refreshConfigUseCase: RefreshConfigUseCase, + private val refreshLinkedAccountsUseCase: RefreshLinkedAccountsUseCase, + private val refreshBankListUseCase: RefreshBankListUseCase, + private val firestoreDataProvider: FirestoreDataProvider, + private val syncLitmusExperimentsUseCase: SyncLitmusExperimentUseCase, + private val refreshUpiNumbersUseCase: RefreshUpiNumbersUseCase, + private val arcNudgeSyncUseCase: ArcNudgeSyncUseCase, + private val syncUpiLiteMandateInfoUseCase: SyncUpiLiteMandateInfoUseCase, + private val bankUptimePollerUseCase: BankUptimePollerUseCase, + private val liteAccountSyncUseCase: LiteAccountSyncUseCase, + private val syncOrderHistoryUseCase: SyncOrderHistoryUseCase, + private val darkKnightScheduler: DarkKnightScheduler, + private val upiNumberRepository: UpiNumberRepository, + private val naviCacheRepository: NaviCacheRepository, + @NaviPayGsonBuilder private val gson: Gson, +) { + private val customerDataPoller by lazy { + NaviApiPoller(repeatInterval = 5.seconds, numberOfIterations = 1) + } + + private val pspRoutingBucketsPoller by lazy { + NaviApiPoller(repeatInterval = 5.seconds, numberOfIterations = 1) + } + + private val naviPayAnalytics: NaviPayAnalytics.NaviPayDataInitAndSyncUseCase = + NaviPayAnalytics.INSTANCE.NaviPayDataInitAndSyncUseCase() + + suspend fun execute(screenName: String, numberOfPollerIterations: Int = 3) = + withContext(Dispatchers.IO) { + launch { refreshBankListUseCase.execute(screenName = screenName) } + launch { refreshConfigUseCase.execute(screenName = screenName) } + launch { + syncLitmusExperimentsUseCase.execute(experiments = NAVI_PAY_LITMUS_EXPERIMENTS) + } + launch { + refreshLinkedAccountsUseCase.execute( + skipLastSyncedTimestampCheck = false, + screenName = screenName, + ) + } + launch { + refreshUpiNumbersUseCase.execute( + skipLastSyncedTimestampCheck = false, + screenName = screenName, + ) + } + + launch { syncUpiLiteMandateInfoUseCase.execute(screenName = screenName) } + + launch { arcNudgeSyncUseCase.execute() } + + launch { + bankUptimePollerUseCase.executePollerForBankUptime( + numberOfIterations = numberOfPollerIterations + ) + } + + launch { initFireStorePollerForCustomerData() } + + launch { initFireStorePollerForPspRoutingBuckets() } + + launch { liteAccountSyncUseCase.execute(screenName = screenName) } + + launch { darkKnightScheduler.schedulePeriodicSync() } + + launch { syncTransactionHistory(screenName = screenName) } + } + + @OptIn(DelicateCoroutinesApi::class) + private suspend fun initFireStorePollerForCustomerData() { + customerDataPoller + .startPolling { + try { + firestoreDataProvider.getDocumentSnapShotForDocumentPath( + documentPath = + "$FIRESTORE_CUSTOMER_DATA_COLLECTION_PATH/${generateSHA256Hash(input = "${getPhoneNumberWithNinetyOneCode()}${BuildConfig.NAVIPAY_FIRESTORE_CUSTOMER_DATA_SALT}")}" + ) + } catch (exception: Exception) { + naviPayAnalytics.onCustomerDataFetchFailed( + phoneNumber = getPhoneNumberWithNinetyOneCode(), + exception = exception, + ) + customerDataPoller.stopPolling() + } + } + .collect { + try { + val customerDataDocumentSnapshot = it as? DocumentSnapshot? + naviPayAnalytics.onCustomerDataFetchSuccess( + phoneNumber = getPhoneNumberWithNinetyOneCode(), + customerData = customerDataDocumentSnapshot, + ) + processDocumentSnapShotForCustomerData( + customerDataDocumentSnapshot = customerDataDocumentSnapshot + ) + } catch (exception: Exception) { + naviPayAnalytics.onCustomerDataFetchFailed( + phoneNumber = getPhoneNumberWithNinetyOneCode(), + exception = exception, + ) + customerDataPoller.stopPolling() + } + } + } + + private suspend fun initFireStorePollerForPspRoutingBuckets() { + pspRoutingBucketsPoller + .startPolling { + try { + firestoreDataProvider.getQuerySnapShotForCollectionPath( + collectionPath = FIRESTORE_PSP_ROUTING_BUCKETS_COLLECTION_PATH + ) + } catch (exception: Exception) { + naviPayAnalytics.onErrorOccurredInGetQuerySnapshot(exception = exception) + pspRoutingBucketsPoller.stopPolling() + } + } + .collect { + try { + val pspRoutingBucketsQuerySnapshot = it as? QuerySnapshot? + processQuerySnapShotForPspRoutingBuckets( + pspRoutingBucketsQuerySnapShot = pspRoutingBucketsQuerySnapshot + ) + } catch (exception: Exception) { + naviPayAnalytics.onErrorOccurredInProcessingQuerySnapshot(exception = exception) + pspRoutingBucketsPoller.stopPolling() + } + } + } + + private suspend fun processDocumentSnapShotForCustomerData( + customerDataDocumentSnapshot: DocumentSnapshot? + ) { + customerDataDocumentSnapshot?.let { documentSnapshot -> + val upiNumberData = documentSnapshot.get("upiNumberData") as? Map + upiNumberData?.let { data -> + upiNumberRepository.upsertUpiNumberEntity( + upiNumberEntity = data.toUpiNumberEntity() + ) + } + } + } + + private suspend fun processQuerySnapShotForPspRoutingBuckets( + pspRoutingBucketsQuerySnapShot: QuerySnapshot? + ) { + pspRoutingBucketsQuerySnapShot?.let { querySnapshot -> + val routingDistribution = mutableMapOf>() + querySnapshot.documents.forEach { documentSnapshot -> + val bucketId = documentSnapshot.id + val config: Map? = documentSnapshot.data as? Map + if (config != null) { + routingDistribution[bucketId] = config + } + } + naviCacheRepository.save( + naviCacheEntity = + NaviCacheEntity( + key = NAVI_PAY_PSP_ROUTING_BUCKETS_KEY, + value = gson.toJson(routingDistribution), + version = 1, + ) + ) + } + } + + /** + * Sync transaction history only when user enters UPI flow for the first time or after logout + * and login. After that, it will not sync again. + */ + private suspend fun syncTransactionHistory(screenName: String) { + val syncStatus = naviCacheRepository.get(key = IS_TRANSACTION_HISTORY_SYNCED_ONCE)?.value + val isAlreadySynced = syncStatus.toBooleanWithSafe() + if (!isAlreadySynced) { + syncOrderHistoryUseCase.execute(screenName) + } + } +} diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayViewModel.kt index 1f756686f0..38ac109bee 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayViewModel.kt @@ -11,59 +11,28 @@ import android.content.Intent import android.net.Uri import android.os.Bundle import androidx.lifecycle.viewModelScope -import com.google.firebase.firestore.DocumentSnapshot -import com.google.firebase.firestore.QuerySnapshot -import com.google.gson.Gson import com.google.gson.reflect.TypeToken -import com.navi.base.cache.model.NaviCacheEntity -import com.navi.base.cache.repository.NaviCacheRepository -import com.navi.base.utils.BaseUtils.getPhoneNumberWithNinetyOneCode -import com.navi.base.utils.FirestoreDataProvider -import com.navi.base.utils.toBooleanWithSafe import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper import com.navi.common.model.AppUpgradeResponse import com.navi.common.upi.WITHOUT_ONBOARDING_FLOW -import com.navi.common.usecase.SyncLitmusExperimentUseCase import com.navi.common.utils.EMPTY -import com.navi.common.utils.NaviApiPoller -import com.navi.pay.BuildConfig import com.navi.pay.analytics.NaviPayAnalytics import com.navi.pay.analytics.NaviPayAnalytics.Companion.NAVI_PAY_ACTIVITY -import com.navi.pay.common.batman.DarkKnightScheduler import com.navi.pay.common.model.config.NaviPayDefaultConfig import com.navi.pay.common.model.view.NaviPayScreenType -import com.navi.pay.common.model.view.PspType import com.navi.pay.common.setup.NaviPayCustomerStatusHandler import com.navi.pay.common.setup.NaviPayManager import com.navi.pay.common.setup.NaviPayRouter -import com.navi.pay.common.usecase.BankUptimePollerUseCase import com.navi.pay.common.usecase.NaviPayConfigUseCase -import com.navi.pay.common.usecase.RefreshBankListUseCase -import com.navi.pay.common.usecase.RefreshConfigUseCase -import com.navi.pay.common.usecase.RefreshLinkedAccountsUseCase -import com.navi.pay.common.usecase.RefreshUpiNumbersUseCase -import com.navi.pay.common.usecase.SyncUpiLiteMandateInfoUseCase -import com.navi.pay.common.usecase.lite.LiteAccountSyncUseCase -import com.navi.pay.common.utils.generateSHA256Hash +import com.navi.pay.common.usecase.NaviPayDataSetupAndSyncUseCase import com.navi.pay.common.utils.getIncomingUrlFromIntent import com.navi.pay.common.viewmodel.NaviPayBaseVM import com.navi.pay.management.chat.util.SyncConversationsUseCase import com.navi.pay.management.chat.util.SyncMessagesUseCase -import com.navi.pay.management.upinumber.list.model.view.toUpiNumberEntity -import com.navi.pay.management.upinumber.list.repository.UpiNumberRepository -import com.navi.pay.network.di.NaviPayGsonBuilder -import com.navi.pay.tstore.list.usecase.SyncOrderHistoryUseCase import com.navi.pay.utils.DEFAULT_CONFIG -import com.navi.pay.utils.FIRESTORE_CUSTOMER_DATA_COLLECTION_PATH -import com.navi.pay.utils.FIRESTORE_PSP_ROUTING_BUCKETS_COLLECTION_PATH -import com.navi.pay.utils.IS_TRANSACTION_HISTORY_SYNCED_ONCE -import com.navi.pay.utils.NAVI_PAY_LITMUS_EXPERIMENTS -import com.navi.pay.utils.NAVI_PAY_PSP_ROUTING_BUCKETS_KEY -import com.navi.payments.shared.feature.arc.usecase.ArcNudgeSyncUseCase import com.ramcosta.composedestinations.spec.Direction import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject -import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableSharedFlow @@ -81,37 +50,15 @@ class NaviPayViewModel @Inject constructor( private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, - private val refreshBankListUseCase: RefreshBankListUseCase, - private val refreshConfigUseCase: RefreshConfigUseCase, - private val refreshLinkedAccountsUseCase: RefreshLinkedAccountsUseCase, - private val liteAccountSyncUseCase: LiteAccountSyncUseCase, - private val firestoreDataProvider: FirestoreDataProvider, - private val naviCacheRepository: NaviCacheRepository, - private val syncLitmusExperimentsUseCase: SyncLitmusExperimentUseCase, - private val refreshUpiNumbersUseCase: RefreshUpiNumbersUseCase, - private val upiNumberRepository: UpiNumberRepository, - private val syncUpiLiteMandateInfoUseCase: SyncUpiLiteMandateInfoUseCase, - private val bankUptimePollerUseCase: BankUptimePollerUseCase, - @NaviPayGsonBuilder private val gson: Gson, - private val arcNudgeSyncUseCase: ArcNudgeSyncUseCase, - private val darkKnightScheduler: DarkKnightScheduler, private val syncConversationsUseCase: SyncConversationsUseCase, private val syncMessagesUseCase: SyncMessagesUseCase, private val naviPayConfigUseCase: NaviPayConfigUseCase, - private val syncOrderHistoryUseCase: SyncOrderHistoryUseCase, + private val naviPayDataSetupAndSyncUseCase: NaviPayDataSetupAndSyncUseCase, ) : NaviPayBaseVM() { private val naviPayAnalytics: NaviPayAnalytics.NaviPayViewModel = NaviPayAnalytics.INSTANCE.NaviPayViewModel() - private val customerDataPoller by lazy { - NaviApiPoller(repeatInterval = 5.seconds, numberOfIterations = 1) - } - - private val pspRoutingBucketsPoller by lazy { - NaviApiPoller(repeatInterval = 5.seconds, numberOfIterations = 1) - } - private val naviPayDefaultConfig = MutableStateFlow(NaviPayDefaultConfig()) @@ -152,13 +99,11 @@ constructor( init { viewModelScope.launch(Dispatchers.IO) { naviPayAnalytics.onNaviPayViewModelInit() + naviPayDataSetupAndSyncUseCase.execute(screenName) updateNaviPayDefaultConfig() launch { performMinimumAllowedVersionForNaviPayAccessCheck() } - launch { refreshBankListUseCase.execute(screenName = screenName) } - - launch { refreshConfigUseCase.execute(screenName = screenName) } launch { syncConversationsUseCase.execute(screenName = screenName) syncMessagesUseCase.execute( @@ -166,51 +111,6 @@ constructor( screenName = screenName, ) } - - launch { - syncLitmusExperimentsUseCase.execute(experiments = NAVI_PAY_LITMUS_EXPERIMENTS) - } - - launch { - refreshLinkedAccountsUseCase.execute( - skipLastSyncedTimestampCheck = false, - screenName = screenName, - ) - } - launch { - refreshUpiNumbersUseCase.execute( - skipLastSyncedTimestampCheck = false, - screenName = screenName, - ) - } - - launch { syncUpiLiteMandateInfoUseCase.execute(screenName = screenName) } - - launch { arcNudgeSyncUseCase.execute() } - - launch { bankUptimePollerUseCase.executePollerForBankUptime() } - - initFireStorePollerForCustomerData() - - initFireStorePollerForPspRoutingBuckets() - - initUpiLiteSync() // Onboarding check is not required here - - launch { darkKnightScheduler.schedulePeriodicSync() } - - launch { syncTransactionHistory() } - } - } - - /** - * Sync transaction history only when user enters UPI flow for the first time or after logout - * and login. After that, it will not sync again. - */ - private suspend fun syncTransactionHistory() { - val syncStatus = naviCacheRepository.get(key = IS_TRANSACTION_HISTORY_SYNCED_ONCE)?.value - val isAlreadySynced = syncStatus.toBooleanWithSafe() - if (!isAlreadySynced) { - syncOrderHistoryUseCase.execute(screenName) } } @@ -229,13 +129,6 @@ constructor( } } - private fun initUpiLiteSync() { - viewModelScope.launch(Dispatchers.IO) { - // Onboarding check is not required here - liteAccountSyncUseCase.execute(screenName = screenName) - } - } - private fun isCurrentAppVersionLowerThanMinimumAllowedVersionForUpiUsage(): Boolean { val currentAppVersion = NaviPayManager.appVersionCode.toIntOrNull() ?: Int.MAX_VALUE val minAppVersionAllowedForOnboarding = @@ -277,109 +170,6 @@ constructor( return naviPayCustomerStatusHandler.isUserDeviceBoundForAnyPsp() } - private fun initFireStorePollerForCustomerData() { - viewModelScope.launch(Dispatchers.IO) { - customerDataPoller - .startPolling { - try { - firestoreDataProvider.getDocumentSnapShotForDocumentPath( - documentPath = - "$FIRESTORE_CUSTOMER_DATA_COLLECTION_PATH/${generateSHA256Hash(input = "${getPhoneNumberWithNinetyOneCode()}${BuildConfig.NAVIPAY_FIRESTORE_CUSTOMER_DATA_SALT}")}" - ) - } catch (exception: Exception) { - naviPayAnalytics.onCustomerDataFetchFailed( - phoneNumber = getPhoneNumberWithNinetyOneCode(), - exception = exception, - ) - customerDataPoller.stopPolling() - } - } - .collect { - try { - val customerDataDocumentSnapshot = it as? DocumentSnapshot? - naviPayAnalytics.onCustomerDataFetchSuccess( - phoneNumber = getPhoneNumberWithNinetyOneCode(), - customerData = customerDataDocumentSnapshot, - ) - processDocumentSnapShotForCustomerData( - customerDataDocumentSnapshot = customerDataDocumentSnapshot - ) - } catch (exception: Exception) { - naviPayAnalytics.onCustomerDataFetchFailed( - phoneNumber = getPhoneNumberWithNinetyOneCode(), - exception = exception, - ) - customerDataPoller.stopPolling() - } - } - } - } - - private fun initFireStorePollerForPspRoutingBuckets() { - viewModelScope.launch(Dispatchers.IO) { - pspRoutingBucketsPoller - .startPolling { - try { - firestoreDataProvider.getQuerySnapShotForCollectionPath( - collectionPath = FIRESTORE_PSP_ROUTING_BUCKETS_COLLECTION_PATH - ) - } catch (exception: Exception) { - naviPayAnalytics.onErrorOccurredInGetQuerySnapshot(exception = exception) - pspRoutingBucketsPoller.stopPolling() - } - } - .collect { - try { - val pspRoutingBucketsQuerySnapshot = it as? QuerySnapshot? - processQuerySnapShotForPspRoutingBuckets( - pspRoutingBucketsQuerySnapShot = pspRoutingBucketsQuerySnapshot - ) - } catch (exception: Exception) { - naviPayAnalytics.onErrorOccurredInProcessingQuerySnapshot( - exception = exception - ) - pspRoutingBucketsPoller.stopPolling() - } - } - } - } - - private suspend fun processDocumentSnapShotForCustomerData( - customerDataDocumentSnapshot: DocumentSnapshot? - ) { - customerDataDocumentSnapshot?.let { documentSnapshot -> - val upiNumberData = documentSnapshot.get("upiNumberData") as? Map - upiNumberData?.let { data -> - upiNumberRepository.upsertUpiNumberEntity( - upiNumberEntity = data.toUpiNumberEntity() - ) - } - } - } - - private suspend fun processQuerySnapShotForPspRoutingBuckets( - pspRoutingBucketsQuerySnapShot: QuerySnapshot? - ) { - pspRoutingBucketsQuerySnapShot?.let { querySnapshot -> - val routingDistribution = mutableMapOf>() - querySnapshot.documents.forEach { documentSnapshot -> - val bucketId = documentSnapshot.id - val config: Map? = documentSnapshot.data as? Map - if (config != null) { - routingDistribution[bucketId] = config - } - } - naviCacheRepository.save( - naviCacheEntity = - NaviCacheEntity( - key = NAVI_PAY_PSP_ROUTING_BUCKETS_KEY, - value = gson.toJson(routingDistribution), - version = 1, - ) - ) - } - } - fun onBlockedVpaBottomSheetDescriptionClicked() { naviPayAnalytics.onBlockedVpaBottomSheetDescriptionClicked() }