UNPKG

@shopgate/pwa-common-commerce

Version:

Commerce library for the Shopgate Connect PWA.

83 lines (77 loc) 3.63 kB
import PipelineRequest from '@shopgate/pwa-core/classes/PipelineRequest'; import { PROCESS_SEQUENTIAL } from '@shopgate/pwa-core/constants/ProcessTypes'; import { mutable } from '@shopgate/pwa-common/helpers/redux'; import { SHOPGATE_CART_ADD_PRODUCTS } from "../constants/Pipelines"; import createPipelineErrorList from "../helpers/createPipelineErrorList"; import { ECART } from "../constants/PipelineErrors"; import addProductsToCart from "../action-creators/addProductsToCart"; import successAddProductsToCart from "../action-creators/successAddProductsToCart"; import errorAddProductsToCart from "../action-creators/errorAddProductsToCart"; import setCartProductPendingCount from "../action-creators/setCartProductPendingCount"; import { getProductPendingCount, getAddToCartMetadata, getCartItems } from "../selectors"; import { getProduct } from "../../product/selectors/product"; import { messagesHaveErrors, createErrorMessageList } from "../helpers"; import { getDisplayedProductQuantity } from "../helpers/quantity"; import { handleFulfillmentSlots } from "../helpers/fulfillmentSlots"; /** * Adds products to the cart. * @param {Array} data The options for the products to be added. * @return {Function} A redux thunk. */ function addToCart(data) { return async (dispatch, getState) => { const state = getState(); const preCartItems = getCartItems(state); const pendingProductCount = getProductPendingCount(state); let quantity = 0; let products = data.map(product => { const productData = getProduct(state, { productId: product.productId }) || {}; // Count quantity for pending count. quantity += getDisplayedProductQuantity({ ...product, product: productData }, preCartItems); // Restructure into a productId and a variantId (only productId if not adding a variant) const productId = productData.baseProductId || product.productId; const variantId = productData.baseProductId ? productData.id : undefined; const metadata = getAddToCartMetadata(state, { productId, variantId }); // Return the current product if it already had metadata, otherwise add some, if any available return product.metadata && product || { ...product, ...(metadata && { metadata }) }; }); products = await handleFulfillmentSlots(state, products); // Dispatch pipeline request. dispatch(addProductsToCart(products)); dispatch(setCartProductPendingCount(pendingProductCount + quantity)); const request = new PipelineRequest(SHOPGATE_CART_ADD_PRODUCTS).setInput({ products }).setResponseProcessed(PROCESS_SEQUENTIAL).setRetries(0).setErrorBlacklist(ECART).dispatch(); request.then(result => { if (result.messages && messagesHaveErrors(result.messages)) { /** * @deprecated: The property "messages" is not supposed to be part of the * pipeline response. Specification demands errors to be returned as response * object with an "error" property. This code snippet needs to be removed after * fixing the `@shopgate/legacy-cart` extension. */ dispatch(errorAddProductsToCart(products, createErrorMessageList(SHOPGATE_CART_ADD_PRODUCTS, result.messages))); return; } dispatch(successAddProductsToCart()); }).catch(error => { dispatch(errorAddProductsToCart(products, createPipelineErrorList(SHOPGATE_CART_ADD_PRODUCTS, error))); }); return request; }; } /** @mixes {MutableFunction} */ export default mutable(addToCart);