diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/list/usecase/SyncOrderHistoryUseCase.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/list/usecase/SyncOrderHistoryUseCase.kt index d2864cbf4b..3942e0da19 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/list/usecase/SyncOrderHistoryUseCase.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/list/usecase/SyncOrderHistoryUseCase.kt @@ -15,7 +15,9 @@ import com.navi.pay.common.sync.repository.SyncRepository import com.navi.pay.onboarding.account.add.repository.BankRepository import com.navi.pay.tstore.details.ui.upi.NaviPayTransactionDetailsMetadata import com.navi.pay.tstore.list.model.network.OrderHistoryRequest +import com.navi.pay.tstore.list.model.network.OrderItem import com.navi.pay.tstore.list.model.network.toOrderEntity +import com.navi.pay.tstore.list.model.view.OrderEntity import com.navi.pay.tstore.list.repository.OrderRepository import com.navi.pay.utils.NAVI_PAY_SYNC_TABLE_ORDER_HISTORY_KEY import com.navi.pay.utils.ZERO_STRING @@ -23,6 +25,8 @@ import com.navi.pay.utils.parallelMap import java.util.concurrent.atomic.AtomicBoolean import javax.inject.Inject import javax.inject.Singleton +import org.joda.time.DateTime +import org.joda.time.DateTimeZone @Singleton class SyncOrderHistoryUseCase @@ -37,24 +41,22 @@ constructor( private val naviPayMetadataType = object : TypeToken() {}.type private val isProcessRunning = AtomicBoolean(false) + private val isCurrentLoopForLatestDataFetch = AtomicBoolean(false) + private val defaultTimestamp = ZERO_STRING suspend fun execute() { if (isProcessRunning.get()) { return } isProcessRunning.set(true) - val defaultTimestamp = ZERO_STRING + while (isProcessRunning.get()) { - val orderHistorySyncEntity = - syncRepository.get(key = NAVI_PAY_SYNC_TABLE_ORDER_HISTORY_KEY) + + val updatedAtForApiRequest = getUpdatedAtForApiRequest() val orderHistoryAPIResponse = orderRepository.getOrderHistoryFromNetwork( - orderHistoryRequest = - OrderHistoryRequest( - updatedAt = - orderHistorySyncEntity?.lastSyncedTimestamp ?: defaultTimestamp - ) + orderHistoryRequest = OrderHistoryRequest(updatedAt = updatedAtForApiRequest) ) if (!orderHistoryAPIResponse.isSuccessWithData()) { @@ -64,21 +66,8 @@ constructor( val orderHistoryItemList = orderHistoryAPIResponse.data?.orderItemList.orEmpty() - val bankCodeList = - orderHistoryItemList.flatMap { listOfNotNull(it.bankCode) }.distinct() - - // If we have bank entity data in local DB, then we override the data - val bankEntityMap = - bankRepository.getBankEntityMapFromBankCodes(bankCodeList = bankCodeList) - val orderEntityList = - orderHistoryItemList.parallelMap { - it.toOrderEntity( - gson = gson, - bankEntityMap = bankEntityMap, - naviPayMetadataType = naviPayMetadataType - ) - } + processOrderHistoryItemList(orderHistoryItemList = orderHistoryItemList) if (orderEntityList.isEmpty()) { isProcessRunning.set(false) @@ -86,23 +75,77 @@ constructor( } orderRepository.insertOrders(orderEntityList = orderEntityList) + + val lastSyncTsForSyncEntity = + if (isCurrentLoopForLatestDataFetch.get()) { + // When latest data is fetched, set sync repository with default timestamp + // So as to signify that once this flow has executed for latest data + defaultTimestamp + } else { + orderHistoryItemList.maxByOrNull { it.updatedAt.orEmpty() }?.updatedAt + ?: defaultTimestamp + } + syncRepository.insert( syncEntity = SyncEntity( key = NAVI_PAY_SYNC_TABLE_ORDER_HISTORY_KEY, - lastSyncedTimestamp = - orderHistoryItemList.maxByOrNull { it.updatedAt.orEmpty() }?.updatedAt - ?: defaultTimestamp, - updatedAt = orderEntityList.last().orderTimestamp.millis + lastSyncedTimestamp = lastSyncTsForSyncEntity ) ) - if ( - orderHistoryAPIResponse.data?.listComplete == true - ) { // Since we filter few transactions (Self Pay), hence original size is needed + // If current loop is for latest data fetch, then turn it off & restart the loop + if (isCurrentLoopForLatestDataFetch.get()) { + isCurrentLoopForLatestDataFetch.set(false) + continue + } + + if (orderHistoryAPIResponse.data?.listComplete == true) { isProcessRunning.set(false) break } } } + + private suspend fun processOrderHistoryItemList( + orderHistoryItemList: List + ): List { + val bankCodeList = orderHistoryItemList.flatMap { listOfNotNull(it.bankCode) }.distinct() + + // If we have bank entity data in local DB, then we override the data + val bankEntityMap = + bankRepository.getBankEntityMapFromBankCodes(bankCodeList = bankCodeList) + + val orderEntityList = + orderHistoryItemList.parallelMap { + it.toOrderEntity( + gson = gson, + bankEntityMap = bankEntityMap, + naviPayMetadataType = naviPayMetadataType + ) + } + + return orderEntityList + } + + private suspend fun getUpdatedAtForApiRequest(): String { + val orderHistorySyncEntity = syncRepository.get(key = NAVI_PAY_SYNC_TABLE_ORDER_HISTORY_KEY) + + val isFirstTimeSyncTriggered = orderHistorySyncEntity?.lastSyncedTimestamp == null + + // If its first time sync then we fetch data for latest X days + if (isFirstTimeSyncTriggered) { + isCurrentLoopForLatestDataFetch.set(true) + return getUpdatedAtForLatestDataFetch() + } + + return orderHistorySyncEntity?.lastSyncedTimestamp ?: defaultTimestamp + } + + private fun getUpdatedAtForLatestDataFetch(): String { + val dateTime = DateTime.now(DateTimeZone.UTC) + val dateTimeMinusDays = dateTime.minusDays(5) + val epochMillis = dateTimeMinusDays.millis + return (epochMillis * 1000).toString() + } }