@@ -30,8 +30,10 @@ import kotlinx.coroutines.flow.flowOn
3030import kotlinx.coroutines.flow.map
3131import kotlinx.coroutines.flow.take
3232import kotlinx.coroutines.withContext
33+ import org.wordpress.android.fluxc.model.LocalOrRemoteId
3334import org.wordpress.android.fluxc.model.WCProductModel
3435import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooResult
36+ import org.wordpress.android.fluxc.network.rest.wpcom.wc.product.ProductRestClient
3537import org.wordpress.android.fluxc.store.WCProductStore
3638import org.wordpress.android.fluxc.store.pos.localcatalog.WooPosLocalCatalogStore
3739import 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(
140155class 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
202237class 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
0 commit comments