@dropins/storefront-quick-order 0.0.1-alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/LICENSE.md +188 -0
  2. package/api/fetch-graphql/fetch-graphql.d.ts +8 -0
  3. package/api/fetch-graphql/index.d.ts +2 -0
  4. package/api/index.d.ts +3 -0
  5. package/api/initialize/index.d.ts +2 -0
  6. package/api/initialize/initialize.d.ts +10 -0
  7. package/api.d.ts +1 -0
  8. package/api.js +4 -0
  9. package/api.js.map +1 -0
  10. package/chunks/CsvFileInput.js +4 -0
  11. package/chunks/CsvFileInput.js.map +1 -0
  12. package/chunks/Search.js +4 -0
  13. package/chunks/Search.js.map +1 -0
  14. package/components/CsvFileInput/CsvFileInput.d.ts +5 -0
  15. package/components/CsvFileInput/index.d.ts +19 -0
  16. package/components/QuickOrderItemsList/QuickOrderItemsList.d.ts +5 -0
  17. package/components/QuickOrderItemsList/index.d.ts +19 -0
  18. package/components/QuickOrderListItem/QuickOrderListItem.d.ts +5 -0
  19. package/components/QuickOrderListItem/index.d.ts +19 -0
  20. package/components/Search/Search.d.ts +4 -0
  21. package/components/Search/index.d.ts +19 -0
  22. package/components/SkuListInput/SkuListInput.d.ts +5 -0
  23. package/components/SkuListInput/index.d.ts +19 -0
  24. package/components/index.d.ts +22 -0
  25. package/configs/index.d.ts +19 -0
  26. package/configs/order-item.config.d.ts +4 -0
  27. package/configs/search-filter.config.d.ts +5 -0
  28. package/containers/QuickOrderCsvUpload/QuickOrderCsvUpload.d.ts +5 -0
  29. package/containers/QuickOrderCsvUpload/index.d.ts +19 -0
  30. package/containers/QuickOrderCsvUpload.d.ts +3 -0
  31. package/containers/QuickOrderCsvUpload.js +7 -0
  32. package/containers/QuickOrderCsvUpload.js.map +1 -0
  33. package/containers/QuickOrderItems/QuickOrderItems.d.ts +5 -0
  34. package/containers/QuickOrderItems/index.d.ts +19 -0
  35. package/containers/QuickOrderItems.d.ts +3 -0
  36. package/containers/QuickOrderItems.js +4 -0
  37. package/containers/QuickOrderItems.js.map +1 -0
  38. package/containers/QuickOrderMultipleSku/QuickOrderMultipleSku.d.ts +5 -0
  39. package/containers/QuickOrderMultipleSku/index.d.ts +19 -0
  40. package/containers/QuickOrderMultipleSku.d.ts +3 -0
  41. package/containers/QuickOrderMultipleSku.js +4 -0
  42. package/containers/QuickOrderMultipleSku.js.map +1 -0
  43. package/containers/index.d.ts +20 -0
  44. package/data/models/index.d.ts +2 -0
  45. package/data/transforms/index.d.ts +2 -0
  46. package/hooks/index.d.ts +21 -0
  47. package/hooks/useItemSearch.d.ts +11 -0
  48. package/hooks/useQuickOrderCsvUpload.d.ts +4 -0
  49. package/hooks/useQuickOrderItems.d.ts +4 -0
  50. package/hooks/useQuickOrderMultipleSku.d.ts +4 -0
  51. package/i18n/en_US.json.d.ts +66 -0
  52. package/lib/addOrMergeItems.d.ts +13 -0
  53. package/lib/buildCartItem.d.ts +32 -0
  54. package/lib/buildCartItemsFromForms.d.ts +8 -0
  55. package/lib/cleanCsvValue.d.ts +24 -0
  56. package/lib/findDuplicateItem.d.ts +19 -0
  57. package/lib/generateItemId.d.ts +22 -0
  58. package/lib/getItemScope.d.ts +8 -0
  59. package/lib/index.d.ts +35 -0
  60. package/lib/mapProductsToOrderItems.d.ts +11 -0
  61. package/lib/mergeDuplicateItems.d.ts +8 -0
  62. package/lib/processFormOptions.d.ts +29 -0
  63. package/lib/productOptionsStorage.d.ts +41 -0
  64. package/lib/removeReplacedItems.d.ts +7 -0
  65. package/lib/replaceOrAddItems.d.ts +18 -0
  66. package/lib/searchBlurHandler.d.ts +38 -0
  67. package/lib/searchKeyboardNavigation.d.ts +42 -0
  68. package/lib/updateItemInList.d.ts +13 -0
  69. package/lib/validateCsvContent.d.ts +20 -0
  70. package/lib/validateOrderItems.d.ts +18 -0
  71. package/package.json +1 -0
  72. package/render/Provider.d.ts +8 -0
  73. package/render/index.d.ts +2 -0
  74. package/render/render.d.ts +4 -0
  75. package/render.d.ts +1 -0
  76. package/render.js +6 -0
  77. package/render.js.map +1 -0
  78. package/types/index.d.ts +21 -0
  79. package/types/quickOrderCsvUpload.types.d.ts +32 -0
  80. package/types/quickOrderItems.types.d.ts +205 -0
  81. package/types/quickOrderMultipleSku.types.d.ts +34 -0
  82. package/types/search.types.d.ts +41 -0
@@ -0,0 +1,5 @@
1
+ export declare const SEARCH_FILTER: {
2
+ attribute: string;
3
+ in: string[];
4
+ }[];
5
+ //# sourceMappingURL=search-filter.config.d.ts.map
@@ -0,0 +1,5 @@
1
+ import { QuickOrderCsvUploadProps } from '../../types/quickOrderCsvUpload.types';
2
+ import { Container } from '@dropins/tools/types/elsie/src/lib';
3
+
4
+ export declare const QuickOrderCsvUpload: Container<QuickOrderCsvUploadProps>;
5
+ //# sourceMappingURL=QuickOrderCsvUpload.d.ts.map
@@ -0,0 +1,19 @@
1
+ /********************************************************************
2
+ * ADOBE CONFIDENTIAL
3
+ * __________________
4
+ *
5
+ * Copyright 2024 Adobe
6
+ * All Rights Reserved.
7
+ *
8
+ * NOTICE: All information contained herein is, and remains
9
+ * the property of Adobe and its suppliers, if any. The intellectual
10
+ * and technical concepts contained herein are proprietary to Adobe
11
+ * and its suppliers and are protected by all applicable intellectual
12
+ * property laws, including trade secret and copyright laws.
13
+ * Dissemination of this information or reproduction of this material
14
+ * is strictly forbidden unless prior written permission is obtained
15
+ * from Adobe.
16
+ *******************************************************************/
17
+ export * from './QuickOrderCsvUpload';
18
+ export { QuickOrderCsvUpload as default } from './QuickOrderCsvUpload';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ export * from './QuickOrderCsvUpload/index'
2
+ import _default from './QuickOrderCsvUpload/index'
3
+ export default _default
@@ -0,0 +1,7 @@
1
+ /*! Copyright 2026 Adobe
2
+ All Rights Reserved. */
3
+ import{jsx as v}from"@dropins/tools/preact-jsx-runtime.js";import{C as w}from"../chunks/CsvFileInput.js";import{useState as f,useCallback as k}from"@dropins/tools/preact-hooks.js";import{events as Q}from"@dropins/tools/event-bus.js";import{useText as V}from"@dropins/tools/i18n.js";import{classes as O}from"@dropins/tools/lib.js";import"@dropins/tools/preact-compat.js";import"@dropins/tools/components.js";const F=o=>o.trim().replace(/^["']|["']$/g,""),x=200,h=(o,i)=>{const t=o.replace(/^\uFEFF/,"").trim().split(/\r?\n|\r/);if(!t.some(r=>r.trim()))return{isValid:!1,error:i.emptyFile};const a=t[0].split(",").map(r=>F(r).toLowerCase()),e=a.indexOf("sku"),c=a.indexOf("qty");if(e===-1||c===-1)return{isValid:!1,error:i.missingColumns};if(a.length!==2)return{isValid:!1,error:i.extraColumns};if(t.length-1>x)return{isValid:!1,error:i.maxRowsExceeded.replace("{maxRows}",x.toString())};const d=[];for(let r=1;r<t.length;r++){const s=t[r].trim();if(!s)continue;const u=s.split(",").map(S=>F(S)),n=u[e],C=u[c];if(!n)return{isValid:!1,error:i.skuRequired.replace("{rowNumber}",r.toString())};const l=parseInt(C,10);if(isNaN(l)||l<=0||!Number.isInteger(l))return{isValid:!1,error:i.invalidQuantity.replace("{rowNumber}",r.toString())};d.push({sku:n,quantity:l})}return d.length===0?{isValid:!1,error:i.noValidData}:{isValid:!0,data:d}},y=({routeSampleCSV:o,onFileUpload:i})=>{const[p,t]=f(null),[m,a]=f(null),e=V({invalidFile:"QuickOrder.CsvFileInput.uploadCSVErrors.invalidFile",emptyFile:"QuickOrder.CsvFileInput.uploadCSVErrors.emptyFile",missingColumns:"QuickOrder.CsvFileInput.uploadCSVErrors.missingColumns",extraColumns:"QuickOrder.CsvFileInput.uploadCSVErrors.extraColumns",maxRowsExceeded:"QuickOrder.CsvFileInput.uploadCSVErrors.maxRowsExceeded",skuRequired:"QuickOrder.CsvFileInput.uploadCSVErrors.skuRequired",invalidQuantity:"QuickOrder.CsvFileInput.uploadCSVErrors.invalidQuantity",noValidData:"QuickOrder.CsvFileInput.uploadCSVErrors.noValidData",onlyCSV:"QuickOrder.CsvFileInput.uploadCSVErrors.onlyCSV",failedToRead:"QuickOrder.CsvFileInput.uploadCSVErrors.failedToRead",failedToParse:"QuickOrder.CsvFileInput.uploadCSVErrors.failedToParse"}),c=k(r=>{if(t(null),a(r.name),!r.name.toLowerCase().endsWith(".csv")){t(e.onlyCSV);return}const s=new FileReader;s.onload=u=>{var n;try{const C=(n=u.target)==null?void 0:n.result,l=h(C,{emptyFile:e.emptyFile,missingColumns:e.missingColumns,extraColumns:e.extraColumns,maxRowsExceeded:e.maxRowsExceeded,skuRequired:e.skuRequired,invalidQuantity:e.invalidQuantity,noValidData:e.noValidData});if(!l.isValid){t(l.error);return}i?i(l.data):Q.emit("quick-order/add-items",l.data),a(null),t(null)}catch{t(e.failedToParse)}},s.onerror=()=>{t(e.failedToRead)},s.readAsText(r)},[i,e]),d=k(()=>{if(o)window.open(o,"_blank");else{const r=`SKU,QTY
4
+ SKU123,1
5
+ SKU456,2
6
+ SKU789,3`,s=new Blob([r],{type:"text/csv"}),u=URL.createObjectURL(s),n=document.createElement("a");n.href=u,n.download="sample-quick-order.csv",document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(u)}},[o]);return{handleFileUpload:c,error:p,fileName:m,handleDownloadSample:d,showSampleDownload:!0}},g=({className:o,routeSampleCSV:i,onFileUpload:p})=>{const t=V({title:"QuickOrder.CsvFileInput.title",helperText:"QuickOrder.CsvFileInput.helperText",downloadSample:"QuickOrder.CsvFileInput.downloadSample",inputLabel:"QuickOrder.CsvFileInput.inputLabel",selectedFile:"QuickOrder.CsvFileInput.selectedFile"}),{handleFileUpload:m,error:a,fileName:e,handleDownloadSample:c,showSampleDownload:d}=y({routeSampleCSV:i,onFileUpload:p});return v("div",{className:O(["b2b-quick-order-quick-order-upload-csv",o]),"data-testid":"quick-order-upload-csv",children:v(w,{t,onFileUpload:m,error:a,fileName:e,onDownloadSample:c,showSampleDownload:d})})};export{g as QuickOrderCsvUpload,g as default};
7
+ //# sourceMappingURL=QuickOrderCsvUpload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuickOrderCsvUpload.js","sources":["/@dropins/storefront-quick-order/src/lib/cleanCsvValue.ts","/@dropins/storefront-quick-order/src/lib/validateCsvContent.ts","/@dropins/storefront-quick-order/src/hooks/useQuickOrderCsvUpload.tsx","/@dropins/storefront-quick-order/src/containers/QuickOrderCsvUpload/QuickOrderCsvUpload.tsx"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\n/**\n * Cleans CSV value by removing surrounding quotes and trimming whitespace\n * Handles both double quotes (\") and single quotes (')\n * @param val - The raw CSV value to clean\n * @returns Cleaned string value\n */\nexport const cleanCsvValue = (val: string): string =>\n val.trim().replace(/^[\"']|[\"']$/g, '');\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { CSVValidationResult, SubmitSkuValue } from '@/b2b-quick-order/types';\nimport { cleanCsvValue } from './cleanCsvValue';\n\n// Maximum number of rows allowed in CSV\nconst MAX_ROWS = 200;\n\nexport interface ValidationMessages {\n emptyFile: string;\n missingColumns: string;\n extraColumns: string;\n maxRowsExceeded: string;\n skuRequired: string;\n invalidQuantity: string;\n noValidData: string;\n}\n\n/**\n * Validates CSV content and extracts SKU/quantity data\n * Handles BOM, different line endings, quoted values, and empty lines\n * @param content - Raw CSV file content\n * @param messages - Localized error messages\n * @returns Validation result with data or error\n */\nexport const validateCsvContent = (\n content: string,\n messages: ValidationMessages\n): CSVValidationResult => {\n // Remove BOM if present\n const cleanContent = content.replace(/^\\uFEFF/, '');\n\n // Split by different line endings (handle \\r\\n, \\n, \\r)\n const lines = cleanContent.trim().split(/\\r?\\n|\\r/);\n\n // Check if file is effectively empty after removing empty lines\n const hasContent = lines.some((line) => line.trim());\n if (!hasContent) {\n return { isValid: false, error: messages.emptyFile };\n }\n\n const header = lines[0]\n .split(',')\n .map((col) => cleanCsvValue(col).toLowerCase());\n const skuIndex = header.indexOf('sku');\n const qtyIndex = header.indexOf('qty');\n\n if (skuIndex === -1 || qtyIndex === -1) {\n return {\n isValid: false,\n error: messages.missingColumns,\n };\n }\n\n if (header.length !== 2) {\n return {\n isValid: false,\n error: messages.extraColumns,\n };\n }\n\n if (lines.length - 1 > MAX_ROWS) {\n return {\n isValid: false,\n error: messages.maxRowsExceeded.replace('{maxRows}', MAX_ROWS.toString()),\n };\n }\n\n const data: SubmitSkuValue = [];\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i].trim();\n if (!line) continue;\n\n const values = line.split(',').map((val) => cleanCsvValue(val));\n const sku = values[skuIndex];\n const qty = values[qtyIndex];\n\n if (!sku) {\n return {\n isValid: false,\n error: messages.skuRequired.replace('{rowNumber}', i.toString()),\n };\n }\n\n const quantity = parseInt(qty, 10);\n if (isNaN(quantity) || quantity <= 0 || !Number.isInteger(quantity)) {\n return {\n isValid: false,\n error: messages.invalidQuantity.replace('{rowNumber}', i.toString()),\n };\n }\n\n data.push({ sku, quantity });\n }\n\n if (data.length === 0) {\n return { isValid: false, error: messages.noValidData };\n }\n\n return { isValid: true, data };\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { useCallback, useState } from 'preact/hooks';\nimport {\n UseQuickOrderCsvUploadProps,\n UseQuickOrderCsvUploadReturn,\n} from '@/b2b-quick-order/types/quickOrderCsvUpload.types';\nimport { events } from '@adobe-commerce/event-bus';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { validateCsvContent } from '@/b2b-quick-order/lib';\n\nexport const useQuickOrderCsvUpload = ({\n routeSampleCSV,\n onFileUpload,\n}: UseQuickOrderCsvUploadProps): UseQuickOrderCsvUploadReturn => {\n const [error, setError] = useState<string | null>(null);\n const [fileName, setFileName] = useState<string | null>(null);\n\n const t = useText({\n invalidFile: 'QuickOrder.CsvFileInput.uploadCSVErrors.invalidFile',\n emptyFile: 'QuickOrder.CsvFileInput.uploadCSVErrors.emptyFile',\n missingColumns: 'QuickOrder.CsvFileInput.uploadCSVErrors.missingColumns',\n extraColumns: 'QuickOrder.CsvFileInput.uploadCSVErrors.extraColumns',\n maxRowsExceeded: 'QuickOrder.CsvFileInput.uploadCSVErrors.maxRowsExceeded',\n skuRequired: 'QuickOrder.CsvFileInput.uploadCSVErrors.skuRequired',\n invalidQuantity: 'QuickOrder.CsvFileInput.uploadCSVErrors.invalidQuantity',\n noValidData: 'QuickOrder.CsvFileInput.uploadCSVErrors.noValidData',\n onlyCSV: 'QuickOrder.CsvFileInput.uploadCSVErrors.onlyCSV',\n failedToRead: 'QuickOrder.CsvFileInput.uploadCSVErrors.failedToRead',\n failedToParse: 'QuickOrder.CsvFileInput.uploadCSVErrors.failedToParse',\n });\n\n const handleFileUpload = useCallback(\n (file: File) => {\n setError(null);\n setFileName(file.name);\n\n if (!file.name.toLowerCase().endsWith('.csv')) {\n setError(t.onlyCSV);\n return;\n }\n\n const reader = new FileReader();\n\n reader.onload = (e) => {\n try {\n const content = e.target?.result as string;\n const validation = validateCsvContent(content, {\n emptyFile: t.emptyFile,\n missingColumns: t.missingColumns,\n extraColumns: t.extraColumns,\n maxRowsExceeded: t.maxRowsExceeded,\n skuRequired: t.skuRequired,\n invalidQuantity: t.invalidQuantity,\n noValidData: t.noValidData,\n });\n\n if (!validation.isValid) {\n setError(validation.error!);\n return;\n }\n\n // Success - emit event or call custom callback\n if (onFileUpload) {\n onFileUpload(validation.data!);\n } else {\n events.emit('quick-order/add-items', validation.data!);\n }\n\n // Reset state after successful upload\n setFileName(null);\n setError(null);\n } catch (err) {\n setError(t.failedToParse);\n }\n };\n\n reader.onerror = () => {\n setError(t.failedToRead);\n };\n\n reader.readAsText(file);\n },\n [onFileUpload, t]\n );\n\n const handleDownloadSample = useCallback(() => {\n if (routeSampleCSV) {\n window.open(routeSampleCSV, '_blank');\n } else {\n const csvContent = 'SKU,QTY\\nSKU123,1\\nSKU456,2\\nSKU789,3';\n const blob = new Blob([csvContent], { type: 'text/csv' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = 'sample-quick-order.csv';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n }, [routeSampleCSV]);\n\n return {\n handleFileUpload,\n error,\n fileName,\n handleDownloadSample,\n showSampleDownload: true,\n };\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { CsvFileInput } from '@/b2b-quick-order/components/CsvFileInput';\nimport { useQuickOrderCsvUpload } from '@/b2b-quick-order/hooks/useQuickOrderCsvUpload';\nimport { QuickOrderCsvUploadProps } from '@/b2b-quick-order/types/quickOrderCsvUpload.types';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { classes, Container } from '@adobe-commerce/elsie/lib';\n\nexport const QuickOrderCsvUpload: Container<QuickOrderCsvUploadProps> = ({\n className,\n routeSampleCSV,\n onFileUpload,\n}) => {\n const t = useText({\n title: 'QuickOrder.CsvFileInput.title',\n helperText: 'QuickOrder.CsvFileInput.helperText',\n downloadSample: 'QuickOrder.CsvFileInput.downloadSample',\n inputLabel: 'QuickOrder.CsvFileInput.inputLabel',\n selectedFile: 'QuickOrder.CsvFileInput.selectedFile',\n });\n\n const {\n handleFileUpload,\n error,\n fileName,\n handleDownloadSample,\n showSampleDownload,\n } = useQuickOrderCsvUpload({\n routeSampleCSV,\n onFileUpload,\n });\n\n return (\n <div\n className={classes(['b2b-quick-order-quick-order-upload-csv', className])}\n data-testid=\"quick-order-upload-csv\"\n >\n <CsvFileInput\n t={t}\n onFileUpload={handleFileUpload}\n error={error}\n fileName={fileName}\n onDownloadSample={handleDownloadSample}\n showSampleDownload={showSampleDownload}\n />\n </div>\n );\n};\n"],"names":["cleanCsvValue","val","MAX_ROWS","validateCsvContent","content","messages","lines","line","header","col","skuIndex","qtyIndex","data","i","values","sku","qty","quantity","useQuickOrderCsvUpload","routeSampleCSV","onFileUpload","error","setError","useState","fileName","setFileName","t","useText","handleFileUpload","useCallback","file","reader","e","_a","validation","events","handleDownloadSample","csvContent","blob","url","link","QuickOrderCsvUpload","className","showSampleDownload","jsx","classes","CsvFileInput"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { QuickOrderItemsProps } from '../../types';
2
+ import { Container } from '@dropins/tools/types/elsie/src/lib';
3
+
4
+ export declare const QuickOrderItems: Container<QuickOrderItemsProps>;
5
+ //# sourceMappingURL=QuickOrderItems.d.ts.map
@@ -0,0 +1,19 @@
1
+ /********************************************************************
2
+ * ADOBE CONFIDENTIAL
3
+ * __________________
4
+ *
5
+ * Copyright 2024 Adobe
6
+ * All Rights Reserved.
7
+ *
8
+ * NOTICE: All information contained herein is, and remains
9
+ * the property of Adobe and its suppliers, if any. The intellectual
10
+ * and technical concepts contained herein are proprietary to Adobe
11
+ * and its suppliers and are protected by all applicable intellectual
12
+ * property laws, including trade secret and copyright laws.
13
+ * Dissemination of this information or reproduction of this material
14
+ * is strictly forbidden unless prior written permission is obtained
15
+ * from Adobe.
16
+ *******************************************************************/
17
+ export * from './QuickOrderItems';
18
+ export { QuickOrderItems as default } from './QuickOrderItems';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ export * from './QuickOrderItems/index'
2
+ import _default from './QuickOrderItems/index'
3
+ export default _default
@@ -0,0 +1,4 @@
1
+ /*! Copyright 2026 Adobe
2
+ All Rights Reserved. */
3
+ import{jsx as U}from"@dropins/tools/preact-jsx-runtime.js";import"@dropins/tools/components.js";import{Q as K}from"../chunks/Search.js";import"../chunks/CsvFileInput.js";import{useState as A,useCallback as v,useEffect as b}from"@dropins/tools/preact-hooks.js";import{events as S}from"@dropins/tools/event-bus.js";import{classes as x}from"@dropins/tools/lib.js";import{useText as P}from"@dropins/tools/i18n.js";import"@dropins/tools/preact-compat.js";const R=["sku","parentSku","quantity","optionsUIDs","valid","productType"],_=n=>{const r=[],t=[];return n.forEach((e,o)=>{if(R.includes(o))return;const s=e;s&&s.match(/^[A-Za-z0-9+/=]+$/)?r.push(s):t.push({uid:o,value:s})}),{optionUIDs:r,enteredOptions:t}},M=n=>{const r=Number(n.get("quantity")),t=!r||r<1?1:r,e={sku:n.get("sku"),quantity:t},o=n.get("parentSku");o&&(e.parentSku=o);const{optionUIDs:s,enteredOptions:a}=_(n);return s.length>0&&(e.optionsUIDs=s),a.length>0&&(e.enteredOptions=a),e},T={sku:"",quantity:1,name:"",images:[],inStock:!1,addToCartAllowed:!1,isBundle:!1,prices:{},attributes:[],options:[],url:"",urlKey:"",externalId:"",productType:"simple",shortDescription:"",metaDescription:"",metaKeyword:"",metaTitle:"",description:""},C=(n,r)=>!r||!Array.isArray(r)?n.map(t=>({...T,sku:t.sku,quantity:t.quantity??1})):n.map(t=>{const e=r.find(o=>(o==null?void 0:o.sku)===(t==null?void 0:t.sku));return e?{...e,...t.variantSku&&{variantSku:t.variantSku},quantity:t.quantity??1}:{...T,sku:t.sku,...t.variantSku&&{variantSku:t.variantSku},quantity:t.quantity??1}}),V=n=>n.length===0?!1:n.every(r=>!((r.urlKey||r.url)&&r.name)||r.inStock===!1?!1:r.options&&r.options.length>0?r.options.some(o=>o.items&&o.items.length>0&&o.items.some(s=>s.selected===!0)):!0),D=n=>`quick-order-item-${n.id||n.variantSku||n.sku}`,F=n=>`${n}-${Date.now()}-${Math.random().toString(36).substring(2,9)}`,$=(n,r)=>n.findIndex(t=>r.variantSku&&t.variantSku?t.variantSku===r.variantSku:t.variantSku&&!r.variantSku&&r.sku?t.variantSku===r.sku:r.variantSku&&!t.variantSku&&t.sku?t.sku===r.variantSku:!r.variantSku&&!t.variantSku?t.sku===r.sku:!1),j=(n,r,t)=>n.findIndex(e=>e.id===t?!1:r.variantSku&&e.variantSku?e.variantSku===r.variantSku:r.variantSku&&!e.variantSku&&e.sku?e.sku===r.variantSku:!1),J=(n,r,t,e=1)=>n.map((o,s)=>s===t?{...o,quantity:o.quantity+e}:s===r?null:o).filter(Boolean),z=(n,r,t)=>{const e=[...n],o=[],s=[],a=[];return r.forEach((l,Q)=>{const h=t[Q];if(h!=null&&h.replaceItemSku){const d=e.findIndex(f=>f.sku===h.replaceItemSku||f.id===h.replaceItemSku);if(d!==-1){const f=$(e,l);if(f!==-1&&f!==d){e.splice(d,1);const m=f>d?f-1:f;e[m]={...e[m],quantity:e[m].quantity+l.quantity},a.push(e[m])}else{const m={...l,id:F(l.sku)};e[d]=m,s.push(m)}return}}const p=$(e,l);if(p!==-1)e[p]={...e[p],quantity:e[p].quantity+l.quantity},a.push(e[p]);else{const d={...l,id:F(l.sku)};e.push(d),o.push(d)}}),{updatedItems:e,addedItems:o,replacedItems:s,mergedItems:a}},G=(n,r,t,e=1)=>{const o=r?j(n,t,r):-1;if(o!==-1){const a=n.findIndex(l=>l.id===r);return{updatedItems:J(n,a,o,e),wasMerged:!0,mergedIntoIndex:o}}return{updatedItems:n.map(a=>r&&a.id===r?{...a,...t,id:r}:!r&&a.sku===t.sku?{...a,...t}:a),wasMerged:!1}},Y=n=>n.map(r=>{const t=r.id||r.sku,e=document.forms[`form-${t}`];if(!e)return null;const o=new FormData(e);return o.get("valid")==="true"?M(o):null}),Z=n=>{let r=[];return n&&typeof n=="object"?n.optionsUIDs&&Array.isArray(n.optionsUIDs)?r=n.optionsUIDs:Array.isArray(n)&&(r=n):typeof n=="string"&&(r=[n]),r},B=n=>{try{const r=localStorage.getItem(n);if(r)return JSON.parse(r)}catch(r){console.error("Error reading from localStorage:",r)}return{}},H=(n,r,t)=>{if(t.length!==0)try{const e=B(n);e[r]=t,localStorage.setItem(n,JSON.stringify(e))}catch(e){console.error("Error saving to localStorage:",e)}},X=(n,r,t)=>n.map(e=>{const o=r.find(s=>e.sku===s.sku||e.sku===s.variantSku);if(o){const s=o.id||o.sku,a=t[s];if(a&&a.length>0)return{...e,optionsUIDs:a}}return e}),w=({getProductsData:n,onAddAllToCart:r}={})=>{const[t,e]=A([]),[o,s]=A(!1),[a,l]=A(new Set),[Q,h]=A(!1),p="quick-order-selected-options",d=v(u=>{h(u)},[]);b(()=>{const u=S.on("quick-order/loading",i=>{s(i)},{eager:!0});return()=>{u==null||u.off()}},[]),b(()=>{const u=S.on("quick-order/add-items",async i=>{if(i&&i.length>0){if(!n)return;s(!0),S.emit("quick-order/loading",!0);const k=i.map(c=>c.sku).filter(Boolean);l(c=>new Set([...Array.from(c),...k]));try{let c=[];try{const O=await n(i);d(i.length!==O.length),c=C(i,O)}catch(O){console.error("Error fetching products data:",O),c=C(i,[])}e(O=>{const{updatedItems:g,addedItems:q,mergedItems:N,replacedItems:W}=z(O,c,i);return W.forEach(I=>{const y=D(I);S.emit(`${y}/pdp/data`,I)}),N.forEach(I=>{const y=D(I);S.emit(`${y}/pdp/data`,I)}),q.forEach(I=>{const y=D(I);S.emit(`${y}/pdp/data`,I)}),g})}finally{s(!1),S.emit("quick-order/loading",!1),l(c=>new Set(Array.from(c).filter(O=>!k.includes(O))))}}},{eager:!0});return()=>{u==null||u.off()}},[n,d]),b(()=>{const u=t.map(i=>{const k=D(i),c=i.id;return S.on(`${k}/pdp/data`,O=>{e(g=>G(g,c||"",O,i.quantity||1).updatedItems)})});return()=>{u==null||u.forEach(i=>{i==null||i.off()})}},[t]),b(()=>{const u=V(t);d(!u)},[t,d]),b(()=>{const u=t.map(i=>{const k=D(i),c=i.id||i.sku;return S.on(`${k}/pdp/values`,O=>{const g=Z(O);H(p,c,g)})});return()=>{u.forEach(i=>{i==null||i.off()})}},[t,p]);const f=v(u=>{e(i=>i.filter(k=>k.id!==u&&k.sku!==u))},[]),m=v((u,i)=>{e(k=>k.map(c=>c.sku===u?{...c,quantity:i}:c))},[]),E=v(u=>a.has(u),[a]),L=v(()=>{const u=Y(t).filter(c=>c!==null),i=B(p),k=X(u,t,i);r?r(k):S.emit("quick-order/add-to-cart",k)},[t,r,p]);return{items:t,loading:o,removeItem:f,updateItemQuantity:m,handleAddToCart:L,isItemUpdating:E,isDisabledButton:Q,setDisabledCartButton:d}},cr=({className:n,slots:r,getProductsData:t,onAddAllToCart:e,productsSearch:o,searchFilter:s})=>{const a=P({title:"QuickOrder.QuickOrderItem.title",quantity:"QuickOrder.QuickOrderItem.quantity",price:"QuickOrder.QuickOrderItem.price",remove:"QuickOrder.QuickOrderItem.remove",removeItem:"QuickOrder.QuickOrderItem.removeItem",showOptions:"QuickOrder.QuickOrderItem.showOptions",hideOptions:"QuickOrder.QuickOrderItem.hideOptions",additionalOptions:"QuickOrder.QuickOrderItem.additionalOptions",noAdditionalOptions:"QuickOrder.QuickOrderItem.noAdditionalOptions",emptyList:"QuickOrder.QuickOrderItem.emptyList",sku:"QuickOrder.QuickOrderItem.sku",loading:"QuickOrder.QuickOrderItem.loading",productNotFound:"QuickOrder.QuickOrderItem.productNotFound",productNotFoundDescription:"QuickOrder.QuickOrderItem.productNotFoundDescription",productOptions:"QuickOrder.QuickOrderItem.productOptions",configurableProductError:"QuickOrder.QuickOrderItem.configurableProductError",configurableProductErrorDescription:"QuickOrder.QuickOrderItem.configurableProductErrorDescription",addAllToCart:"QuickOrder.QuickOrderItem.addAllToCart",configurableOptionsWarning:"QuickOrder.QuickOrderItem.configurableOptionsWarning",configurableOptionsWarningDescription:"QuickOrder.QuickOrderItem.configurableOptionsWarningDescription",outOfStock:"QuickOrder.QuickOrderItem.outOfStock",searchPlaceholder:"QuickOrder.Search.placeholder",searchAriaLabel:"QuickOrder.Search.ariaLabel",searchEmptyState:"QuickOrder.Search.emptyState",resultsAvailable:"QuickOrder.Search.resultsAvailable",resultAvailable:"QuickOrder.Search.resultAvailable",srInstructions:"QuickOrder.Search.srInstructions"}),{items:l,loading:Q,removeItem:h,updateItemQuantity:p,handleAddToCart:d,isItemUpdating:f,setDisabledCartButton:m,isDisabledButton:E}=w({getProductsData:t,onAddAllToCart:e});return U("div",{className:x(["b2b-quick-order-quick-order-items",n]),"data-testid":"quick-order-items",children:U(K,{t:a,items:l,onRemove:h,onUpdateQuantity:p,handleAddToCart:d,isItemUpdating:f,slots:r,loading:Q,setDisabledCartButton:m,isDisabledButton:E,productsSearch:o,searchFilter:s})})};export{cr as QuickOrderItems,cr as default};
4
+ //# sourceMappingURL=QuickOrderItems.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuickOrderItems.js","sources":["/@dropins/storefront-quick-order/src/lib/processFormOptions.ts","/@dropins/storefront-quick-order/src/lib/buildCartItem.ts","/@dropins/storefront-quick-order/src/configs/order-item.config.ts","/@dropins/storefront-quick-order/src/lib/mapProductsToOrderItems.ts","/@dropins/storefront-quick-order/src/lib/validateOrderItems.ts","/@dropins/storefront-quick-order/src/lib/getItemScope.ts","/@dropins/storefront-quick-order/src/lib/generateItemId.ts","/@dropins/storefront-quick-order/src/lib/findDuplicateItem.ts","/@dropins/storefront-quick-order/src/lib/mergeDuplicateItems.ts","/@dropins/storefront-quick-order/src/lib/replaceOrAddItems.ts","/@dropins/storefront-quick-order/src/lib/updateItemInList.ts","/@dropins/storefront-quick-order/src/lib/buildCartItemsFromForms.ts","/@dropins/storefront-quick-order/src/lib/productOptionsStorage.ts","/@dropins/storefront-quick-order/src/hooks/useQuickOrderItems.tsx","/@dropins/storefront-quick-order/src/containers/QuickOrderItems/QuickOrderItems.tsx"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nconst STANDARD_FIELDS = [\n 'sku',\n 'parentSku',\n 'quantity',\n 'optionsUIDs',\n 'valid',\n 'productType',\n];\n\nexport interface ProcessedFormOptions {\n optionUIDs: string[];\n enteredOptions: { uid: string; value: string }[];\n}\n\n/**\n * Processes form data to extract product options\n * Separates base64-encoded configurable options (optionUIDs) from custom entered options\n */\nexport const processFormOptions = (\n formData: FormData\n): ProcessedFormOptions => {\n const optionUIDs: string[] = [];\n const enteredOptions: { uid: string; value: string }[] = [];\n\n formData.forEach((value, key) => {\n if (STANDARD_FIELDS.includes(key)) return;\n\n const valueStr = value as string;\n // Check if this is an option UID (base64 encoded configurable option)\n if (valueStr && valueStr.match(/^[A-Za-z0-9+/=]+$/)) {\n optionUIDs.push(valueStr);\n } else {\n enteredOptions.push({ uid: key, value: valueStr });\n }\n });\n\n return { optionUIDs, enteredOptions };\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { processFormOptions } from './processFormOptions';\n\nexport interface CartItem {\n sku: string;\n quantity: number;\n parentSku?: string;\n optionsUIDs?: string[];\n enteredOptions?: { uid: string; value: string }[];\n}\n\n/**\n * Builds a cart item object from form data\n * Extracts SKU, quantity, parent SKU, and product options\n */\nexport const buildCartItem = (formData: FormData): CartItem => {\n const quantityValue = Number(formData.get('quantity'));\n const quantity = !quantityValue || quantityValue < 1 ? 1 : quantityValue;\n\n const cartItem: CartItem = {\n sku: formData.get('sku') as string,\n quantity,\n };\n\n const parentSku = formData.get('parentSku');\n if (parentSku) {\n cartItem.parentSku = parentSku as string;\n }\n\n const { optionUIDs, enteredOptions } = processFormOptions(formData);\n\n if (optionUIDs.length > 0) {\n cartItem.optionsUIDs = optionUIDs;\n }\n\n if (enteredOptions.length > 0) {\n cartItem.enteredOptions = enteredOptions;\n }\n\n return cartItem;\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { OrderItem } from '@/b2b-quick-order/types/quickOrderItems.types';\n\nexport const DEFAULT_QUICK_ORDER_ITEM: OrderItem = {\n sku: '',\n quantity: 1,\n name: '',\n images: [],\n inStock: false,\n addToCartAllowed: false,\n isBundle: false,\n prices: {} as any,\n attributes: [],\n options: [],\n url: '',\n urlKey: '',\n externalId: '',\n productType: 'simple',\n shortDescription: '',\n metaDescription: '',\n metaKeyword: '',\n metaTitle: '',\n description: '',\n} as OrderItem;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { OrderItem, OrderItemInput } from '@/b2b-quick-order/types';\nimport { DEFAULT_QUICK_ORDER_ITEM } from '@/b2b-quick-order/configs';\n\n/**\n * Maps fetched products to OrderItems\n * Creates error items for products not found in the response\n * @param requestedItems - Items that were requested\n * @param products - Products returned from API\n * @returns Array of OrderItems with proper quantity set\n */\nexport const mapProductsToOrderItems = (\n requestedItems: OrderItemInput[],\n products: OrderItem[]\n): OrderItem[] => {\n // Handle empty or undefined products array\n if (!products || !Array.isArray(products)) {\n return requestedItems.map((requestedItem) => ({\n ...DEFAULT_QUICK_ORDER_ITEM,\n sku: requestedItem.sku,\n quantity: requestedItem.quantity ?? 1,\n })) as OrderItem[];\n }\n\n return requestedItems.map((requestedItem) => {\n const foundProduct = products.find((p) => p?.sku === requestedItem?.sku);\n\n if (foundProduct) {\n return {\n ...foundProduct,\n ...(requestedItem.variantSku && {\n variantSku: requestedItem.variantSku,\n }),\n quantity: requestedItem.quantity ?? 1,\n };\n }\n\n // Product not found - create error item\n return {\n ...DEFAULT_QUICK_ORDER_ITEM,\n sku: requestedItem.sku,\n ...(requestedItem.variantSku && { variantSku: requestedItem.variantSku }),\n quantity: requestedItem.quantity ?? 1,\n } as OrderItem;\n });\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { OrderItem } from '@/b2b-quick-order/types';\n\n/**\n * Validates order items to determine if all items are ready for cart addition\n * @param items - Array of order items to validate\n * @returns true if all items are valid, false otherwise\n */\nexport const validateOrderItems = (items: OrderItem[]): boolean => {\n if (items.length === 0) {\n return false;\n }\n\n return items.every((item) => {\n const hasBasicData = (item.urlKey || item.url) && item.name;\n if (!hasBasicData) {\n return false;\n }\n\n // Check if item is in stock\n if (item.inStock === false) {\n return false;\n }\n\n if (item.options && item.options.length > 0) {\n const hasSelectedOption = item.options.some(\n (option) =>\n option.items &&\n option.items.length > 0 &&\n option.items.some((optionItem) => optionItem.selected === true)\n );\n return hasSelectedOption;\n }\n\n return true;\n });\n};\n\n/**\n * Get items that are out of stock\n * @param items - Array of order items to check\n * @returns Array of out of stock items with their names\n */\nexport const getOutOfStockItems = (\n items: OrderItem[]\n): Array<{ sku: string; name: string }> => {\n return items\n .filter((item) => item.inStock === false)\n .map((item) => ({\n sku: item.sku,\n name: item.name,\n }));\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { OrderItem } from '@/b2b-quick-order/types';\n\n/**\n * Get unique scope identifier for an item\n * Uses unique id if available, otherwise falls back to variantSku or sku\n */\nexport const getItemScope = (item: OrderItem): string => {\n const scopeKey = item.id || item.variantSku || item.sku;\n return `quick-order-item-${scopeKey}`;\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\n/**\n * Generate unique ID for an item\n * Format: {sku}-{timestamp}-{random}\n */\nexport const generateItemId = (sku: string): string => {\n return `${sku}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { OrderItem } from '@/b2b-quick-order/types';\n\n/**\n * Find duplicate item in the list based on multiple comparison strategies\n * Returns the index of the duplicate item, or -1 if not found\n *\n * Strategies:\n * 1. Both have variantSku - compare variants\n * 2. Existing has variantSku, new has sku - compare them\n * 3. New has variantSku, existing has sku - compare them\n * 4. Neither has variantSku - compare base SKU\n */\nexport const findDuplicateItem = (\n items: OrderItem[],\n newItem: OrderItem\n): number => {\n return items.findIndex((existing) => {\n // Strategy 1: Both have variantSku - compare variants\n if (newItem.variantSku && existing.variantSku) {\n return existing.variantSku === newItem.variantSku;\n }\n\n // Strategy 2: Existing has variantSku, new has sku - compare them\n // (e.g., existing configured product vs search result variant)\n if (existing.variantSku && !newItem.variantSku && newItem.sku) {\n return existing.variantSku === newItem.sku;\n }\n\n // Strategy 3: New has variantSku, existing has sku - compare them\n // (opposite of strategy 2)\n if (newItem.variantSku && !existing.variantSku && existing.sku) {\n return existing.sku === newItem.variantSku;\n }\n\n // Strategy 4: Neither has variantSku - compare base sku\n if (!newItem.variantSku && !existing.variantSku) {\n return existing.sku === newItem.sku;\n }\n\n return false;\n });\n};\n\n/**\n * Find duplicate item excluding a specific item by ID\n * Used when checking for duplicates after an item update\n */\nexport const findDuplicateItemExcluding = (\n items: OrderItem[],\n updatedItem: OrderItem,\n excludeItemId: string\n): number => {\n return items.findIndex((existing) => {\n // Skip the item being updated\n if (existing.id === excludeItemId) return false;\n\n // Check if updatedItem's variantSku matches existing item\n if (updatedItem.variantSku && existing.variantSku) {\n return existing.variantSku === updatedItem.variantSku;\n }\n\n // Check if updatedItem's variantSku matches existing item's sku\n if (updatedItem.variantSku && !existing.variantSku && existing.sku) {\n return existing.sku === updatedItem.variantSku;\n }\n\n return false;\n });\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { OrderItem } from '@/b2b-quick-order/types';\n\n/**\n * Merge duplicate items by removing the item at removeIndex and\n * adding its quantity to the item at mergeIntoIndex\n */\nexport const mergeDuplicateItems = (\n items: OrderItem[],\n removeIndex: number,\n mergeIntoIndex: number,\n quantityToAdd: number = 1\n): OrderItem[] => {\n return items\n .map((item, index) => {\n if (index === mergeIntoIndex) {\n // Increase quantity of the duplicate\n return {\n ...item,\n quantity: item.quantity + quantityToAdd,\n };\n } else if (index === removeIndex) {\n // Remove the item being merged\n return null;\n }\n return item;\n })\n .filter(Boolean) as OrderItem[];\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { OrderItem, OrderItemInput } from '@/b2b-quick-order/types';\nimport { findDuplicateItem } from './findDuplicateItem';\nimport { generateItemId } from './generateItemId';\n\nexport interface ReplaceOrAddItemsResult {\n updatedItems: OrderItem[];\n addedItems: OrderItem[];\n replacedItems: OrderItem[];\n mergedItems: OrderItem[];\n}\n\n/**\n * Replace, merge, or add items into existing list\n * Handles three scenarios:\n * 1. Replace: When inputItem has replaceItemSku, replace item at same position\n * - If new item already exists in list, collapse by removing replaced item and merging quantity\n * 2. Merge: When item exists, increase quantity\n * 3. Add: When item doesn't exist, add to end\n */\nexport const replaceOrAddItems = (\n existingItems: OrderItem[],\n newItems: OrderItem[],\n inputItems: OrderItemInput[]\n): ReplaceOrAddItemsResult => {\n const updatedItems = [...existingItems];\n const addedItems: OrderItem[] = [];\n const replacedItems: OrderItem[] = [];\n const mergedItems: OrderItem[] = [];\n\n newItems.forEach((newItem, index) => {\n const inputItem = inputItems[index];\n\n // Scenario 1: Replace existing item at same position\n if (inputItem?.replaceItemSku) {\n const replaceIndex = updatedItems.findIndex(\n (item) =>\n item.sku === inputItem.replaceItemSku ||\n item.id === inputItem.replaceItemSku\n );\n\n if (replaceIndex !== -1) {\n // Check if new item already exists elsewhere in the list (collapse case)\n const existingIndex = findDuplicateItem(updatedItems, newItem);\n\n if (existingIndex !== -1 && existingIndex !== replaceIndex) {\n // Item already exists - remove replaced item and merge quantity into existing\n updatedItems.splice(replaceIndex, 1);\n // Adjust index if existing item was after the removed one\n const adjustedIndex =\n existingIndex > replaceIndex ? existingIndex - 1 : existingIndex;\n updatedItems[adjustedIndex] = {\n ...updatedItems[adjustedIndex],\n quantity: updatedItems[adjustedIndex].quantity + newItem.quantity,\n };\n mergedItems.push(updatedItems[adjustedIndex]);\n } else {\n // Replace item at the same position\n const itemWithId = {\n ...newItem,\n id: generateItemId(newItem.sku),\n };\n updatedItems[replaceIndex] = itemWithId;\n replacedItems.push(itemWithId);\n }\n return;\n }\n // If item to replace not found, fall through to add logic\n }\n\n // Scenario 2 & 3: Merge or Add\n const existingIndex = findDuplicateItem(updatedItems, newItem);\n\n if (existingIndex !== -1) {\n // Item exists - merge by increasing quantity\n updatedItems[existingIndex] = {\n ...updatedItems[existingIndex],\n quantity: updatedItems[existingIndex].quantity + newItem.quantity,\n };\n mergedItems.push(updatedItems[existingIndex]);\n } else {\n // Item doesn't exist - add new with unique ID\n const itemWithId = {\n ...newItem,\n id: generateItemId(newItem.sku),\n };\n updatedItems.push(itemWithId);\n addedItems.push(itemWithId);\n }\n });\n\n return { updatedItems, addedItems, replacedItems, mergedItems };\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { OrderItem } from '@/b2b-quick-order/types';\nimport { findDuplicateItemExcluding } from './findDuplicateItem';\nimport { mergeDuplicateItems } from './mergeDuplicateItems';\n\nexport interface UpdateItemResult {\n updatedItems: OrderItem[];\n wasMerged: boolean;\n mergedIntoIndex?: number;\n}\n\n/**\n * Update a specific item in the list and check for duplicates\n * If duplicate is found, merge the items\n */\nexport const updateItemInList = (\n items: OrderItem[],\n itemId: string,\n updatedItem: OrderItem,\n currentQuantity: number = 1\n): UpdateItemResult => {\n // Check if the updated item's variantSku matches another existing item\n const duplicateIndex = itemId\n ? findDuplicateItemExcluding(items, updatedItem, itemId)\n : -1;\n\n if (duplicateIndex !== -1) {\n // Find the index of the item being updated\n const removingIndex = items.findIndex((prevItem) => prevItem.id === itemId);\n\n // Duplicate found - merge items\n return {\n updatedItems: mergeDuplicateItems(\n items,\n removingIndex,\n duplicateIndex,\n currentQuantity\n ),\n wasMerged: true,\n mergedIntoIndex: duplicateIndex,\n };\n }\n\n // No duplicate - just update the item\n const updatedItems = items.map((prevItem) => {\n if (itemId && prevItem.id === itemId) {\n // Match by ID - update with preserved ID\n return {\n ...prevItem,\n ...updatedItem,\n id: itemId,\n };\n } else if (!itemId && prevItem.sku === updatedItem.sku) {\n // Fallback for items without ID (backward compatibility)\n return {\n ...prevItem,\n ...updatedItem,\n };\n }\n return prevItem;\n });\n\n return {\n updatedItems,\n wasMerged: false,\n };\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { OrderItem } from '@/b2b-quick-order/types';\nimport { buildCartItem } from './buildCartItem';\n\n/**\n * Build cart items from forms for all order items\n * Only includes valid items (items with valid forms)\n */\nexport const buildCartItemsFromForms = (items: OrderItem[]) => {\n return items.map((item) => {\n const formId = item.id || item.sku;\n const form = document.forms[`form-${formId}` as any] as HTMLFormElement;\n if (!form) return null;\n\n const formData = new FormData(form);\n const isValid = formData.get('valid') === 'true';\n\n return isValid ? buildCartItem(formData) : null;\n });\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\n/**\n * Extract optionsUIDs from various data formats\n */\nexport const extractOptionsUIDs = (valuesData: any): string[] => {\n let optionsUIDs: string[] = [];\n\n if (valuesData && typeof valuesData === 'object') {\n if (valuesData.optionsUIDs && Array.isArray(valuesData.optionsUIDs)) {\n optionsUIDs = valuesData.optionsUIDs;\n } else if (Array.isArray(valuesData)) {\n optionsUIDs = valuesData;\n }\n } else if (typeof valuesData === 'string') {\n optionsUIDs = [valuesData];\n }\n\n return optionsUIDs;\n};\n\n/**\n * Get options from localStorage\n */\nexport const getOptionsFromStorage = (\n storageKey: string\n): Record<string, string[]> => {\n try {\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n return JSON.parse(stored);\n }\n } catch (e) {\n console.error('Error reading from localStorage:', e);\n }\n return {};\n};\n\n/**\n * Save options to localStorage\n */\nexport const saveOptionsToStorage = (\n storageKey: string,\n itemId: string,\n optionsUIDs: string[]\n): void => {\n if (optionsUIDs.length === 0) {\n return;\n }\n\n try {\n const storageData = getOptionsFromStorage(storageKey);\n storageData[itemId] = optionsUIDs;\n localStorage.setItem(storageKey, JSON.stringify(storageData));\n } catch (e) {\n console.error('Error saving to localStorage:', e);\n }\n};\n\n/**\n * Enrich cart items with selected options from storage\n */\nexport const enrichCartItemsWithOptions = <T extends { sku: string }>(\n cartItems: T[],\n items: Array<{ id?: string; sku: string; variantSku?: string }>,\n storageData: Record<string, string[]>\n): Array<T & { optionsUIDs?: string[] }> => {\n return cartItems.map((cartItem) => {\n const item = items.find((i) => {\n return cartItem.sku === i.sku || cartItem.sku === i.variantSku;\n });\n\n if (item) {\n const itemId = item.id || item.sku;\n const selectedOptions = storageData[itemId];\n\n if (selectedOptions && selectedOptions.length > 0) {\n return {\n ...cartItem,\n optionsUIDs: selectedOptions,\n };\n }\n }\n\n return cartItem;\n });\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { useCallback, useEffect, useState } from 'preact/hooks';\nimport {\n OrderItemInput,\n OrderItem,\n UseQuickOrderItemsProps,\n UseQuickOrderItemsReturn,\n} from '@/b2b-quick-order/types';\nimport { events } from '@adobe-commerce/event-bus';\nimport {\n mapProductsToOrderItems,\n validateOrderItems,\n getItemScope,\n replaceOrAddItems,\n updateItemInList,\n buildCartItemsFromForms,\n extractOptionsUIDs,\n saveOptionsToStorage,\n getOptionsFromStorage,\n enrichCartItemsWithOptions,\n} from '@/b2b-quick-order/lib';\n\nexport const useQuickOrderItems = ({\n getProductsData,\n onAddAllToCart,\n}: UseQuickOrderItemsProps = {}): UseQuickOrderItemsReturn => {\n const [items, setItems] = useState<OrderItem[]>([]);\n const [loading, setLoading] = useState(false);\n const [updatingItems, setUpdatingItems] = useState<Set<string>>(new Set());\n const [isDisabledButton, setIsDisabledButton] = useState(false);\n\n const STORAGE_KEY = 'quick-order-selected-options';\n\n const setDisabledCartButton = useCallback((disabled: boolean) => {\n setIsDisabledButton(disabled);\n }, []);\n\n useEffect(() => {\n const loadingEvent = events.on(\n 'quick-order/loading',\n (loadingState) => {\n setLoading(loadingState);\n },\n {\n eager: true,\n }\n );\n return () => {\n loadingEvent?.off();\n };\n }, []);\n\n useEffect(() => {\n const itemsEvent = events.on(\n 'quick-order/add-items',\n async (data: OrderItemInput[]) => {\n if (data && data.length > 0) {\n if (!getProductsData) {\n return;\n }\n\n setLoading(true);\n events.emit('quick-order/loading', true);\n const requestedSkus = data.map((item) => item.sku).filter(Boolean);\n setUpdatingItems(\n (prev) => new Set([...Array.from(prev), ...requestedSkus])\n );\n\n try {\n let newItems: OrderItem[] = [];\n try {\n const products = await getProductsData(data);\n setDisabledCartButton(data.length !== products.length);\n newItems = mapProductsToOrderItems(data, products);\n } catch (error) {\n console.error('Error fetching products data:', error);\n newItems = mapProductsToOrderItems(data, []);\n }\n\n // Merge or add items with deduplication logic\n setItems((prevItems) => {\n // Replace, merge or add new items in a single pass\n const { updatedItems, addedItems, mergedItems, replacedItems } =\n replaceOrAddItems(prevItems, newItems, data);\n\n // Emit update events for replaced items\n replacedItems.forEach((item) => {\n const scope = getItemScope(item);\n events.emit(`${scope}/pdp/data`, item);\n });\n\n // Emit update events for merged items\n mergedItems.forEach((item) => {\n const scope = getItemScope(item);\n events.emit(`${scope}/pdp/data`, item);\n });\n\n // Emit pdp/data events for newly added items\n addedItems.forEach((item) => {\n const scope = getItemScope(item);\n events.emit(`${scope}/pdp/data`, item);\n });\n\n return updatedItems;\n });\n } finally {\n setLoading(false);\n events.emit('quick-order/loading', false);\n setUpdatingItems(\n (prev) =>\n new Set(\n Array.from(prev).filter((sku) => !requestedSkus.includes(sku))\n )\n );\n }\n }\n },\n {\n eager: true,\n }\n );\n\n return () => {\n itemsEvent?.off();\n };\n }, [getProductsData, setDisabledCartButton]);\n\n // Listen to pdp/data events for reactive updates\n useEffect(() => {\n const scopesList = items.map((item) => {\n const scope = getItemScope(item);\n const itemId = item.id; // Capture the specific item's ID for this listener\n\n return events.on(`${scope}/pdp/data`, (updatedItem: OrderItem) => {\n setItems((prevItems) => {\n const result = updateItemInList(\n prevItems,\n itemId || '',\n updatedItem,\n item.quantity || 1\n );\n return result.updatedItems;\n });\n });\n });\n\n return () => {\n scopesList?.forEach((scope) => {\n scope?.off();\n });\n };\n }, [items]);\n\n useEffect(() => {\n const isValid = validateOrderItems(items);\n setDisabledCartButton(!isValid);\n }, [items, setDisabledCartButton]);\n\n useEffect(() => {\n const eventsList = items.map((item) => {\n const scope = getItemScope(item);\n const itemId = item.id || item.sku;\n\n return events.on(`${scope}/pdp/values`, (valuesData: any) => {\n const optionsUIDs = extractOptionsUIDs(valuesData);\n saveOptionsToStorage(STORAGE_KEY, itemId, optionsUIDs);\n });\n });\n\n return () => {\n eventsList.forEach((event) => {\n event?.off();\n });\n };\n }, [items, STORAGE_KEY]);\n\n const removeItem = useCallback((identifier: string) => {\n // identifier can be either item.id or item.sku for backward compatibility\n setItems((prevItems) =>\n prevItems.filter(\n (item) => item.id !== identifier && item.sku !== identifier\n )\n );\n }, []);\n\n const updateItemQuantity = useCallback((sku: string, quantity: number) => {\n setItems((prevItems) =>\n prevItems.map((item) => (item.sku === sku ? { ...item, quantity } : item))\n );\n }, []);\n\n const isItemUpdating = useCallback(\n (sku: string) => {\n return updatingItems.has(sku);\n },\n [updatingItems]\n );\n\n const handleAddToCart = useCallback(() => {\n const cartItems = buildCartItemsFromForms(items).filter(\n (item): item is NonNullable<typeof item> => item !== null\n );\n const storageData = getOptionsFromStorage(STORAGE_KEY);\n const enrichedCartItems = enrichCartItemsWithOptions(\n cartItems,\n items,\n storageData\n );\n\n if (onAddAllToCart) {\n onAddAllToCart(enrichedCartItems);\n } else {\n events.emit('quick-order/add-to-cart', enrichedCartItems);\n }\n }, [items, onAddAllToCart, STORAGE_KEY]);\n\n return {\n items,\n loading,\n removeItem,\n updateItemQuantity,\n handleAddToCart,\n isItemUpdating,\n isDisabledButton,\n setDisabledCartButton,\n };\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { QuickOrderItemsList } from '@/b2b-quick-order/components';\nimport { useQuickOrderItems } from '@/b2b-quick-order/hooks';\nimport { QuickOrderItemsProps } from '@/b2b-quick-order/types';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { classes, Container } from '@adobe-commerce/elsie/lib';\n\nexport const QuickOrderItems: Container<QuickOrderItemsProps> = ({\n className,\n slots,\n getProductsData,\n onAddAllToCart,\n productsSearch,\n searchFilter,\n}) => {\n const t = useText({\n title: 'QuickOrder.QuickOrderItem.title',\n quantity: 'QuickOrder.QuickOrderItem.quantity',\n price: 'QuickOrder.QuickOrderItem.price',\n remove: 'QuickOrder.QuickOrderItem.remove',\n removeItem: 'QuickOrder.QuickOrderItem.removeItem',\n showOptions: 'QuickOrder.QuickOrderItem.showOptions',\n hideOptions: 'QuickOrder.QuickOrderItem.hideOptions',\n additionalOptions: 'QuickOrder.QuickOrderItem.additionalOptions',\n noAdditionalOptions: 'QuickOrder.QuickOrderItem.noAdditionalOptions',\n emptyList: 'QuickOrder.QuickOrderItem.emptyList',\n sku: 'QuickOrder.QuickOrderItem.sku',\n loading: 'QuickOrder.QuickOrderItem.loading',\n productNotFound: 'QuickOrder.QuickOrderItem.productNotFound',\n productNotFoundDescription:\n 'QuickOrder.QuickOrderItem.productNotFoundDescription',\n productOptions: 'QuickOrder.QuickOrderItem.productOptions',\n configurableProductError:\n 'QuickOrder.QuickOrderItem.configurableProductError',\n configurableProductErrorDescription:\n 'QuickOrder.QuickOrderItem.configurableProductErrorDescription',\n addAllToCart: 'QuickOrder.QuickOrderItem.addAllToCart',\n configurableOptionsWarning:\n 'QuickOrder.QuickOrderItem.configurableOptionsWarning',\n configurableOptionsWarningDescription:\n 'QuickOrder.QuickOrderItem.configurableOptionsWarningDescription',\n outOfStock: 'QuickOrder.QuickOrderItem.outOfStock',\n searchPlaceholder: 'QuickOrder.Search.placeholder',\n searchAriaLabel: 'QuickOrder.Search.ariaLabel',\n searchEmptyState: 'QuickOrder.Search.emptyState',\n resultsAvailable: 'QuickOrder.Search.resultsAvailable',\n resultAvailable: 'QuickOrder.Search.resultAvailable',\n srInstructions: 'QuickOrder.Search.srInstructions',\n });\n\n const {\n items,\n loading,\n removeItem,\n updateItemQuantity,\n handleAddToCart,\n isItemUpdating,\n setDisabledCartButton,\n isDisabledButton,\n } = useQuickOrderItems({\n getProductsData,\n onAddAllToCart,\n });\n\n return (\n <div\n className={classes(['b2b-quick-order-quick-order-items', className])}\n data-testid=\"quick-order-items\"\n >\n <QuickOrderItemsList\n t={t}\n items={items}\n onRemove={removeItem}\n onUpdateQuantity={updateItemQuantity}\n handleAddToCart={handleAddToCart}\n isItemUpdating={isItemUpdating}\n slots={slots}\n loading={loading}\n setDisabledCartButton={setDisabledCartButton}\n isDisabledButton={isDisabledButton}\n productsSearch={productsSearch}\n searchFilter={searchFilter}\n />\n </div>\n );\n};\n"],"names":["STANDARD_FIELDS","processFormOptions","formData","optionUIDs","enteredOptions","value","key","valueStr","buildCartItem","quantityValue","quantity","cartItem","parentSku","DEFAULT_QUICK_ORDER_ITEM","mapProductsToOrderItems","requestedItems","products","requestedItem","foundProduct","p","validateOrderItems","items","item","option","optionItem","getItemScope","generateItemId","sku","findDuplicateItem","newItem","existing","findDuplicateItemExcluding","updatedItem","excludeItemId","mergeDuplicateItems","removeIndex","mergeIntoIndex","quantityToAdd","index","replaceOrAddItems","existingItems","newItems","inputItems","updatedItems","addedItems","replacedItems","mergedItems","inputItem","replaceIndex","existingIndex","adjustedIndex","itemWithId","updateItemInList","itemId","currentQuantity","duplicateIndex","removingIndex","prevItem","buildCartItemsFromForms","formId","form","extractOptionsUIDs","valuesData","optionsUIDs","getOptionsFromStorage","storageKey","stored","e","saveOptionsToStorage","storageData","enrichCartItemsWithOptions","cartItems","i","selectedOptions","useQuickOrderItems","getProductsData","onAddAllToCart","setItems","useState","loading","setLoading","updatingItems","setUpdatingItems","isDisabledButton","setIsDisabledButton","STORAGE_KEY","setDisabledCartButton","useCallback","disabled","useEffect","loadingEvent","events","loadingState","itemsEvent","data","requestedSkus","prev","error","prevItems","scope","scopesList","isValid","eventsList","event","removeItem","identifier","updateItemQuantity","isItemUpdating","handleAddToCart","enrichedCartItems","QuickOrderItems","className","slots","productsSearch","searchFilter","t","useText","jsx","classes","QuickOrderItemsList"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { QuickOrderMultipleSkuProps } from '../../types';
2
+ import { Container } from '@dropins/tools/types/elsie/src/lib';
3
+
4
+ export declare const QuickOrderMultipleSku: Container<QuickOrderMultipleSkuProps>;
5
+ //# sourceMappingURL=QuickOrderMultipleSku.d.ts.map
@@ -0,0 +1,19 @@
1
+ /********************************************************************
2
+ * ADOBE CONFIDENTIAL
3
+ * __________________
4
+ *
5
+ * Copyright 2024 Adobe
6
+ * All Rights Reserved.
7
+ *
8
+ * NOTICE: All information contained herein is, and remains
9
+ * the property of Adobe and its suppliers, if any. The intellectual
10
+ * and technical concepts contained herein are proprietary to Adobe
11
+ * and its suppliers and are protected by all applicable intellectual
12
+ * property laws, including trade secret and copyright laws.
13
+ * Dissemination of this information or reproduction of this material
14
+ * is strictly forbidden unless prior written permission is obtained
15
+ * from Adobe.
16
+ *******************************************************************/
17
+ export * from './QuickOrderMultipleSku';
18
+ export { QuickOrderMultipleSku as default } from './QuickOrderMultipleSku';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ export * from './QuickOrderMultipleSku/index'
2
+ import _default from './QuickOrderMultipleSku/index'
3
+ export default _default
@@ -0,0 +1,4 @@
1
+ /*! Copyright 2026 Adobe
2
+ All Rights Reserved. */
3
+ import{jsxs as T,jsx as c}from"@dropins/tools/preact-jsx-runtime.js";import{TextArea as q,Button as O}from"@dropins/tools/components.js";import{c as Q,d as v}from"../chunks/Search.js";import"../chunks/CsvFileInput.js";import{useState as h,useRef as x,useEffect as p,useCallback as m,useMemo as I}from"@dropins/tools/preact-hooks.js";import{events as A}from"@dropins/tools/event-bus.js";import{Slot as M,classes as _}from"@dropins/tools/lib.js";import{useText as N}from"@dropins/tools/i18n.js";import"@dropins/tools/preact-compat.js";const B=({t,onChange:u,textAreaValue:r,loading:o})=>T("div",{className:Q(["b2b-quick-order-sku-list-input"]),children:[c("div",{className:"b2b-quick-order-sku-list-input__title",children:t.title}),c(q,{id:"quick-order-sku-list-input",label:t.label,className:"b2b-quick-order-sku-list-input__textarea",placeholder:t.textAreaPlaceholder,onChange:u,value:r,disabled:o}),c("div",{className:"b2b-quick-order-sku-list-input__message",children:t.helperText})]}),C=({onChange:t})=>{const[u,r]=h(""),[o,k]=h(!1),l=x([]),i=x(!0);p(()=>()=>{i.current=!1},[]);const d=m(e=>{const a=e.split(/[\s,]+/).map(s=>s.trim()).filter(s=>s.length>0),n=new Map;a.forEach(s=>{n.set(s,(n.get(s)||0)+1)});const b=Array.from(n.entries()).map(([s,L])=>({sku:s,quantity:L}));return l.current=b,b},[]),f=I(()=>v(e=>{t&&i.current&&t(e)},300),[t]);p(()=>{f(d(u))},[u,f,d]),p(()=>{const e=A.on("quick-order/loading",a=>{i.current&&k(a)},{eager:!0});return()=>{e==null||e.off()}},[]);const g=m(e=>{const n=e.target.value;r(n)},[]),S=m(e=>{const a=l.current,n=e?[...a,...e]:a;A.emit("quick-order/add-items",n),r("")},[]);return{handleChange:g,textAreaValue:u,loading:o,handleAddToList:S}},D=({className:t,onChange:u,slots:r})=>{const o=N({title:"QuickOrder.SkuListInput.title",helperText:"QuickOrder.SkuListInput.helperText",textAreaPlaceholder:"QuickOrder.SkuListInput.textArea.placeholder",buttonText:"QuickOrder.SkuListInput.button",label:"QuickOrder.SkuListInput.textArea.label"}),{handleChange:k,textAreaValue:l,loading:i,handleAddToList:d}=C({onChange:u});return T("div",{className:_(["b2b-quick-order-quick-order-multiple-sku",t]),"data-testid":"storefrontQuickOrderTest",children:[c(B,{loading:i,textAreaValue:l,onChange:k,t:o}),c(M,{"data-testid":"addToListButtonTest",name:"AddToListButton",slot:r==null?void 0:r.AddToListButton,context:{handleAddToList:d,loading:i,textAreaValue:l},children:c(O,{onClick:()=>d(),disabled:i||!l.length,children:o.buttonText})})]})};export{D as QuickOrderMultipleSku,D as default};
4
+ //# sourceMappingURL=QuickOrderMultipleSku.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuickOrderMultipleSku.js","sources":["/@dropins/storefront-quick-order/src/components/SkuListInput/SkuListInput.tsx","/@dropins/storefront-quick-order/src/hooks/useQuickOrderMultipleSku.tsx","/@dropins/storefront-quick-order/src/containers/QuickOrderMultipleSku/QuickOrderMultipleSku.tsx"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { FunctionComponent } from 'preact/compat';\nimport { TextArea } from '@adobe-commerce/elsie/components';\nimport { classes } from '@adobe-commerce/elsie/lib/classes';\nimport { SkuListInputProps } from '@/b2b-quick-order/types';\nimport '@/b2b-quick-order/components/SkuListInput/SkuListInput.css';\n\nexport const SkuListInput: FunctionComponent<SkuListInputProps> = ({\n t,\n onChange,\n textAreaValue,\n loading,\n}) => {\n return (\n <div className={classes(['b2b-quick-order-sku-list-input'])}>\n <div className=\"b2b-quick-order-sku-list-input__title\">{t.title}</div>\n <TextArea\n id={'quick-order-sku-list-input'}\n label={t.label}\n className=\"b2b-quick-order-sku-list-input__textarea\"\n placeholder={t.textAreaPlaceholder}\n onChange={onChange}\n value={textAreaValue}\n disabled={loading}\n />\n <div className=\"b2b-quick-order-sku-list-input__message\">\n {t.helperText}\n </div>\n </div>\n );\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport {\n useCallback,\n useEffect,\n useMemo,\n useState,\n useRef,\n} from 'preact/hooks';\nimport {\n SubmitSkuValue,\n UseQuickOrderMultipleSkuProps,\n UseQuickOrderMultipleSkuReturn,\n} from '@/b2b-quick-order/types';\nimport { debounce } from '@adobe-commerce/elsie/lib/debounce';\nimport { events } from '@adobe-commerce/event-bus';\n\nexport const useQuickOrderMultipleSku = ({\n onChange,\n}: UseQuickOrderMultipleSkuProps): UseQuickOrderMultipleSkuReturn => {\n const [textAreaValue, setTextAreaValue] = useState<string>('');\n const [loading, setLoading] = useState(false);\n // Store parsed SKU values without triggering re-renders (transient data for debounced callback)\n const textAreaValueRef = useRef<SubmitSkuValue>([]);\n // Track component mount status to prevent state updates after unmount\n const isMountedRef = useRef(true);\n\n useEffect(() => {\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n const modifySkuString = useCallback((value: string) => {\n const parsed = value\n .split(/[\\s,]+/)\n .map((item) => item.trim())\n .filter((sku) => sku.length > 0);\n\n // Deduplicate: sum quantities for duplicate SKUs\n const skuMap = new Map<string, number>();\n parsed.forEach((sku) => {\n skuMap.set(sku, (skuMap.get(sku) || 0) + 1);\n });\n\n const result = Array.from(skuMap.entries()).map(([sku, quantity]) => ({\n sku,\n quantity,\n }));\n\n textAreaValueRef.current = result;\n\n return result;\n }, []);\n\n const debouncedOnChange = useMemo(\n () =>\n debounce((skus: string[]) => {\n if (onChange && isMountedRef.current) {\n onChange(skus);\n }\n }, 300),\n [onChange]\n );\n\n useEffect(() => {\n debouncedOnChange(modifySkuString(textAreaValue));\n }, [textAreaValue, debouncedOnChange, modifySkuString]);\n\n useEffect(() => {\n const loadingEvent = events.on(\n 'quick-order/loading',\n (loading) => {\n if (isMountedRef.current) {\n setLoading(loading);\n }\n },\n {\n eager: true,\n }\n );\n return () => {\n loadingEvent?.off();\n };\n }, []);\n\n const handleChange = useCallback((e: Event) => {\n const target = e.target as HTMLTextAreaElement;\n const value = target.value;\n setTextAreaValue(value);\n }, []);\n\n const handleAddToList = useCallback(\n (additionalValues?: Array<{ sku: string; quantity: number }>) => {\n const textAreaSkus = textAreaValueRef.current;\n const allSkus = additionalValues\n ? [...textAreaSkus, ...additionalValues]\n : textAreaSkus;\n events.emit('quick-order/add-items', allSkus);\n setTextAreaValue('');\n },\n []\n );\n\n return {\n handleChange,\n textAreaValue,\n loading,\n handleAddToList,\n };\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { SkuListInput } from '@/b2b-quick-order/components';\nimport { useQuickOrderMultipleSku } from '@/b2b-quick-order/hooks';\nimport { QuickOrderMultipleSkuProps } from '@/b2b-quick-order/types';\nimport { Button } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { classes, Container, Slot } from '@adobe-commerce/elsie/lib';\n\nexport const QuickOrderMultipleSku: Container<QuickOrderMultipleSkuProps> = ({\n className,\n onChange,\n slots,\n}) => {\n const t = useText({\n title: 'QuickOrder.SkuListInput.title',\n helperText: 'QuickOrder.SkuListInput.helperText',\n textAreaPlaceholder: 'QuickOrder.SkuListInput.textArea.placeholder',\n buttonText: 'QuickOrder.SkuListInput.button',\n label: 'QuickOrder.SkuListInput.textArea.label',\n });\n\n const { handleChange, textAreaValue, loading, handleAddToList } =\n useQuickOrderMultipleSku({\n onChange,\n });\n\n return (\n <div\n className={classes([\n 'b2b-quick-order-quick-order-multiple-sku',\n className,\n ])}\n data-testid=\"storefrontQuickOrderTest\"\n >\n <SkuListInput\n loading={loading}\n textAreaValue={textAreaValue}\n onChange={handleChange}\n t={t}\n />\n <Slot\n data-testid=\"addToListButtonTest\"\n name=\"AddToListButton\"\n slot={slots?.AddToListButton}\n context={{ handleAddToList, loading, textAreaValue }}\n >\n <Button\n onClick={() => handleAddToList()}\n disabled={loading || !textAreaValue.length}\n >\n {t.buttonText}\n </Button>\n </Slot>\n </div>\n );\n};\n"],"names":["SkuListInput","onChange","textAreaValue","loading","classes","jsx","TextArea","useQuickOrderMultipleSku","setTextAreaValue","useState","setLoading","textAreaValueRef","useRef","isMountedRef","useEffect","modifySkuString","useCallback","value","parsed","item","sku","skuMap","result","quantity","debouncedOnChange","useMemo","debounce","skus","loadingEvent","events","handleChange","handleAddToList","additionalValues","textAreaSkus","allSkus","QuickOrderMultipleSku","className","slots","t","useText","jsxs","Slot","Button"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /********************************************************************
2
+ * ADOBE CONFIDENTIAL
3
+ * __________________
4
+ *
5
+ * Copyright 2025 Adobe
6
+ * All Rights Reserved.
7
+ *
8
+ * NOTICE: All information contained herein is, and remains
9
+ * the property of Adobe and its suppliers, if any. The intellectual
10
+ * and technical concepts contained herein are proprietary to Adobe
11
+ * and its suppliers and are protected by all applicable intellectual
12
+ * property laws, including trade secret and copyright laws.
13
+ * Dissemination of this information or reproduction of this material
14
+ * is strictly forbidden unless prior written permission is obtained
15
+ * from Adobe.
16
+ *******************************************************************/
17
+ export * from './QuickOrderMultipleSku/QuickOrderMultipleSku';
18
+ export * from './QuickOrderCsvUpload/QuickOrderCsvUpload';
19
+ export * from './QuickOrderItems/QuickOrderItems';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,21 @@
1
+ /********************************************************************
2
+ * ADOBE CONFIDENTIAL
3
+ * __________________
4
+ *
5
+ * Copyright 2024 Adobe
6
+ * All Rights Reserved.
7
+ *
8
+ * NOTICE: All information contained herein is, and remains
9
+ * the property of Adobe and its suppliers, if any. The intellectual
10
+ * and technical concepts contained herein are proprietary to Adobe
11
+ * and its suppliers and are protected by all applicable intellectual
12
+ * property laws, including trade secret and copyright laws.
13
+ * Dissemination of this information or reproduction of this material
14
+ * is strictly forbidden unless prior written permission is obtained
15
+ * from Adobe.
16
+ *******************************************************************/
17
+ export * from './useQuickOrderMultipleSku';
18
+ export * from './useQuickOrderCsvUpload';
19
+ export * from './useQuickOrderItems';
20
+ export * from './useItemSearch';
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,11 @@
1
+ import { OrderItem, UseItemSearchProps } from '../types';
2
+
3
+ export declare const useItemSearch: ({ productsSearch, initialSku, replaceItemSku, searchFilter, }: UseItemSearchProps) => {
4
+ searchValue: string;
5
+ searchResults: OrderItem[];
6
+ handleSearchChange: (e: Event) => void;
7
+ shouldShowResults: boolean;
8
+ resetSearch: () => void;
9
+ handleItemClick: (clickedItem: OrderItem) => void;
10
+ };
11
+ //# sourceMappingURL=useItemSearch.d.ts.map
@@ -0,0 +1,4 @@
1
+ import { UseQuickOrderCsvUploadProps, UseQuickOrderCsvUploadReturn } from '../types/quickOrderCsvUpload.types';
2
+
3
+ export declare const useQuickOrderCsvUpload: ({ routeSampleCSV, onFileUpload, }: UseQuickOrderCsvUploadProps) => UseQuickOrderCsvUploadReturn;
4
+ //# sourceMappingURL=useQuickOrderCsvUpload.d.ts.map
@@ -0,0 +1,4 @@
1
+ import { UseQuickOrderItemsProps, UseQuickOrderItemsReturn } from '../types';
2
+
3
+ export declare const useQuickOrderItems: ({ getProductsData, onAddAllToCart, }?: UseQuickOrderItemsProps) => UseQuickOrderItemsReturn;
4
+ //# sourceMappingURL=useQuickOrderItems.d.ts.map
@@ -0,0 +1,4 @@
1
+ import { UseQuickOrderMultipleSkuProps, UseQuickOrderMultipleSkuReturn } from '../types';
2
+
3
+ export declare const useQuickOrderMultipleSku: ({ onChange, }: UseQuickOrderMultipleSkuProps) => UseQuickOrderMultipleSkuReturn;
4
+ //# sourceMappingURL=useQuickOrderMultipleSku.d.ts.map
@@ -0,0 +1,66 @@
1
+ declare const _default: {
2
+ "QuickOrder": {
3
+ "Search": {
4
+ "placeholder": "Search by SKU...",
5
+ "ariaLabel": "Search for products by SKU",
6
+ "emptyState": "No results found",
7
+ "resultsAvailable": "results available",
8
+ "resultAvailable": "result available",
9
+ "srInstructions": "Use arrow keys or Tab to navigate, Enter or Space to select, Escape to close."
10
+ },
11
+ "SkuListInput": {
12
+ "title": "Add Products by SKU",
13
+ "helperText": "Use commas or paragraphs to separate SKUs.",
14
+ "textArea": {
15
+ "label": "Enter Multiple SKUs",
16
+ "placeholder": "Enter SKUs here..."
17
+ },
18
+ "button": "Add to List"
19
+ },
20
+ "CsvFileInput": {
21
+ "title": "Add from File",
22
+ "helperText": "File must be in .csv format and include \"SKU\" and \"QTY\" columns ",
23
+ "downloadSample": "Download sample",
24
+ "inputLabel": "Choose File",
25
+ "selectedFile": "Selected file",
26
+ "uploadCSVErrors": {
27
+ "invalidFile": "Invalid CSV file",
28
+ "emptyFile": "File is empty",
29
+ "missingColumns": "Must contain \"SKU\" and \"QTY\" columns",
30
+ "extraColumns": "Must contain only \"SKU\" and \"QTY\" columns",
31
+ "maxRowsExceeded": "File exceeds maximum of {maxRows} rows",
32
+ "skuRequired": "Row {rowNumber}: SKU is required",
33
+ "invalidQuantity": "Row {rowNumber}: QTY must be a positive integer",
34
+ "noValidData": "File contains no valid data rows",
35
+ "onlyCSV": "Only CSV files are allowed",
36
+ "failedToRead": "Failed to read file",
37
+ "failedToParse": "Failed to parse CSV file"
38
+ }
39
+ },
40
+ "QuickOrderItem": {
41
+ "title": "Enter SKU or search by Product Name",
42
+ "quantity": "Quantity: ",
43
+ "price": "Price: ",
44
+ "sku": "SKU",
45
+ "remove": "Remove",
46
+ "removeItem": "Remove item",
47
+ "showOptions": "Show additional options",
48
+ "hideOptions": "Hide additional options",
49
+ "additionalOptions": "Additional options",
50
+ "noAdditionalOptions": "No additional options available",
51
+ "emptyList": "No products in the list",
52
+ "loading": "Loading...",
53
+ "productNotFound": "Product not found",
54
+ "productNotFoundDescription": "The product with SKU {sku} could not be found",
55
+ "configurableProductError": "Configuration required",
56
+ "configurableProductErrorDescription": "Configurable products aren’t supported here. Use the correct component for products with options. ",
57
+ "configurableOptionsWarning": "Product configuration required",
58
+ "configurableOptionsWarningDescription": "Please select all required product options before adding to cart",
59
+ "productOptions": "Product Options",
60
+ "outOfStock": "Out of Stock",
61
+ "addAllToCart": "Add to Cart"
62
+ }
63
+ }
64
+ };
65
+
66
+ export default _default;
@@ -0,0 +1,13 @@
1
+ import { OrderItem } from '../types';
2
+
3
+ export interface AddOrMergeItemsResult {
4
+ updatedItems: OrderItem[];
5
+ addedItems: OrderItem[];
6
+ mergedItems: OrderItem[];
7
+ }
8
+ /**
9
+ * Add or merge items into existing list
10
+ * Returns updated list and information about which items were added/merged
11
+ */
12
+ export declare const addOrMergeItems: (existingItems: OrderItem[], newItems: OrderItem[]) => AddOrMergeItemsResult;
13
+ //# sourceMappingURL=addOrMergeItems.d.ts.map
@@ -0,0 +1,32 @@
1
+ /********************************************************************
2
+ * ADOBE CONFIDENTIAL
3
+ * __________________
4
+ *
5
+ * Copyright 2024 Adobe
6
+ * All Rights Reserved.
7
+ *
8
+ * NOTICE: All information contained herein is, and remains
9
+ * the property of Adobe and its suppliers, if any. The intellectual
10
+ * and technical concepts contained herein are proprietary to Adobe
11
+ * and its suppliers and are protected by all applicable intellectual
12
+ * property laws, including trade secret and copyright laws.
13
+ * Dissemination of this information or reproduction of this material
14
+ * is strictly forbidden unless prior written permission is obtained
15
+ * from Adobe.
16
+ *******************************************************************/
17
+ export interface CartItem {
18
+ sku: string;
19
+ quantity: number;
20
+ parentSku?: string;
21
+ optionsUIDs?: string[];
22
+ enteredOptions?: {
23
+ uid: string;
24
+ value: string;
25
+ }[];
26
+ }
27
+ /**
28
+ * Builds a cart item object from form data
29
+ * Extracts SKU, quantity, parent SKU, and product options
30
+ */
31
+ export declare const buildCartItem: (formData: FormData) => CartItem;
32
+ //# sourceMappingURL=buildCartItem.d.ts.map
@@ -0,0 +1,8 @@
1
+ import { OrderItem } from '../types';
2
+
3
+ /**
4
+ * Build cart items from forms for all order items
5
+ * Only includes valid items (items with valid forms)
6
+ */
7
+ export declare const buildCartItemsFromForms: (items: OrderItem[]) => (import('./buildCartItem').CartItem | null)[];
8
+ //# sourceMappingURL=buildCartItemsFromForms.d.ts.map
@@ -0,0 +1,24 @@
1
+ /********************************************************************
2
+ * ADOBE CONFIDENTIAL
3
+ * __________________
4
+ *
5
+ * Copyright 2024 Adobe
6
+ * All Rights Reserved.
7
+ *
8
+ * NOTICE: All information contained herein is, and remains
9
+ * the property of Adobe and its suppliers, if any. The intellectual
10
+ * and technical concepts contained herein are proprietary to Adobe
11
+ * and its suppliers and are protected by all applicable intellectual
12
+ * property laws, including trade secret and copyright laws.
13
+ * Dissemination of this information or reproduction of this material
14
+ * is strictly forbidden unless prior written permission is obtained
15
+ * from Adobe.
16
+ *******************************************************************/
17
+ /**
18
+ * Cleans CSV value by removing surrounding quotes and trimming whitespace
19
+ * Handles both double quotes (") and single quotes (')
20
+ * @param val - The raw CSV value to clean
21
+ * @returns Cleaned string value
22
+ */
23
+ export declare const cleanCsvValue: (val: string) => string;
24
+ //# sourceMappingURL=cleanCsvValue.d.ts.map
@@ -0,0 +1,19 @@
1
+ import { OrderItem } from '../types';
2
+
3
+ /**
4
+ * Find duplicate item in the list based on multiple comparison strategies
5
+ * Returns the index of the duplicate item, or -1 if not found
6
+ *
7
+ * Strategies:
8
+ * 1. Both have variantSku - compare variants
9
+ * 2. Existing has variantSku, new has sku - compare them
10
+ * 3. New has variantSku, existing has sku - compare them
11
+ * 4. Neither has variantSku - compare base SKU
12
+ */
13
+ export declare const findDuplicateItem: (items: OrderItem[], newItem: OrderItem) => number;
14
+ /**
15
+ * Find duplicate item excluding a specific item by ID
16
+ * Used when checking for duplicates after an item update
17
+ */
18
+ export declare const findDuplicateItemExcluding: (items: OrderItem[], updatedItem: OrderItem, excludeItemId: string) => number;
19
+ //# sourceMappingURL=findDuplicateItem.d.ts.map