diff --git a/lib/sylius/index.ts b/lib/sylius/index.ts index 73c82b7ee1..3ac0dc8069 100644 --- a/lib/sylius/index.ts +++ b/lib/sylius/index.ts @@ -1,8 +1,15 @@ import { REST_METHODS, SYLIUS_API_ENDPOINT } from 'lib/constants'; +import { normalizeCart } from './normalizer/cart-normalizer'; import { normalizeCollection } from './normalizer/collection-normalizer'; import { normalizeProduct } from './normalizer/product-normalizer'; import { SyliusProduct, SyliusTaxon } from './sylius-types/product-types'; -import { AddToCartPayload, Collection, GetCollectionProductsPayload, GetProductsPayload } from './types'; +import { + AddToCartPayload, + Cart, + Collection, + GetCollectionProductsPayload, + GetProductsPayload +} from './types'; const DOMAIN = `${process.env.SYLIUS_STORE_DOMAIN}`; const ENDPOINT = `${DOMAIN}${SYLIUS_API_ENDPOINT}`; @@ -146,9 +153,11 @@ export const getCollectionProducts = async (payload: GetCollectionProductsPayloa }; // Cart -export const createCart = async () => { - const cart = await syliusRequest(REST_METHODS.POST, '/orders', { localeCode: 'fr_FR' }); - return cart; +export const createCart = async (): Promise => { + const data = await syliusRequest(REST_METHODS.POST, '/orders', { localeCode: 'fr_FR' }); + const syliusCart = data.body; + + return normalizeCart(syliusCart); }; export const getCart = (cartId: string) => { syliusRequest(REST_METHODS.GET, `/orders/${cartId}`); @@ -162,13 +171,13 @@ export const removeFromCart = () => {}; export const updateCart = () => {}; // Site -export const getMenu = async () => { +export const getMenu = async () => { const collections = await getCollections(); return [ { title: 'All', path: '/search' }, - ...collections.slice(0,2).map(({ title, path }) => ({ title, path })) + ...collections.slice(0, 2).map(({ title, path }) => ({ title, path })) ]; }; diff --git a/lib/sylius/normalizer/cart-normalizer.ts b/lib/sylius/normalizer/cart-normalizer.ts new file mode 100644 index 0000000000..fa7568cd83 --- /dev/null +++ b/lib/sylius/normalizer/cart-normalizer.ts @@ -0,0 +1,50 @@ +import { SyliusCart, SyliusCartItem } from '../sylius-types/cart-types'; +import { SyliusProductOption, SyliusProductOptionValue } from '../sylius-types/product-types'; +import { Cart, CartItem } from '../types'; +import { normalizeProduct } from './product-normalizer'; +import { normalizePrice } from './utils-normalizer'; + +export const normalizeCart = (syliusCart: SyliusCart): Cart => { + return { + id: syliusCart.tokenValue, + checkoutUrl: '', + cost: { + subtotalAmount: normalizePrice(syliusCart.itemsTotal), + totalAmount: normalizePrice(syliusCart.total), + totalTaxAmount: normalizePrice(syliusCart.taxTotal) + }, + lines: syliusCart.items.map((item) => normalizeCartItem(item)), + totalQuantity: syliusCart.items.reduce((acc, item) => acc + item.quantity, 0) + }; +}; + +const normalizeCartItem = (syliusCartItem: SyliusCartItem): CartItem => { + return { + id: syliusCartItem.id.toString(), + quantity: syliusCartItem.quantity, + cost: { + totalAmount: normalizePrice(syliusCartItem.total) + }, + merchandise: { + id: syliusCartItem.variant.id.toString(), + title: syliusCartItem.variant.name, + selectedOptions: syliusCartItem.variant.optionValues.map((optionValue) => + normalizeOrderItemOptionValue(optionValue, syliusCartItem.product.options) + ), + product: normalizeProduct(syliusCartItem.product) + } + }; +}; + +const normalizeOrderItemOptionValue = ( + optionValue: SyliusProductOptionValue, + options: SyliusProductOption[] +): { name: string; value: string } => { + const selectedOption = options.filter((option) => + option.values.some((value) => value.code === optionValue.code) + )[0]; + return { + name: selectedOption?.name ?? '', + value: optionValue.value + }; +}; diff --git a/lib/sylius/normalizer/product-normalizer.ts b/lib/sylius/normalizer/product-normalizer.ts index e58e52bff5..f846fa2085 100644 --- a/lib/sylius/normalizer/product-normalizer.ts +++ b/lib/sylius/normalizer/product-normalizer.ts @@ -4,7 +4,8 @@ import { SyliusProductOption, SyliusProductVariant } from '../sylius-types/product-types'; -import { Image, Money, Product, ProductOption, ProductVariant } from '../types'; +import { Image, Product, ProductOption, ProductVariant } from '../types'; +import { normalizePrice } from './utils-normalizer'; export const normalizeProduct = (product: SyliusProduct): Product => ({ seo: { @@ -51,11 +52,6 @@ export const normalizeProductImage = (image: SyliusProductImage): Image => ({ height: 400 }); -const normalizePrice = (amount: number): Money => ({ - amount: (amount / 100).toString(), - currencyCode: 'EUR' -}); - const normalizePriceRange = (product: SyliusProduct) => { let minVariantPrice = 0; let maxVariantPrice = 0; diff --git a/lib/sylius/normalizer/utils-normalizer.ts b/lib/sylius/normalizer/utils-normalizer.ts new file mode 100644 index 0000000000..303d068ae0 --- /dev/null +++ b/lib/sylius/normalizer/utils-normalizer.ts @@ -0,0 +1,8 @@ +import { Money } from '../types'; + +export const normalizePrice = (amount: number): Money => ({ + amount: centsPriceToUnitsPrice(amount).toString(), + currencyCode: 'EUR' +}); + +export const centsPriceToUnitsPrice = (amount: number): number => amount / 100; diff --git a/lib/sylius/sylius-types/cart-types.ts b/lib/sylius/sylius-types/cart-types.ts new file mode 100644 index 0000000000..c1b40a1230 --- /dev/null +++ b/lib/sylius/sylius-types/cart-types.ts @@ -0,0 +1,35 @@ +import { SyliusProduct, SyliusProductOptionValue, SyliusProductVariant } from './product-types'; + +export interface SyliusCart { + id: number; + tokenValue: string; + currencyCode: string; + taxTotal: number; + itemsTotal: number; + total: number; + taxExcludedTotal: number; + taxIncludedTotal: number; + shippingTotal: number; + orderPromotionTotal: number; + items: SyliusCartItem[]; +} + +export interface SyliusCartItem { + id: number; + productName: string; + quantity: number; + unitPrice: number; + discountedUnitPrice: number; + variant: SyliusProductVariant; + optionValues: SyliusProductOptionValue[]; + product: SyliusProduct; + adjustments: SyliusAdjustment[]; + total: number; +} + +export interface SyliusAdjustment { + id: number; + type: string; + label: string; + amount: number; +}