{
  "version": 3,
  "sources": ["/cdn/shop/t/4/assets/ims-inventory.js?bust=20260618"],
  "sourcesContent": ["(function () {\n  'use strict';\n  const db = () => window.SM.DB;\n  const ui = () => window.SM.UI;\n  const util = () => window.SM.UTIL;\n  const canSeeCost = () => window.SM.AUTH.canSeeCost();\n  const isAdmin = () => window.SM.AUTH.isAdmin();\n\n  let _activeTab = 'catalogue';\n\n  // \u2500\u2500\u2500 INIT TABS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  function initTabs() {\n    const tabs = document.getElementById('ims-inv-tabs');\n    if (!tabs) return;\n    tabs.querySelectorAll('.ims__tab').forEach(tab => {\n      tab.addEventListener('click', () => {\n        tabs.querySelectorAll('.ims__tab').forEach(t => t.classList.remove('ims__tab--active'));\n        tab.classList.add('ims__tab--active');\n        _activeTab = tab.dataset.tab;\n        loadTab(_activeTab);\n      });\n    });\n  }\n\n  function loadTab(tab) {\n    if (tab === 'catalogue') loadCatalogue();\n    else loadStock();\n  }\n\n  // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n  // TAB 1 \u2014 PRODUCT CATALOGUE\n  // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n  async function loadCatalogue() {\n    const content = document.getElementById('ims-inv-content');\n    if (!content) return;\n\n    const actions = document.getElementById('ims-inv-actions');\n    if (actions) {\n      actions.innerHTML = `\n        ${canSeeCost() ? '<button class=\"ims__btn ims__btn--secondary\" id=\"ims-cat-cost-btn\"><i class=\"ti ti-currency-pound\"></i> Update cost prices</button>' : ''}\n        <button class=\"ims__btn ims__btn--secondary\" id=\"ims-cat-export-btn\"><i class=\"ti ti-download\"></i> Export</button>\n        <button class=\"ims__btn ims__btn--secondary\" id=\"ims-cat-import-btn\"><i class=\"ti ti-upload\"></i> Import SKUs</button>\n        <button class=\"ims__btn ims__btn--primary\" id=\"ims-cat-new-btn\"><i class=\"ti ti-plus\"></i> Add new SKU</button>`;\n      document.getElementById('ims-cat-new-btn')?.addEventListener('click', () => showSKUForm());\n      document.getElementById('ims-cat-import-btn')?.addEventListener('click', showImport);\n      document.getElementById('ims-cat-export-btn')?.addEventListener('click', exportProducts);\n      document.getElementById('ims-cat-cost-btn')?.addEventListener('click', () => showCostUpdate());\n    }\n\n    content.innerHTML = `\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:14px\">\n        <i class=\"ti ti-info-circle\"></i>\n        <span><strong>Product Catalogue</strong> \u2014 Define your products here first. Stock is managed separately in the Stock Levels tab.</span>\n      </div>\n      <div class=\"ims__filters\">\n        <div class=\"ims__search-wrap\"><i class=\"ti ti-search\"></i><input class=\"ims__input\" type=\"text\" id=\"ims-cat-search\" placeholder=\"Name, SKU, barcode, category...\"></div>\n        <select class=\"ims__select\" id=\"ims-cat-category\"><option value=\"\">All categories</option></select>\n        <select class=\"ims__select\" id=\"ims-cat-status\"><option value=\"\">All products</option><option value=\"active\">Active</option><option value=\"inactive\">Inactive</option></select>\n      </div>\n      <div class=\"ims__card\">\n        <div class=\"ims__table-wrap\">\n          <table class=\"ims__table\">\n            <thead><tr>\n              <th>SKU</th><th>Product name</th><th>Category</th><th>Unit</th>\n              ${canSeeCost() ? '<th>Cost price</th>' : ''}\n              <th>Wholesale</th><th>RRP</th><th>Boxes</th><th>Reorder at</th><th>Status</th><th></th>\n            </tr></thead>\n            <tbody id=\"ims-cat-tbody\"><tr><td colspan=\"${canSeeCost()?11:10}\" class=\"ims__table-empty\"><i class=\"ti ti-loader-2 ims__spin\"></i></td></tr></tbody>\n          </table>\n        </div>\n      </div>`;\n\n    const searchEl = document.getElementById('ims-cat-search');\n    if (searchEl) searchEl.addEventListener('input', util().debounce(loadCatalogueData, 350));\n    document.getElementById('ims-cat-category')?.addEventListener('change', loadCatalogueData);\n    document.getElementById('ims-cat-status')?.addEventListener('change', loadCatalogueData);\n\n    await loadCatalogueData();\n  }\n\n  async function loadCatalogueData() {\n    const tbody = document.getElementById('ims-cat-tbody');\n    if (!tbody) return;\n    const search   = document.getElementById('ims-cat-search')?.value?.trim() || '';\n    const category = document.getElementById('ims-cat-category')?.value || '';\n    const status   = document.getElementById('ims-cat-status')?.value || '';\n\n    const { data: products, error } = await db().select('products', { order: { col: 'name' } });\n    if (error) { ui().toast('Failed to load catalogue', 'error'); return; }\n\n    let items = products || [];\n    if (search) {\n      const s = search.toLowerCase();\n      items = items.filter(p => p.name?.toLowerCase().includes(s) || p.sku?.toLowerCase().includes(s) || p.category?.toLowerCase().includes(s) || p.barcode?.toLowerCase().includes(s));\n    }\n    if (category) items = items.filter(p => p.category === category);\n    if (status === 'active')   items = items.filter(p => p.is_active !== false);\n    if (status === 'inactive') items = items.filter(p => p.is_active === false);\n\n    const catSel = document.getElementById('ims-cat-category');\n    if (catSel && catSel.options.length <= 1) {\n      const cats = [...new Set((products||[]).map(p => p.category).filter(Boolean))].sort();\n      cats.forEach(c => { const o = document.createElement('option'); o.value = c; o.textContent = c; catSel.appendChild(o); });\n    }\n\n    if (!items.length) {\n      tbody.innerHTML = `<tr><td colspan=\"${canSeeCost()?11:10}\" class=\"ims__table-empty\">No products in catalogue yet \u2014 click <strong>Add new SKU</strong> to start</td></tr>`;\n      return;\n    }\n\n    // Batch load prices\n    const priceMap = {};\n    const productIds = items.map(p => p.id);\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const { data: allPrices } = await client\n      .from('product_prices')\n      .select('product_id, price_type, price')\n      .in('product_id', productIds)\n      .is('platform_id', null);\n    (allPrices || []).forEach(pp => {\n      if (!priceMap[pp.product_id]) priceMap[pp.product_id] = { cost: null, wholesale: null, rrp: null };\n      priceMap[pp.product_id][pp.price_type] = pp.price;\n    });\n\n    // Batch load box counts\n    const boxCountMap = {};\n    const { data: allBoxes } = await client\n      .from('product_boxes')\n      .select('product_id')\n      .in('product_id', productIds);\n    (allBoxes || []).forEach(b => {\n      boxCountMap[b.product_id] = (boxCountMap[b.product_id] || 0) + 1;\n    });\n\n    tbody.innerHTML = items.map(p => {\n      const pr = priceMap[p.id] || {};\n      const boxCount = boxCountMap[p.id] || 0;\n      return `<tr>\n        <td><span class=\"ims__link\" onclick=\"window.IMS_INVENTORY.openSKU('${util().jsArg(p.id)}')\">${util().sanitize(p.sku || '\u2014')}</span></td>\n        <td><span class=\"ims__link\" onclick=\"window.IMS_INVENTORY.openSKU('${util().jsArg(p.id)}')\">${util().sanitize(p.name)}</span></td>\n        <td>${util().sanitize(p.category || '\u2014')}</td>\n        <td>${util().sanitize(p.unit || 'each')}</td>\n        ${canSeeCost() ? `<td>${pr.cost !== null && pr.cost !== undefined ? util().formatCurrency(pr.cost) : '<span style=\"color:var(--ims-warning)\">Not set</span>'}</td>` : ''}\n        <td>${pr.wholesale !== null && pr.wholesale !== undefined ? util().formatCurrency(pr.wholesale) : '<span style=\"color:var(--ims-warning)\">Not set</span>'}</td>\n        <td>${pr.rrp !== null && pr.rrp !== undefined ? util().formatCurrency(pr.rrp) : '<span style=\"color:var(--ims-warning)\">Not set</span>'}</td>\n        <td>${boxCount > 0 ? `<span class=\"ims__pill ims__pill--info\">${boxCount} box${boxCount>1?'es':''}</span>` : '<span style=\"color:var(--ims-text-muted);font-size:11px\">Not set</span>'}</td>\n        <td>${p.reorder_threshold || 10}</td>\n        <td><span class=\"ims__pill ims__pill--${p.is_active !== false ? 'success' : 'neutral'}\">${p.is_active !== false ? 'Active' : 'Inactive'}</span></td>\n        <td>\n          <div class=\"ims__btn-group\">\n            <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_INVENTORY.openSKU('${util().jsArg(p.id)}')\" title=\"View\"><i class=\"ti ti-eye\"></i></button>\n            ${isAdmin() ? `<button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_INVENTORY.showSKUForm('${util().jsArg(p.id)}')\" title=\"Edit\"><i class=\"ti ti-edit\"></i></button>` : ''}\n            ${canSeeCost() ? `<button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_INVENTORY.managePlatformPrices('${util().jsArg(p.id)}','${util().jsArg(p.name)}')\" title=\"Platform prices\"><i class=\"ti ti-apps\"></i></button>` : ''}\n            ${isAdmin() ? `<button class=\"ims__btn ims__btn--danger ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_INVENTORY.deleteSKU('${util().jsArg(p.id)}','${util().jsArg(p.name)}')\" title=\"Delete product\"><i class=\"ti ti-trash\"></i></button>` : ''}\n          </div>\n        </td>\n      </tr>`;\n    }).join('');\n  }\n\n  // \u2500\u2500\u2500 SKU DETAIL VIEW \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  async function openSKU(id) {\n    const { data: p } = await db().select('products', { eq: { id }, maybeSingle: true, noCompanyFilter: true });\n    if (!p) return;\n    const prices = await db().getProductPrices(id);\n    const cost      = prices.find(x => x.price_type === 'cost' && !x.platform_id)?.price;\n    const wholesale = prices.find(x => x.price_type === 'wholesale' && !x.platform_id)?.price;\n    const rrp       = prices.find(x => x.price_type === 'rrp' && !x.platform_id)?.price;\n    const platPrices= prices.filter(x => x.price_type === 'platform');\n\n    const { data: stock } = await db().select('stock_levels', {\n      select: 'quantity,reserved_qty,reserved_by_allocations,bin_reference,warehouses(name)',\n      eq: { product_id: id }, noCompanyFilter: true\n    });\n    const onHand    = (stock||[]).reduce((s, l) => s + (l.quantity||0), 0);\n    const reserved  = (stock||[]).reduce((s, l) => s + (l.reserved_qty||0), 0);\n    const allocated = (stock||[]).reduce((s, l) => s + (l.reserved_by_allocations||0), 0);\n\n    // Load boxes\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const { data: boxes } = await client\n      .from('product_boxes')\n      .select('*')\n      .eq('product_id', id)\n      .order('box_number');\n    const boxList = boxes || [];\n    const totalWeight = boxList.reduce((s, b) => s + (b.weight_kg || 0), 0);\n    const totalVol = boxList.reduce((s, b) => {\n      const vol = ((b.length_cm||0) * (b.width_cm||0) * (b.height_cm||0)) / 5000;\n      return s + vol;\n    }, 0);\n\n    ui().openModal(`SKU: ${p.name}`, `\n      <div style=\"display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px\">\n        <div><span class=\"ims__label\">SKU</span><div style=\"font-weight:700;font-size:18px\">${util().sanitize(p.sku || '\u2014')}</div></div>\n        <div><span class=\"ims__label\">Category</span><div>${util().sanitize(p.category || '\u2014')}</div></div>\n        <div><span class=\"ims__label\">Barcode</span><div>${util().sanitize(p.barcode || '\u2014')}</div></div>\n        <div><span class=\"ims__label\">Unit of measure</span><div>${util().sanitize(p.unit || 'each')}</div></div>\n        <div><span class=\"ims__label\">Reorder threshold</span><div>${p.reorder_threshold || 10} units</div></div>\n        <div><span class=\"ims__label\">Reorder quantity</span><div>${p.reorder_quantity || 50} units</div></div>\n        <div><span class=\"ims__label\">Default bin</span><div>${util().sanitize(p.default_bin || '\u2014')}</div></div>\n        <div><span class=\"ims__label\">Status</span><div><span class=\"ims__pill ims__pill--${p.is_active!==false?'success':'neutral'}\">${p.is_active!==false?'Active':'Inactive'}</span></div></div>\n        ${p.notes ? `<div style=\"grid-column:1/-1\"><span class=\"ims__label\">Notes</span><div>${util().sanitize(p.notes)}</div></div>` : ''}\n      </div>\n      <hr class=\"ims__divider\">\n      <strong style=\"font-size:13px\">Pricing</strong>\n      <div style=\"display:grid;grid-template-columns:repeat(${canSeeCost()?3:2},1fr);gap:8px;margin:8px 0\">\n        ${canSeeCost() ? `<div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Cost price</div><div class=\"ims__stat-value\" style=\"font-size:18px\">${cost!==null&&cost!==undefined?util().formatCurrency(cost):'<span style=\"color:var(--ims-warning);font-size:13px\">Not set</span>'}</div></div>` : ''}\n        <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Wholesale price</div><div class=\"ims__stat-value\" style=\"font-size:18px\">${wholesale!==null&&wholesale!==undefined?util().formatCurrency(wholesale):'<span style=\"color:var(--ims-warning);font-size:13px\">Not set</span>'}</div></div>\n        <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">RRP</div><div class=\"ims__stat-value\" style=\"font-size:18px\">${rrp!==null&&rrp!==undefined?util().formatCurrency(rrp):'<span style=\"color:var(--ims-warning);font-size:13px\">Not set</span>'}</div></div>\n      </div>\n      ${platPrices.length ? `\n        <strong style=\"font-size:13px;display:block;margin:10px 0 6px\">Platform-specific prices</strong>\n        <table class=\"ims__table\">\n          <thead><tr><th>Platform</th><th>Price</th></tr></thead>\n          <tbody>${platPrices.map(pp => `<tr><td>${util().sanitize(pp.platforms?.name||'\u2014')}</td><td>${util().formatCurrency(pp.price)}</td></tr>`).join('')}</tbody>\n        </table>` : ''}\n      <hr class=\"ims__divider\">\n      <strong style=\"font-size:13px\">Packaging</strong>\n      ${boxList.length ? `\n        <div style=\"display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:8px 0\">\n          <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Total boxes</div><div class=\"ims__stat-value\" style=\"font-size:22px\">${boxList.length}</div></div>\n          <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Total weight</div><div class=\"ims__stat-value\" style=\"font-size:22px\">${totalWeight.toFixed(1)} kg</div></div>\n          <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Vol. weight</div><div class=\"ims__stat-value\" style=\"font-size:18px\">${totalVol.toFixed(1)} kg</div></div>\n        </div>\n        <table class=\"ims__table\" style=\"margin-top:6px\">\n          <thead><tr><th>Box</th><th>Label</th><th>L \u00D7 W \u00D7 H (cm)</th><th>Weight (kg)</th><th>Vol. wt (kg)</th></tr></thead>\n          <tbody>${boxList.map(b => {\n            const vol = ((b.length_cm||0)*(b.width_cm||0)*(b.height_cm||0))/5000;\n            return `<tr>\n              <td style=\"font-weight:600\">Box ${b.box_number}</td>\n              <td>${util().sanitize(b.label||'\u2014')}</td>\n              <td>${b.length_cm||'?'} \u00D7 ${b.width_cm||'?'} \u00D7 ${b.height_cm||'?'}</td>\n              <td>${b.weight_kg||'\u2014'}</td>\n              <td style=\"color:var(--ims-text-muted)\">${vol>0?vol.toFixed(1):'\u2014'}</td>\n            </tr>`;\n          }).join('')}</tbody>\n        </table>` :\n        `<p style=\"font-size:12px;color:var(--ims-text-muted);margin-top:6px\">No packaging data \u2014 add box dimensions when editing this SKU</p>`}\n      <hr class=\"ims__divider\">\n      <strong style=\"font-size:13px\">Current stock</strong>\n      <div style=\"display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:8px 0\">\n        <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">On hand</div><div class=\"ims__stat-value\" style=\"font-size:22px\">${onHand}</div></div>\n        <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Reserved (orders)</div><div class=\"ims__stat-value\" style=\"font-size:22px\">${reserved}</div></div>\n        <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Allocated (dropship)</div><div class=\"ims__stat-value\" style=\"font-size:22px\">${allocated}</div></div>\n        <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Available</div><div class=\"ims__stat-value ims__stat-value--${(onHand-reserved-allocated)<0?'danger':''}\" style=\"font-size:22px\">${onHand-reserved-allocated}</div></div>\n      </div>\n      ${(stock||[]).length ? `\n        <table class=\"ims__table\" style=\"margin-top:6px\">\n          <thead><tr><th>Warehouse</th><th>Bin/shelf</th><th>Qty</th><th>Reserved</th><th>Allocated</th><th>Available</th></tr></thead>\n          <tbody>${(stock||[]).map(s => `<tr><td>${util().sanitize(s.warehouses?.name||'\u2014')}</td><td>${util().sanitize(s.bin_reference||'\u2014')}</td><td>${s.quantity||0}</td><td>${s.reserved_qty||0}</td><td>${s.reserved_by_allocations||0}</td><td style=\"font-weight:600;color:${((s.quantity||0)-(s.reserved_qty||0)-(s.reserved_by_allocations||0))<0?'var(--ims-danger)':''}\">${(s.quantity||0)-(s.reserved_qty||0)-(s.reserved_by_allocations||0)}</td></tr>`).join('')}</tbody>\n        </table>` : '<p style=\"font-size:12px;color:var(--ims-text-muted);margin-top:6px\">No stock yet \u2014 add stock via GRN, PO receiving or Stock Levels tab</p>'}\n    `, `\n      ${isAdmin() ? `<button class=\"ims__btn ims__btn--ghost\" onclick=\"window.IMS_INVENTORY.showSKUForm('${util().jsArg(p.id)}')\"><i class=\"ti ti-edit\"></i> Edit SKU</button>` : ''}\n      ${canSeeCost() ? `<button class=\"ims__btn ims__btn--ghost\" onclick=\"window.IMS_INVENTORY.managePlatformPrices('${util().jsArg(p.id)}','${util().jsArg(p.name)}')\"><i class=\"ti ti-apps\"></i> Platform prices</button>` : ''}\n      <button class=\"ims__btn ims__btn--secondary\" onclick=\"window.IMS_INVENTORY.switchToAddStock('${util().jsArg(p.id)}','${util().jsArg(p.name)}')\"><i class=\"ti ti-adjustments\"></i> Add / adjust stock</button>\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.SM.UI.closeModal()\">Close</button>\n    `, 'xl');\n  }\n\n  // \u2500\u2500\u2500 ADD / EDIT SKU FORM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // _skuBoxes holds the in-memory box list during the form session\n  let _skuBoxes = [];\n\n  async function showSKUForm(existingId = null) {\n    let p = null;\n    let prices = {};\n    _skuBoxes = [];\n\n    const {data:catData}=await db().select('products',{select:'category',order:{col:'category'}});\n    const existingCategories=[...new Set((catData||[]).map(p=>p.category).filter(Boolean))];\n\n    if (existingId) {\n      const { data } = await db().select('products', { eq: { id: existingId }, maybeSingle: true, noCompanyFilter: true });\n      p = data;\n      const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n      const { data: priceRows } = await client\n        .from('product_prices')\n        .select('price_type, price, platform_id')\n        .eq('product_id', existingId)\n        .is('platform_id', null);\n      (priceRows || []).forEach(pp => { prices[pp.price_type] = pp.price; });\n\n      // Load existing boxes\n      const { data: boxRows } = await client\n        .from('product_boxes')\n        .select('*')\n        .eq('product_id', existingId)\n        .order('box_number');\n      _skuBoxes = (boxRows || []).map(b => ({\n        id: b.id,\n        box_number: b.box_number,\n        label: b.label || '',\n        length_cm: b.length_cm || '',\n        width_cm: b.width_cm || '',\n        height_cm: b.height_cm || '',\n        weight_kg: b.weight_kg || ''\n      }));\n    }\n\n    const { data: whs } = await db().select('warehouses', { eq: { is_active: true } });\n    const whOpts = (whs||[]).map(w => `<option value=\"${w.id}\" ${p?.default_warehouse_id===w.id?'selected':''}>${util().sanitize(w.name)}</option>`).join('');\n\n    ui().openModal(existingId ? `Edit SKU: ${p?.name}` : 'Add new SKU \u2014 Product catalogue', `\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:12px\">\n        <i class=\"ti ti-info-circle\"></i>\n        <span>This adds the product to your <strong>catalogue only</strong>. Stock is managed separately via GRN, PO receiving, or the Stock Levels tab.</span>\n      </div>\n      <div class=\"ims__form-grid\">\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Product name</label><input class=\"ims__input\" type=\"text\" id=\"ims-sku-name\" value=\"${util().sanitize(p?.name||'')}\"></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">SKU code</label><input class=\"ims__input\" type=\"text\" id=\"ims-sku-code\" value=\"${util().sanitize(p?.sku||'')}\" placeholder=\"e.g. CHR-001\"></div>\n        <div class=\"ims__form-group\">\n          <label class=\"ims__label\">Category</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-sku-cat\" value=\"${util().sanitize(p?.category||'')}\"\n            placeholder=\"e.g. Recliner Sofa\" list=\"ims-sku-cat-list\" autocomplete=\"off\">\n          <datalist id=\"ims-sku-cat-list\">\n            ${existingCategories.map(cat=>`<option value=\"${util().sanitize(cat)}\">`).join('')}\n          </datalist>\n        </div>\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Barcode</label><input class=\"ims__input\" type=\"text\" id=\"ims-sku-barcode\" value=\"${util().sanitize(p?.barcode||'')}\"></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Unit of measure</label><input class=\"ims__input\" type=\"text\" id=\"ims-sku-unit\" value=\"${util().sanitize(p?.unit||'each')}\" placeholder=\"each, pair, box, set...\"></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Reorder threshold</label><input class=\"ims__input\" type=\"number\" id=\"ims-sku-threshold\" value=\"${p?.reorder_threshold!==undefined&&p?.reorder_threshold!==null?p.reorder_threshold:10}\"><span class=\"ims__input-hint\">Alert when stock falls below this</span></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Reorder quantity</label><input class=\"ims__input\" type=\"number\" id=\"ims-sku-reorder-qty\" value=\"${p?.reorder_quantity!==undefined&&p?.reorder_quantity!==null?p.reorder_quantity:50}\"><span class=\"ims__input-hint\">Suggested PO quantity</span></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Default bin / shelf</label><input class=\"ims__input\" type=\"text\" id=\"ims-sku-bin\" value=\"${util().sanitize(p?.default_bin||'')}\" placeholder=\"e.g. A-51\"></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Default warehouse</label><select class=\"ims__select\" id=\"ims-sku-warehouse\"><option value=\"\">None</option>${whOpts}</select></div>\n      </div>\n\n      <hr class=\"ims__divider\">\n      <strong style=\"font-size:13px\">Pricing</strong>\n      <div class=\"ims__form-grid\" style=\"margin-top:10px\">\n        ${canSeeCost() ? `<div class=\"ims__form-group\"><label class=\"ims__label\">Cost price (\u00A3)</label><input class=\"ims__input\" type=\"number\" step=\"0.01\" min=\"0\" id=\"ims-sku-cost\" value=\"${prices.cost??''}\"><span class=\"ims__input-hint\">Supplier invoice price \u2014 not shown to staff</span></div>` : ''}\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Wholesale price (\u00A3)</label><input class=\"ims__input\" type=\"number\" step=\"0.01\" min=\"0\" id=\"ims-sku-wholesale\" value=\"${prices.wholesale??''}\"></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">RRP / retail price (\u00A3)</label><input class=\"ims__input\" type=\"number\" step=\"0.01\" min=\"0\" id=\"ims-sku-rrp\" value=\"${prices.rrp??''}\"></div>\n      </div>\n      <div class=\"ims__form-group\" style=\"margin-top:10px\"><label class=\"ims__label\">Notes</label><textarea class=\"ims__textarea\" id=\"ims-sku-notes\" rows=\"2\">${util().sanitize(p?.notes||'')}</textarea></div>\n\n      <hr class=\"ims__divider\">\n      <div style=\"display:flex;justify-content:space-between;align-items:center;margin-bottom:10px\">\n        <div>\n          <strong style=\"font-size:13px\">Packaging / boxes</strong>\n          <div style=\"font-size:11px;color:var(--ims-text-muted);margin-top:2px\">One row per physical box. Used for courier labels, manifests and volumetric weight.</div>\n        </div>\n        <button class=\"ims__btn ims__btn--secondary ims__btn--sm\" type=\"button\" onclick=\"window.IMS_INVENTORY.addBoxRow()\"><i class=\"ti ti-plus\"></i> Add box</button>\n      </div>\n      <div id=\"ims-sku-boxes-wrap\">\n        ${_skuBoxes.length ? '' : `<div id=\"ims-sku-boxes-empty\" style=\"font-size:12px;color:var(--ims-text-muted);padding:10px 0\">No boxes defined yet \u2014 click <strong>Add box</strong> to start.</div>`}\n        <table class=\"ims__table\" id=\"ims-sku-boxes-table\" style=\"${_skuBoxes.length ? '' : 'display:none'}\">\n          <thead>\n            <tr>\n              <th style=\"width:60px\">Box #</th>\n              <th>Label <span style=\"font-weight:400;font-size:10px\">(e.g. Headboard, Frame)</span></th>\n              <th>L (cm)</th>\n              <th>W (cm)</th>\n              <th>H (cm)</th>\n              <th>Weight (kg)</th>\n              <th>Vol. wt</th>\n              <th></th>\n            </tr>\n          </thead>\n          <tbody id=\"ims-sku-boxes-tbody\">\n            ${_skuBoxes.map((b, i) => _renderBoxRow(i, b)).join('')}\n          </tbody>\n        </table>\n      </div>\n    `, `\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_INVENTORY.saveSKU('${util().jsArg(existingId||'')}')\"><i class=\"ti ti-check\"></i> ${existingId ? 'Save changes' : 'Add to catalogue'}</button>\n    `, 'lg');\n  }\n\n  function _renderBoxRow(i, b = {}) {\n    const vol = (parseFloat(b.length_cm)||0) * (parseFloat(b.width_cm)||0) * (parseFloat(b.height_cm)||0) / 5000;\n    return `<tr id=\"ims-box-row-${i}\">\n      <td style=\"font-weight:600;text-align:center\">${(b.box_number||i+1)}</td>\n      <td><input class=\"ims__input ims__input--sm\" type=\"text\" id=\"ims-box-label-${i}\" value=\"${util().sanitize(b.label||'')}\" placeholder=\"e.g. Headboard\"></td>\n      <td><input class=\"ims__input ims__input--sm\" type=\"number\" min=\"0\" step=\"0.1\" id=\"ims-box-l-${i}\" value=\"${b.length_cm||''}\" placeholder=\"0\" oninput=\"window.IMS_INVENTORY.updateVolWt(${i})\" style=\"width:70px\"></td>\n      <td><input class=\"ims__input ims__input--sm\" type=\"number\" min=\"0\" step=\"0.1\" id=\"ims-box-w-${i}\" value=\"${b.width_cm||''}\" placeholder=\"0\" oninput=\"window.IMS_INVENTORY.updateVolWt(${i})\" style=\"width:70px\"></td>\n      <td><input class=\"ims__input ims__input--sm\" type=\"number\" min=\"0\" step=\"0.1\" id=\"ims-box-h-${i}\" value=\"${b.height_cm||''}\" placeholder=\"0\" oninput=\"window.IMS_INVENTORY.updateVolWt(${i})\" style=\"width:70px\"></td>\n      <td><input class=\"ims__input ims__input--sm\" type=\"number\" min=\"0\" step=\"0.01\" id=\"ims-box-wt-${i}\" value=\"${b.weight_kg||''}\" placeholder=\"0\" style=\"width:80px\"></td>\n      <td id=\"ims-box-vol-${i}\" style=\"font-size:12px;color:var(--ims-text-muted);white-space:nowrap\">${vol > 0 ? vol.toFixed(2)+' kg' : '\u2014'}</td>\n      <td><button class=\"ims__btn ims__btn--danger ims__btn--sm ims__btn--icon\" type=\"button\" onclick=\"window.IMS_INVENTORY.removeBoxRow(${i})\" title=\"Remove box\"><i class=\"ti ti-trash\"></i></button></td>\n    </tr>`;\n  }\n\n  function addBoxRow() {\n    _skuBoxes.push({ box_number: _skuBoxes.length + 1, label: '', length_cm: '', width_cm: '', height_cm: '', weight_kg: '' });\n    const i = _skuBoxes.length - 1;\n    const tbody = document.getElementById('ims-sku-boxes-tbody');\n    const table = document.getElementById('ims-sku-boxes-table');\n    const empty = document.getElementById('ims-sku-boxes-empty');\n    if (empty) empty.style.display = 'none';\n    if (table) table.style.display = '';\n    if (tbody) tbody.insertAdjacentHTML('beforeend', _renderBoxRow(i, _skuBoxes[i]));\n  }\n\n  function removeBoxRow(i) {\n    _skuBoxes.splice(i, 1);\n    // Re-render the full table to keep indices in sync\n    const tbody = document.getElementById('ims-sku-boxes-tbody');\n    const table = document.getElementById('ims-sku-boxes-table');\n    const empty = document.getElementById('ims-sku-boxes-empty');\n    if (!_skuBoxes.length) {\n      if (table) table.style.display = 'none';\n      if (empty) empty.style.display = '';\n      if (tbody) tbody.innerHTML = '';\n      return;\n    }\n    if (tbody) tbody.innerHTML = _skuBoxes.map((b, idx) => _renderBoxRow(idx, b)).join('');\n  }\n\n  function updateVolWt(i) {\n    const l = parseFloat(document.getElementById(`ims-box-l-${i}`)?.value) || 0;\n    const w = parseFloat(document.getElementById(`ims-box-w-${i}`)?.value) || 0;\n    const h = parseFloat(document.getElementById(`ims-box-h-${i}`)?.value) || 0;\n    const vol = (l * w * h) / 5000;\n    const el = document.getElementById(`ims-box-vol-${i}`);\n    if (el) el.textContent = vol > 0 ? vol.toFixed(2) + ' kg' : '\u2014';\n  }\n\n  function _readBoxRows() {\n    return _skuBoxes.map((_, i) => ({\n      box_number: i + 1,\n      label: document.getElementById(`ims-box-label-${i}`)?.value?.trim() || null,\n      length_cm: parseFloat(document.getElementById(`ims-box-l-${i}`)?.value) || null,\n      width_cm:  parseFloat(document.getElementById(`ims-box-w-${i}`)?.value) || null,\n      height_cm: parseFloat(document.getElementById(`ims-box-h-${i}`)?.value) || null,\n      weight_kg: parseFloat(document.getElementById(`ims-box-wt-${i}`)?.value) || null,\n    }));\n  }\n\n  async function saveSKU(existingId) {\n    const g = id => document.getElementById(id)?.value?.trim() || '';\n    const name = g('ims-sku-name'), sku = g('ims-sku-code');\n    if (!name) { ui().toast('Product name is required', 'error'); return; }\n    if (!sku)  { ui().toast('SKU code is required', 'error'); return; }\n\n    const data = {\n      name, sku,\n      category:             g('ims-sku-cat') || null,\n      barcode:              g('ims-sku-barcode') || null,\n      unit:                 g('ims-sku-unit') || 'each',\n      reorder_threshold:    g('ims-sku-threshold')!=='' ? parseInt(g('ims-sku-threshold')) : 10,\n      reorder_quantity:     g('ims-sku-reorder-qty')!=='' ? parseInt(g('ims-sku-reorder-qty')) : 50,\n      default_bin:          g('ims-sku-bin') || null,\n      default_warehouse_id: g('ims-sku-warehouse') || null,\n      notes:                g('ims-sku-notes') || null,\n      updated_at:           new Date().toISOString()\n    };\n\n    let productId;\n    if (existingId) {\n      const { error } = await db().update('products', existingId, data);\n      if (error) { ui().toast('Failed: ' + error.message, 'error'); return; }\n      productId = existingId;\n    } else {\n      const { data: created, error } = await db().insert('products', data);\n      if (error) { ui().toast('Failed: ' + error.message, 'error'); return; }\n      productId = created.id;\n    }\n\n    // Save prices\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const priceFields = [\n      canSeeCost() ? { type: 'cost', id: 'ims-sku-cost' } : null,\n      { type: 'wholesale', id: 'ims-sku-wholesale' },\n      { type: 'rrp',       id: 'ims-sku-rrp'       }\n    ].filter(Boolean);\n\n    await Promise.all(priceFields.map(async ({ type, id }) => {\n      const fieldEl = document.getElementById(id);\n      if (!fieldEl) return;\n      const rawVal = fieldEl.value.trim();\n      await client.from('product_prices')\n        .delete()\n        .eq('product_id', productId)\n        .eq('price_type', type)\n        .is('platform_id', null);\n      if (rawVal === '') return;\n      const val = parseFloat(rawVal);\n      if (isNaN(val)) return;\n      await client.from('product_prices')\n        .insert({ product_id: productId, price_type: type, platform_id: null, price: val });\n    }));\n\n    // Save boxes \u2014 delete all existing, re-insert from form\n    await client.from('product_boxes').delete().eq('product_id', productId);\n    const boxRows = _readBoxRows();\n    if (boxRows.length) {\n      await client.from('product_boxes').insert(\n        boxRows.map(b => ({ ...b, product_id: productId }))\n      );\n    }\n\n    ui().closeModal();\n    ui().toast(`${existingId ? 'SKU updated' : `\"${name}\" added to catalogue`}`, 'success');\n    loadCatalogueData();\n  }\n\n  // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n  // TAB 2 \u2014 STOCK LEVELS\n  // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n  async function loadStock() {\n    const content = document.getElementById('ims-inv-content');\n    if (!content) return;\n\n    const actions = document.getElementById('ims-inv-actions');\n    if (actions) {\n      actions.innerHTML = `\n        <button class=\"ims__btn ims__btn--secondary\" id=\"ims-stock-import-btn\"><i class=\"ti ti-upload\"></i> Bulk import stock</button>\n        <button class=\"ims__btn ims__btn--primary\" id=\"ims-stock-add-btn\"><i class=\"ti ti-plus\"></i> Add stock</button>`;\n      document.getElementById('ims-stock-add-btn')?.addEventListener('click', () => showAddStockForm());\n      document.getElementById('ims-stock-import-btn')?.addEventListener('click', () => showBulkStockImport());\n    }\n\n    content.innerHTML = `\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:14px\">\n        <i class=\"ti ti-info-circle\"></i>\n        <span><strong>Stock Levels</strong> \u2014 Live inventory quantities per product and warehouse. Stock is added automatically via GRN and PO receiving. Use <strong>Add stock</strong> for opening stock or manual corrections only.</span>\n      </div>\n      <div class=\"ims__filters\">\n        <div class=\"ims__search-wrap\"><i class=\"ti ti-search\"></i><input class=\"ims__input\" type=\"text\" id=\"ims-stk-search\" placeholder=\"Product name or SKU...\"></div>\n        <select class=\"ims__select\" id=\"ims-stk-warehouse\"><option value=\"\">All warehouses</option></select>\n        <select class=\"ims__select\" id=\"ims-stk-filter\">\n          <option value=\"\">All stock</option>\n          <option value=\"over\">Over-promised</option>\n          <option value=\"low\">Low stock</option>\n          <option value=\"out\">Out of stock</option>\n          <option value=\"ok\">In stock</option>\n        </select>\n      </div>\n      <div class=\"ims__card\">\n        <div class=\"ims__table-wrap\">\n          <table class=\"ims__table\">\n            <thead><tr>\n              <th>SKU</th><th>Product</th><th>Warehouse</th><th>Bin / shelf</th>\n              <th>On hand</th><th>Reserved</th><th>Available</th><th>Status</th><th></th>\n            </tr></thead>\n            <tbody id=\"ims-stk-tbody\"><tr><td colspan=\"9\" class=\"ims__table-empty\"><i class=\"ti ti-loader-2 ims__spin\"></i></td></tr></tbody>\n          </table>\n        </div>\n      </div>`;\n\n    const { data: whs } = await db().select('warehouses', { eq: { is_active: true } });\n    const whSel = document.getElementById('ims-stk-warehouse');\n    if (whSel) {\n      whSel.innerHTML = '<option value=\"\">All warehouses</option>';\n      (whs||[]).forEach(w => { const o = document.createElement('option'); o.value = w.id; o.textContent = w.name; whSel.appendChild(o); });\n    }\n\n    document.getElementById('ims-stk-search')?.addEventListener('input', util().debounce(loadStockData, 350));\n    document.getElementById('ims-stk-warehouse')?.addEventListener('change', loadStockData);\n    document.getElementById('ims-stk-filter')?.addEventListener('change', loadStockData);\n\n    await loadStockData();\n  }\n\n  // One rule for the Status pill and the stock filter, based on what is\n  // actually free to sell (on hand, minus reserved, minus what is held for\n  // dropship partners). Before, both looked at on hand alone, so stock\n  // fully promised to a partner, or even over-promised, still showed \"OK\".\n  function _stockStatus(s) {\n    const qty = s.quantity || 0;\n    const avail = qty - (s.reserved_qty || 0) - (s.reserved_by_allocations || 0);\n    const threshold = s.products?.reorder_threshold || 10;\n    if (qty <= 0)           return { key: 'out',  label: 'Out of stock',  pill: 'danger',  avail };\n    if (avail < 0)          return { key: 'over', label: 'Over-promised', pill: 'danger',  avail };\n    if (avail === 0)        return { key: 'low',  label: 'All reserved',  pill: 'warning', avail };\n    if (avail <= threshold) return { key: 'low',  label: 'Low stock',     pill: 'warning', avail };\n    return { key: 'ok', label: 'OK', pill: 'success', avail };\n  }\n\n  async function loadStockData() {\n    const tbody = document.getElementById('ims-stk-tbody');\n    if (!tbody) return;\n\n    const search     = document.getElementById('ims-stk-search')?.value?.trim().toLowerCase() || '';\n    const warehouseF = document.getElementById('ims-stk-warehouse')?.value || '';\n    const stockF     = document.getElementById('ims-stk-filter')?.value || '';\n\n    const opts = {\n      select: 'quantity,reserved_qty,reserved_by_allocations,bin_reference,warehouse_id,product_id,warehouses(name),products(id,name,sku,reorder_threshold)',\n      noCompanyFilter: true,\n      order: { col: 'quantity' }\n    };\n    if (warehouseF) opts.eq = { warehouse_id: warehouseF };\n\n    const { data: stock } = await db().select('stock_levels', opts);\n    const { data: companyProducts } = await db().select('products', { select: 'id' });\n    const myProductIds = new Set((companyProducts||[]).map(p => p.id));\n    let items = (stock||[]).filter(s => s.products && myProductIds.has(s.product_id));\n\n    if (search) items = items.filter(s => s.products?.name?.toLowerCase().includes(search) || s.products?.sku?.toLowerCase().includes(search));\n    if (stockF) items = items.filter(s => _stockStatus(s).key === stockF);\n\n    if (!items.length) {\n      tbody.innerHTML = `<tr><td colspan=\"9\" class=\"ims__table-empty\">${stockF||search ? 'No products match your filter' : 'No stock records yet \u2014 stock is added via GRN, PO receiving, or the Add stock button'}</td></tr>`;\n      return;\n    }\n\n    // Partner names for the \"held for\" note in the Reserved column, from\n    // allocations that still have units remaining. DB.select has no\n    // \"greater than\" filter, so empty allocations are dropped here.\n    const { data: allocRows } = await db().select('dropship_allocations', {\n      select: 'product_id,warehouse_id,remaining_qty,dropship_customers(business_name)', noCompanyFilter: true\n    });\n    const holderSets = {};\n    (allocRows || []).filter(a => (a.remaining_qty || 0) > 0).forEach(a => {\n      const key = `${a.product_id}|${a.warehouse_id}`;\n      if (!holderSets[key]) holderSets[key] = new Set();\n      if (a.dropship_customers?.business_name) holderSets[key].add(a.dropship_customers.business_name);\n    });\n    const heldBy = {};\n    Object.entries(holderSets).forEach(([key, set]) => { if (set.size) heldBy[key] = [...set].join(', '); });\n\n    tbody.innerHTML = items.map(s => {\n      const status = _stockStatus(s);\n      const avail = status.avail;\n      const st = status.pill;\n      const stLabel = status.label;\n      return `<tr>\n        <td>${util().sanitize(s.products?.sku||'\u2014')}</td>\n        <td><span class=\"ims__link\" onclick=\"window.IMS_INVENTORY.openSKU('${util().jsArg(s.product_id)}')\">${util().sanitize(s.products?.name||'\u2014')}</span></td>\n        <td>${util().sanitize(s.warehouses?.name||'\u2014')}</td>\n        <td>${util().sanitize(s.bin_reference||'\u2014')}</td>\n        <td style=\"font-weight:600\">${s.quantity||0}</td>\n        <td>${s.reserved_qty||0}${s.reserved_by_allocations?` <span style=\"color:var(--ims-text-muted);font-size:10px\">(+${s.reserved_by_allocations} ${util().sanitize(heldBy[`${s.product_id}|${s.warehouse_id}`]||'alloc.')})</span>`:''}</td>\n        <td style=\"font-weight:600;color:${avail<0?'var(--ims-danger)':''}\">${avail}</td>\n        <td><span class=\"ims__pill ims__pill--${st}\">${stLabel}</span></td>\n        <td>\n          <div class=\"ims__btn-group\">\n            <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_INVENTORY.showAdjustStock('${util().jsArg(s.product_id)}','${util().jsArg(s.products?.name||'')}','${util().jsArg(s.warehouse_id)}')\" title=\"Adjust stock\"><i class=\"ti ti-adjustments\"></i></button>\n          </div>\n        </td>\n      </tr>`;\n    }).join('');\n  }\n\n  // \u2500\u2500\u2500 ADD STOCK FORM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  async function showAddStockForm(preselectedProductId = null, preselectedName = '') {\n    const { data: products } = await db().select('products', { eq: { is_active: true }, order: { col: 'name' }, select: 'id,name,sku' });\n    const { data: whs } = await db().select('warehouses', { eq: { is_active: true } });\n\n    const prodOpts = (products||[]).map(p =>\n      `<option value=\"${p.id}\" ${p.id===preselectedProductId?'selected':''}>${util().sanitize(p.name)} (${p.sku})</option>`\n    ).join('');\n    const whOpts = (whs||[]).map(w => `<option value=\"${w.id}\">${util().sanitize(w.name)}</option>`).join('');\n\n    if (!products?.length) {\n      ui().toast('Add products to the catalogue first before adding stock', 'warning', 5000);\n      return;\n    }\n\n    ui().openModal('Add stock \u2014 select from catalogue', `\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:12px\">\n        <i class=\"ti ti-info-circle\"></i>\n        <span>Use this for <strong>opening stock entry</strong> or <strong>manual corrections</strong> only. Stock should normally arrive through GRN or PO receiving.</span>\n      </div>\n      <div class=\"ims__form-grid\">\n        <div class=\"ims__form-group ims__form-group--full\">\n          <label class=\"ims__label ims__label--req\">Product</label>\n          <select class=\"ims__select\" id=\"ims-as-product\" onchange=\"window.IMS_INVENTORY.onProductSelected()\">\n            <option value=\"\">Select product from catalogue...</option>${prodOpts}\n          </select>\n        </div>\n        <div class=\"ims__form-group\" id=\"ims-as-bin-group\" style=\"display:none\">\n          <label class=\"ims__label\">Current default bin</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-as-default-bin\" readonly style=\"background:var(--ims-surface2)\">\n        </div>\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Warehouse</label>\n          <select class=\"ims__select\" id=\"ims-as-warehouse\"><option value=\"\">Select warehouse</option>${whOpts}</select></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Quantity to add</label>\n          <input class=\"ims__input\" type=\"number\" min=\"1\" id=\"ims-as-qty\" placeholder=\"Enter quantity\"></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Bin / shelf reference</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-as-bin\" placeholder=\"e.g. A-51 (leave blank to use default)\"></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Reason</label>\n          <select class=\"ims__select\" id=\"ims-as-reason\">\n            <option value=\"Opening stock\">Opening stock entry</option>\n            <option value=\"Stock correction\">Stock correction (count discrepancy)</option>\n            <option value=\"Sample stock\">Sample / display stock</option>\n            <option value=\"Returned to stock\">Customer return restocked</option>\n            <option value=\"Other\">Other</option>\n          </select></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Reference</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-as-ref\" placeholder=\"e.g. opening stock, correction ref...\"></div>\n      </div>\n    `, `\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_INVENTORY.saveAddStock()\"><i class=\"ti ti-check\"></i> Add to stock</button>\n    `, 'sm');\n  }\n\n  async function onProductSelected() {\n    const productId = document.getElementById('ims-as-product')?.value;\n    if (!productId) return;\n    const { data: p } = await db().select('products', { eq: { id: productId }, maybeSingle: true, noCompanyFilter: true });\n    if (!p) return;\n    const binGroup = document.getElementById('ims-as-bin-group');\n    const binEl    = document.getElementById('ims-as-default-bin');\n    if (binEl && p.default_bin) {\n      binEl.value = p.default_bin;\n      if (binGroup) binGroup.style.display = '';\n      const binInput = document.getElementById('ims-as-bin');\n      if (binInput && !binInput.value) binInput.value = p.default_bin;\n    } else {\n      if (binGroup) binGroup.style.display = 'none';\n    }\n  }\n\n  async function saveAddStock() {\n    const productId   = document.getElementById('ims-as-product')?.value;\n    const warehouseId = document.getElementById('ims-as-warehouse')?.value;\n    const qty         = parseInt(document.getElementById('ims-as-qty')?.value) || 0;\n    const bin         = document.getElementById('ims-as-bin')?.value?.trim();\n    const reason      = document.getElementById('ims-as-reason')?.value;\n    const ref         = document.getElementById('ims-as-ref')?.value?.trim();\n\n    if (!productId)   { ui().toast('Please select a product', 'error'); return; }\n    if (!warehouseId) { ui().toast('Please select a warehouse', 'error'); return; }\n    if (qty <= 0)     { ui().toast('Please enter a quantity greater than 0', 'error'); return; }\n\n    const { data: existing } = await db().select('stock_levels', {\n      eq: { product_id: productId, warehouse_id: warehouseId },\n      maybeSingle: true, noCompanyFilter: true\n    });\n\n    if (existing) {\n      await db().update('stock_levels', existing.id, {\n        quantity:      (existing.quantity||0) + qty,\n        bin_reference: bin || existing.bin_reference,\n        last_updated:  new Date().toISOString()\n      });\n    } else {\n      await db().insert('stock_levels', {\n        product_id:    productId,\n        warehouse_id:  warehouseId,\n        quantity:      qty,\n        reserved_qty:  0,\n        bin_reference: bin || null\n      });\n    }\n\n    await db().insert('stock_movements', {\n      product_id:    productId,\n      warehouse_id:  warehouseId,\n      movement_type: 'stock_in',\n      quantity:      qty,\n      reference:     ref || null,\n      reason,\n      user_id:       window.SM.AUTH.user?.id\n    });\n\n    ui().closeModal();\n    ui().toast(`${qty} units added to stock`, 'success');\n    loadStockData();\n  }\n\n  function switchToAddStock(productId, productName) {\n    ui().closeModal();\n    const tabs = document.getElementById('ims-inv-tabs');\n    tabs?.querySelectorAll('.ims__tab').forEach(t => t.classList.remove('ims__tab--active'));\n    tabs?.querySelector('[data-tab=\"stock\"]')?.classList.add('ims__tab--active');\n    _activeTab = 'stock';\n    loadStock().then(() => {\n      setTimeout(() => showAddStockForm(productId, productName), 300);\n    });\n  }\n\n  // \u2500\u2500\u2500 STOCK ADJUSTMENT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  async function showAdjustStock(productId, productName, warehouseId){\n    const {data:sl}=await db().select('stock_levels',{eq:{product_id:productId,warehouse_id:warehouseId},maybeSingle:true,noCompanyFilter:true});\n    const current=sl?.quantity||0;\n    const currentBin=sl?.bin_reference||'\u2014';\n\n    ui().openModal(`Adjust stock: ${productName}`,`\n      <div style=\"margin-bottom:14px;padding:12px;background:var(--ims-surface2);border-radius:var(--ims-radius)\">\n        <span class=\"ims__label\">Current stock</span>\n        <div style=\"font-size:28px;font-weight:700\">${current} units</div>\n        <div style=\"font-size:12px;color:var(--ims-text-muted);margin-top:2px\">Current location: <strong>${util().sanitize(currentBin)}</strong></div>\n      </div>\n      <div class=\"ims__form-grid\">\n        <div class=\"ims__form-group ims__form-group--full\">\n          <label class=\"ims__label ims__label--req\">Adjustment type</label>\n          <select class=\"ims__select\" id=\"ims-adj-type\" onchange=\"window.IMS_INVENTORY.onAdjTypeChange()\">\n            <option value=\"stock_in\">Add stock (+)</option>\n            <option value=\"stock_out\">Remove stock (\u2212)</option>\n            <option value=\"adjustment\">Set exact quantity</option>\n            <option value=\"move\">Move to new location</option>\n          </select>\n        </div>\n      </div>\n\n      <!-- Standard adjustment fields -->\n      <div id=\"ims-adj-standard\" class=\"ims__form-grid\" style=\"margin-top:8px\">\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Quantity</label>\n          <input class=\"ims__input\" type=\"number\" min=\"0\" id=\"ims-adj-qty\" placeholder=\"Enter quantity\"></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label\">New bin reference</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-adj-bin\" value=\"${util().sanitize(sl?.bin_reference||'')}\" placeholder=\"Leave blank to keep current\"></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Reference</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-adj-ref\" placeholder=\"e.g. cycle count, correction...\"></div>\n        <div class=\"ims__form-group ims__form-group--full\"><label class=\"ims__label ims__label--req\">Reason</label>\n          <textarea class=\"ims__textarea\" id=\"ims-adj-reason\" rows=\"2\" placeholder=\"Explain reason for this adjustment\"></textarea></div>\n      </div>\n\n      <!-- Move to new location fields -->\n      <div id=\"ims-adj-move\" class=\"ims__form-grid\" style=\"margin-top:8px;display:none\">\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Quantity to move</label>\n          <input class=\"ims__input\" type=\"number\" min=\"1\" max=\"${current}\" id=\"ims-adj-move-qty\" placeholder=\"How many units to move\"></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label\">From location</label>\n          <input class=\"ims__input\" type=\"text\" value=\"${util().sanitize(currentBin)}\" readonly style=\"background:var(--ims-surface2)\"></div>\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">To location (new bin)</label>\n          <input class=\"ims__input\" type=\"text\" id=\"ims-adj-move-bin\" placeholder=\"e.g. B-12\"></div>\n        <div class=\"ims__form-group ims__form-group--full\"><label class=\"ims__label ims__label--req\">Reason</label>\n          <textarea class=\"ims__textarea\" id=\"ims-adj-move-reason\" rows=\"2\" placeholder=\"e.g. Reorganised storage, overflow to new bay\"></textarea></div>\n      </div>\n    `,`\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_INVENTORY.saveAdjustment('${util().jsArg(productId)}','${util().jsArg(warehouseId)}',${current})\"><i class=\"ti ti-check\"></i> Save</button>\n    `,'sm');\n  }\n\n  function onAdjTypeChange(){\n    const type=document.getElementById('ims-adj-type')?.value;\n    const standard=document.getElementById('ims-adj-standard');\n    const move=document.getElementById('ims-adj-move');\n    if(standard) standard.style.display=type==='move'?'none':'grid';\n    if(move)     move.style.display=type==='move'?'grid':'none';\n  }\n\n  async function saveAdjustment(productId, warehouseId, current){\n    const type=document.getElementById('ims-adj-type')?.value;\n\n    // \u2500\u2500 MOVE TO NEW LOCATION \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    if(type==='move'){\n      const moveQty=parseInt(document.getElementById('ims-adj-move-qty')?.value)||0;\n      const moveBin=document.getElementById('ims-adj-move-bin')?.value?.trim();\n      const reason=document.getElementById('ims-adj-move-reason')?.value?.trim();\n      if(!moveQty||moveQty<=0){ui().toast('Enter a quantity to move','error');return;}\n      if(moveQty>current){ui().toast(`Cannot move more than current stock (${current})`,'error');return;}\n      if(!moveBin){ui().toast('Enter the destination bin location','error');return;}\n      if(!reason){ui().toast('Please enter a reason','error');return;}\n\n      // Reduce from current row\n      const {data:existing}=await db().select('stock_levels',{eq:{product_id:productId,warehouse_id:warehouseId},maybeSingle:true,noCompanyFilter:true});\n      if(existing){\n        await db().update('stock_levels',existing.id,{quantity:current-moveQty,last_updated:new Date().toISOString()});\n      }\n\n      // Add to destination bin \u2014 check if a row already exists for that bin\n      const {data:destRow}=await db().select('stock_levels',{\n        select:'id,quantity',\n        eq:{product_id:productId,warehouse_id:warehouseId,bin_reference:moveBin},\n        maybeSingle:true,noCompanyFilter:true\n      });\n\n      if(destRow){\n        await db().update('stock_levels',destRow.id,{quantity:(destRow.quantity||0)+moveQty,last_updated:new Date().toISOString()});\n      } else {\n        await db().insert('stock_levels',{product_id:productId,warehouse_id:warehouseId,quantity:moveQty,reserved_qty:0,bin_reference:moveBin,company_id:window.SM.AUTH.company?.id});\n      }\n\n      // Log two movements: out from old bin, in to new bin\n      await db().insert('stock_movements',{product_id:productId,warehouse_id:warehouseId,movement_type:'stock_out',quantity:-moveQty,reason:`Location move: to ${moveBin} \u2014 ${reason}`,user_id:window.SM.AUTH.user?.id});\n      await db().insert('stock_movements',{product_id:productId,warehouse_id:warehouseId,movement_type:'stock_in',quantity:moveQty,reason:`Location move: from existing bin \u2014 ${reason}`,reference:moveBin,user_id:window.SM.AUTH.user?.id});\n\n      ui().closeModal();\n      ui().toast(`${moveQty} units moved to ${moveBin}`,'success');\n      loadStockData();\n      return;\n    }\n\n    // \u2500\u2500 STANDARD ADJUSTMENT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    const qty=parseInt(document.getElementById('ims-adj-qty')?.value);\n    const bin=document.getElementById('ims-adj-bin')?.value?.trim();\n    const ref=document.getElementById('ims-adj-ref')?.value?.trim();\n    const reason=document.getElementById('ims-adj-reason')?.value?.trim();\n    if(isNaN(qty)||qty<0){ui().toast('Please enter a valid quantity','error');return;}\n    if(!reason){ui().toast('Please enter a reason','error');return;}\n\n    let newQty,movement;\n    if(type==='adjustment'){newQty=qty;movement=qty-current;}\n    else if(type==='stock_in'){newQty=current+qty;movement=qty;}\n    else{newQty=Math.max(0,current-qty);movement=-(Math.min(qty,current));}\n\n    const {data:existing}=await db().select('stock_levels',{eq:{product_id:productId,warehouse_id:warehouseId},maybeSingle:true,noCompanyFilter:true});\n    if(existing){\n      await db().update('stock_levels',existing.id,{quantity:newQty,bin_reference:bin||existing.bin_reference,last_updated:new Date().toISOString()});\n    } else {\n      await db().insert('stock_levels',{product_id:productId,warehouse_id:warehouseId,quantity:newQty,reserved_qty:0,bin_reference:bin||null});\n    }\n\n    await db().insert('stock_movements',{product_id:productId,warehouse_id:warehouseId,movement_type:type,quantity:movement,reference:ref||null,reason,user_id:window.SM.AUTH.user?.id});\n\n    ui().closeModal();\n    ui().toast(`Stock adjusted \u2014 new quantity: ${newQty}`,'success');\n    loadStockData();\n  }\n\n  // \u2500\u2500\u2500 BULK OPENING STOCK IMPORT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  function showBulkStockImport() {\n    ui().openModal('Bulk import opening stock', `\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:12px\">\n        <i class=\"ti ti-info-circle\"></i>\n        <span>Use this to upload opening stock quantities in bulk. Download the template, fill in quantities for each product, and upload. <strong>This adds to existing stock \u2014 it does not overwrite.</strong></span>\n      </div>\n      <div class=\"ims__btn-group\" style=\"margin-bottom:14px\">\n        <button class=\"ims__btn ims__btn--secondary\" onclick=\"window.IMS_INVENTORY.downloadStockTemplate()\"><i class=\"ti ti-download\"></i> Download stock template</button>\n      </div>\n      <div class=\"ims__form-group\">\n        <label class=\"ims__label ims__label--req\">Select warehouse</label>\n        <select class=\"ims__select\" id=\"ims-bulk-wh-sel\"><option value=\"\">Loading warehouses...</option></select>\n      </div>\n      <div class=\"ims__form-group\">\n        <label class=\"ims__label\">Select CSV file</label>\n        <input type=\"file\" accept=\".csv\" id=\"ims-bulk-stock-file\" class=\"ims__input\"\n          onchange=\"window.IMS_INVENTORY.previewBulkStock(this)\">\n      </div>\n      <div id=\"ims-bulk-stock-preview\"></div>\n    `, `\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\n      <button class=\"ims__btn ims__btn--primary\" id=\"ims-bulk-stock-commit\" style=\"display:none\"\n        onclick=\"window.IMS_INVENTORY.commitBulkStock()\"><i class=\"ti ti-check\"></i> Import stock</button>\n    `, 'lg');\n\n    db().select('warehouses', { eq: { is_active: true } }).then(({ data: whs }) => {\n      const sel = document.getElementById('ims-bulk-wh-sel');\n      if (!sel) return;\n      sel.innerHTML = '<option value=\"\">Select warehouse...</option>' +\n        (whs||[]).map(w => `<option value=\"${w.id}\">${util().sanitize(w.name)}</option>`).join('');\n    });\n  }\n\n  async function downloadStockTemplate() {\n    const { data: products } = await db().select('products', { select: 'sku,name,category,default_bin', order: { col: 'name' } });\n    const headers = ['SKU', 'Product Name', 'Category', 'Default Bin', 'Quantity', 'Bin Reference (leave blank to use default)'];\n    const rows = (products||[]).map(p => [p.sku, p.name, p.category||'', p.default_bin||'', '0', '']);\n    if (!rows.length) { ui().toast('Add products to the catalogue first', 'warning'); return; }\n    util().exportCSV(headers, rows, 'opening_stock_template');\n    ui().toast(`Template downloaded with ${rows.length} products`, 'success');\n  }\n\n  let _bulkStockRows = [];\n\n  async function previewBulkStock(input) {\n    const file = input.files?.[0];\n    if (!file) return;\n    const text = await file.text();\n    const { headers, rows } = util().parseCSV(text);\n    const preview = document.getElementById('ims-bulk-stock-preview');\n    const commitBtn = document.getElementById('ims-bulk-stock-commit');\n\n    const { data: products } = await db().select('products', { select: 'id,sku,name' });\n    const skuMap = {};\n    (products||[]).forEach(p => { skuMap[p.sku.toUpperCase()] = p; });\n\n    _bulkStockRows = rows.map(row => {\n      const get = col => { const i = headers.indexOf(col); return i >= 0 ? row[i]||'' : ''; };\n      const sku = get('SKU').toUpperCase();\n      const qty = parseInt(get('Quantity')) || 0;\n      const bin = get('Bin Reference (leave blank to use default)') || get('Default Bin') || '';\n      const product = skuMap[sku];\n      return {\n        sku,\n        name: get('Product Name') || product?.name || '\u2014',\n        productId: product?.id || null,\n        qty,\n        bin: bin || product?.default_bin || '',\n        valid: !!product && qty > 0\n      };\n    }).filter(r => r.sku);\n\n    const valid   = _bulkStockRows.filter(r => r.valid).length;\n    const skipped = _bulkStockRows.filter(r => !r.productId).length;\n    const zeroQty = _bulkStockRows.filter(r => r.productId && r.qty === 0).length;\n\n    if (preview) preview.innerHTML = `\n      <div class=\"ims__alert ims__alert--${valid>0?'success':'warning'}\" style=\"margin-top:12px\">\n        <i class=\"ti ti-${valid>0?'check':'alert-triangle'}\"></i>\n        <span><strong>${valid} products</strong> will have stock added &nbsp;|&nbsp; ${zeroQty} skipped (zero qty) &nbsp;|&nbsp; ${skipped} SKUs not found</span>\n      </div>\n      <div class=\"ims__table-wrap\" style=\"max-height:220px;overflow-y:auto;margin-top:8px\">\n        <table class=\"ims__table\">\n          <thead><tr><th>SKU</th><th>Product</th><th>Qty</th><th>Bin</th><th>Status</th></tr></thead>\n          <tbody>${_bulkStockRows.slice(0,15).map(r=>`<tr>\n            <td>${util().sanitize(r.sku)}</td><td>${util().sanitize(r.name)}</td>\n            <td style=\"font-weight:600\">${r.qty}</td><td>${util().sanitize(r.bin||'\u2014')}</td>\n            <td>${r.valid?'<span class=\"ims__pill ims__pill--success\">\u2713 Will import</span>':r.productId?'<span class=\"ims__pill ims__pill--neutral\">Zero qty</span>':'<span class=\"ims__pill ims__pill--danger\">SKU not found</span>'}</td>\n          </tr>`).join('')}\n          ${_bulkStockRows.length>15?`<tr><td colspan=\"5\" class=\"ims__table-empty\">...and ${_bulkStockRows.length-15} more rows</td></tr>`:''}\n          </tbody>\n        </table>\n      </div>`;\n\n    if (commitBtn) commitBtn.style.display = valid > 0 ? 'inline-flex' : 'none';\n  }\n\n  async function commitBulkStock() {\n    const warehouseId = document.getElementById('ims-bulk-wh-sel')?.value;\n    if (!warehouseId) { ui().toast('Please select a warehouse', 'error'); return; }\n    const valid = _bulkStockRows.filter(r => r.valid);\n    if (!valid.length) { ui().toast('No valid rows to import', 'error'); return; }\n    const commitBtn = document.getElementById('ims-bulk-stock-commit');\n    if (commitBtn) { commitBtn.disabled = true; commitBtn.innerHTML = '<i class=\"ti ti-loader-2 ims__spin\"></i> Importing...'; }\n    const preview = document.getElementById('ims-bulk-stock-preview');\n    const total = valid.length;\n    if (preview) preview.innerHTML += `<div style=\"margin-top:12px\"><div style=\"display:flex;justify-content:space-between;font-size:12px;margin-bottom:4px\"><span id=\"ims-stk-progress-label\">Starting...</span><span id=\"ims-stk-progress-pct\">0%</span></div><div style=\"background:var(--ims-border);border-radius:999px;height:8px;overflow:hidden\"><div id=\"ims-stk-progress-bar\" style=\"height:100%;background:var(--ims-primary);width:0%;transition:width 0.2s;border-radius:999px\"></div></div></div>`;\n    let imported = 0;\n    for (let i = 0; i < valid.length; i++) {\n      const row = valid[i];\n      const pct = Math.round(((i+1)/total)*100);\n      document.getElementById('ims-stk-progress-label')?.setAttribute('textContent', `Importing ${i+1} of ${total}: ${row.name}`);\n      const pctEl = document.getElementById('ims-stk-progress-pct'); if (pctEl) pctEl.textContent = pct+'%';\n      const bar = document.getElementById('ims-stk-progress-bar'); if (bar) bar.style.width = pct+'%';\n      const { data: existing } = await db().select('stock_levels', { eq: { product_id: row.productId, warehouse_id: warehouseId }, maybeSingle: true, noCompanyFilter: true });\n      if (existing) {\n        await db().update('stock_levels', existing.id, { quantity: (existing.quantity||0)+row.qty, bin_reference: row.bin||existing.bin_reference, last_updated: new Date().toISOString() });\n      } else {\n        await db().insert('stock_levels', { product_id: row.productId, warehouse_id: warehouseId, quantity: row.qty, reserved_qty: 0, bin_reference: row.bin||null });\n      }\n      await db().insert('stock_movements', { product_id: row.productId, warehouse_id: warehouseId, movement_type: 'stock_in', quantity: row.qty, reference: 'Bulk opening stock import', reason: 'Opening stock entry', user_id: window.SM.AUTH.user?.id });\n      imported++;\n    }\n    ui().closeModal();\n    ui().toast(`Opening stock imported \u2014 ${imported} products updated`, 'success', 5000);\n    _bulkStockRows = [];\n    loadStockData();\n  }\n\n  // \u2500\u2500\u2500 PLATFORM PRICES \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  async function managePlatformPrices(productId, productName) {\n    const companyId = window.SM.AUTH.company?.id;\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const [{ data: sys }, { data: custom }] = await Promise.all([\n      client.from('platforms').select('id,name,order_type').is('company_id', null).eq('is_active', true).order('sort_order'),\n      client.from('platforms').select('id,name,order_type').eq('company_id', companyId).eq('is_active', true).order('name')\n    ]);\n    const platforms = [...(sys||[]), ...(custom||[])];\n    const { data: existing } = await client.from('product_prices').select('*').eq('product_id', productId).eq('price_type', 'platform');\n    const priceMap = {};\n    (existing||[]).forEach(p => { priceMap[p.platform_id] = p.price; });\n\n    ui().openModal(`Platform prices: ${productName}`, `\n      <p style=\"font-size:12px;color:var(--ims-text-muted);margin-bottom:14px\">Set a specific price for each platform. Leave blank to use the default wholesale or RRP.</p>\n      <div class=\"ims__table-wrap\">\n        <table class=\"ims__table\">\n          <thead><tr><th>Platform</th><th>Type</th><th>Price (\u00A3)</th><th>Note</th></tr></thead>\n          <tbody>${platforms.map(p=>`<tr>\n            <td><strong>${util().sanitize(p.name)}</strong></td>\n            <td><span class=\"ims__pill ims__pill--${p.order_type==='wholesale'?'info':'neutral'}\">${p.order_type}</span></td>\n            <td><input class=\"ims__input\" type=\"number\" step=\"0.01\" min=\"0\" id=\"ims-pp-${p.id}\" value=\"${priceMap[p.id]!==undefined?priceMap[p.id]:''}\" placeholder=\"Use default\" style=\"width:120px\"></td>\n            <td style=\"font-size:11px;color:var(--ims-text-muted)\">${p.order_type==='wholesale'||p.name==='Wayfair'||p.name==='Temu'?'Excl. VAT':''}</td>\n          </tr>`).join('')}\n          </tbody>\n        </table>\n      </div>\n    `, `\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_INVENTORY.savePlatformPrices('${util().jsArg(productId)}',${JSON.stringify(platforms.map(p=>p.id)).replace(/\"/g,\"'\")})\"><i class=\"ti ti-check\"></i> Save platform prices</button>\n    `, 'lg');\n  }\n\n  async function savePlatformPrices(productId, platformIds) {\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    let saved = 0;\n    for (const pid of platformIds) {\n      const input = document.getElementById(`ims-pp-${pid}`);\n      if (!input) continue;\n      const val = input.value.trim();\n      if (val === '') {\n        await client.from('product_prices').delete().eq('product_id', productId).eq('price_type', 'platform').eq('platform_id', pid);\n      } else {\n        const price = parseFloat(val);\n        if (isNaN(price)) continue;\n        await client.from('product_prices').upsert(\n          { product_id: productId, price_type: 'platform', platform_id: pid, price },\n          { onConflict: 'product_id,price_type,platform_id' }\n        );\n        saved++;\n      }\n    }\n    ui().closeModal();\n    ui().toast(`Platform prices saved (${saved} set)`, 'success');\n    loadCatalogueData();\n  }\n\n  // \u2500\u2500\u2500 DELETE SKU \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  async function deleteSKU(productId, productName) {\n    const [{ data: stock }, { data: orderItems }] = await Promise.all([\n      db().select('stock_levels', { eq: { product_id: productId }, noCompanyFilter: true }),\n      db().select('order_items', { eq: { product_id: productId }, noCompanyFilter: true, limit: 1 })\n    ]);\n    const hasStock  = (stock||[]).some(s => (s.quantity||0) > 0);\n    const hasOrders = (orderItems||[]).length > 0;\n    const stockWarn = hasStock ? \" This product has stock in your warehouse. Deleting it will remove stock records.\" : \"\";\n    const orderWarn = hasOrders ? \" This product appears on past orders. Order history is kept but the product link removed.\" : \"\";\n    ui().confirm(`Delete \"${productName}\" from the catalogue?${stockWarn}${orderWarn} This cannot be undone.`, async () => {\n      const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n      await client.from('product_prices').delete().eq('product_id', productId);\n      await client.from('product_boxes').delete().eq('product_id', productId);\n      await client.from('stock_levels').delete().eq('product_id', productId);\n      await client.from('stock_movements').delete().eq('product_id', productId);\n      const { error } = await db().remove('products', productId);\n      if (error) { ui().toast('Failed: ' + error.message, 'error'); return; }\n      ui().toast(`\"${productName}\" deleted from catalogue`, 'success');\n      loadCatalogueData();\n    }, 'Delete product', true);\n  }\n\n  // \u2500\u2500\u2500 IMPORT SKUs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  function showImport() {\n    ui().openModal('Import SKUs \u2014 Product catalogue', `\n      <div class=\"ims__alert ims__alert--info\"><i class=\"ti ti-info-circle\"></i>\n        <span>This imports product definitions into the catalogue only. No stock is created.</span>\n      </div>\n      <div class=\"ims__btn-group\" style=\"margin:12px 0\">\n        <button class=\"ims__btn ims__btn--secondary\" onclick=\"window.IMS_INVENTORY.downloadTemplate()\"><i class=\"ti ti-download\"></i> Download template</button>\n      </div>\n      <div class=\"ims__form-group\">\n        <label class=\"ims__label\">Select CSV file</label>\n        <input type=\"file\" accept=\".csv\" id=\"ims-inv-import-file\" class=\"ims__input\" onchange=\"window.IMS_INVENTORY.previewImport(this)\">\n      </div>\n      <div id=\"ims-inv-import-preview\"></div>\n    `, `\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\n      <button class=\"ims__btn ims__btn--primary\" id=\"ims-inv-commit-btn\" style=\"display:none\" onclick=\"window.IMS_INVENTORY.commitImport()\"><i class=\"ti ti-check\"></i> Import SKUs</button>\n    `, 'lg');\n  }\n\n  function downloadTemplate() {\n    util().exportCSV(\n      ['SKU', 'Product Name', 'Category', 'Barcode', 'Unit', 'Cost Price', 'Wholesale Price', 'RRP', 'Reorder Threshold', 'Reorder Quantity', 'Default Bin', 'Notes'],\n      [['CHR-001', 'Example Chair', 'Furniture', '1234567890', 'each', '10.00', '18.00', '35.00', '10', '50', 'A-51', 'Sample product']],\n      'sku_catalogue_template'\n    );\n  }\n\n  let _invImportRows = [];\n\n  async function previewImport(input) {\n    const file = input.files?.[0];\n    if (!file) return;\n    const text = await file.text();\n    const { headers, rows } = util().parseCSV(text);\n    const preview = document.getElementById('ims-inv-import-preview');\n    const commitBtn = document.getElementById('ims-inv-commit-btn');\n\n    const { data: existingProducts } = await db().select('products', { select: 'id,sku,barcode,name' });\n    const existingSkuMap = {}, existingBarcodeMap = {};\n    (existingProducts||[]).forEach(p => {\n      if (p.sku)     existingSkuMap[p.sku.toUpperCase()] = p.name;\n      if (p.barcode) existingBarcodeMap[p.barcode] = { sku: p.sku, name: p.name };\n    });\n\n    const skusInFile = {}, barcodesInFile = {};\n    _invImportRows = rows.map((row, rowIndex) => {\n      const get = col => { const i = headers.indexOf(col); return i >= 0 ? row[i] || '' : ''; };\n      const sku     = get('SKU').trim().toUpperCase();\n      const name    = get('Product Name').trim();\n      const barcode = get('Barcode').trim();\n      const warnings = [], errors = [];\n\n      if (!sku)  errors.push('SKU is required');\n      if (!name) errors.push('Product name is required');\n      if (sku) {\n        if (skusInFile[sku] !== undefined) { errors.push(`Duplicate SKU in file (row ${skusInFile[sku]+2})`); } else { skusInFile[sku] = rowIndex; }\n        if (existingSkuMap[sku]) warnings.push(`Will update existing: \"${existingSkuMap[sku]}\"`);\n      }\n      if (barcode) {\n        if (barcodesInFile[barcode] !== undefined) { errors.push(`Duplicate barcode in file (row ${barcodesInFile[barcode]+2})`); } else { barcodesInFile[barcode] = rowIndex; }\n        if (existingBarcodeMap[barcode] && existingBarcodeMap[barcode].sku.toUpperCase() !== sku) warnings.push(`Barcode already on SKU: ${existingBarcodeMap[barcode].sku}`);\n      }\n\n      return {\n        sku, name, barcode,\n        category:   get('Category'),\n        unit:       get('Unit') || 'each',\n        cost:       get('Cost Price')!=='' ? parseFloat(get('Cost Price')) : null,\n        wholesale:  get('Wholesale Price')!=='' ? parseFloat(get('Wholesale Price')) : null,\n        rrp:        get('RRP')!=='' ? parseFloat(get('RRP')) : null,\n        threshold:  get('Reorder Threshold')!=='' ? parseInt(get('Reorder Threshold')) : 10,\n        reorderQty: get('Reorder Quantity')!=='' ? parseInt(get('Reorder Quantity')) : 50,\n        bin:        get('Default Bin'),\n        notes:      get('Notes'),\n        errors, warnings,\n        valid: errors.length === 0 && !!sku && !!name\n      };\n    });\n\n    const valid    = _invImportRows.filter(r => r.valid).length;\n    const withWarn = _invImportRows.filter(r => r.valid && r.warnings.length).length;\n    const invalid  = _invImportRows.filter(r => !r.valid).length;\n    const updates  = _invImportRows.filter(r => r.valid && r.warnings.some(w=>w.startsWith('Will update'))).length;\n\n    if (preview) preview.innerHTML = `\n      <div class=\"ims__alert ims__alert--${invalid>0?'warning':'success'}\" style=\"margin-top:12px\">\n        <i class=\"ti ti-${invalid>0?'alert-triangle':'check'}\"></i>\n        <span><strong>${_invImportRows.length} rows</strong> &nbsp;|&nbsp; <span style=\"color:var(--ims-success)\">${valid} valid</span> &nbsp;|&nbsp; <span style=\"color:var(--ims-accent)\">${updates} updates</span> &nbsp;|&nbsp; ${invalid>0?`<span style=\"color:var(--ims-danger)\">${invalid} errors</span>`:'No errors'}</span>\n      </div>\n      <div class=\"ims__table-wrap\" style=\"max-height:250px;overflow-y:auto;margin-top:8px\">\n        <table class=\"ims__table\">\n          <thead><tr><th>SKU</th><th>Name</th><th>Barcode</th><th>Wholesale</th><th>RRP</th><th>Status</th></tr></thead>\n          <tbody>${_invImportRows.map(r=>`<tr>\n            <td>${util().sanitize(r.sku||'\u2014')}</td><td>${util().sanitize(r.name||'\u2014')}</td>\n            <td style=\"font-size:11px\">${util().sanitize(r.barcode||'\u2014')}</td>\n            <td>${r.wholesale!==null?util().formatCurrency(r.wholesale):'\u2014'}</td>\n            <td>${r.rrp!==null?util().formatCurrency(r.rrp):'\u2014'}</td>\n            <td>${r.errors.length?`<span class=\"ims__pill ims__pill--danger\" title=\"${util().sanitize(r.errors.join(', '))}\">\u2717 ${util().sanitize(r.errors[0])}</span>`:r.warnings.length?`<span class=\"ims__pill ims__pill--warning\" title=\"${util().sanitize(r.warnings.join(', '))}\">\u26A0 ${util().sanitize(r.warnings[0])}</span>`:'<span class=\"ims__pill ims__pill--success\">\u2713 New</span>'}</td>\n          </tr>`).join('')}\n          </tbody>\n        </table>\n      </div>`;\n\n    if (commitBtn) commitBtn.style.display = valid > 0 ? 'inline-flex' : 'none';\n  }\n\n  async function commitImport() {\n    const valid = _invImportRows.filter(r => r.valid);\n    if (!valid.length) return;\n    let created = 0, updated = 0;\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const commitBtn = document.getElementById('ims-inv-commit-btn');\n    const preview = document.getElementById('ims-inv-import-preview');\n    if (commitBtn) { commitBtn.disabled = true; commitBtn.innerHTML = '<i class=\"ti ti-loader-2 ims__spin\"></i> Importing...'; }\n    let done = 0;\n    const total = valid.length;\n    const updateProgress = () => {\n      const pct = Math.round((done/total)*100);\n      if (preview) preview.innerHTML = `<div style=\"margin-top:12px\"><div style=\"display:flex;justify-content:space-between;font-size:12px;margin-bottom:4px\"><span>Importing ${done} of ${total}...</span><span>${pct}%</span></div><div style=\"background:var(--ims-border);border-radius:999px;height:8px\"><div style=\"background:var(--ims-primary);width:${pct}%;height:8px;border-radius:999px;transition:width 0.2s\"></div></div></div>`;\n    };\n    updateProgress();\n    for (const row of valid) {\n      const { data: existing } = await db().select('products', { eq: { sku: row.sku }, maybeSingle: true });\n      let productId;\n      if (existing) {\n        await db().update('products', existing.id, { name: row.name, category: row.category||null, barcode: row.barcode||null, unit: row.unit, reorder_threshold: row.threshold, reorder_quantity: row.reorderQty, default_bin: row.bin||null, notes: row.notes||null });\n        productId = existing.id; updated++;\n      } else {\n        const { data, error } = await db().insert('products', { sku: row.sku, name: row.name, category: row.category||null, barcode: row.barcode||null, unit: row.unit, reorder_threshold: row.threshold, reorder_quantity: row.reorderQty, default_bin: row.bin||null, notes: row.notes||null });\n        if (!error) { productId = data.id; created++; }\n      }\n      done++;\n      updateProgress();\n      if (productId) {\n        const priceUpdates = [\n          row.cost !== null ? { price_type: 'cost', price: row.cost } : null,\n          row.wholesale !== null ? { price_type: 'wholesale', price: row.wholesale } : null,\n          row.rrp !== null ? { price_type: 'rrp', price: row.rrp } : null,\n        ].filter(Boolean);\n        for (const pu of priceUpdates) {\n          await client.from('product_prices').delete().eq('product_id', productId).eq('price_type', pu.price_type).is('platform_id', null);\n          await client.from('product_prices').insert({ product_id: productId, platform_id: null, price_type: pu.price_type, price: pu.price });\n        }\n      }\n    }\n    ui().closeModal();\n    ui().toast(`Import complete: ${created} added, ${updated} updated`, 'success');\n    _invImportRows = [];\n    loadCatalogueData();\n  }\n\n  // \u2500\u2500\u2500 EXPORT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n  // UPDATE COST PRICES (cost only; nothing else about a product changes)\n  // Download a cost sheet (missing/zero costs, or all), fill in \"New cost\",\n  // upload it (Excel or CSV), check the preview, confirm. Existing cost\n  // records are UPDATED (so the audit log shows old -> new); missing ones\n  // are added. Only roles that can see costs can use it.\n  // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n  let _cost = { products: [], byId: {}, bySku: {}, rows: [] };\n  const _money2 = n => Math.round(Number(n) * 100) / 100;\n  async function _costLoad() {\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    const products = [];\n    for (let from = 0; ; from += 1000) {\n      const { data, error } = await client.from('products').select('id,sku,name').eq('company_id', window.SM.AUTH.company?.id).order('sku').range(from, from + 999);\n      if (error) throw new Error(error.message);\n      products.push(...(data || [])); if (!data || data.length < 1000) break;\n    }\n    const ids = products.map(p => p.id), costs = {};\n    for (let i = 0; i < ids.length; i += 150) {\n      const { data, error } = await client.from('product_prices').select('id,product_id,price').eq('price_type', 'cost').is('platform_id', null).in('product_id', ids.slice(i, i + 150));\n      if (error) throw new Error(error.message);\n      (data || []).forEach(r => { costs[r.product_id] = { rowId: r.id, price: r.price == null ? null : Number(r.price) }; });\n    }\n    _cost.products = products.map(p => ({ ...p, rowId: costs[p.id]?.rowId || null, cost: costs[p.id] ? costs[p.id].price : null }));\n    _cost.byId = {}; _cost.bySku = {};\n    _cost.products.forEach(p => { _cost.byId[p.id] = p; if (p.sku) _cost.bySku[String(p.sku).trim().toUpperCase()] = p; });\n  }\n  const _isMissing = p => p.cost == null || Number(p.cost) === 0;\n\n  async function showCostUpdate(mode) {\n    if (!canSeeCost()) { ui().toast('Only roles that can see costs can update them', 'warning'); return; }\n    ui().openModal('Update cost prices', '<div class=\"ims__loading\"><i class=\"ti ti-loader-2 ims__spin\"></i></div>', '');\n    try { await _costLoad(); } catch (e) { ui().toast('Could not load the products: ' + e.message, 'error', 8000); ui().closeModal(); return; }\n    const missing = _cost.products.filter(_isMissing).length, all = _cost.products.length;\n    const pick = mode === 'all' ? 'all' : 'missing';\n    ui().openModal('Update cost prices', `\n      <p style=\"font-size:13px;margin:0 0 12px\">This changes <strong>cost prices only</strong>: nothing else about a product is touched. Every change is recorded in the Audit log.</p>\n      <div class=\"ims__card\" style=\"padding:12px;margin-bottom:12px\">\n        <div style=\"font-weight:600;margin-bottom:8px\">1. Download the cost sheet</div>\n        <label style=\"display:flex;gap:8px;align-items:center;font-size:13px;margin-bottom:6px\"><input type=\"radio\" name=\"ims-cost-mode\" value=\"missing\" ${pick === 'missing' ? 'checked' : ''}> Missing or zero costs only (${missing} product${missing === 1 ? '' : 's'})</label>\n        <label style=\"display:flex;gap:8px;align-items:center;font-size:13px;margin-bottom:10px\"><input type=\"radio\" name=\"ims-cost-mode\" value=\"all\" ${pick === 'all' ? 'checked' : ''}> All products (${all})</label>\n        <button class=\"ims__btn ims__btn--secondary ims__btn--sm\" onclick=\"window.IMS_INVENTORY.downloadCostSheet()\"><i class=\"ti ti-download\"></i> Download cost sheet</button>\n        <div style=\"font-size:12px;color:var(--ims-text-muted);margin-top:8px\">Fill in the <strong>New cost</strong> column (before VAT). Leave it blank where nothing should change.</div>\n      </div>\n      <div class=\"ims__card\" style=\"padding:12px\">\n        <div style=\"font-weight:600;margin-bottom:8px\">2. Upload it (Excel or CSV)</div>\n        <input type=\"file\" accept=\".csv,.xlsx,.xls\" class=\"ims__input\" onchange=\"window.IMS_INVENTORY.previewCostFile(this)\">\n      </div>\n      <div id=\"ims-cost-preview\" style=\"margin-top:12px\"></div>`, `\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\n      <button class=\"ims__btn ims__btn--primary\" id=\"ims-cost-confirm\" disabled onclick=\"window.IMS_INVENTORY.confirmCostUpdate()\"><i class=\"ti ti-check\"></i> Update cost prices</button>`, 'lg');\n  }\n\n  function downloadCostSheet() {\n    const mode = document.querySelector('input[name=\"ims-cost-mode\"]:checked')?.value || 'missing';\n    const list = mode === 'all' ? _cost.products : _cost.products.filter(_isMissing);\n    if (!list.length) { ui().toast('No products to list', 'info'); return; }\n    util().exportCSV(['SKU', 'Product', 'Current cost', 'New cost'],\n      list.map(p => [p.sku || '', p.name || '', p.cost == null ? '' : Number(p.cost).toFixed(2), '']),\n      mode === 'all' ? 'cost_prices_all_products' : 'cost_prices_missing');\n  }\n\n  function _loadXlsx() {\n    if (window.XLSX) return Promise.resolve(window.XLSX);\n    return new Promise((resolve, reject) => {\n      const sc = document.createElement('script');\n      sc.src = 'https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js';\n      sc.onload = () => resolve(window.XLSX);\n      sc.onerror = () => reject(new Error('The Excel reader could not be loaded. Save the file as CSV and upload that instead.'));\n      document.head.appendChild(sc);\n    });\n  }\n  async function _readSheet(file) {\n    if (/\\.(xlsx|xls)$/i.test(file.name)) {\n      const XLSX = await _loadXlsx();\n      const wb = XLSX.read(await file.arrayBuffer(), { type: 'array' });\n      const rows = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1, raw: false, defval: '' });\n      return { headers: (rows[0] || []).map(h => String(h)), rows: rows.slice(1) };\n    }\n    return util().parseCSV(await file.text());\n  }\n  // \"\u00A31,234.50\" -> 1234.5; null if not a valid amount.\n  function _amount(v) {\n    const t = String(v ?? '').replace(/[\u00A3,\\s]/g, '');\n    if (!/^\\d+(\\.\\d+)?$/.test(t)) return null;\n    return _money2(parseFloat(t));\n  }\n\n  async function previewCostFile(input) {\n    const out = document.getElementById('ims-cost-preview'), btn = document.getElementById('ims-cost-confirm');\n    const file = input.files?.[0]; if (!file || !out) return;\n    if (btn) btn.disabled = true;\n    let sheet;\n    try { sheet = await _readSheet(file); } catch (e) { out.innerHTML = `<div class=\"ims__alert ims__alert--danger\"><i class=\"ti ti-alert-circle\"></i><span>${util().sanitize(e.message)}</span></div>`; return; }\n    const norm = h => String(h || '').trim().toLowerCase();\n    const hs = (sheet.headers || []).map(norm);\n    const iSku = hs.indexOf('sku');\n    let iNew = hs.indexOf('new cost'); if (iNew < 0) iNew = hs.indexOf('new cost price'); if (iNew < 0) iNew = hs.indexOf('cost price');\n    if (iSku < 0 || iNew < 0) {\n      out.innerHTML = `<div class=\"ims__alert ims__alert--danger\"><i class=\"ti ti-alert-circle\"></i><span>The file needs a <strong>SKU</strong> column and a <strong>New cost</strong> column. Use the downloaded cost sheet.</span></div>`;\n      return;\n    }\n    const seen = {}; _cost.rows = [];\n    (sheet.rows || []).forEach((r, i) => {\n      const sku = String(r[iSku] ?? '').trim().toUpperCase(), raw = String(r[iNew] ?? '').trim();\n      if (!sku && !raw) return;\n      if (!raw) return;                                   // blank: nothing to change\n      const row = { line: i + 2, sku, raw, product: _cost.bySku[sku] || null, next: _amount(raw), status: 'ok', note: '', include: true };\n      if (!sku) { row.status = 'error'; row.note = 'No SKU'; }\n      else if (seen[sku]) { row.status = 'error'; row.note = `Listed twice (also row ${seen[sku]})`; }\n      else if (!row.product) { row.status = 'error'; row.note = 'SKU not found'; }\n      else if (row.next == null) { row.status = 'error'; row.note = 'Not a valid amount'; }\n      else {\n        const cur = row.product.cost;\n        if (cur != null && _money2(cur) === row.next) { row.status = 'same'; row.note = 'No change'; }\n        else if (row.next === 0) { row.status = 'warn'; row.note = 'Zero cost'; row.include = false; }\n        else if (cur != null && Number(cur) > 0 && Math.abs(row.next - cur) / cur > 0.5) { row.status = 'warn'; row.note = `Large change (${row.next > cur ? '+' : ''}${Math.round((row.next - cur) / cur * 100)}%): a typo?`; row.include = false; }\n      }\n      if (sku && !seen[sku]) seen[sku] = i + 2;\n      _cost.rows.push(row);\n    });\n    _renderCostPreview();\n  }\n  function _renderCostPreview() {\n    const out = document.getElementById('ims-cost-preview'), btn = document.getElementById('ims-cost-confirm'); if (!out) return;\n    const rows = _cost.rows, fm = n => n == null ? '<span style=\"color:var(--ims-text-muted)\">none</span>' : util().formatCurrency(n);\n    const apply = rows.filter(r => (r.status === 'ok' || r.status === 'warn') && r.include);\n    const n = s => rows.filter(r => r.status === s).length;\n    if (!rows.length) { out.innerHTML = '<div class=\"ims__alert ims__alert--info\"><i class=\"ti ti-info-circle\"></i><span>No new costs found in the file (the New cost column is empty).</span></div>'; if (btn) btn.disabled = true; return; }\n    const pill = r => r.status === 'ok' ? '<span class=\"ims__pill ims__pill--success\">Will update</span>'\n      : r.status === 'same' ? '<span class=\"ims__pill ims__pill--neutral\">No change</span>'\n      : r.status === 'warn' ? `<label style=\"display:flex;gap:6px;align-items:center;font-size:12px\"><input type=\"checkbox\" ${r.include ? 'checked' : ''} onchange=\"window.IMS_INVENTORY.costInclude(${rows.indexOf(r)},this.checked)\"> <span style=\"color:var(--ims-warning)\">&#9888; ${util().sanitize(r.note)}</span> Include anyway</label>`\n      : `<span style=\"color:var(--ims-danger)\">&#9888; ${util().sanitize(r.note)}: left out</span>`;\n    out.innerHTML = `\n      <div style=\"font-size:13px;margin-bottom:8px\"><strong>${apply.length}</strong> to update${n('same') ? `, ${n('same')} unchanged` : ''}${n('warn') ? `, <span style=\"color:var(--ims-warning)\">${n('warn')} to check</span>` : ''}${n('error') ? `, <span style=\"color:var(--ims-danger)\">${n('error')} left out</span>` : ''}.</div>\n      <div class=\"ims__table-wrap\" style=\"max-height:340px;overflow:auto\"><table class=\"ims__table\"><thead><tr><th>Row</th><th>SKU</th><th>Product</th><th>Current</th><th>New</th><th>Status</th></tr></thead><tbody>\n        ${rows.map(r => `<tr><td>${r.line}</td><td>${util().sanitize(r.sku || '')}</td><td>${util().sanitize(r.product?.name || '')}</td><td>${r.product ? fm(r.product.cost) : ''}</td><td>${r.next == null ? util().sanitize(r.raw) : util().formatCurrency(r.next)}</td><td>${pill(r)}</td></tr>`).join('')}\n      </tbody></table></div>`;\n    if (btn) { btn.disabled = !apply.length; btn.innerHTML = `<i class=\"ti ti-check\"></i> Update ${apply.length} cost price${apply.length === 1 ? '' : 's'}`; }\n  }\n  function costInclude(i, on) { if (_cost.rows[i]) { _cost.rows[i].include = !!on; _renderCostPreview(); } }\n\n  async function confirmCostUpdate() {\n    if (!canSeeCost()) return;\n    const apply = _cost.rows.filter(r => (r.status === 'ok' || r.status === 'warn') && r.include && r.product && r.next != null);\n    if (!apply.length) return;\n    const btn = document.getElementById('ims-cost-confirm'); if (btn) { btn.disabled = true; btn.innerHTML = '<i class=\"ti ti-loader-2 ims__spin\"></i> Saving...'; }\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\n    let done = 0; const failed = [];\n    for (const r of apply) {\n      const p = r.product;\n      const res = p.rowId\n        ? await client.from('product_prices').update({ price: r.next }).eq('id', p.rowId)\n        : await client.from('product_prices').insert({ product_id: p.id, platform_id: null, price_type: 'cost', price: r.next });\n      if (res.error) failed.push(`${r.sku}: ${res.error.message}`); else done++;\n    }\n    ui().closeModal();\n    if (failed.length) ui().toast(`Updated ${done} cost price${done === 1 ? '' : 's'}. ${failed.length} could not be saved: ${failed.slice(0, 3).join('; ')}`, 'warning', 12000);\n    else ui().toast(`Updated ${done} cost price${done === 1 ? '' : 's'}`, 'success');\n    if (document.getElementById('ims-inv-content')) loadCatalogue();\n  }\n  // From elsewhere (e.g. the Clearance planner): open Inventory, then the tool.\n  function openCostUpdate(mode) {\n    if (window.SM?.UI?.showPanel) window.SM.UI.showPanel('inventory');\n    setTimeout(() => showCostUpdate(mode || 'missing'), 150);\n  }\n\n  async function exportProducts() {\n    const { data: products } = await db().select('products', { order: { col: 'name' } });\n    if (!products?.length) { ui().toast('No products to export', 'warning'); return; }\n    const priceMap = {};\n    await Promise.all(products.map(async p => {\n      const [cost, wholesale, rrp] = await Promise.all([\n        canSeeCost() ? db().getProductPrice(p.id, 'cost') : Promise.resolve(null),\n        db().getProductPrice(p.id, 'wholesale'),\n        db().getProductPrice(p.id, 'rrp')\n      ]);\n      priceMap[p.id] = { cost, wholesale, rrp };\n    }));\n    const headers = canSeeCost()\n      ? ['SKU','Name','Category','Barcode','Unit','Cost Price','Wholesale Price','RRP','Reorder Threshold','Default Bin']\n      : ['SKU','Name','Category','Barcode','Unit','Wholesale Price','RRP','Reorder Threshold','Default Bin'];\n    const rows = products.map(p => {\n      const pr = priceMap[p.id] || {};\n      return canSeeCost()\n        ? [p.sku, p.name, p.category||'', p.barcode||'', p.unit||'each', pr.cost??'', pr.wholesale??'', pr.rrp??'', p.reorder_threshold||10, p.default_bin||'']\n        : [p.sku, p.name, p.category||'', p.barcode||'', p.unit||'each', pr.wholesale??'', pr.rrp??'', p.reorder_threshold||10, p.default_bin||''];\n    });\n    util().exportCSV(headers, rows, 'product_catalogue');\n  }\n\n  // \u2500\u2500\u2500 BINDINGS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  window.addEventListener('ims:panel', e => {\n    if (e.detail.panel === 'inventory') { initTabs(); loadCatalogue(); }\n  });\n\n  window.IMS_INVENTORY = { showCostUpdate, downloadCostSheet, previewCostFile, costInclude, confirmCostUpdate, openCostUpdate,\n    load: loadCatalogue, initTabs, loadCatalogue, loadCatalogueData,\n    deleteSKU, onAdjTypeChange,\n    loadStock, loadStockData, openSKU,\n    showSKUForm, saveSKU,\n    addBoxRow, removeBoxRow, updateVolWt,\n    showAddStockForm, onProductSelected, saveAddStock, switchToAddStock,\n    showAdjustStock, saveAdjustment,\n    showBulkStockImport, downloadStockTemplate, previewBulkStock, commitBulkStock,\n    managePlatformPrices, savePlatformPrices,\n    showImport, downloadTemplate, previewImport, commitImport, exportProducts,\n    editProduct: showSKUForm, adjustStock: showAdjustStock\n  };\n})();\n"],
  "mappings": "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",
  "names": ["p", "reason", "existing", "n"]
}
