UNPKG

@automattic/shopping-cart

Version:
223 lines 8.18 kB
import debugFactory from 'debug'; import { getEmptyResponseCart } from './empty-carts'; const debug = debugFactory('shopping-cart:cart-functions'); let lastUUID = 100; const emptyResponseCart = getEmptyResponseCart(); function convertResponseCartProductToRequestCartProduct(product) { const { product_slug, meta, product_id, extra, volume, quantity } = product; return { product_slug, meta, volume, quantity, product_id, extra, }; } export function convertResponseCartToRequestCart({ products, coupon, tax, blog_id, }) { let requestCartTax = null; if (tax.location.country_code || tax.location.postal_code || tax.location.subdivision_code || tax.location.vat_id || tax.location.organization || tax.location.address || tax.location.city) { requestCartTax = { location: { country_code: tax.location.country_code, postal_code: tax.location.postal_code, subdivision_code: tax.location.subdivision_code, vat_id: tax.location.vat_id, organization: tax.location.organization, address: tax.location.address, city: tax.location.city, }, }; } return { blog_id, products: products.map(convertResponseCartProductToRequestCartProduct), coupon, temporary: false, tax: requestCartTax, }; } export function convertTempResponseCartToResponseCart(cart) { return { ...cart, products: cart.products.filter(isValidResponseCartProduct), }; } function isValidResponseCartProduct(product) { return 'uuid' in product; } export function removeItemFromResponseCart(cart, uuidToRemove) { return { ...cart, products: cart.products.filter((product) => { return isValidResponseCartProduct(product) ? product.uuid !== uuidToRemove : true; }), }; } export function addCouponToResponseCart(cart, couponToAdd) { return { ...cart, coupon: couponToAdd, is_coupon_applied: false, }; } export function removeCouponFromResponseCart(cart) { return { ...cart, coupon: '', is_coupon_applied: false, }; } export function addLocationToResponseCart(cart, location) { return { ...cart, tax: { ...cart.tax, location: { country_code: location.countryCode || undefined, postal_code: location.postalCode || undefined, subdivision_code: location.subdivisionCode || undefined, vat_id: location.vatId || undefined, organization: location.organization || undefined, address: location.address || undefined, city: location.city || undefined, }, }, }; } export function doesCartLocationDifferFromResponseCartLocation(cart, location) { const { countryCode: newCountryCode = '', postalCode: newPostalCode = '', subdivisionCode: newSubdivisionCode = '', vatId: newVatId = '', organization: newOrganization = '', address: newAddress = '', city: newCity = '', } = location; const { country_code: oldCountryCode = '', postal_code: oldPostalCode = '', subdivision_code: oldSubdivisionCode = '', vat_id: oldVatId = '', organization: oldOrganization = '', address: oldAddress = '', city: oldCity = '', } = cart.tax?.location ?? {}; if (location.countryCode !== undefined && newCountryCode !== oldCountryCode) { return true; } if (location.postalCode !== undefined && newPostalCode !== oldPostalCode) { return true; } if (location.subdivisionCode !== undefined && newSubdivisionCode !== oldSubdivisionCode) { return true; } if (location.vatId !== undefined && newVatId !== oldVatId) { return true; } if (location.organization !== undefined && newOrganization !== oldOrganization) { return true; } if (location.address !== undefined && newAddress !== oldAddress) { return true; } if (location.city !== undefined && newCity !== oldCity) { return true; } return false; } export function convertRawResponseCartToResponseCart(rawResponseCart) { if (typeof rawResponseCart !== 'object' || rawResponseCart === null) { return emptyResponseCart; } // If tax.location is an empty PHP associative array, it will be JSON serialized to [] but we need {} let taxLocation = {}; if (rawResponseCart.tax?.location) { if (Array.isArray(rawResponseCart.tax.location)) { taxLocation = {}; } else { taxLocation = rawResponseCart.tax.location; } } const rawProducts = rawResponseCart.products?.length && Array.isArray(rawResponseCart.products) ? rawResponseCart.products : []; return { ...emptyResponseCart, ...rawResponseCart, tax: { location: taxLocation, display_taxes: rawResponseCart.tax?.display_taxes ?? false, }, // Add uuid to products returned by the server products: rawProducts.filter(isRealProduct).map((product) => { return { ...product, uuid: product.product_slug + lastUUID++, }; }), }; } function isRealProduct(serverCartItem) { // Credits are reported separately, so we do not need to include the pseudo-product in the line items. if (serverCartItem.product_slug === 'wordpress-com-credits') { return false; } return true; } function shouldProductReplaceCart(product, responseCart) { const doesCartHaveRenewals = responseCart.products.some((cartProduct) => cartProduct.extra?.purchaseType === 'renewal'); if (!doesCartHaveRenewals && product.extra?.purchaseType === 'renewal' && product.product_slug !== 'domain_redemption') { // adding a renewal replaces the cart unless it is a privacy protection (comment copied from original code from old checkout; is domain_redemption really privacy protection?) return true; } if (doesCartHaveRenewals && product.extra?.purchaseType !== 'renewal') { // all items should replace the cart if the cart contains a renewal return true; } return false; } function shouldProductsReplaceCart(products, responseCart) { return products.some((product) => shouldProductReplaceCart(product, responseCart)); } export function addItemsToResponseCart(responseCart, products) { if (shouldProductsReplaceCart(products, responseCart)) { debug('items should replace response cart', products); return replaceAllItemsInResponseCart(responseCart, products); } debug('items should not replace response cart', products); return { ...responseCart, products: [...responseCart.products, ...products], }; } export function replaceAllItemsInResponseCart(responseCart, products) { return { ...responseCart, products: [...products], }; } export function replaceItemInResponseCart(cart, uuidToReplace, productPropertiesToChange) { return { ...cart, products: cart.products.map((item) => { if (isValidResponseCartProduct(item) && item.uuid === uuidToReplace) { return { ...item, ...productPropertiesToChange }; } return item; }), }; } export function doesResponseCartContainProductMatching(responseCart, productProperties) { return responseCart.products.some((product) => { return (isValidResponseCartProduct(product) && Object.keys(productProperties).every((key) => { const typedKey = key; return product[typedKey] === productProperties[typedKey]; })); }); } export async function findCartKeyFromSiteSlug(slug, getCart) { try { const cart = await getCart(slug); return cart.cart_key; } catch { return 'no-site'; } } //# sourceMappingURL=cart-functions.js.map