JezK
Edit File: sc-checkout-stock-alert2.js.map
{"file":"sc-checkout-stock-alert2.js","mappings":"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","names":[],"sources":["src/functions/stock.ts","src/components/controllers/checkout-form/checkout/checkout-stock-alert/sc-checkout-stock-alert.scss?tag=sc-checkout-stock-alert&encapsulation=shadow","src/components/controllers/checkout-form/checkout/checkout-stock-alert/sc-checkout-stock-alert.tsx"],"sourcesContent":["import { ImageAttributes, LineItem, LineItemData, Price, Product } from '../types';\nimport { getPerBundleQuantity } from './line-items';\n\nexport interface StockAlertRow {\n name?: string;\n variant?: string;\n image?: ImageAttributes;\n from: number;\n to: number;\n}\n\n/**\n * Reconstruct a bundle's `bundle_component_variants` map from its component\n * line items (componentProductId -> variantId).\n *\n * The platform treats `bundle_component_variants` on the parent as write-only:\n * it's accepted on create/update but reads back empty, so the live selection\n * has to be derived from each component line item's chosen variant. Any update\n * that re-posts the map (e.g. a stock swap) must rebuild the *full* map this way\n * — seeding from the empty parent field drops the other components and trips the\n * platform's \"selection required\" validation.\n */\nexport const getBundleComponentVariants = (parentId: string, lineItems: LineItem[] = []): Record<string, string> => {\n const map: Record<string, string> = {};\n (lineItems || []).forEach(item => {\n if (item?.bundle_line_item !== parentId) return;\n const productId = ((item?.price as Price)?.product as Product)?.id;\n const variantId = item?.variant?.id;\n if (productId && variantId) map[productId] = variantId;\n });\n return map;\n};\n\n/** Available stock for a line item (variant takes precedence over product). */\nexport const getAvailableStock = (lineItem: LineItem): number => {\n const product = lineItem?.price?.product as Product;\n const stock = lineItem?.variant?.id ? lineItem?.variant?.available_stock : product?.available_stock;\n return Math.max(Number(stock) || 0, 0);\n};\n\n/** Out-of-stock line items (standalone items and bundle components). */\nexport const getOutOfStockLineItems = (lineItems: LineItem[] = []): LineItem[] =>\n (lineItems || []).filter(lineItem => lineItem?.purchasable_status === 'out_of_stock' && getAvailableStock(lineItem) < lineItem.quantity);\n\n/**\n * A bundle is atomic, so a short component caps the bundle, not the component:\n * floor(stock / perBundleQty), smallest cap across components. Returns a map of\n * bundle parent id -> reduced quantity.\n *\n * `swappedProductsByParent` lists component products being swapped to an in-stock\n * variant — those are skipped so they don't cap a bundle they no longer limit.\n */\nexport const getBundleQuantityReductions = (lineItems: LineItem[] = [], swappedProductsByParent: Map<string, Set<string>> = new Map()): Map<string, number> => {\n const reductions = new Map<string, number>();\n\n getOutOfStockLineItems(lineItems).forEach(component => {\n if (!component.component_line_item || !component.bundle_line_item) return;\n const parent = (lineItems || []).find(li => li.id === component.bundle_line_item);\n if (!parent?.id) return;\n\n // Skip a component that's being swapped — its old stock no longer caps the bundle.\n const productId = ((component.price as Price)?.product as Product)?.id;\n if (productId && swappedProductsByParent.get(parent.id)?.has(productId)) return;\n\n const perBundle = getPerBundleQuantity(component, parent.quantity);\n const maxBundles = Math.floor(getAvailableStock(component) / perBundle);\n\n const current = reductions.get(parent.id) ?? parent.quantity;\n reductions.set(parent.id, Math.max(Math.min(current, maxBundles), 0));\n });\n\n return reductions;\n};\n\n/**\n * Payload to fix a stock alert. Posts parents only (components derive from the\n * parent): bundles drop to their reduced quantity, standalone items to available\n * stock. A swapped component is excluded from its bundle's cap, so any *other*\n * short component still reduces the bundle correctly.\n */\nexport const buildStockAdjustedLineItems = (lineItems: LineItem[] = [], bundleVariantOverrides: Map<string, Record<string, string>> = new Map()): LineItemData[] => {\n // Component products being swapped, keyed by bundle parent.\n const swappedProductsByParent = new Map<string, Set<string>>(Array.from(bundleVariantOverrides, ([parentId, map]) => [parentId, new Set(Object.keys(map))]));\n const reductions = getBundleQuantityReductions(lineItems, swappedProductsByParent);\n\n const standalone = new Map<string, number>();\n getOutOfStockLineItems(lineItems).forEach(lineItem => {\n if (lineItem.component_line_item || !lineItem.id) return;\n standalone.set(lineItem.id, getAvailableStock(lineItem));\n });\n\n return (lineItems || [])\n .filter(lineItem => !lineItem.component_line_item)\n .map(lineItem => {\n const id = lineItem.id;\n const hasSwap = !!id && bundleVariantOverrides.has(id);\n let quantity = lineItem.quantity;\n if (id && reductions.has(id)) quantity = reductions.get(id) ?? quantity;\n else if (id && standalone.has(id)) quantity = standalone.get(id) ?? quantity;\n\n return {\n id,\n price_id: (lineItem.price as Price)?.id,\n quantity,\n ...(lineItem?.variant?.id ? { variant: lineItem.variant.id } : {}),\n ...(id && hasSwap ? { bundle_component_variants: bundleVariantOverrides.get(id) } : {}),\n };\n });\n};\n\n/**\n * Rows for the stock alert dialog. Bundle components roll up into a single\n * parent row (the bundle quantity is what changes); standalone items show\n * themselves.\n */\nexport const buildStockAlertRows = (lineItems: LineItem[] = []): StockAlertRow[] => {\n const reductions = getBundleQuantityReductions(lineItems);\n const seenParents = new Set<string>();\n const rows: StockAlertRow[] = [];\n\n getOutOfStockLineItems(lineItems).forEach(lineItem => {\n if (lineItem.component_line_item && lineItem.bundle_line_item) {\n const parent = (lineItems || []).find(li => li.id === lineItem.bundle_line_item);\n if (!parent?.id || seenParents.has(parent.id)) return;\n seenParents.add(parent.id);\n const product = parent.price?.product as Product;\n rows.push({\n name: product?.name,\n variant: parent?.variant_display_options,\n image: parent?.image,\n from: parent.quantity,\n to: Math.max(reductions.get(parent.id) ?? parent.quantity, 0),\n });\n return;\n }\n\n const product = lineItem.price?.product as Product;\n rows.push({\n name: product?.name,\n variant: lineItem?.variant_display_options,\n image: lineItem?.image,\n from: lineItem.quantity,\n to: getAvailableStock(lineItem),\n });\n });\n\n return rows;\n};\n",":host {\n display: block;\n}\n\nsc-table {\n height: auto;\n}\n\nh4 {\n display: block;\n margin: 0;\n font-weight: var(--sc-font-weight-bold);\n font-size: var(--sc-font-size-medium);\n}\n\n.stock-alert {\n --body-spacing: var(--sc-spacing-x-large);\n --width: 500px;\n\n &__image {\n width: 50px;\n height: 50px;\n object-fit: cover;\n margin-right: 10px;\n display: block;\n }\n &__product-info {\n display: flex;\n flex-direction: column;\n gap: var(--sc-spacing-xx-small);\n }\n &__variant {\n color: var(--sc-color-gray-500);\n font-size: var(--sc-font-size-small);\n }\n &__quantity {\n color: var(--sc-color-gray-500);\n font-weight: var(--sc-font-weight-bold);\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--sc-spacing-xx-small);\n }\n}\n","import { Component, Host, h, State, EventEmitter, Event } from '@stencil/core';\nimport { __ } from '@wordpress/i18n';\nimport { Checkout, LineItemData, Product } from 'src/types';\nimport { state as checkoutState } from '@store/checkout';\nimport { updateCheckout } from '@services/session';\nimport { currentFormState } from '@store/form/getters';\nimport { buildStockAdjustedLineItems, buildStockAlertRows, getBundleComponentVariants, getBundleQuantityReductions, getOutOfStockLineItems } from '../../../../../functions/stock';\n\n/**\n * This component listens for stock requirements and displays a dialog to the user.\n */\n@Component({\n tag: 'sc-checkout-stock-alert',\n styleUrl: 'sc-checkout-stock-alert.scss',\n shadow: true,\n})\nexport class ScCheckoutStockAlert {\n /** Stock errors */\n @State() stockErrors: Array<any> = [];\n\n /** Toggle line item event */\n @Event() scUpdateLineItem: EventEmitter<LineItemData>;\n\n /** Is it busy */\n @State() busy: boolean;\n\n /** Update stock error. */\n @State() error: string;\n\n /** Current checkout line items. */\n get lineItems() {\n return checkoutState.checkout?.line_items?.data || [];\n }\n\n /**\n * Update the checkout to the max available stock.\n *\n * Bundle shortages reduce the whole bundle quantity (a bundle is atomic). A\n * bundle that can't make even one unit (reduced to 0) is first rescued by\n * swapping a gone variant to an in-stock sibling when one exists; otherwise\n * the unfulfillable bundle is dropped from the cart, matching the \"→ 0\" the\n * dialog already shows.\n */\n async onSubmit() {\n let attemptedBundleSwap = false;\n try {\n this.busy = true;\n this.error = null;\n\n const items = this.lineItems;\n const reductions = getBundleQuantityReductions(items);\n\n // Only bundles reduced to 0 need rescuing — try swapping the gone\n // variant to an in-stock sibling so we don't drop a recoverable bundle.\n // If no swap exists the bundle stays at 0 and is removed below.\n const parentOverrides = new Map<string, Record<string, string>>();\n getOutOfStockLineItems(items).forEach(oos => {\n if (!oos.component_line_item || !oos.bundle_line_item) return;\n const parent = items.find(li => li.id === oos.bundle_line_item);\n if (!parent?.id || (reductions.get(parent.id) ?? 0) >= 1) return;\n\n const product = oos.price?.product as Product;\n if (!product?.id) return;\n const swap = (product?.variants?.data || []).find(v => v.id !== oos.variant?.id && (v.available_stock ?? 0) > 0);\n if (!swap?.id) return;\n\n // Rebuild the full selection from the component line items (the parent\n // field reads back empty), then swap the gone variant — posting only the\n // swapped component would fail the platform's per-component requirement.\n const map = parentOverrides.get(parent.id) || getBundleComponentVariants(parent.id, items);\n map[product.id] = swap.id;\n parentOverrides.set(parent.id, map);\n });\n\n attemptedBundleSwap = parentOverrides.size > 0;\n\n // Bundles still capped at 0 (no in-stock swap) fall to quantity 0 and are\n // filtered out here — the unfulfillable bundle is simply removed.\n const lineItems = buildStockAdjustedLineItems(items, parentOverrides).filter(lineItem => !!lineItem.quantity);\n\n checkoutState.checkout = (await updateCheckout({\n id: checkoutState.checkout.id,\n data: { line_items: lineItems },\n })) as Checkout;\n } catch (error) {\n // A rejected bundle swap surfaces as a generic 500 — show an actionable\n // message so the shopper can remove the item or pick another bundle.\n if (attemptedBundleSwap) {\n this.error = __('We could not automatically update an out-of-stock bundle item. Please remove it or choose a different bundle.', 'surecart');\n } else {\n // Build the message defensively — `additionalErrors?.length && ...`\n // used to evaluate to the literal `0` when there were no additional\n // errors, which then got stringified into the displayed error.\n const additionalErrors = (error?.additional_errors || []).map(e => e?.message).filter(Boolean);\n const parts = [error?.message || __('Something went wrong.', 'surecart')];\n if (additionalErrors.length) parts.push(additionalErrors.join('. '));\n this.error = parts.join(' ');\n }\n } finally {\n this.busy = false;\n }\n }\n\n render() {\n const stockErrors = buildStockAlertRows(this.lineItems);\n\n // we have at least one fully out-of-stock item.\n const hasOutOfStockItems = stockErrors?.some(item => item?.to < 1);\n\n return (\n <Host>\n <sc-dialog open={!!stockErrors.length && currentFormState() === 'draft'} noHeader={true} onScRequestClose={e => e.preventDefault()} class=\"stock-alert\">\n <sc-dashboard-module class=\"subscription-cancel\" error={this.error} style={{ '--sc-dashboard-module-spacing': '1em' }}>\n <sc-flex slot=\"heading\" align-items=\"center\" justify-content=\"flex-start\">\n <sc-icon name=\"alert-circle\" style={{ color: 'var(--sc-color-primary-500' }}></sc-icon>\n {hasOutOfStockItems ? __('Out of Stock', 'surecart') : __('Quantity Update', 'surecart')}\n </sc-flex>\n <span slot=\"description\">\n {hasOutOfStockItems\n ? __('Some items are no longer available. Your cart will be updated.', 'surecart')\n : __('Available quantities for these items have changed. Your cart will be updated.', 'surecart')}\n </span>\n\n <sc-card no-padding>\n <sc-table>\n <sc-table-cell slot=\"head\">{__('Description', 'surecart')}</sc-table-cell>\n <sc-table-cell slot=\"head\" style={{ width: '100px', textAlign: 'right' }}>\n {__('Quantity', 'surecart')}\n </sc-table-cell>\n\n {stockErrors.map((item, index) => {\n const isLastChild = index === stockErrors.length - 1;\n return (\n <sc-table-row\n style={{\n '--columns': '2',\n ...(isLastChild ? { border: 'none' } : {}),\n }}\n >\n <sc-table-cell>\n <sc-flex justifyContent=\"flex-start\" alignItems=\"center\">\n {item?.image && <img {...(item.image as any)} class=\"stock-alert__image\" />}\n <div class=\"stock-alert__product-info\">\n <h4>{item.name}</h4>\n {item?.variant && <span class=\"stock-alert__variant\">{item.variant}</span>}\n </div>\n </sc-flex>\n </sc-table-cell>\n <sc-table-cell style={{ width: '100px', textAlign: 'right' }}>\n <span class=\"stock-alert__quantity\">\n <span>{item?.from}</span> <sc-icon name=\"arrow-right\" /> <span>{Math.max(item?.to, 0)}</span>\n </span>\n </sc-table-cell>\n </sc-table-row>\n );\n })}\n </sc-table>\n </sc-card>\n </sc-dashboard-module>\n\n <sc-button slot=\"footer\" type=\"primary\" loading={this.busy} onClick={() => this.onSubmit()}>\n {__('Continue', 'surecart')}\n <sc-icon name=\"arrow-right\" slot=\"suffix\" />\n </sc-button>\n\n {this.busy && <sc-block-ui spinner></sc-block-ui>}\n </sc-dialog>\n </Host>\n );\n }\n}\n"],"version":3}