Skip to content

Commit 194dbb5

Browse files
authored
Merge pull request #14814 from woocommerce/issue/woomob-1574-woo-poslocal-catalog-use-local-db-in-cart-and-totals-screen
[WOOMOB-1574] Use DataSource in Totals and Cart
2 parents 7dd8996 + 9515879 commit 194dbb5

File tree

6 files changed

+86
-88
lines changed

6 files changed

+86
-88
lines changed
Lines changed: 3 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,16 @@
11
package com.woocommerce.android.ui.woopos.common.data
22

3-
import com.woocommerce.android.tools.SelectedSite
43
import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModel
5-
import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelMapper
6-
import com.woocommerce.android.ui.woopos.common.data.models.WooPosWCProductToWooPosProductModelMapper
7-
import com.woocommerce.android.ui.woopos.featureflags.WooPosLocalCatalogM1Enabled
4+
import com.woocommerce.android.ui.woopos.home.items.products.WooPosProductsDataSource
85
import kotlinx.coroutines.Dispatchers.IO
96
import kotlinx.coroutines.withContext
107
import org.wordpress.android.fluxc.model.LocalOrRemoteId
11-
import org.wordpress.android.fluxc.network.rest.wpcom.wc.product.ProductRestClient
12-
import org.wordpress.android.fluxc.store.pos.localcatalog.WooPosLocalCatalogStore
138
import javax.inject.Inject
149

1510
class WooPosGetProductById @Inject constructor(
16-
private val selectedSite: SelectedSite,
17-
private val cache: WooPosProductsCache,
18-
private val productRestClient: ProductRestClient,
19-
private val wcProductToWooPosProductModelMapper: WooPosWCProductToWooPosProductModelMapper,
20-
private val productMapper: WooPosProductModelMapper,
21-
private val localCatalogStore: WooPosLocalCatalogStore,
22-
private val wooPosLocalCatalogM1Enabled: WooPosLocalCatalogM1Enabled,
11+
private val dataSource: WooPosProductsDataSource,
2312
) {
2413
suspend operator fun invoke(productId: Long): WooPosProductModel? = withContext(IO) {
25-
when {
26-
wooPosLocalCatalogM1Enabled() -> {
27-
val result = localCatalogStore.getProduct(
28-
siteId = LocalOrRemoteId.LocalId(selectedSite.get().id),
29-
remoteProductId = LocalOrRemoteId.RemoteId(productId)
30-
)
31-
result.getOrNull()?.let { entity ->
32-
productMapper.fromEntity(entity)
33-
}
34-
}
35-
36-
else -> getFromInMemoryCache(productId)
37-
}
38-
}
39-
40-
@Suppress("ReturnCount")
41-
private suspend fun getFromInMemoryCache(productId: Long): WooPosProductModel? {
42-
val cachedProduct = cache.getProductById(productId)
43-
if (cachedProduct != null) {
44-
return cachedProduct
45-
}
46-
47-
return if (cache.getAll().size >= WooPosProductsCache.MAX_CACHE_SIZE) {
48-
val remoteProductResult = productRestClient.fetchSingleProduct(
49-
site = selectedSite.get(),
50-
remoteProductId = productId,
51-
)
52-
53-
return if (!remoteProductResult.isError) {
54-
val remoteProduct = remoteProductResult.productWithMetaData.product
55-
val product = wcProductToWooPosProductModelMapper.map(remoteProduct)
56-
cache.addAll(listOf(product))
57-
product
58-
} else {
59-
null
60-
}
61-
} else {
62-
null
63-
}
14+
dataSource.getProductById(LocalOrRemoteId.RemoteId(productId))
6415
}
6516
}
Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,9 @@
11
package com.woocommerce.android.ui.woopos.common.data
22

3-
import com.woocommerce.android.tools.SelectedSite
4-
import com.woocommerce.android.ui.woopos.featureflags.WooPosLocalCatalogM1Enabled
5-
import kotlinx.coroutines.Dispatchers.IO
6-
import kotlinx.coroutines.withContext
7-
import org.wordpress.android.fluxc.store.WCProductStore
8-
import org.wordpress.android.fluxc.store.pos.localcatalog.WooPosLocalCatalogStore
3+
import com.woocommerce.android.ui.woopos.home.items.products.WooPosProductsDataSource
94
import javax.inject.Inject
105

11-
class WooPosGetVariationById @Inject constructor(
12-
private val store: WCProductStore,
13-
private val site: SelectedSite,
14-
private val mapper: WooPosVariationMapper,
15-
private val localCatalogStore: WooPosLocalCatalogStore,
16-
private val wooPosLocalCatalogM1Enabled: WooPosLocalCatalogM1Enabled,
17-
) {
18-
suspend operator fun invoke(productId: Long, variationId: Long): WooPosVariation? = withContext(IO) {
19-
when {
20-
wooPosLocalCatalogM1Enabled() -> {
21-
val siteModel = site.getOrNull() ?: return@withContext null
22-
val result = localCatalogStore.getVariation(
23-
siteId = siteModel.id,
24-
productId = productId,
25-
variationId = variationId
26-
)
27-
result.getOrNull()?.toWooPosVariation(mapper)
28-
}
29-
else -> getFromInMemoryCache(productId, variationId)
30-
}
31-
}
32-
33-
private suspend fun getFromInMemoryCache(productId: Long, variationId: Long): WooPosVariation? {
34-
val siteModel = site.getOrNull() ?: return null
35-
return store.getVariationByRemoteId(siteModel, productId, variationId)?.toWooPosVariation(mapper)
36-
}
6+
class WooPosGetVariationById @Inject constructor(private val dataSource: WooPosProductsDataSource) {
7+
suspend operator fun invoke(productId: Long, variationId: Long): WooPosVariation? =
8+
dataSource.getVariationById(productId, variationId)
379
}

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsDataSource.kt

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ import kotlinx.coroutines.flow.flowOn
3030
import kotlinx.coroutines.flow.map
3131
import kotlinx.coroutines.flow.take
3232
import kotlinx.coroutines.withContext
33+
import org.wordpress.android.fluxc.model.LocalOrRemoteId
3334
import org.wordpress.android.fluxc.model.WCProductModel
3435
import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooResult
36+
import org.wordpress.android.fluxc.network.rest.wpcom.wc.product.ProductRestClient
3537
import org.wordpress.android.fluxc.store.WCProductStore
3638
import org.wordpress.android.fluxc.store.pos.localcatalog.WooPosLocalCatalogStore
3739
import java.util.concurrent.atomic.AtomicBoolean
@@ -99,6 +101,11 @@ class WooPosProductsDataSource @Inject constructor(
99101
val hasMorePages: Boolean
100102
get() = activeSource?.hasMoreProductsPages ?: error("hasMorePages - Data source not selected")
101103

104+
suspend fun getProductById(productId: LocalOrRemoteId.RemoteId): WooPosProductModel? {
105+
return activeSource?.getProductById(productId)
106+
?: error("GetProductById - Data source not selected")
107+
}
108+
102109
suspend fun resetVariationsListHandler() {
103110
remoteDataSource.resetVariationsListHandler()
104111
localDbDataSource.resetVariationsListHandler()
@@ -120,6 +127,14 @@ class WooPosProductsDataSource @Inject constructor(
120127
activeSource?.canLoadMoreVariations(numOfVariations)
121128
?: error("canLoadMoreVariations - Data source not selected")
122129

130+
suspend fun getVariationById(
131+
productId: Long,
132+
variationId: Long
133+
): WooPosVariation? {
134+
return activeSource?.getVariationById(productId, variationId)
135+
?: error("GetVariationById - Data source not selected")
136+
}
137+
123138
sealed class ProductsResult {
124139
data class Cached(val products: List<WooPosProductModel>) : ProductsResult()
125140
data class Remote(val productsResult: Result<List<WooPosProductModel>>) : ProductsResult()
@@ -140,19 +155,19 @@ class WooPosProductsDataSource @Inject constructor(
140155
class WooPosProductsInDbDataSource @Inject constructor(
141156
private val posLocalCatalogStore: WooPosLocalCatalogStore,
142157
private val selectedSite: SelectedSite,
143-
private val mapper: WooPosProductModelMapper,
158+
private val productMapper: WooPosProductModelMapper,
144159
private val variationMapper: WooPosVariationMapper,
145160
private val performInstantCatalogFullSync: WooPosPerformInstantCatalogFullSync,
146161
) : WooPosProductsDataSourceInterface {
147162

148163
private fun getProductsFromDatabaseFlow(): Flow<List<WooPosProductModel>> {
149164
val siteModel = selectedSite.getOrNull() ?: return flow { emit(emptyList()) }
150-
val siteId = org.wordpress.android.fluxc.model.LocalOrRemoteId.LocalId(siteModel.id)
165+
val siteId = LocalOrRemoteId.LocalId(siteModel.id)
151166

152167
return posLocalCatalogStore.observeProducts(siteId)
153168
.map { result ->
154169
result.getOrNull()?.map { entity ->
155-
mapper.fromEntity(entity)
170+
productMapper.fromEntity(entity)
156171
} ?: emptyList()
157172
}
158173
}
@@ -171,6 +186,16 @@ class WooPosProductsInDbDataSource @Inject constructor(
171186

172187
override val hasMoreProductsPages: Boolean = false
173188

189+
override suspend fun getProductById(productId: LocalOrRemoteId.RemoteId): WooPosProductModel? {
190+
val result = posLocalCatalogStore.getProduct(
191+
siteId = LocalOrRemoteId.LocalId(selectedSite.get().id),
192+
remoteProductId = productId
193+
)
194+
return result.getOrNull()?.let { entity ->
195+
productMapper.fromEntity(entity)
196+
}
197+
}
198+
174199
override suspend fun resetVariationsListHandler() = Unit
175200

176201
override suspend fun prepopulateCache(): Result<Unit> = performInstantCatalogFullSync()
@@ -197,10 +222,21 @@ class WooPosProductsInDbDataSource @Inject constructor(
197222
}
198223

199224
override fun canLoadMoreVariations(numOfVariations: Int): Boolean = false
225+
226+
override suspend fun getVariationById(productId: Long, variationId: Long): WooPosVariation? {
227+
val siteModel = selectedSite.getOrNull() ?: return null
228+
val result = posLocalCatalogStore.getVariation(
229+
siteId = siteModel.id,
230+
productId = productId,
231+
variationId = variationId
232+
)
233+
return result.getOrNull()?.toWooPosVariation(variationMapper)
234+
}
200235
}
201236

202237
class WooPosProductsRemoteDataSource @Inject constructor(
203238
private val productStore: WCProductStore,
239+
private val productRestClient: ProductRestClient,
204240
private val selectedSite: SelectedSite,
205241
private val productsCache: WooPosProductsCache,
206242
private val productsIndex: WooPosProductsIndex,
@@ -343,6 +379,31 @@ class WooPosProductsRemoteDataSource @Inject constructor(
343379
WooLog.e(WooLog.T.POS, "Loading products failed - $errorMessage")
344380
}
345381

382+
override suspend fun getProductById(productId: LocalOrRemoteId.RemoteId): WooPosProductModel? {
383+
val cachedProduct = productsCache.getProductById(productId.value)
384+
if (cachedProduct != null) {
385+
return cachedProduct
386+
}
387+
388+
return if (productsCache.getAll().size >= WooPosProductsCache.MAX_CACHE_SIZE) {
389+
val remoteProductResult = productRestClient.fetchSingleProduct(
390+
site = selectedSite.get(),
391+
remoteProductId = productId.value,
392+
)
393+
394+
if (!remoteProductResult.isError) {
395+
val remoteProduct = remoteProductResult.productWithMetaData.product
396+
val product = posProductMapper.map(remoteProduct)
397+
productsCache.addAll(listOf(product))
398+
product
399+
} else {
400+
null
401+
}
402+
} else {
403+
null
404+
}
405+
}
406+
346407
override suspend fun resetVariationsListHandler() {
347408
variationHandler.resetState()
348409
}
@@ -421,6 +482,12 @@ class WooPosProductsRemoteDataSource @Inject constructor(
421482
}
422483
}
423484

485+
override suspend fun getVariationById(productId: Long, variationId: Long): WooPosVariation? {
486+
val siteModel = selectedSite.getOrNull() ?: return null
487+
return productStore.getVariationByRemoteId(siteModel, productId, variationId)
488+
?.toWooPosVariation(variationMapper)
489+
}
490+
424491
companion object {
425492
private const val NORMAL_PAGE_SIZE = 25
426493
private const val PRE_POPULATION_PAGE_SIZE = 100

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsDataSourceInterface.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.woocommerce.android.ui.woopos.home.items.products
33
import com.woocommerce.android.ui.woopos.common.data.WooPosVariation
44
import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModel
55
import kotlinx.coroutines.flow.Flow
6+
import org.wordpress.android.fluxc.model.LocalOrRemoteId
67

78
interface WooPosProductsDataSourceInterface {
89
fun fetchFirstProductsPage(
@@ -13,6 +14,8 @@ interface WooPosProductsDataSourceInterface {
1314

1415
val hasMoreProductsPages: Boolean
1516

17+
suspend fun getProductById(productId: LocalOrRemoteId.RemoteId): WooPosProductModel?
18+
1619
suspend fun resetVariationsListHandler()
1720

1821
suspend fun prepopulateCache(): Result<Unit>
@@ -25,4 +28,6 @@ interface WooPosProductsDataSourceInterface {
2528
suspend fun loadMoreVariations(productId: Long): Result<List<WooPosVariation>>
2629

2730
fun canLoadMoreVariations(numOfVariations: Int): Boolean
31+
32+
suspend fun getVariationById(productId: Long, variationId: Long): WooPosVariation?
2833
}

WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/WooPosProductsRemoteDataSourceTest.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import org.wordpress.android.fluxc.network.BaseRequest.GenericErrorType
4646
import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooError
4747
import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooErrorType
4848
import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooResult
49+
import org.wordpress.android.fluxc.network.rest.wpcom.wc.product.ProductRestClient
4950
import org.wordpress.android.fluxc.store.WCProductStore
5051
import kotlin.test.Test
5152

@@ -101,6 +102,7 @@ class WooPosProductsRemoteDataSourceTest {
101102

102103
private val productStore: WCProductStore = mock()
103104
private val siteModel: SiteModel = mock()
105+
private val productRestClient: ProductRestClient = mock()
104106
private val selectedSite: SelectedSite = mock {
105107
on { get() }.thenReturn(siteModel)
106108
}
@@ -1071,6 +1073,7 @@ class WooPosProductsRemoteDataSourceTest {
10711073
private fun createSUT(): WooPosProductsRemoteDataSource {
10721074
val sut = WooPosProductsRemoteDataSource(
10731075
productStore,
1076+
productRestClient,
10741077
selectedSite,
10751078
productsCache,
10761079
productsIndex,

WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsInDbDataSourceTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class WooPosProductsInDbDataSourceTest {
3737
sut = WooPosProductsInDbDataSource(
3838
posLocalCatalogStore = posLocalCatalogStore,
3939
selectedSite = selectedSite,
40-
mapper = mapper,
40+
productMapper = mapper,
4141
performInstantCatalogFullSync = performInstantCatalogFullSync,
4242
variationMapper = mock()
4343
)

0 commit comments

Comments
 (0)