Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package com.woocommerce.android.ui.woopos.localcatalog

import com.woocommerce.android.ui.woopos.common.util.WooPosLogWrapper
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.network.rest.wpcom.wc.product.CoreProductStatus
import org.wordpress.android.fluxc.persistence.entity.pos.WooPosProductEntity
import org.wordpress.android.fluxc.store.pos.localcatalog.WooPosLocalCatalogFetchProductsResult
import org.wordpress.android.fluxc.store.pos.localcatalog.WooPosLocalCatalogStore
import javax.inject.Inject

private typealias ServerDate = String

class WooPosSyncProductsAction @Inject constructor(
private val posLocalCatalogStore: WooPosLocalCatalogStore,
private val logger: WooPosLogWrapper,
Expand All @@ -30,21 +32,30 @@ class WooPosSyncProductsAction @Inject constructor(
maxPages: Int
): WooPosSyncProductsResult {
return runCatching {
val isFullSync = modifiedAfterGmt == null

val (products, serverDate) = fetchAllPages(site, modifiedAfterGmt, pageSize, maxPages)

val trashProducts = if (!isFullSync) {
fetchAllTrashProducts(site, pageSize)
} else {
emptyList()
}

val allProducts = products + trashProducts

posLocalCatalogStore.executeInTransaction {
val isFullSync = modifiedAfterGmt == null
if (isFullSync) {
posLocalCatalogStore.deleteAllProducts(
siteId = site.localId()
).getOrThrow()
}

posLocalCatalogStore.upsertProducts(products).getOrThrow()
posLocalCatalogStore.upsertProducts(allProducts).getOrThrow()
}.fold(
onSuccess = {
logger.d("Local Catalog transaction committed successfully")
WooPosSyncProductsResult.Success(products.size, serverDate)
WooPosSyncProductsResult.Success(allProducts.size, serverDate)
},
onFailure = { error ->
handleTransactionError(error)
Expand Down Expand Up @@ -147,6 +158,49 @@ class WooPosSyncProductsAction @Inject constructor(
}
}

private suspend fun fetchAllTrashProducts(
site: SiteModel,
pageSize: Int
): List<WooPosProductEntity> {
var currentOffset = 0
var pagesSynced = 0
val trashProducts = mutableListOf<WooPosProductEntity>()

logger.d("Fetching all trash products for incremental sync")

while (true) {
val result = posLocalCatalogStore.fetchRecentlyModifiedProducts(
site = site,
pageSize = pageSize,
modifiedAfterGmt = null,
offset = currentOffset,
includeStatus = listOf(CoreProductStatus.TRASH)
)

result.fold(
onSuccess = { syncResult ->
trashProducts.addAll(syncResult.products)
pagesSynced++

if (!syncResult.hasMore || syncResult.syncedCount == 0) {
logger.d(
"Finished fetching trash products: ${trashProducts.size} total across $pagesSynced pages"
)
break
} else {
currentOffset = syncResult.nextOffset
}
},
onFailure = { error ->
logger.e("Failed to fetch trash products on page ${pagesSynced + 1}: ${error.message}")
throw error
}
)
}

return trashProducts.toList()
}

internal class CatalogTooLargeException(
val totalPages: Int,
val maxPages: Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.woocommerce.android.ui.woopos.localcatalog

import com.woocommerce.android.ui.woopos.common.util.WooPosLogWrapper
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.network.rest.wpcom.wc.product.CoreProductStatus
import org.wordpress.android.fluxc.persistence.entity.pos.WooPosVariationEntity
import org.wordpress.android.fluxc.store.pos.localcatalog.WooPosLocalCatalogStore
import org.wordpress.android.fluxc.store.pos.localcatalog.WooPosVariationsFetchResult
Expand Down Expand Up @@ -29,21 +30,30 @@ class WooPosSyncVariationsAction @Inject constructor(
maxPages: Int
): WooPosSyncVariationsResult {
return runCatching {
val isFullSync = modifiedAfterGmt == null

val (variations, serverDate) = fetchAllPages(site, modifiedAfterGmt, pageSize, maxPages)

val trashVariations = if (!isFullSync) {
fetchAllTrashVariations(site, pageSize)
} else {
emptyList()
}

val allVariations = variations + trashVariations

posLocalCatalogStore.executeInTransaction {
val isFullSync = modifiedAfterGmt == null
if (isFullSync) {
posLocalCatalogStore.deleteAllVariations(
siteId = site.localId()
).getOrThrow()
}

posLocalCatalogStore.upsertVariations(variations).getOrThrow()
posLocalCatalogStore.upsertVariations(allVariations).getOrThrow()
}.fold(
onSuccess = {
logger.d("Local Catalog variations transaction committed successfully")
WooPosSyncVariationsResult.Success(variations.size, serverDate)
WooPosSyncVariationsResult.Success(allVariations.size, serverDate)
},
onFailure = { error ->
handleTransactionError(error)
Expand Down Expand Up @@ -147,6 +157,50 @@ class WooPosSyncVariationsAction @Inject constructor(
}
}

private suspend fun fetchAllTrashVariations(
site: SiteModel,
pageSize: Int
): List<WooPosVariationEntity> {
var currentPage = 1
var pagesSynced = 0
val trashVariations = mutableListOf<WooPosVariationEntity>()

logger.d("Fetching all trash variations for incremental sync")

while (true) {
val result = posLocalCatalogStore.fetchRecentlyModifiedVariations(
site = site,
modifiedAfterGmt = null,
page = currentPage,
pageSize = pageSize,
includeStatus = listOf(CoreProductStatus.TRASH)
)

result.fold(
onSuccess = { syncResult ->
trashVariations.addAll(syncResult.variations)
pagesSynced++

if (!syncResult.hasMore || syncResult.syncedCount == 0) {
logger.d(
"Finished fetching trash variations: ${trashVariations.size} " +
"total across $pagesSynced pages"
)
break
} else {
currentPage = syncResult.nextPage
}
},
onFailure = { error ->
logger.e("Failed to fetch trash variations on page ${pagesSynced + 1}: ${error.message}")
throw error
}
)
}

return trashVariations.toList()
}

internal class CatalogTooLargeException(
val totalPages: Int,
val maxPages: Int
Expand Down
Loading