UNPKG

@salla.sa/twilight-components

Version:
198 lines (194 loc) 7.46 kB
/*! * Crafted with ❤ by Salla */ 'use strict'; var interfaces = require('./interfaces-Bh7W0bEU.js'); let addedOrderItemCounter = 0; function generateAddedOrderItemId(productId) { const cryptoRef = (typeof globalThis !== 'undefined' ? globalThis.crypto : undefined); if (cryptoRef && typeof cryptoRef.randomUUID === 'function') { return `new-${productId}-${cryptoRef.randomUUID()}`; } addedOrderItemCounter += 1; return `new-${productId}-${Date.now()}-${addedOrderItemCounter}`; } function cloneOrderEditProduct(product) { if (product == null) { return product; } return typeof structuredClone === 'function' ? structuredClone(product) : JSON.parse(JSON.stringify(product)); } function buildSavePayload(payload) { return { items: { update: payload.items.update, remove: payload.items.remove, add: payload.items.add.map(({ itemId, ...addItem }) => addItem), }, }; } function createAddedOrderItem(product, quantity, optionDefinitions, selectedOptions = {}) { const productData = cloneOrderEditProduct(product); return { id: generateAddedOrderItemId(product.id), quantity, isNew: true, selectedOptions, product: { ...productData, options: cloneOrderEditProduct(optionDefinitions), }, }; } function normalizeOrderEditOptionValue(value) { if (typeof File !== 'undefined' && value instanceof File) { return value.name; } return String(value); } function normalizeSelectedOptions(selectedOptions = {}) { return JSON.stringify(Object.entries(selectedOptions) .filter(([, value]) => value != null && normalizeOrderEditOptionValue(value).length > 0) .map(([optionId, value]) => [String(optionId), normalizeOrderEditOptionValue(value)]) .sort(([leftId], [rightId]) => leftId.localeCompare(rightId))); } function hasSelectedOptions(selectedOptions) { return Boolean(selectedOptions && Object.values(selectedOptions).some(value => value != null && normalizeOrderEditOptionValue(value).length > 0)); } const detailIdOptionTypes = new Set([ interfaces.DisplayType.COLOR, interfaces.DisplayType.COUNTRY, interfaces.DisplayType.DIGITAL_CARD_VALUE, interfaces.DisplayType.MULTIPLE_OPTIONS, interfaces.DisplayType.RADIO, interfaces.DisplayType.SINGLE_OPTION, interfaces.DisplayType.THUMBNAIL, ]); function getProductOptionSelectedOptions(options = []) { return options.reduce((acc, option) => { if (option?.id == null) { return acc; } const selectedDetails = option.details?.filter(detail => detail?.is_selected) || []; const selectedDetail = selectedDetails[selectedDetails.length - 1]; const value = selectedDetail?.id ?? option.value; if (value == null || String(value).length === 0) { return acc; } acc[String(option.id)] = String(value); return acc; }, {}); } function getOrderDetailSelectedOptionValue(item, optionId, value) { const productOption = item?.product?.options?.find(option => String(option.id) === String(optionId)); const normalizedValue = String(value); if (!productOption?.details?.length || !detailIdOptionTypes.has(productOption.type)) { return normalizedValue; } const selectedDetail = productOption.details.find(detail => [ detail.id, detail.name, detail.option_value, detail.color, detail.image, detail.code, detail.display_value, ].some(detailValue => detailValue != null && String(detailValue) === normalizedValue)); return selectedDetail ? String(selectedDetail.id) : normalizedValue; } function getOrderDetailsSelectedOptions(item) { return (item?.options || []).reduce((acc, option) => { if (option?.id == null) { return acc; } const value = option.value ?? option.display_value; if (value == null || String(value).length === 0) { return acc; } acc[String(option.id)] = getOrderDetailSelectedOptionValue(item, option.id, value); return acc; }, {}); } function getOrderItemSelectedOptions(item) { if (hasSelectedOptions(item?.selectedOptions)) { return item.selectedOptions; } const productSelectedOptions = getProductOptionSelectedOptions(item?.product?.options); if (hasSelectedOptions(productSelectedOptions)) { return productSelectedOptions; } return getOrderDetailsSelectedOptions(item); } function findMergeableItem(items = [], productId, selectedOptions = {}) { const targetSelectedOptions = normalizeSelectedOptions(selectedOptions); return items.find(item => String(item.product?.id) === String(productId) && normalizeSelectedOptions(getOrderItemSelectedOptions(item)) === targetSelectedOptions); } function getOrderEditProductMaxQuantity(product) { const rawQuantity = product?.max_quantity ?? product?.max_quantity_per_order; const parsedQuantity = Number(rawQuantity); return Number.isFinite(parsedQuantity) && parsedQuantity > 0 ? parsedQuantity : undefined; } function clampOrderEditQuantity(quantity, maxQuantity) { if (!Number.isFinite(quantity) || quantity < 1) { return 1; } if (maxQuantity && quantity > maxQuantity) { return maxQuantity; } return quantity; } function patchOrderItem(item, quantity, optionDefinitions, selectedOptions) { return { ...item, quantity, selectedOptions: selectedOptions ?? getOrderItemSelectedOptions(item), product: item.product ? { ...item.product, options: optionDefinitions ?? item.product.options, } : item.product, }; } function updateOrderItems(items = [], itemId, quantity, optionDefinitions, selectedOptions) { return items.map(item => item.id === itemId ? patchOrderItem(item, quantity, optionDefinitions, selectedOptions) : item); } function removeOrderItems(items = [], itemId) { return items.filter(item => item.id !== itemId); } function mergePayloadItems(items, patch) { return { ...items, ...patch, }; } function upsertPayloadUpdateList(updateList = [], itemId, quantity, options = {}) { const nextUpdateList = updateList.filter(item => item.id !== itemId); nextUpdateList.push({ id: itemId, quantity, options }); return nextUpdateList; } function updateAddedPayloadList(addList = [], itemId, quantity, options) { return addList.map(item => item.itemId === itemId ? { ...item, quantity, options: options ?? item.options, } : item); } exports.buildSavePayload = buildSavePayload; exports.clampOrderEditQuantity = clampOrderEditQuantity; exports.cloneOrderEditProduct = cloneOrderEditProduct; exports.createAddedOrderItem = createAddedOrderItem; exports.findMergeableItem = findMergeableItem; exports.getOrderEditProductMaxQuantity = getOrderEditProductMaxQuantity; exports.getOrderItemSelectedOptions = getOrderItemSelectedOptions; exports.mergePayloadItems = mergePayloadItems; exports.removeOrderItems = removeOrderItems; exports.updateAddedPayloadList = updateAddedPayloadList; exports.updateOrderItems = updateOrderItems; exports.upsertPayloadUpdateList = upsertPayloadUpdateList;