diff --git a/plugins/woocommerce/src/main/java/org/wordpress/android/fluxc/action/WCProductAction.java b/plugins/woocommerce/src/main/java/org/wordpress/android/fluxc/action/WCProductAction.java index 907f304e14..fbc2fc9391 100644 --- a/plugins/woocommerce/src/main/java/org/wordpress/android/fluxc/action/WCProductAction.java +++ b/plugins/woocommerce/src/main/java/org/wordpress/android/fluxc/action/WCProductAction.java @@ -28,6 +28,7 @@ import org.wordpress.android.fluxc.store.WCProductStore.RemoteUpdateProductImagesPayload; import org.wordpress.android.fluxc.store.WCProductStore.RemoteUpdateProductPayload; import org.wordpress.android.fluxc.store.WCProductStore.RemoteUpdatedProductPasswordPayload; +import org.wordpress.android.fluxc.store.WCProductStore.SearchProductsByGlobalUniqueIdPayload; import org.wordpress.android.fluxc.store.WCProductStore.SearchProductsPayload; import org.wordpress.android.fluxc.store.WCProductStore.UpdateProductImagesPayload; import org.wordpress.android.fluxc.store.WCProductStore.UpdateProductPasswordPayload; @@ -40,6 +41,8 @@ public enum WCProductAction implements IAction { FETCH_PRODUCTS, @Action(payloadType = SearchProductsPayload.class) SEARCH_PRODUCTS, + @Action(payloadType = SearchProductsByGlobalUniqueIdPayload.class) + SEARCH_PRODUCTS_BY_GLOBAL_UNIQUE_ID, @Action(payloadType = FetchProductShippingClassListPayload.class) FETCH_PRODUCT_SHIPPING_CLASS_LIST, @Action(payloadType = FetchSingleProductShippingClassPayload.class) diff --git a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/product/ProductRestClient.kt b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/product/ProductRestClient.kt index 2aeb1e80fa..ecebccb600 100644 --- a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/product/ProductRestClient.kt +++ b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/product/ProductRestClient.kt @@ -420,6 +420,7 @@ class ProductRestClient @Inject constructor( sortType: ProductSorting = DEFAULT_PRODUCT_SORTING, searchQuery: String? = null, skuSearchOptions: SkuSearchOptions = SkuSearchOptions.Disabled, + globalUniqueIdSearchQuery: String? = null, includedProductIds: List? = null, filterOptions: Map? = null, excludedProductIds: List? = null @@ -432,6 +433,7 @@ class ProductRestClient @Inject constructor( offset = offset, searchQuery = searchQuery, skuSearchOptions = skuSearchOptions, + globalUniqueIdSearchQuery = globalUniqueIdSearchQuery, includedProductIds = includedProductIds, excludedProductIds = excludedProductIds, filterOptions = filterOptions @@ -452,7 +454,7 @@ class ProductRestClient @Inject constructor( val loadedMore = offset > 0 val canLoadMore = productModels.size == pageSize - if (searchQuery == null) { + if (searchQuery == null && globalUniqueIdSearchQuery == null) { val payload = RemoteProductListPayload( site, productModels, @@ -497,6 +499,26 @@ class ProductRestClient @Inject constructor( } } + fun searchProductsByGlobalUniqueId( + site: SiteModel, + globalUniqueIdSearchQuery: String? = null, + pageSize: Int = DEFAULT_PRODUCT_PAGE_SIZE, + offset: Int = 0, + sorting: ProductSorting = DEFAULT_PRODUCT_SORTING, + excludedProductIds: List? = null, + filterOptions: Map? = null + ) { + fetchProducts( + site = site, + pageSize = pageSize, + offset = offset, + sortType = sorting, + globalUniqueIdSearchQuery = globalUniqueIdSearchQuery, + excludedProductIds = excludedProductIds, + filterOptions = filterOptions + ) + } + fun searchProducts( site: SiteModel, searchQuery: String, @@ -583,6 +605,7 @@ class ProductRestClient @Inject constructor( offset: Int, searchQuery: String?, skuSearchOptions: SkuSearchOptions, + globalUniqueIdSearchQuery: String? = null, includedProductIds: List? = null, excludedProductIds: List? = null, filterOptions: Map? = null @@ -631,9 +654,20 @@ class ProductRestClient @Inject constructor( } } + addGlobalUniqueIdSearchQuery(params, globalUniqueIdSearchQuery) + return params } + private fun addGlobalUniqueIdSearchQuery( + params: MutableMap, + globalUniqueIdSearchQuery: String? + ) { + if (!globalUniqueIdSearchQuery.isNullOrEmpty()) { + params["global_unique_id"] = globalUniqueIdSearchQuery + } + } + /** * Makes a GET request to `/wp-json/wc/v3/products/categories` retrieving a list of product * categories for the given WooCommerce [SiteModel]. diff --git a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/store/WCProductStore.kt b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/store/WCProductStore.kt index b87c53948c..541ca53957 100644 --- a/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/store/WCProductStore.kt +++ b/plugins/woocommerce/src/main/kotlin/org/wordpress/android/fluxc/store/WCProductStore.kt @@ -125,6 +125,16 @@ class WCProductStore @Inject constructor( var filterOptions: Map? = null, ) : Payload() + class SearchProductsByGlobalUniqueIdPayload( + var site: SiteModel, + var globalUniqueId: String, + var pageSize: Int = DEFAULT_PRODUCT_PAGE_SIZE, + var offset: Int = 0, + var sorting: ProductSorting = DEFAULT_PRODUCT_SORTING, + var excludedProductIds: List? = null, + var filterOptions: Map? = null, + ) : Payload() + class FetchProductVariationsPayload( var site: SiteModel, var remoteProductId: Long, @@ -905,6 +915,9 @@ class WCProductStore @Inject constructor( WCProductAction.SEARCH_PRODUCTS -> searchProducts(action.payload as SearchProductsPayload) + WCProductAction.SEARCH_PRODUCTS_BY_GLOBAL_UNIQUE_ID -> + searchProductsByGlobalUniqueId(action.payload as SearchProductsByGlobalUniqueIdPayload) + WCProductAction.UPDATE_PRODUCT_IMAGES -> updateProductImages(action.payload as UpdateProductImagesPayload) @@ -1211,6 +1224,20 @@ class WCProductStore @Inject constructor( } } + private fun searchProductsByGlobalUniqueId(payload: SearchProductsByGlobalUniqueIdPayload) { + with(payload) { + wcProductRestClient.searchProductsByGlobalUniqueId( + site = site, + globalUniqueIdSearchQuery = globalUniqueId, + pageSize = pageSize, + offset = offset, + sorting = sorting, + excludedProductIds = excludedProductIds, + filterOptions = filterOptions + ) + } + } + suspend fun fetchProductVariations(payload: FetchProductVariationsPayload): OnProductChanged { return coroutineEngine.withDefaultContext(API, this, "fetchProductVariations") { val result = with(payload) { diff --git a/plugins/woocommerce/src/test/java/org/wordpress/android/fluxc/network/rest/wpcom/wc/product/ProductRestClientTest.kt b/plugins/woocommerce/src/test/java/org/wordpress/android/fluxc/network/rest/wpcom/wc/product/ProductRestClientTest.kt index 843db0d2cc..238c631d3e 100644 --- a/plugins/woocommerce/src/test/java/org/wordpress/android/fluxc/network/rest/wpcom/wc/product/ProductRestClientTest.kt +++ b/plugins/woocommerce/src/test/java/org/wordpress/android/fluxc/network/rest/wpcom/wc/product/ProductRestClientTest.kt @@ -162,6 +162,33 @@ class ProductRestClientTest { } } + @Test + fun `when fetch products called with the global unique id, then correct params is used for network call`() { + runBlockingTest { + val globalUniqueIdSearchQuery = "test global unique id" + sut.fetchProducts( + site = site, + globalUniqueIdSearchQuery = globalUniqueIdSearchQuery + ) + val argumentCaptor = argumentCaptor>() + verify(wooNetwork).executeGetGsonRequest( + any(), + any(), + clazz = eq(Array::class.java), + params = argumentCaptor.capture(), + enableCaching = any(), + cacheTimeToLive = any(), + forced = any(), + requestTimeout = any(), + retries = any() + ) + + assertThat(argumentCaptor.firstValue.getOrDefault("global_unique_id", null)).isEqualTo( + globalUniqueIdSearchQuery + ) + } + } + private fun WCProductModel.withRegularPrice(newRegularPrice: String): WCProductModel = copy().apply { remoteProductId = this@withRegularPrice.remoteProductId