NTP-8396 | Initial data fetch during full sync (#13238)

This commit is contained in:
Ujjwal Kumar
2024-10-21 17:54:13 +05:30
committed by GitHub
parent d2f3db9c55
commit b96f5866c0

View File

@@ -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<NaviPayTransactionDetailsMetadata>() {}.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<OrderItem>
): List<OrderEntity> {
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()
}
}