From d4db3ed3c1baa0cd0970389cfa96108d7c6f73c6 Mon Sep 17 00:00:00 2001 From: Ujjwal Kumar Date: Mon, 21 Apr 2025 17:07:50 +0530 Subject: [PATCH] NTP-55678 | Added check of user loggedin & active transaction count for batman (#15864) --- .../pay/common/batman/DarkKnightWorkerTest.kt | 3 +++ .../viewmodel/UPIIdInputViewModelTest.kt | 3 +++ .../navi/pay/analytics/NaviPayAnalytics.kt | 8 +++++++ .../pay/common/batman/DarkKnightWorker.kt | 23 +++++++++++++++++++ .../navi/pay/tstore/list/db/dao/OrderDao.kt | 9 ++++++++ .../tstore/list/repository/OrderRepository.kt | 9 ++++++++ 6 files changed, 55 insertions(+) diff --git a/android/navi-pay/src/androidTest/kotlin/com/navi/pay/common/batman/DarkKnightWorkerTest.kt b/android/navi-pay/src/androidTest/kotlin/com/navi/pay/common/batman/DarkKnightWorkerTest.kt index e2b62270fe..4ff3bfea10 100644 --- a/android/navi-pay/src/androidTest/kotlin/com/navi/pay/common/batman/DarkKnightWorkerTest.kt +++ b/android/navi-pay/src/androidTest/kotlin/com/navi/pay/common/batman/DarkKnightWorkerTest.kt @@ -23,6 +23,7 @@ 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.UpiRequestIdUseCase +import com.navi.pay.tstore.list.repository.OrderRepository import io.mockk.mockk import junit.framework.TestCase.assertEquals import kotlinx.coroutines.test.runTest @@ -43,6 +44,7 @@ class DarkKnightWorkerTest { private val syncUpiLiteMandateInfoUseCase: SyncUpiLiteMandateInfoUseCase = mockk(relaxed = true) private val upiRequestIdUseCase: UpiRequestIdUseCase = mockk(relaxed = true) private val commonRepository: CommonRepository = mockk(relaxed = true) + private val orderRepository: OrderRepository = mockk(relaxed = true) @Before fun setUp() { @@ -71,6 +73,7 @@ class DarkKnightWorkerTest { syncUpiLiteMandateInfoUseCase = syncUpiLiteMandateInfoUseCase, upiRequestIdUseCase = upiRequestIdUseCase, commonRepository = commonRepository, + orderRepository = orderRepository, ) } else { null diff --git a/android/navi-pay/src/androidTest/kotlin/com/navi/pay/management/common/upiid/viewmodel/UPIIdInputViewModelTest.kt b/android/navi-pay/src/androidTest/kotlin/com/navi/pay/management/common/upiid/viewmodel/UPIIdInputViewModelTest.kt index b9c5e17ccf..dfc489992c 100644 --- a/android/navi-pay/src/androidTest/kotlin/com/navi/pay/management/common/upiid/viewmodel/UPIIdInputViewModelTest.kt +++ b/android/navi-pay/src/androidTest/kotlin/com/navi/pay/management/common/upiid/viewmodel/UPIIdInputViewModelTest.kt @@ -18,6 +18,7 @@ import com.navi.pay.common.usecase.LinkedAccountsUseCase import com.navi.pay.common.usecase.NaviPayConfigUseCase import com.navi.pay.common.usecase.ValidateVpaUseCase import com.navi.pay.common.utils.DeviceInfoImplTest +import com.navi.pay.entry.NaviPayActivityDataProvider import com.navi.pay.network.testsetup.NaviPayAndroidTest import dagger.hilt.android.testing.HiltAndroidTest import io.mockk.coEvery @@ -36,6 +37,7 @@ class UpiIdViewModelUnitTest : NaviPayAndroidTest() { private var naviPaySessionHelper: NaviPaySessionHelper = mockk() private var validateVpaUseCase: ValidateVpaUseCase = mockk() private var resourceProvider: ResourceProvider = mockk() + private var naviPayActivityDataProvider: NaviPayActivityDataProvider = mockk() private lateinit var upiIdInputViewModel: UPIIdInputViewModel @@ -60,6 +62,7 @@ class UpiIdViewModelUnitTest : NaviPayAndroidTest() { naviPaySessionHelper, validateVpaUseCase, resourceProvider, + naviPayActivityDataProvider, ) } 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 b79b91c4e3..f236a7d189 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 @@ -229,6 +229,14 @@ class NaviPayDarkKnightWorker { eventValues = mapOf("message" to message), ) } + + fun onUserNotLoggedIn() { + NaviTrackEvent.trackEventOnClickStream(eventName = "NaviPay_DarkKnight_UserNotLoggedIn") + } + + fun onNoActiveTransaction() { + NaviTrackEvent.trackEventOnClickStream(eventName = "NaviPay_DarkKnight_NoActiveTransaction") + } } class NaviPayAnalytics private constructor() { diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/batman/DarkKnightWorker.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/batman/DarkKnightWorker.kt index 47cb0e76d2..f1dccfe92c 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/batman/DarkKnightWorker.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/batman/DarkKnightWorker.kt @@ -11,6 +11,7 @@ import android.content.Context import androidx.hilt.work.HiltWorker import androidx.work.CoroutineWorker import androidx.work.WorkerParameters +import com.navi.base.utils.BaseUtils import com.navi.base.utils.DateUtils import com.navi.base.utils.TrustedTimeAccessor import com.navi.base.utils.log @@ -29,6 +30,8 @@ import com.navi.pay.common.usecase.SyncUpiLiteMandateInfoUseCase import com.navi.pay.common.usecase.UpiRequestIdUseCase import com.navi.pay.common.utils.getMetricInfo import com.navi.pay.npcicl.NpciKeysResponse +import com.navi.pay.tstore.list.model.view.OrderStatusOfView +import com.navi.pay.tstore.list.repository.OrderRepository import com.navi.pay.utils.DARK_KNIGHT_WORKER import com.navi.pay.utils.DATE_TIME_FORMAT_DATE_MONTH_NAME_YEAR_AT_TIME import com.navi.pay.utils.NAVI_PAY_LITMUS_EXPERIMENTS @@ -57,11 +60,13 @@ constructor( private val syncUpiLiteMandateInfoUseCase: SyncUpiLiteMandateInfoUseCase, private val upiRequestIdUseCase: UpiRequestIdUseCase, private val commonRepository: CommonRepository, + private val orderRepository: OrderRepository, ) : CoroutineWorker(context, workerParams) { private val screenName = DARK_KNIGHT_WORKER private val naviPayAnalytics: NaviPayDarkKnightWorker = NaviPayDarkKnightWorker() + private val activeTransactionThresholdInDays = 7 override suspend fun doWork(): Result = withContext( @@ -82,6 +87,24 @@ constructor( ) ) + if (!BaseUtils.isUserLoggedIn()) { + naviPayAnalytics.onUserNotLoggedIn() + return@withContext Result.success() + } + + val activeTransactionCount = + orderRepository.getTransactionCountByStatusAndDate( + orderStatusOfView = OrderStatusOfView.Debit, + startDate = + DateTime(TrustedTimeAccessor.getCurrentTimeMillis()) + .minusDays(activeTransactionThresholdInDays), + ) + + if (activeTransactionCount == 0) { + naviPayAnalytics.onNoActiveTransaction() + return@withContext Result.success() + } + val tasks = mutableListOf>() tasks.add( diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/list/db/dao/OrderDao.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/list/db/dao/OrderDao.kt index 95ce2c8b3c..98f094fd4f 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/list/db/dao/OrderDao.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/list/db/dao/OrderDao.kt @@ -17,6 +17,7 @@ import androidx.room.Upsert import androidx.sqlite.db.SupportSQLiteQuery import com.navi.pay.tstore.list.model.view.OrderEntity import com.navi.pay.tstore.list.model.view.OrderHistoryEntity +import com.navi.pay.tstore.list.model.view.OrderStatusOfView import com.navi.pay.utils.NAVI_PAY_DATABASE_T_STORE_ORDER_HISTORY_TABLE_NAME import kotlinx.coroutines.flow.Flow import org.joda.time.DateTime @@ -104,4 +105,12 @@ interface OrderDao { minDateTime: DateTime, maxDateTime: DateTime, ): List + + @Query( + "SELECT COUNT(*) FROM $NAVI_PAY_DATABASE_T_STORE_ORDER_HISTORY_TABLE_NAME WHERE orderStatusOfView = :orderStatusOfView AND orderTimestamp >= :startDate" + ) + suspend fun getTransactionCountByStatusAndDate( + orderStatusOfView: OrderStatusOfView, + startDate: DateTime, + ): Int } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/list/repository/OrderRepository.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/list/repository/OrderRepository.kt index 0f1ca32b91..1a482ac668 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/list/repository/OrderRepository.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/list/repository/OrderRepository.kt @@ -324,6 +324,15 @@ constructor( return orderDao.getLatestOrderTimestamp() } + suspend fun getTransactionCountByStatusAndDate( + orderStatusOfView: OrderStatusOfView, + startDate: DateTime, + ) = + orderDao.getTransactionCountByStatusAndDate( + orderStatusOfView = orderStatusOfView, + startDate = startDate, + ) + private suspend fun insertOrderEntityListDataIntoVpaTransactionInsightsDb( orderEntityList: List ) {