Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.woocommerce.android.ui.woopos.common.data

import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.ui.woopos.common.data.models.WCProductToWooPosProductModelMapper
import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2
import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModel
import com.woocommerce.android.ui.woopos.common.data.models.WooPosWCProductToWooPosProductModelMapper
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.withContext
import org.wordpress.android.fluxc.network.rest.wpcom.wc.product.ProductRestClient
Expand All @@ -12,9 +12,9 @@ class WooPosGetProductById @Inject constructor(
private val selectedSite: SelectedSite,
private val cache: WooPosProductsCache,
private val productRestClient: ProductRestClient,
private val productMapper: WCProductToWooPosProductModelMapper,
private val productMapper: WooPosWCProductToWooPosProductModelMapper,
) {
suspend operator fun invoke(productId: Long): WooPosProductModelVersion2? = withContext(IO) {
suspend operator fun invoke(productId: Long): WooPosProductModel? = withContext(IO) {
val cachedProduct = cache.getProductById(productId)
if (cachedProduct != null) {
return@withContext cachedProduct
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.woocommerce.android.ui.woopos.common.data

import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.ui.woopos.common.data.models.WCProductToWooPosProductModelMapper
import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2
import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModel
import com.woocommerce.android.ui.woopos.common.data.models.WooPosWCProductToWooPosProductModelMapper
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import org.wordpress.android.fluxc.store.WCProductStore
Expand All @@ -16,16 +16,16 @@ class WooPosPopularProductsProvider @Inject constructor(
private val productStore: WCProductStore,
private val productsCache: WooPosProductsCache,
private val productsTypesFilterConfig: WooPosProductsTypesFilterConfig,
private val productMapper: WCProductToWooPosProductModelMapper,
private val productMapper: WooPosWCProductToWooPosProductModelMapper,
) {
companion object {
private const val MAX_POPULAR_PRODUCTS = 10
}

private val mutex = Mutex()
private val popularProductsCache = mutableListOf<WooPosProductModelVersion2>()
private val popularProductsCache = mutableListOf<WooPosProductModel>()

suspend fun getPopularProducts(): List<WooPosProductModelVersion2> = mutex.withLock { popularProductsCache }
suspend fun getPopularProducts(): List<WooPosProductModel> = mutex.withLock { popularProductsCache }

suspend fun addPopularItemsToCache() = mutex.withLock {
productsCache.addAll(popularProductsCache)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package com.woocommerce.android.ui.woopos.common.data

import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2
import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModel

interface WooPosProductsCache {
companion object {
const val MAX_CACHE_SIZE = 2_000
}

suspend fun addAll(products: List<WooPosProductModelVersion2>)
suspend fun addAll(products: List<WooPosProductModel>)

suspend fun getAll(): List<WooPosProductModelVersion2>
suspend fun getAll(): List<WooPosProductModel>

suspend fun getProductById(productId: Long): WooPosProductModelVersion2?
suspend fun getProductById(productId: Long): WooPosProductModel?

suspend fun getProductByGlobalUniqueIdentifier(globalUniqueIdentifier: String): WooPosProductModelVersion2?
suspend fun getProductByGlobalUniqueIdentifier(globalUniqueIdentifier: String): WooPosProductModel?

suspend fun updateProduct(product: WooPosProductModelVersion2)
suspend fun updateProduct(product: WooPosProductModel)

suspend fun deleteProduct(productId: Long)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.woocommerce.android.ui.woopos.common.data

import com.woocommerce.android.ui.woopos.common.data.WooPosProductsCache.Companion.MAX_CACHE_SIZE
import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2
import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModel
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import javax.inject.Inject
Expand All @@ -16,13 +16,13 @@ class WooPosProductsInMemoryCache @Inject constructor() : WooPosProductsCache {
private const val LOAD_FACTOR = 0.75f
}

private val productsCache = LinkedHashMap<Long, WooPosProductModelVersion2>(INITIAL_CAPACITY, LOAD_FACTOR, true)
private val productsCache = LinkedHashMap<Long, WooPosProductModel>(INITIAL_CAPACITY, LOAD_FACTOR, true)

override suspend fun addAll(products: List<WooPosProductModelVersion2>) = mutex.withLock {
override suspend fun addAll(products: List<WooPosProductModel>) = mutex.withLock {
addAllInternal(products)
}

override suspend fun updateProduct(product: WooPosProductModelVersion2) = mutex.withLock {
override suspend fun updateProduct(product: WooPosProductModel) = mutex.withLock {
productsCache[product.remoteId] = product
}

Expand All @@ -32,11 +32,11 @@ class WooPosProductsInMemoryCache @Inject constructor() : WooPosProductsCache {
}
}

override suspend fun getAll(): List<WooPosProductModelVersion2> = mutex.withLock {
override suspend fun getAll(): List<WooPosProductModel> = mutex.withLock {
return productsCache.values.toList()
}

override suspend fun getProductById(productId: Long): WooPosProductModelVersion2? = mutex.withLock {
override suspend fun getProductById(productId: Long): WooPosProductModel? = mutex.withLock {
return productsCache[productId]
}

Expand All @@ -47,7 +47,7 @@ class WooPosProductsInMemoryCache @Inject constructor() : WooPosProductsCache {
productsCache.clear()
}

private fun addAllInternal(products: List<WooPosProductModelVersion2>) {
private fun addAllInternal(products: List<WooPosProductModel>) {
products.forEach { product ->
productsCache[product.remoteId] = product
if (productsCache.size > MAX_CACHE_SIZE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.google.gson.JsonSyntaxException
import com.google.gson.reflect.TypeToken
import com.woocommerce.android.R
import com.woocommerce.android.model.ProductVariation
import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2
import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModel
import com.woocommerce.android.util.WooLog
import com.woocommerce.android.viewmodel.ResourceProvider
import org.wordpress.android.fluxc.model.WCProductVariationModel
Expand Down Expand Up @@ -91,7 +91,7 @@ class WooPosVariationMapper @Inject constructor(

fun getNameForPOS(
variation: WooPosVariation,
parentProduct: WooPosProductModelVersion2? = null,
parentProduct: WooPosProductModel? = null,
resourceProvider: ResourceProvider,
): String {
return parentProduct?.variationEnabledAttributes?.joinToString(", ") { attribute ->
Expand All @@ -117,7 +117,7 @@ class WooPosVariationMapper @Inject constructor(
}
}

fun getName(variation: WooPosVariation, parentProduct: WooPosProductModelVersion2? = null): String {
fun getName(variation: WooPosVariation, parentProduct: WooPosProductModel? = null): String {
return parentProduct?.variationEnabledAttributes?.joinToString(" - ") { attribute ->
val option = variation.attributes.firstOrNull { it.name == attribute.name }
option?.option ?: "Any ${attribute.name}"
Expand Down Expand Up @@ -167,9 +167,9 @@ fun WCPosVariationModel.toWooPosVariation(mapper: WooPosVariationMapper): WooPos

fun WooPosVariation.getNameForPOS(
mapper: WooPosVariationMapper,
parentProduct: WooPosProductModelVersion2? = null,
parentProduct: WooPosProductModel? = null,
resourceProvider: ResourceProvider,
): String = mapper.getNameForPOS(this, parentProduct, resourceProvider)

fun WooPosVariation.getName(mapper: WooPosVariationMapper, parentProduct: WooPosProductModelVersion2? = null): String =
fun WooPosVariation.getName(mapper: WooPosVariationMapper, parentProduct: WooPosProductModel? = null): String =
mapper.getName(this, parentProduct)
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import java.math.BigDecimal
* and the view layer, ensuring all required data is present and properly typed.
*/
@Parcelize
data class WooPosProductModelVersion2(
data class WooPosProductModel(
val remoteId: Long,
val parentId: Long?,
val name: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import javax.inject.Inject
* The mapper ensures clean data handling:
*/
@Reusable
class WooPosProductModelVersion2Mapper @Inject constructor(val logger: WooPosLogWrapper) {
class WooPosProductModelMapper @Inject constructor(val logger: WooPosLogWrapper) {
private val gson = Gson()
fun fromEntity(entity: WCPosProductEntity): WooPosProductModelVersion2 {
return WooPosProductModelVersion2(
fun fromEntity(entity: WCPosProductEntity): WooPosProductModel {
return WooPosProductModel(
remoteId = entity.remoteId.value,
parentId = entity.parentId,
name = entity.name,
Expand All @@ -45,7 +45,7 @@ class WooPosProductModelVersion2Mapper @Inject constructor(val logger: WooPosLog
)
}

fun fromEntities(entities: List<WCPosProductEntity>): List<WooPosProductModelVersion2> {
fun fromEntities(entities: List<WCPosProductEntity>): List<WooPosProductModel> {
return entities.map { fromEntity(it) }
}

Expand All @@ -62,7 +62,7 @@ class WooPosProductModelVersion2Mapper @Inject constructor(val logger: WooPosLog
}
}

fun parseImages(imagesJson: String): List<WooPosProductModelVersion2.WooPosProductImage> {
fun parseImages(imagesJson: String): List<WooPosProductModel.WooPosProductImage> {
return try {
if (imagesJson.isBlank()) {
emptyList()
Expand All @@ -79,7 +79,7 @@ class WooPosProductModelVersion2Mapper @Inject constructor(val logger: WooPosLog
}
}

private fun parseImage(imageMap: Map<String, Any?>): WooPosProductModelVersion2.WooPosProductImage? {
private fun parseImage(imageMap: Map<String, Any?>): WooPosProductModel.WooPosProductImage? {
val id = when (val idValue = imageMap["id"]) {
is Double -> idValue.toLong()
is Int -> idValue.toLong()
Expand All @@ -94,10 +94,10 @@ class WooPosProductModelVersion2Mapper @Inject constructor(val logger: WooPosLog
logger.w("Failed to parse images JSON, id or url is null: $id, $url")
return null
}
return WooPosProductModelVersion2.WooPosProductImage(id, url, name, alt)
return WooPosProductModel.WooPosProductImage(id, url, name, alt)
}

fun parseAttributes(attributesJson: String): List<WooPosProductModelVersion2.WooPosProductAttribute> {
fun parseAttributes(attributesJson: String): List<WooPosProductModel.WooPosProductAttribute> {
return try {
if (attributesJson.isBlank()) {
emptyList()
Expand All @@ -114,7 +114,7 @@ class WooPosProductModelVersion2Mapper @Inject constructor(val logger: WooPosLog
}
}

private fun parseAttribute(attrMap: Map<String, Any?>): WooPosProductModelVersion2.WooPosProductAttribute? {
private fun parseAttribute(attrMap: Map<String, Any?>): WooPosProductModel.WooPosProductAttribute? {
val id = when (val idValue = attrMap["id"]) {
is Double -> idValue.toLong()
is Int -> idValue.toLong()
Expand All @@ -130,10 +130,10 @@ class WooPosProductModelVersion2Mapper @Inject constructor(val logger: WooPosLog
}
val isVisible = attrMap["visible"] as? Boolean ?: true
val isVariation = attrMap["variation"] as? Boolean ?: false
return WooPosProductModelVersion2.WooPosProductAttribute(id, name, options, isVisible, isVariation)
return WooPosProductModel.WooPosProductAttribute(id, name, options, isVisible, isVariation)
}

fun parseCategories(categoriesJson: String): List<WooPosProductModelVersion2.WooPosProductCategory> {
fun parseCategories(categoriesJson: String): List<WooPosProductModel.WooPosProductCategory> {
return try {
if (categoriesJson.isBlank()) {
emptyList()
Expand All @@ -150,7 +150,7 @@ class WooPosProductModelVersion2Mapper @Inject constructor(val logger: WooPosLog
}
}

private fun parseCategory(catMap: Map<String, Any?>): WooPosProductModelVersion2.WooPosProductCategory? {
private fun parseCategory(catMap: Map<String, Any?>): WooPosProductModel.WooPosProductCategory? {
val id = when (val idValue = catMap["id"]) {
is Double -> idValue.toLong()
is Int -> idValue.toLong()
Expand All @@ -164,10 +164,10 @@ class WooPosProductModelVersion2Mapper @Inject constructor(val logger: WooPosLog
logger.w("Failed to parse category JSON, id or name is null: $id, $name")
return null
}
return WooPosProductModelVersion2.WooPosProductCategory(id, name, slug)
return WooPosProductModel.WooPosProductCategory(id, name, slug)
}

fun parseTags(tagsJson: String): List<WooPosProductModelVersion2.WooPosProductTag> {
fun parseTags(tagsJson: String): List<WooPosProductModel.WooPosProductTag> {
return try {
if (tagsJson.isBlank()) {
emptyList()
Expand All @@ -184,7 +184,7 @@ class WooPosProductModelVersion2Mapper @Inject constructor(val logger: WooPosLog
}
}

private fun parseTag(tagMap: Map<String, Any?>): WooPosProductModelVersion2.WooPosProductTag? {
private fun parseTag(tagMap: Map<String, Any?>): WooPosProductModel.WooPosProductTag? {
val id = when (val idValue = tagMap["id"]) {
is Double -> idValue.toLong()
is Int -> idValue.toLong()
Expand All @@ -198,7 +198,7 @@ class WooPosProductModelVersion2Mapper @Inject constructor(val logger: WooPosLog
logger.w("Failed to parse tag JSON, id or name is null: $id, $name")
return null
}
return WooPosProductModelVersion2.WooPosProductTag(id, name, slug)
return WooPosProductModel.WooPosProductTag(id, name, slug)
}

private fun parseVariationIds(variationsJson: String): List<Long> {
Expand Down Expand Up @@ -229,51 +229,51 @@ class WooPosProductModelVersion2Mapper @Inject constructor(val logger: WooPosLog
regularPrice: BigDecimal?,
salePrice: BigDecimal?,
isOnSale: Boolean
): WooPosProductModelVersion2.WooPosPricing {
): WooPosProductModel.WooPosPricing {
return when {
isOnSale && salePrice != null && regularPrice != null -> {
WooPosProductModelVersion2.WooPosPricing.SalePricing(regularPrice, salePrice)
WooPosProductModel.WooPosPricing.SalePricing(regularPrice, salePrice)
}

isOnSale && salePrice != null && price != null -> {
WooPosProductModelVersion2.WooPosPricing.SalePricing(price, salePrice)
WooPosProductModel.WooPosPricing.SalePricing(price, salePrice)
}

regularPrice != null -> {
WooPosProductModelVersion2.WooPosPricing.RegularPricing(regularPrice)
WooPosProductModel.WooPosPricing.RegularPricing(regularPrice)
}

price != null -> {
WooPosProductModelVersion2.WooPosPricing.RegularPricing(price)
WooPosProductModel.WooPosPricing.RegularPricing(price)
}

else -> WooPosProductModelVersion2.WooPosPricing.NoPricing
else -> WooPosProductModel.WooPosPricing.NoPricing
}
}

fun mapProductType(type: String): WooPosProductModelVersion2.WooPosProductType {
fun mapProductType(type: String): WooPosProductModel.WooPosProductType {
return when (type.lowercase()) {
"simple" -> WooPosProductModelVersion2.WooPosProductType.SIMPLE
"variable" -> WooPosProductModelVersion2.WooPosProductType.VARIABLE
"grouped" -> WooPosProductModelVersion2.WooPosProductType.GROUPED
"external" -> WooPosProductModelVersion2.WooPosProductType.EXTERNAL
"variation" -> WooPosProductModelVersion2.WooPosProductType.VARIATION
"subscription" -> WooPosProductModelVersion2.WooPosProductType.SUBSCRIPTION
"variable-subscription" -> WooPosProductModelVersion2.WooPosProductType.VARIABLE_SUBSCRIPTION
"bundle" -> WooPosProductModelVersion2.WooPosProductType.BUNDLE
"composite" -> WooPosProductModelVersion2.WooPosProductType.COMPOSITE
else -> WooPosProductModelVersion2.WooPosProductType.CUSTOM
"simple" -> WooPosProductModel.WooPosProductType.SIMPLE
"variable" -> WooPosProductModel.WooPosProductType.VARIABLE
"grouped" -> WooPosProductModel.WooPosProductType.GROUPED
"external" -> WooPosProductModel.WooPosProductType.EXTERNAL
"variation" -> WooPosProductModel.WooPosProductType.VARIATION
"subscription" -> WooPosProductModel.WooPosProductType.SUBSCRIPTION
"variable-subscription" -> WooPosProductModel.WooPosProductType.VARIABLE_SUBSCRIPTION
"bundle" -> WooPosProductModel.WooPosProductType.BUNDLE
"composite" -> WooPosProductModel.WooPosProductType.COMPOSITE
else -> WooPosProductModel.WooPosProductType.CUSTOM
}
}

fun mapProductStatus(status: String): WooPosProductModelVersion2.WooPosProductStatus {
fun mapProductStatus(status: String): WooPosProductModel.WooPosProductStatus {
return when (status.lowercase()) {
"publish" -> WooPosProductModelVersion2.WooPosProductStatus.PUBLISH
"draft" -> WooPosProductModelVersion2.WooPosProductStatus.DRAFT
"pending" -> WooPosProductModelVersion2.WooPosProductStatus.PENDING
"private" -> WooPosProductModelVersion2.WooPosProductStatus.PRIVATE
"trash" -> WooPosProductModelVersion2.WooPosProductStatus.TRASH
else -> WooPosProductModelVersion2.WooPosProductStatus.UNKNOWN
"publish" -> WooPosProductModel.WooPosProductStatus.PUBLISH
"draft" -> WooPosProductModel.WooPosProductStatus.DRAFT
"pending" -> WooPosProductModel.WooPosProductStatus.PENDING
"private" -> WooPosProductModel.WooPosProductStatus.PRIVATE
"trash" -> WooPosProductModel.WooPosProductStatus.TRASH
else -> WooPosProductModel.WooPosProductStatus.UNKNOWN
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import java.math.BigDecimal
import javax.inject.Inject

@Reusable
class WCProductToWooPosProductModelMapper @Inject constructor(
private val wooPosProductModelMapper: WooPosProductModelVersion2Mapper,
class WooPosWCProductToWooPosProductModelMapper @Inject constructor(
private val wooPosProductModelMapper: WooPosProductModelMapper,
private val logger: WooPosLogWrapper
) {
fun map(wcProduct: WCProductModel): WooPosProductModelVersion2 {
return WooPosProductModelVersion2(
fun map(wcProduct: WCProductModel): WooPosProductModel {
return WooPosProductModel(
remoteId = wcProduct.remoteProductId,
parentId = wcProduct.parentId.takeIf { it != 0L },
name = wcProduct.name,
Expand Down
Loading