NTP-63094 | DataInitAndSyncUseCase for UPI (#16790)

This commit is contained in:
Aditya Narayan Malik
2025-07-01 19:19:14 +05:30
committed by GitHub
parent 7f46459090
commit 68e5312780
6 changed files with 275 additions and 244 deletions

View File

@@ -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 {

View File

@@ -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 ->

View File

@@ -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 =

View File

@@ -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 {

View File

@@ -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<String, String>
upiNumberData?.let { data ->
upiNumberRepository.upsertUpiNumberEntity(
upiNumberEntity = data.toUpiNumberEntity()
)
}
}
}
private suspend fun processQuerySnapShotForPspRoutingBuckets(
pspRoutingBucketsQuerySnapShot: QuerySnapshot?
) {
pspRoutingBucketsQuerySnapShot?.let { querySnapshot ->
val routingDistribution = mutableMapOf<String, Map<PspType, Double>>()
querySnapshot.documents.forEach { documentSnapshot ->
val bucketId = documentSnapshot.id
val config: Map<PspType, Double>? = documentSnapshot.data as? Map<PspType, Double>
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)
}
}
}

View File

@@ -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>(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<String, String>
upiNumberData?.let { data ->
upiNumberRepository.upsertUpiNumberEntity(
upiNumberEntity = data.toUpiNumberEntity()
)
}
}
}
private suspend fun processQuerySnapShotForPspRoutingBuckets(
pspRoutingBucketsQuerySnapShot: QuerySnapshot?
) {
pspRoutingBucketsQuerySnapShot?.let { querySnapshot ->
val routingDistribution = mutableMapOf<String, Map<PspType, Double>>()
querySnapshot.documents.forEach { documentSnapshot ->
val bucketId = documentSnapshot.id
val config: Map<PspType, Double>? = documentSnapshot.data as? Map<PspType, Double>
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()
}