diff --git a/packages/sylius/src/utils/normalize/normalize-product.ts b/packages/sylius/src/utils/normalize/normalize-product.ts index d809a06b6..6b9dfc8a7 100644 --- a/packages/sylius/src/utils/normalize/normalize-product.ts +++ b/packages/sylius/src/utils/normalize/normalize-product.ts @@ -10,7 +10,7 @@ import { SyliusProduct, SyliusProductImage, SyliusProductOption, - SyliusProductOptionValues, + SyliusProductOptionValue, SyliusProductVariant, } from '../../types/products' @@ -24,7 +24,7 @@ export const normalizeProduct = (product: SyliusProduct): Product => { path: `/${product.slug}`, images: product.images.map((image) => normalizeProductImage(image)), variants: product.variants.map((variant) => - normalizeProductVariant(variant) + normalizeProductVariant(variant, product.options) ), price: normalizeProductPrice( product.variants[0].price, @@ -35,29 +35,67 @@ export const normalizeProduct = (product: SyliusProduct): Product => { } const normalizeProductVariant = ( - variant: SyliusProductVariant + variant: SyliusProductVariant, + options: SyliusProductOption[] ): ProductVariant => { - const options = - variant.optionValues.length > 0 - ? [ - { - id: '', - displayName: '', - values: variant.optionValues.map((optionValue) => - normalizeProductOptionValue(optionValue) - ), + const availableOptions = variant.optionValues.reduce( + (accumulator: { [id: number]: ProductOption }, currentOptionValue) => { + const optionFromOptionValue = options.filter( + (option: SyliusProductOption) => + option.values.some((value) => value.code === currentOptionValue.code) + )[0] + if (accumulator.hasOwnProperty(optionFromOptionValue.id.toString())) { + return { + ...accumulator, + [optionFromOptionValue.id]: { + ...accumulator[optionFromOptionValue.id], + values: [ + ...accumulator[optionFromOptionValue.id].values, + { + label: currentOptionValue.value ?? '', + }, + ], }, - ] - : [] + } + } else { + const newOption = normalizeProductVariantOption( + currentOptionValue, + optionFromOptionValue + ) + return { + ...accumulator, + [newOption.id]: newOption, + } + } + }, + {} + ) return { - id: variant.id, - options: options, + id: variant.code, + options: Object.values(availableOptions), availableForSale: variant.inStock, } } +const normalizeProductVariantOption = ( + optionValue: SyliusProductOptionValue, + option: SyliusProductOption +): ProductOption => { + return { + __typename: 'MultipleChoiceOption', + id: option.id.toString(), + displayName: option.name, + values: [ + { + label: optionValue.value ?? '', + }, + ], + } +} + const normalizeProductOption = (option: SyliusProductOption): ProductOption => { return { + __typename: 'MultipleChoiceOption', id: option.id.toString(), displayName: option.name, values: option.values.map((optionValue) => @@ -67,14 +105,16 @@ const normalizeProductOption = (option: SyliusProductOption): ProductOption => { } const normalizeProductOptionValue = ( - optionValue: SyliusProductOptionValues + optionValue: SyliusProductOptionValue ): ProductOptionValues => { return { label: optionValue.value ?? '', } } -const normalizeProductImage = (image: SyliusProductImage): ProductImage => { +export const normalizeProductImage = ( + image: SyliusProductImage +): ProductImage => { return { url: process.env.NEXT_PUBLIC_SYLIUS_ALLOWED_IMAGE_URL + image.path, }