{
  "version": 3,
  "sources": ["/cdn/shop/t/4/assets/ims-dropship.js?bust=20260708"],
  "sourcesContent": ["(function(){\r\n  'use strict';\r\n\r\n  // Reusable button-loading helper \u2014 works via the inline `event`\r\n  // global available inside any function invoked from an onclick\r\n  // attribute, so it can be dropped into existing save/action\r\n  // functions without changing any HTML. Call at the top of a function\r\n  // with `const restore=_withBtnSpin(event,'Saving...');`, then call\r\n  // `restore()` before every return path (success or failure).\r\n  function _withBtnSpin(evtOrBtn, label){\r\n    const btn = evtOrBtn?.target?.closest ? evtOrBtn.target.closest('button') : evtOrBtn;\r\n    if(!btn) return ()=>{};\r\n    if(btn.dataset.spinning==='1') return ()=>{}; // already spinning, avoid double-wrap\r\n    btn.dataset.spinning='1';\r\n    const original = btn.innerHTML;\r\n    btn.disabled = true;\r\n    btn.innerHTML = `<i class=\"ti ti-loader-2 ims__spin\"></i> ${label||'Working...'}`;\r\n    return () => { btn.disabled = false; btn.innerHTML = original; delete btn.dataset.spinning; };\r\n  }\r\n  const db=()=>window.SM.DB, ui=()=>window.SM.UI, util=()=>window.SM.UTIL;\r\n\r\n  let _activeTab='customers';\r\n\r\n  function initTabs(){\r\n    const tabs=document.getElementById('ims-ds-tabs');\r\n    if(!tabs)return;\r\n    tabs.querySelectorAll('.ims__tab').forEach(tab=>{\r\n      tab.addEventListener('click',()=>{\r\n        tabs.querySelectorAll('.ims__tab').forEach(t=>t.classList.remove('ims__tab--active'));\r\n        tab.classList.add('ims__tab--active');\r\n        _activeTab=tab.dataset.tab;\r\n        loadTab(_activeTab);\r\n      });\r\n    });\r\n  }\r\n\r\n  function loadTab(tab){\r\n    switch(tab){\r\n      case 'customers':  loadCustomers();  break;\r\n      case 'orders':     loadOrders();     break;\r\n      case 'allocations':loadAllocations();break;\r\n      case 'invoices':   loadInvoices();   break;\r\n      case 'reports':    loadReports();    break;\r\n      case 'deals':      loadDSDeals();    break;\r\n    }\r\n  }\r\n\r\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\r\n  // CUSTOMERS\r\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\r\n  async function loadCustomers(){\r\n    const content=document.getElementById('ims-ds-content');\r\n    if(!content)return;\r\n    content.innerHTML=`<div class=\"ims__loading\"><i class=\"ti ti-loader-2 ims__spin\"></i></div>`;\r\n\r\n    const actions=document.getElementById('ims-ds-actions');\r\n    if(actions) actions.innerHTML=`<button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_DROPSHIP.showCustomerForm()\"><i class=\"ti ti-plus\"></i> Add dropship customer</button>`;\r\n\r\n    const {data:customers}=await db().select('dropship_customers',{order:{col:'business_name'}});\r\n    const items=customers||[];\r\n\r\n    if(!items.length){\r\n      content.innerHTML=`<div class=\"ims__coming-soon\"><i class=\"ti ti-users\"></i><h3>No dropship customers yet</h3><p>Add your first dropship customer to get started.</p></div>`;\r\n      return;\r\n    }\r\n\r\n    const client=window.supabase.createClient(window.IMS_SUPABASE_URL,window.IMS_SUPABASE_ANON_KEY);\r\n    const {data:orders}=await client.from('orders').select('dropship_customer_id,status,delivery_method').eq('fulfillment_type','dropship');\r\n    const {data:allocs}=await db().select('dropship_allocations',{select:'customer_id,remaining_qty'});\r\n\r\n    const orderMap={}, allocMap={};\r\n    (orders||[]).forEach(o=>{\r\n      const cid=o.dropship_customer_id;\r\n      if(!cid)return;\r\n      if(!orderMap[cid])orderMap[cid]={total:0,active:0};\r\n      orderMap[cid].total++;\r\n      if(!['delivered','collected','cancelled'].includes(o.status))orderMap[cid].active++;\r\n    });\r\n    (allocs||[]).forEach(a=>{\r\n      allocMap[a.customer_id]=(allocMap[a.customer_id]||0)+(a.remaining_qty||0);\r\n    });\r\n\r\n    content.innerHTML=`\r\n      <div class=\"ims__table-wrap\">\r\n        <table class=\"ims__table\">\r\n          <thead><tr>\r\n            <th>Business name</th><th>Contact</th><th>Delivery method</th>\r\n            <th>Discount</th><th>Credit limit</th><th>Stock allocated</th><th>Active orders</th><th>Status</th><th></th>\r\n          </tr></thead>\r\n          <tbody>${items.map(c=>`<tr>\r\n            <td><span class=\"ims__link\" onclick=\"window.IMS_DROPSHIP.openCustomer('${util().jsArg(c.id)}')\"><strong>${util().sanitize(c.business_name)}</strong></span></td>\r\n            <td style=\"font-size:12px\">${util().sanitize(c.contact_name||'\u2014')}<br><span style=\"color:var(--ims-text-muted)\">${util().sanitize(c.email||'\u2014')}</span></td>\r\n            <td><span class=\"ims__pill ims__pill--${c.delivery_method==='mdf_delivers'?'info':'neutral'}\">${c.delivery_method==='mdf_delivers'?'We deliver':'Self-arrange'}</span></td>\r\n            <td style=\"font-weight:600;color:var(--ims-success)\">${c.discount_pct||0}% off wholesale</td>\r\n            <td style=\"font-weight:600\">${c.credit_limit>0?util().formatCurrency(c.credit_limit):'\u2014'}</td>\r\n            <td style=\"font-weight:600\">${allocMap[c.id]||0} units</td>\r\n            <td>${orderMap[c.id]?.active||0} orders</td>\r\n            <td><span class=\"ims__pill ims__pill--${c.is_active?'success':'neutral'}\">${c.is_active?'Active':'Inactive'}</span></td>\r\n            <td><div class=\"ims__btn-group\">\r\n              <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_DROPSHIP.openCustomer('${util().jsArg(c.id)}')\" title=\"View\"><i class=\"ti ti-eye\"></i></button>\r\n              <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_DROPSHIP.showCustomerForm('${util().jsArg(c.id)}')\" title=\"Edit\"><i class=\"ti ti-edit\"></i></button>\r\n              <button class=\"ims__btn ims__btn--primary ims__btn--sm\" onclick=\"window.IMS_DROPSHIP.showAllocateForm('${util().jsArg(c.id)}','${util().jsArg(c.business_name)}')\"><i class=\"ti ti-box\"></i> Allocate stock</button>\r\n              <button class=\"ims__btn ims__btn--secondary ims__btn--sm\" onclick=\"window.IMS_DROPSHIP.showCustomerPricing('${util().jsArg(c.id)}','${util().jsArg(c.business_name)}')\"><i class=\"ti ti-tag\"></i> Custom pricing</button>\r\n              ${window.SM.AUTH.isAdmin()?`<button class=\"ims__btn ims__btn--danger ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_DROPSHIP.deleteCustomer('${util().jsArg(c.id)}','${util().jsArg(c.business_name)}')\" title=\"Delete customer\"><i class=\"ti ti-trash\"></i></button>`:''}\r\n            </div></td>\r\n          </tr>`).join('')}\r\n          </tbody>\r\n        </table>\r\n      </div>`;\r\n  }\r\n\r\n  async function openCustomer(id){\r\n    const {data:c}=await db().select('dropship_customers',{eq:{id},maybeSingle:true,noCompanyFilter:true});\r\n    if(!c)return;\r\n    const {data:allocs}=await db().select('dropship_allocations',{\r\n      select:'allocated_qty,remaining_qty,allocation_date,products(name,sku)',\r\n      eq:{customer_id:id},noCompanyFilter:true\r\n    });\r\n    const {data:orders}=await db().select('orders',{\r\n      select:'order_number,end_customer_name,end_postcode,status,total_value,created_at,delivery_method',\r\n      eq:{dropship_customer_id:id,fulfillment_type:'dropship'},order:{col:'order_number',asc:false},limit:10,noCompanyFilter:true\r\n    });\r\n    const totalAllocated=(allocs||[]).reduce((s,a)=>s+(a.allocated_qty||0),0);\r\n    const totalRemaining=(allocs||[]).reduce((s,a)=>s+(a.remaining_qty||0),0);\r\n    const totalSold=totalAllocated-totalRemaining;\r\n\r\n    ui().openModal(`Dropship: ${c.business_name}`,`\r\n      <div style=\"display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px\">\r\n        <div><span class=\"ims__label\">Business name</span><div style=\"font-weight:600\">${util().sanitize(c.business_name)}</div></div>\r\n        <div><span class=\"ims__label\">Contact</span><div>${util().sanitize(c.contact_name||'\u2014')}</div></div>\r\n        <div><span class=\"ims__label\">Email</span><div>${util().sanitize(c.email||'\u2014')}</div></div>\r\n        <div><span class=\"ims__label\">Phone</span><div>${util().sanitize(c.phone||'\u2014')}</div></div>\r\n        <div><span class=\"ims__label\">Delivery method</span><div><span class=\"ims__pill ims__pill--${c.delivery_method==='mdf_delivers'?'info':'neutral'}\">${c.delivery_method==='mdf_delivers'?'MDF London delivers':'Customer self-arranges'}</span></div></div>\r\n        <div><span class=\"ims__label\">Discount</span><div style=\"font-size:18px;font-weight:700;color:var(--ims-success)\">${c.discount_pct||0}% off wholesale</div></div>\r\n        <div><span class=\"ims__label\">Invoice cycle</span><div>Fortnightly</div></div>\r\n        <div><span class=\"ims__label\">Credit terms</span><div>${util().sanitize(c.credit_terms||'Fortnightly')}</div></div>\r\n        <div><span class=\"ims__label\">Credit limit</span><div style=\"font-weight:600;color:${c.credit_limit>0?'var(--ims-text-primary)':'var(--ims-text-muted)'}\">${c.credit_limit>0?util().formatCurrency(c.credit_limit):'No limit set'}</div></div>\r\n        ${c.notes?`<div style=\"grid-column:1/-1\"><span class=\"ims__label\">Notes</span><div>${util().sanitize(c.notes)}</div></div>`:''}\r\n      </div>\r\n      <div style=\"display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:14px\">\r\n        <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Total allocated</div><div class=\"ims__stat-value\" style=\"font-size:20px\">${totalAllocated}</div></div>\r\n        <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Sold / delivered</div><div class=\"ims__stat-value\" style=\"font-size:20px\">${totalSold}</div></div>\r\n        <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Remaining</div><div class=\"ims__stat-value ims__stat-value--${totalRemaining>0?'success':'warning'}\" style=\"font-size:20px\">${totalRemaining}</div></div>\r\n      </div>\r\n      <hr class=\"ims__divider\">\r\n      <strong style=\"font-size:13px\">Stock allocations</strong>\r\n      <table class=\"ims__table\" style=\"margin-top:8px\">\r\n        <thead><tr><th>Product</th><th>SKU</th><th>Allocated</th><th>Remaining</th><th>Date</th></tr></thead>\r\n        <tbody>${(allocs||[]).map(a=>`<tr>\r\n          <td>${util().sanitize(a.products?.name||'\u2014')}</td>\r\n          <td>${util().sanitize(a.products?.sku||'\u2014')}</td>\r\n          <td>${a.allocated_qty||0}</td>\r\n          <td style=\"font-weight:600;color:${(a.remaining_qty||0)>0?'var(--ims-success)':'var(--ims-text-muted)'}\">${a.remaining_qty||0}</td>\r\n          <td>${util().formatDate(a.allocation_date)}</td>\r\n        </tr>`).join('')||'<tr><td colspan=\"5\" class=\"ims__table-empty\">No stock allocated yet</td></tr>'}\r\n        </tbody>\r\n      </table>\r\n      <hr class=\"ims__divider\">\r\n      <strong style=\"font-size:13px\">Recent orders</strong>\r\n      <table class=\"ims__table\" style=\"margin-top:8px\">\r\n        <thead><tr><th>Order #</th><th>End customer</th><th>Postcode</th><th>Delivery</th><th>Value</th><th>Status</th></tr></thead>\r\n        <tbody>${(orders||[]).map(o=>`<tr>\r\n          <td>${util().sanitize(o.order_number)}</td>\r\n          <td>${util().sanitize(o.end_customer_name||'\u2014')}</td>\r\n          <td>${util().sanitize(o.end_postcode||'\u2014')}</td>\r\n          <td><span class=\"ims__pill ims__pill--${o.delivery_method==='mdf_delivers'?'info':'neutral'}\" style=\"font-size:10px\">${o.delivery_method==='mdf_delivers'?'We deliver':'Self-arrange'}</span></td>\r\n          <td>${util().formatCurrency(o.total_value)}</td>\r\n          <td>${util().pill(o.status)}</td>\r\n        </tr>`).join('')||'<tr><td colspan=\"6\" class=\"ims__table-empty\">No orders yet</td></tr>'}\r\n        </tbody>\r\n      </table>\r\n    `,`\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.IMS_DROPSHIP.showCustomerForm('${util().jsArg(c.id)}')\"><i class=\"ti ti-edit\"></i> Edit</button>\r\n      ${window.SM.AUTH.isAdmin()?`<button class=\"ims__btn ims__btn--danger\" onclick=\"window.IMS_DROPSHIP.deleteCustomer('${util().jsArg(c.id)}','${util().jsArg(c.business_name)}')\"><i class=\"ti ti-trash\"></i> Delete customer</button>`:''}\r\n      <button class=\"ims__btn ims__btn--secondary\" onclick=\"window.IMS_DROPSHIP.showAllocateForm('${util().jsArg(c.id)}','${util().jsArg(c.business_name)}')\"><i class=\"ti ti-box\"></i> Allocate stock</button>\r\n      <button class=\"ims__btn ims__btn--secondary\" onclick=\"window.IMS_DROPSHIP.showCustomerPricing('${util().jsArg(c.id)}','${util().jsArg(c.business_name)}')\"><i class=\"ti ti-tag\"></i> Custom pricing</button>\r\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_DROPSHIP.showNewOrder('${util().jsArg(c.id)}','${util().jsArg(c.business_name)}',${c.discount_pct||0},'${util().jsArg(c.delivery_method)}')\"><i class=\"ti ti-plus\"></i> New order</button>\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Close</button>\r\n    `,'xl');\r\n  }\r\n\r\n  async function showCustomerForm(existingId=null){\r\n    let c=null;\r\n    if(existingId){\r\n      const {data}=await db().select('dropship_customers',{eq:{id:existingId},maybeSingle:true,noCompanyFilter:true});\r\n      c=data;\r\n    }\r\n    ui().openModal(existingId?`Edit: ${c?.business_name}`:'Add dropship customer',`\r\n      <div class=\"ims__form-grid\">\r\n        <div class=\"ims__form-group ims__form-group--full\"><label class=\"ims__label ims__label--req\">Business name</label><input class=\"ims__input\" type=\"text\" id=\"ims-dsc-name\" value=\"${util().sanitize(c?.business_name||'')}\"></div>\r\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Contact name</label><input class=\"ims__input\" type=\"text\" id=\"ims-dsc-contact\" value=\"${util().sanitize(c?.contact_name||'')}\"></div>\r\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Email</label><input class=\"ims__input\" type=\"email\" id=\"ims-dsc-email\" value=\"${util().sanitize(c?.email||'')}\"></div>\r\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Phone</label><input class=\"ims__input\" type=\"tel\" id=\"ims-dsc-phone\" value=\"${util().sanitize(c?.phone||'')}\"></div>\r\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Postcode</label><input class=\"ims__input\" type=\"text\" id=\"ims-dsc-postcode\" value=\"${util().sanitize(c?.postcode||'')}\"></div>\r\n        <div class=\"ims__form-group ims__form-group--full\"><label class=\"ims__label\">Address</label><textarea class=\"ims__textarea\" id=\"ims-dsc-address\" rows=\"2\">${util().sanitize(c?.address||'')}</textarea></div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label ims__label--req\">Discount off wholesale (%)</label>\r\n          <input class=\"ims__input\" type=\"number\" step=\"0.1\" min=\"0\" max=\"100\" id=\"ims-dsc-discount\" value=\"${c?.discount_pct||0}\">\r\n          <span class=\"ims__input-hint\">e.g. 10 = customer pays wholesale price minus 10%</span>\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label ims__label--req\">Delivery method</label>\r\n          <select class=\"ims__select\" id=\"ims-dsc-delivery\">\r\n            <option value=\"mdf_delivers\" ${c?.delivery_method==='mdf_delivers'||!c?'selected':''}>MDF London delivers to end customer</option>\r\n            <option value=\"self_arrange\" ${c?.delivery_method==='self_arrange'?'selected':''}>Customer self-arranges delivery</option>\r\n          </select>\r\n        </div>\r\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Credit terms</label>\r\n          <select class=\"ims__select\" id=\"ims-dsc-terms\">\r\n            ${['Fortnightly','30 days net','60 days net','Advance payment'].map(t=>`<option ${c?.credit_terms===t?'selected':''}>${t}</option>`).join('')}\r\n          </select>\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label\">Credit limit (\u00A3)</label>\r\n          <input class=\"ims__input\" type=\"number\" step=\"0.01\" min=\"0\" id=\"ims-dsc-limit\" value=\"${c?.credit_limit||''}\" placeholder=\"0 = no limit\">\r\n          <span class=\"ims__input-hint\">Maximum outstanding balance allowed before orders are blocked</span>\r\n        </div>\r\n        <div class=\"ims__form-group ims__form-group--full\"><label class=\"ims__label\">Notes</label><textarea class=\"ims__textarea\" id=\"ims-dsc-notes\" rows=\"2\">${util().sanitize(c?.notes||'')}</textarea></div>\r\n      </div>\r\n    `,`\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_DROPSHIP.saveCustomer('${util().jsArg(existingId||'')}')\"><i class=\"ti ti-check\"></i> ${existingId?'Save changes':'Add customer'}</button>\r\n    `,'lg');\r\n  }\r\n\r\n  async function saveCustomer(existingId){\r\n    const restore=_withBtnSpin(event,'Saving...');\r\n    try{\r\n    const g=id=>document.getElementById(id)?.value?.trim()||'';\r\n    const name=g('ims-dsc-name');\r\n    if(!name){ui().toast('Business name is required','error');return;}\r\n    const data={business_name:name,contact_name:g('ims-dsc-contact')||null,email:g('ims-dsc-email')||null,phone:g('ims-dsc-phone')||null,postcode:g('ims-dsc-postcode')||null,address:g('ims-dsc-address')||null,discount_pct:parseFloat(g('ims-dsc-discount'))||0,delivery_method:g('ims-dsc-delivery')||'mdf_delivers',credit_terms:g('ims-dsc-terms')||'Fortnightly',credit_limit:parseFloat(g('ims-dsc-limit'))||0,notes:g('ims-dsc-notes')||null};\r\n    const {error}=existingId?await db().update('dropship_customers',existingId,data):await db().insert('dropship_customers',data);\r\n    if(error){ui().toast('Failed: '+error.message,'error');return;}\r\n    ui().closeModal();ui().toast(`Dropship customer ${existingId?'updated':'added'}`,'success');loadCustomers();\r\n    } finally { restore(); }\r\n  }\r\n\r\n  // A partner with sales history (orders collected, delivered or written\r\n  // off, or any invoice) cannot be deleted: that would erase real sales,\r\n  // invoices and accounts. Returns a reason, or null if deleting is safe.\r\n  async function _dsCustomerHistory(client, customerId) {\r\n    const { data: orders } = await client.from('orders').select('order_number,status')\r\n      .eq('dropship_customer_id', customerId).eq('fulfillment_type', 'dropship');\r\n    const { data: invoices } = await client.from('dropship_invoices').select('id').eq('customer_id', customerId);\r\n    const nums = (orders || []).map(o => o.order_number).filter(Boolean);\r\n    let left = (orders || []).filter(o => ['collected', 'delivered'].includes(o.status)).length;\r\n    if (!left && nums.length) {\r\n      const { data: moved } = await db().select('stock_movements', { in: { reference: nums, movement_type: ['sale', 'write_off'] }, limit: 1, noCompanyFilter: true });\r\n      if (moved?.length) left = 1;\r\n    }\r\n    const inv = (invoices || []).length;\r\n    if (!left && !inv) return null;\r\n    const parts = [];\r\n    if (left) parts.push('orders that have been collected or delivered');\r\n    if (inv) parts.push(`${inv} invoice${inv === 1 ? '' : 's'}`);\r\n    return parts.join(' and ');\r\n  }\r\n\r\n  async function deleteCustomer(customerId, customerName) {\r\n    if (!window.SM.AUTH.isAdmin()) { ui().toast('Admin access required', 'error'); return; }\r\n\r\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\r\n\r\n    const history = await _dsCustomerHistory(client, customerId);\r\n    if (history) {\r\n      ui().openModal('Cannot delete this customer', `\r\n        <div class=\"ims__alert ims__alert--warning\"><i class=\"ti ti-alert-triangle\"></i>\r\n          <span><strong>${util().sanitize(customerName)}</strong> has sales history (${history}). Deleting them would erase real sales, invoices and accounts, so it is not allowed.</span>\r\n        </div>\r\n      `, `<button class=\"ims__btn ims__btn--primary\" onclick=\"window.SM.UI.closeModal()\">OK</button>`, 'sm');\r\n      return;\r\n    }\r\n\r\n    const [{ data: allocs }, { data: orders }, { data: invoices }] = await Promise.all([\r\n      client.from('dropship_allocations').select('id, remaining_qty, product_id, warehouse_id').eq('customer_id', customerId),\r\n      client.from('orders').select('id, order_number, status, invoice_id').eq('dropship_customer_id', customerId).eq('fulfillment_type', 'dropship'),\r\n      client.from('dropship_invoices').select('id').eq('customer_id', customerId)\r\n    ]);\r\n\r\n    const totalReserved = (allocs || []).reduce((s, a) => s + (a.remaining_qty || 0), 0);\r\n    const totalOrders = (orders || []).length;\r\n    const totalInvoices = (invoices || []).length;\r\n\r\n    ui().openModal('Delete customer', `\r\n      <div class=\"ims__alert ims__alert--danger\" style=\"margin-bottom:16px\">\r\n        <i class=\"ti ti-alert-triangle\"></i>\r\n        <span>You are about to permanently delete <strong>${util().sanitize(customerName)}</strong>. This cannot be undone.</span>\r\n      </div>\r\n      <div style=\"display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:16px\">\r\n        <div class=\"ims__stat\" style=\"padding:12px\">\r\n          <div class=\"ims__stat-label\">Stock allocations</div>\r\n          <div class=\"ims__stat-value\" style=\"font-size:22px\">${(allocs||[]).length}</div>\r\n          <div style=\"font-size:11px;color:var(--ims-text-muted);margin-top:2px\">${totalReserved} reserved units will be released</div>\r\n        </div>\r\n        <div class=\"ims__stat\" style=\"padding:12px\">\r\n          <div class=\"ims__stat-label\">Dropship orders</div>\r\n          <div class=\"ims__stat-value\" style=\"font-size:22px\">${totalOrders}</div>\r\n          <div style=\"font-size:11px;color:var(--ims-text-muted);margin-top:2px\">All order records will be removed</div>\r\n        </div>\r\n        <div class=\"ims__stat\" style=\"padding:12px\">\r\n          <div class=\"ims__stat-label\">Invoices</div>\r\n          <div class=\"ims__stat-value\" style=\"font-size:22px\">${totalInvoices}</div>\r\n          <div style=\"font-size:11px;color:var(--ims-text-muted);margin-top:2px\">All invoices will be deleted</div>\r\n        </div>\r\n        <div class=\"ims__stat\" style=\"padding:12px\">\r\n          <div class=\"ims__stat-label\">Financial transactions</div>\r\n          <div class=\"ims__stat-value\" style=\"font-size:22px\">All</div>\r\n          <div style=\"font-size:11px;color:var(--ims-text-muted);margin-top:2px\">Linked transactions removed</div>\r\n        </div>\r\n      </div>\r\n      <div style=\"font-size:13px;color:var(--ims-text-muted)\">Activity logs, manifest items, logistics jobs and COD records will also be removed.</div>\r\n    `, `\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n      <button class=\"ims__btn ims__btn--danger\" onclick=\"window.IMS_DROPSHIP.confirmDeleteCustomer('${util().jsArg(customerId)}','${util().jsArg(customerName)}')\">\r\n        <i class=\"ti ti-trash\"></i> Yes, delete everything\r\n      </button>\r\n    `, 'sm');\r\n  }\r\n\r\n  async function confirmDeleteCustomer(customerId, customerName) {\r\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\r\n\r\n    const [{ data: allocs }, { data: orders }] = await Promise.all([\r\n      client.from('dropship_allocations').select('id, remaining_qty, product_id, warehouse_id').eq('customer_id', customerId),\r\n      client.from('orders').select('id, order_number, status').eq('dropship_customer_id', customerId).eq('fulfillment_type', 'dropship')\r\n    ]);\r\n\r\n    const orderIds = (orders || []).map(o => o.id);\r\n\r\n    ui().closeModal();\r\n    // Checked again here, in case an order was collected meanwhile.\r\n    const history = await _dsCustomerHistory(client, customerId);\r\n    if (history) {\r\n      ui().toast(`${customerName} cannot be deleted: they have sales history (${history}).`, 'warning', 9000);\r\n      return;\r\n    }\r\n    ui().toast('Deleting customer, please wait...', 'info', 8000);\r\n\r\n    // 1 - Release this partner's whole reservation: the units left in their\r\n    // allocations, plus the units held by their open (not cancelled)\r\n    // orders, which stay on the shelf ring-fenced for them until they leave.\r\n    // Totalled per product and warehouse first, then applied once per stock\r\n    // row, one row at a time. (Before: releases ran all at once, so two\r\n    // batches of one product lost a release; open orders' units stayed\r\n    // locked; and a separate step added every unit the partner had ever\r\n    // been sold back onto on-hand, even though those goods had long gone.\r\n    // That step is removed: a partner with sales history cannot be deleted.)\r\n    const release = {};\r\n    const addRelease = (productId, whId, qty) => {\r\n      if (!productId || !whId || !qty) return;\r\n      const k = `${productId}|${whId}`;\r\n      release[k] = (release[k] || 0) + qty;\r\n    };\r\n    (allocs || []).forEach(a => addRelease(a.product_id, a.warehouse_id, a.remaining_qty || 0));\r\n    const openOrders = (orders || []).filter(o => o.status !== 'cancelled');\r\n    if (openOrders.length) {\r\n      const { data: openItems } = await client.from('order_items')\r\n        .select('product_id, quantity, dropship_allocation_id, dropship_allocation_split')\r\n        .in('order_id', openOrders.map(o => o.id));\r\n      for (const item of (openItems || [])) {\r\n        if (!item.product_id) continue;\r\n        const split = Array.isArray(item.dropship_allocation_split) ? item.dropship_allocation_split.filter(p => p && p.id && p.qty > 0) : [];\r\n        if (split.length) {\r\n          // Each batch's units are held in that batch's warehouse.\r\n          split.forEach(p => addRelease(item.product_id, (allocs || []).find(a => a.id === p.id)?.warehouse_id, p.qty));\r\n          continue;\r\n        }\r\n        const byId = item.dropship_allocation_id && (allocs || []).find(a => a.id === item.dropship_allocation_id);\r\n        const guess = (allocs || []).find(a => a.product_id === item.product_id);\r\n        addRelease(item.product_id, (byId || guess)?.warehouse_id, item.quantity || 0);\r\n      }\r\n    }\r\n    const releaseProblems = [];\r\n    for (const [k, qty] of Object.entries(release)) {\r\n      const [productId, whId] = k.split('|');\r\n      const { data: sl } = await db().select('stock_levels', {\r\n        eq: { product_id: productId, warehouse_id: whId }, maybeSingle: true, noCompanyFilter: true\r\n      });\r\n      if (!sl) continue;\r\n      const { error } = await db().update('stock_levels', sl.id, {\r\n        reserved_by_allocations: Math.max(0, (sl.reserved_by_allocations || 0) - qty)\r\n      });\r\n      if (error) releaseProblems.push(productId);\r\n    }\r\n    if (releaseProblems.length) {\r\n      ui().toast(`${customerName}: the partner reservation could not be released for ${releaseProblems.length} product(s). Please check stock levels.`, 'warning', 10000);\r\n    }\r\n\r\n    // 3 \u2014 Delete transactions, AR, manifest items, logistics, COD, activity logs, order items\r\n    if (orderIds.length) {\r\n      for (const orderId of orderIds) {\r\n        await client.from('transactions').delete().eq('related_id', orderId);\r\n        await client.from('accounts_receivable').delete().eq('order_id', orderId);\r\n        await client.from('manifest_items').delete().eq('order_id', orderId);\r\n        await client.from('logistics_jobs').delete().eq('order_id', orderId);\r\n        await client.from('cod_transactions').delete().eq('order_id', orderId);\r\n        await client.from('order_activity_log').delete().eq('order_id', orderId);\r\n      }\r\n      const orderNumbers = (orders || []).map(o => o.order_number);\r\n      for (const ref of orderNumbers) {\r\n        await client.from('transactions').delete().eq('reference', ref);\r\n      }\r\n      await client.from('order_items').delete().in('order_id', orderIds);\r\n      await client.from('orders').delete().in('id', orderIds);\r\n    }\r\n\r\n    // 4 \u2014 Delete allocations and invoices\r\n    await client.from('dropship_allocations').delete().eq('customer_id', customerId);\r\n    await client.from('dropship_invoices').delete().eq('customer_id', customerId);\r\n\r\n    // 5 \u2014 Delete the customer\r\n    await db().remove('dropship_customers', customerId);\r\n\r\n    ui().toast(`${customerName} deleted: all records removed and their reserved stock released`, 'success', 6000);\r\n    loadCustomers();\r\n  }\r\n\r\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\r\n  // STOCK ALLOCATIONS \u2014 BULK MULTI-PRODUCT FLOW\r\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\r\n  let _allocSelection = {};   // { productId: { id, name, sku, stockByWh } }\r\n  let _allocCustomerId = '';\r\n  let _allocCustomerName = '';\r\n  let _allocWarehouses = [];\r\n  let _allocAllProducts = [];\r\n\r\n  // STEP 1 \u2014 search & select products\r\n  // \u2500\u2500\u2500 DROPSHIP CUSTOMER-SPECIFIC FLAT PRICING \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n  // Per explicit design decision: dropship customers get a flat\r\n  // per-unit price set directly for them, per product \u2014 completely\r\n  // decoupled from the shared wholesale price table used by regular\r\n  // retailers/wholesalers. Any standing % discount on the customer's\r\n  // record is deducted from THIS flat price (via _dsCalcPrice, already\r\n  // in place), not from the shared wholesale rate. When no override\r\n  // exists for a given product, pricing falls back to the shared\r\n  // wholesale rate exactly as before \u2014 this is purely additive.\r\n  async function showCustomerPricing(customerId, customerName){\r\n    const btn=event?.target?.closest?.('button');\r\n    const restore=_withBtnSpin(btn,'Loading...');\r\n    const [{data:rows},{data:allocs}]=await Promise.all([\r\n      db().select('dropship_customer_prices',{\r\n        select:'id,product_id,unit_price,updated_at,products(name,sku)',\r\n        eq:{customer_id:customerId},\r\n        order:{col:'created_at',asc:false}\r\n      }),\r\n      // Only products actually allocated to this customer should be\r\n      // selectable \u2014 per request, not the entire product catalogue.\r\n      db().select('dropship_allocations',{\r\n        select:'product_id,products(name,sku)',\r\n        eq:{customer_id:customerId}\r\n      })\r\n    ]);\r\n    restore();\r\n\r\n    const alreadyPriced=new Set((rows||[]).map(r=>r.product_id));\r\n    const uniqueAllocs=(allocs||[]).filter((a,i,arr)=>arr.findIndex(x=>x.product_id===a.product_id)===i && !alreadyPriced.has(a.product_id));\r\n    const productOpts=uniqueAllocs.length\r\n      ? uniqueAllocs.map(a=>`<option value=\"${a.product_id}\">${util().sanitize(a.products?.name||'\u2014')}${a.products?.sku?' ('+util().sanitize(a.products.sku)+')':''}</option>`).join('')\r\n      : '';\r\n\r\n    ui().openModal(`Custom pricing: ${customerName}`,`\r\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:12px\">\r\n        <i class=\"ti ti-info-circle\"></i>\r\n        <span>Set a flat per-unit price for this customer, per product. Any standing discount % on their record is deducted from this price. Products without an override here use the standard shared wholesale rate.</span>\r\n      </div>\r\n      <div id=\"ims-cp-list\" style=\"margin-bottom:14px\">\r\n        ${(rows||[]).length?`\r\n          <table class=\"ims__table\">\r\n            <thead><tr><th>Product</th><th>SKU</th><th style=\"text-align:right\">Flat price</th><th></th><th></th></tr></thead>\r\n            <tbody>${rows.map(r=>{\r\n              const isRecent=r.updated_at&&(Date.now()-new Date(r.updated_at).getTime())<5*60*1000;\r\n              return `\r\n              <tr style=\"${isRecent?'background:var(--ims-warning-bg)':''}\">\r\n                <td>${util().sanitize(r.products?.name||'\u2014')}</td>\r\n                <td style=\"font-size:11px;color:var(--ims-text-muted)\">${util().sanitize(r.products?.sku||'\u2014')}</td>\r\n                <td style=\"text-align:right;font-weight:600\">${util().formatCurrency(r.unit_price)}</td>\r\n                <td>${isRecent?'<span class=\"ims__pill ims__pill--warning\" style=\"font-size:10px\">Just updated</span>':''}</td>\r\n                <td><div class=\"ims__btn-group\">\r\n                                    <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" data-price=\"${Number(r.unit_price)||0}\" onclick=\"window.IMS_DROPSHIP.editCustomPrice('${util().jsArg(r.product_id)}',this)\" title=\"Edit price\"><i class=\"ti ti-edit\"></i></button>\r\n                  <button class=\"ims__btn ims__btn--danger ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_DROPSHIP.deleteCustomPrice('${util().jsArg(r.id)}','${util().jsArg(customerId)}','${util().jsArg(customerName)}')\" title=\"Remove\"><i class=\"ti ti-trash\"></i></button>\r\n                </div></td>\r\n              </tr>`;\r\n            }).join('')}\r\n            </tbody>\r\n          </table>` : '<div style=\"font-size:13px;color:var(--ims-text-muted);text-align:center;padding:16px\">No custom prices set yet for this customer</div>'}\r\n      </div>\r\n      <hr class=\"ims__divider\">\r\n      <div style=\"font-size:13px;font-weight:600;margin-bottom:8px\">Add / update a custom price</div>\r\n      <input type=\"hidden\" id=\"ims-cp-editing-product\">\r\n      <div id=\"ims-cp-editing-label\" style=\"display:none;font-size:12px;color:var(--ims-accent);margin-bottom:6px\"></div>\r\n      ${productOpts?`\r\n        <div style=\"display:flex;gap:8px;align-items:center\">\r\n                    <select class=\"ims__select\" id=\"ims-cp-product\" onchange=\"window.IMS_DROPSHIP.clearCustomPriceEdit()\">\r\n            <option value=\"\">Select an allocated product...</option>\r\n            ${productOpts}\r\n          </select>\r\n          <input class=\"ims__input\" type=\"number\" step=\"0.01\" min=\"0\" id=\"ims-cp-price\" placeholder=\"Flat unit price (\u00A3)\" style=\"max-width:160px\">\r\n          <button class=\"ims__btn ims__btn--primary ims__btn--sm\" onclick=\"window.IMS_DROPSHIP.saveCustomPrice('${util().jsArg(customerId)}','${util().jsArg(customerName)}')\"><i class=\"ti ti-check\"></i> Save</button>\r\n        </div>`\r\n        : `<div style=\"display:flex;gap:8px;align-items:center\">\r\n             <input class=\"ims__input\" type=\"number\" step=\"0.01\" min=\"0\" id=\"ims-cp-price\" placeholder=\"Flat unit price (\u00A3)\" style=\"max-width:160px\" disabled>\r\n             <button class=\"ims__btn ims__btn--primary ims__btn--sm\" onclick=\"window.IMS_DROPSHIP.saveCustomPrice('${util().jsArg(customerId)}','${util().jsArg(customerName)}')\" disabled><i class=\"ti ti-check\"></i> Save</button>\r\n           </div>\r\n           <div class=\"ims__input-hint\" style=\"margin-top:6px\">All allocated products already have a custom price \u2014 use the <i class=\"ti ti-edit\"></i> edit button above to change one, or allocate additional stock to price something new.</div>`}\r\n    `,`\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Close</button>\r\n    `,'lg');\r\n  }\r\n\r\n      // Called from the Edit button on a custom price row. The product name is\r\n  // read from the row itself and the price from the button's data-price,\r\n  // rather than being passed inside the onclick. A name containing a quote\r\n  // mark (e.g. 12\" mattress) would otherwise break the button entirely.\r\n  function editCustomPrice(productId, btn){\r\n    const hidden=document.getElementById('ims-cp-editing-product');\r\n    const label=document.getElementById('ims-cp-editing-label');\r\n    const priceInput=document.getElementById('ims-cp-price');\r\n    const dropdown=document.getElementById('ims-cp-product');\r\n    const row=btn?.closest?.('tr');\r\n    const productName=(row?.cells?.[0]?.textContent||'').trim();\r\n    const currentPrice=btn?.dataset?.price||'';\r\n    // Editing a priced row and picking a new product are two separate\r\n    // paths. Clear the dropdown so it is obvious which product Save updates.\r\n    if(dropdown) dropdown.value='';\r\n    if(hidden) hidden.value=productId;\r\n    if(label){\r\n      label.style.display='';\r\n      label.innerHTML='<i class=\"ti ti-edit\"></i> Editing: <strong></strong> <button type=\"button\" class=\"ims__btn ims__btn--ghost ims__btn--sm\" style=\"margin-left:6px\" onclick=\"window.IMS_DROPSHIP.clearCustomPriceEdit()\">Cancel</button>';\r\n      label.querySelector('strong').textContent=productName;\r\n    }\r\n    if(priceInput){\r\n      priceInput.disabled=false;\r\n      priceInput.value=currentPrice;\r\n      // When every allocated product is already priced, the Save button is\r\n      // drawn disabled next to the price box. Editing is the only way to\r\n      // change a price in that state, so Save must be switched on here too.\r\n      const saveBtn=priceInput.parentElement?.querySelector('button.ims__btn--primary');\r\n      if(saveBtn) saveBtn.disabled=false;\r\n      priceInput.focus();\r\n    }\r\n  }\r\n\r\n  // Leaves edit mode. Runs when staff press Cancel, or pick a product from\r\n  // the dropdown. Before this existed, the edit target stayed set after\r\n  // picking from the dropdown, so Save updated the row being edited\r\n  // instead of the product just picked.\r\n  function clearCustomPriceEdit(){\r\n    const hidden=document.getElementById('ims-cp-editing-product');\r\n    const label=document.getElementById('ims-cp-editing-label');\r\n    const priceInput=document.getElementById('ims-cp-price');\r\n    const dropdown=document.getElementById('ims-cp-product');\r\n    const wasEditing=!!hidden?.value;\r\n    if(hidden) hidden.value='';\r\n    if(label){ label.style.display='none'; label.innerHTML=''; }\r\n    if(priceInput){\r\n      // The price in the box belonged to the row being edited, so clear it.\r\n      if(wasEditing) priceInput.value='';\r\n      // With no dropdown (every allocated product already priced), the\r\n      // price box starts disabled. Put it back that way.\r\n      if(!dropdown){\r\n        priceInput.disabled=true;\r\n        const saveBtn=priceInput.parentElement?.querySelector('button.ims__btn--primary');\r\n        if(saveBtn) saveBtn.disabled=true;\r\n      }\r\n    }\r\n  }\r\n\r\n  async function saveCustomPrice(customerId,customerName){\r\n    const btn=event?.target?.closest?.('button');\r\n    const restore=_withBtnSpin(btn,'Saving...');\r\n    // Editing an existing row takes priority over the dropdown, since\r\n    // already-priced products are deliberately excluded from it \u2014 the\r\n    // Edit button is the only path to updating a price once it's set.\r\n    const editingId=document.getElementById('ims-cp-editing-product')?.value;\r\n    const productId=editingId||document.getElementById('ims-cp-product')?.value;\r\n    if(!productId){ui().toast('Please select a product','error');restore();return;}\r\n    const price=parseFloat(document.getElementById('ims-cp-price')?.value);\r\n    if(!price||price<=0){ui().toast('Please enter a valid price','error');restore();return;}\r\n\r\n    const {data:existing}=await db().select('dropship_customer_prices',{\r\n      eq:{customer_id:customerId,product_id:productId},maybeSingle:true\r\n    });\r\n    let error;\r\n    if(existing){\r\n      ({error}=await db().update('dropship_customer_prices',existing.id,{unit_price:price,updated_at:new Date().toISOString()}));\r\n    } else {\r\n      ({error}=await db().insert('dropship_customer_prices',{customer_id:customerId,product_id:productId,unit_price:price}));\r\n    }\r\n    restore();\r\n    if(error){ui().toast('Failed: '+error.message,'error');return;}\r\n    ui().toast('Custom price saved','success');\r\n    showCustomerPricing(customerId,customerName);\r\n  }\r\n\r\n  async function deleteCustomPrice(id,customerId,customerName){\r\n    ui().confirm(\r\n      'Remove this custom price? The product will fall back to the standard shared wholesale rate for this customer.',\r\n      async()=>{\r\n        await db().remove('dropship_customer_prices',id);\r\n        ui().toast('Custom price removed','success');\r\n        showCustomerPricing(customerId,customerName);\r\n      },\r\n      'Remove price', true\r\n    );\r\n  }\r\n\r\n  async function showAllocateForm(customerId, customerName){\r\n    _allocCustomerId   = customerId;\r\n    _allocCustomerName = customerName;\r\n    _allocSelection    = {};\r\n\r\n    const [{data:whs},{data:prods}]=await Promise.all([\r\n      db().select('warehouses',{eq:{is_active:true}}),\r\n      db().select('products',{select:'id,name,sku',order:{col:'name'}})\r\n    ]);\r\n    _allocWarehouses  = whs  || [];\r\n    _allocAllProducts = prods || [];\r\n\r\n    ui().openModal(\r\n      `Allocate stock: ${customerName}`,\r\n      `<div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:12px\">\r\n        <i class=\"ti ti-info-circle\"></i>\r\n        <span>Search by product name or SKU, tick to select multiple products, then click <strong>Next: set quantities</strong>.</span>\r\n      </div>\r\n      <div class=\"ims__search-wrap\" style=\"margin-bottom:10px\">\r\n        <i class=\"ti ti-search\"></i>\r\n        <input class=\"ims__input\" type=\"text\" id=\"ims-alloc-search\"\r\n          placeholder=\"Type product name or SKU...\"\r\n          oninput=\"window.IMS_DROPSHIP.renderAllocSearch(this.value)\"\r\n          autocomplete=\"off\">\r\n      </div>\r\n      <div id=\"ims-alloc-chips\" style=\"display:flex;flex-wrap:wrap;gap:6px;min-height:24px;margin-bottom:10px\"></div>\r\n      <div id=\"ims-alloc-results\" style=\"max-height:360px;overflow-y:auto;border:1px solid var(--ims-border);border-radius:var(--ims-radius)\">\r\n        <div style=\"padding:28px;text-align:center;color:var(--ims-text-muted);font-size:13px\">\r\n          <i class=\"ti ti-search\" style=\"font-size:28px;display:block;margin-bottom:8px;opacity:.25\"></i>\r\n          Start typing to search products\r\n        </div>\r\n      </div>\r\n      <div id=\"ims-alloc-count\" style=\"font-size:12px;color:var(--ims-text-muted);margin-top:8px;text-align:right\">0 products selected</div>`,\r\n      `<button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n       <button class=\"ims__btn ims__btn--primary\" id=\"ims-alloc-next-btn\" disabled\r\n         onclick=\"window.IMS_DROPSHIP.allocConfirmSelection()\">\r\n         <i class=\"ti ti-arrow-right\"></i> Next: set quantities\r\n       </button>`,\r\n      'lg'\r\n    );\r\n    setTimeout(()=>document.getElementById('ims-alloc-search')?.focus(),150);\r\n  }\r\n\r\n  function renderAllocSearch(query){\r\n    const q=(query||'').toLowerCase().trim();\r\n    const resultsEl=document.getElementById('ims-alloc-results');\r\n    if(!resultsEl)return;\r\n\r\n    if(!q){\r\n      resultsEl.innerHTML=`<div style=\"padding:28px;text-align:center;color:var(--ims-text-muted);font-size:13px\">\r\n        <i class=\"ti ti-search\" style=\"font-size:28px;display:block;margin-bottom:8px;opacity:.25\"></i>\r\n        Start typing to search products\r\n      </div>`;\r\n      return;\r\n    }\r\n\r\n    const filtered=_allocAllProducts.filter(p=>\r\n      p.name?.toLowerCase().includes(q)||p.sku?.toLowerCase().includes(q)\r\n    );\r\n\r\n    if(!filtered.length){\r\n      resultsEl.innerHTML=`<div style=\"padding:16px;text-align:center;color:var(--ims-text-muted);font-size:13px\">No products match \"${util().sanitize(query)}\"</div>`;\r\n      return;\r\n    }\r\n\r\n    resultsEl.innerHTML=filtered.slice(0,60).map(p=>{\r\n      const selected=!!_allocSelection[p.id];\r\n      return`<label style=\"display:flex;align-items:center;gap:10px;padding:9px 14px;\r\n        border-bottom:1px solid var(--ims-border);cursor:pointer;\r\n        background:${selected?'var(--ims-accent-bg)':'var(--ims-surface)'};transition:background .1s\"\r\n        onmouseenter=\"this.style.background='${selected?'var(--ims-accent-bg)':'var(--ims-surface2)'}'\"\r\n        onmouseleave=\"this.style.background='${selected?'var(--ims-accent-bg)':'var(--ims-surface)'}'\">\r\n        <input type=\"checkbox\" ${selected?'checked':''}\r\n          onchange=\"window.IMS_DROPSHIP.allocToggleProduct('${util().jsArg(p.id)}','${util().jsArg(p.name)}','${util().jsArg(p.sku||'')}',this.checked)\"\r\n          style=\"width:16px;height:16px;flex-shrink:0;accent-color:var(--ims-accent)\">\r\n        <div style=\"flex:1;min-width:0\">\r\n          <div style=\"font-size:13px;font-weight:${selected?'600':'400'};color:${selected?'var(--ims-accent)':'var(--ims-text)'};white-space:nowrap;overflow:hidden;text-overflow:ellipsis\">${util().sanitize(p.name)}</div>\r\n          <div style=\"font-size:11px;color:var(--ims-text-muted)\">${util().sanitize(p.sku||'\u2014')}</div>\r\n        </div>\r\n        ${selected?'<i class=\"ti ti-check\" style=\"color:var(--ims-accent);font-size:16px;flex-shrink:0\"></i>':''}\r\n      </label>`;\r\n    }).join('')+(filtered.length>60?`<div style=\"padding:8px 14px;font-size:11px;color:var(--ims-text-muted);text-align:center;background:var(--ims-surface2)\">Showing first 60 \u2014 refine your search</div>`:'');\r\n  }\r\n\r\n  function allocToggleProduct(id,name,sku,checked){\r\n    if(checked){\r\n      _allocSelection[id]={id,name,sku,stockByWh:{}};\r\n    } else {\r\n      delete _allocSelection[id];\r\n    }\r\n    // Update chips\r\n    const chipsEl=document.getElementById('ims-alloc-chips');\r\n    const countEl=document.getElementById('ims-alloc-count');\r\n    const nextBtn=document.getElementById('ims-alloc-next-btn');\r\n    const count=Object.keys(_allocSelection).length;\r\n\r\n    if(chipsEl){\r\n      chipsEl.innerHTML=Object.values(_allocSelection).map(p=>`\r\n        <span style=\"display:inline-flex;align-items:center;gap:5px;padding:3px 8px 3px 10px;\r\n          background:var(--ims-accent-bg);color:var(--ims-accent);border-radius:999px;font-size:12px;font-weight:500\">\r\n          ${util().sanitize(p.name)}\r\n          <button onclick=\"window.IMS_DROPSHIP.allocToggleProduct('${util().jsArg(p.id)}','','',false);window.IMS_DROPSHIP.renderAllocSearch(document.getElementById('ims-alloc-search')?.value||'')\"\r\n            style=\"background:none;border:none;color:var(--ims-accent);cursor:pointer;padding:0;line-height:1;font-size:15px\" title=\"Remove\">\u00D7</button>\r\n        </span>`).join('');\r\n    }\r\n    if(countEl) countEl.textContent=`${count} product${count===1?'':'s'} selected`;\r\n    if(nextBtn) nextBtn.disabled=count===0;\r\n\r\n    // Re-render results to reflect new state\r\n    renderAllocSearch(document.getElementById('ims-alloc-search')?.value||'');\r\n  }\r\n\r\n  // STEP 2 \u2014 set warehouse + quantity per selected product\r\n  async function allocConfirmSelection(){\r\n    const selected=Object.values(_allocSelection);\r\n    if(!selected.length)return;\r\n\r\n    // Load available stock for all selected products\r\n    const enriched=await Promise.all(selected.map(async p=>{\r\n      const {data:levels}=await db().select('stock_levels',{\r\n        select:'warehouse_id,quantity,reserved_qty,reserved_by_allocations',\r\n        eq:{product_id:p.id},\r\n        noCompanyFilter:true\r\n      });\r\n      const byWh={};\r\n      (levels||[]).forEach(l=>{byWh[l.warehouse_id]=(l.quantity||0)-(l.reserved_qty||0)-(l.reserved_by_allocations||0);});\r\n      return{...p,stockByWh:byWh};\r\n    }));\r\n    enriched.forEach(p=>{_allocSelection[p.id]=p;});\r\n\r\n    const defaultWhId=_allocWarehouses[0]?.id||'';\r\n\r\n    ui().openModal(\r\n      `Allocate stock: ${_allocCustomerName} \u2014 Set quantities`,\r\n      `<div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:14px\">\r\n        <i class=\"ti ti-info-circle\"></i>\r\n        <span>Set the warehouse and quantity for each product. Available stock updates when you change warehouse. Stock will be <strong>soft reserved</strong> \u2014 stays in your warehouse but shows as reserved.</span>\r\n      </div>\r\n      <div class=\"ims__table-wrap\">\r\n        <table class=\"ims__table\">\r\n          <thead><tr>\r\n            <th>Product</th><th>SKU</th>\r\n            <th style=\"width:190px\">Warehouse</th>\r\n            <th style=\"width:110px\">Available</th>\r\n            <th style=\"width:110px\">Qty to allocate</th>\r\n            <th style=\"width:40px\"></th>\r\n          </tr></thead>\r\n          <tbody id=\"ims-alloc-qty-tbody\">\r\n            ${enriched.map(p=>{\r\n              const avail=p.stockByWh[defaultWhId]??0;\r\n              return`<tr id=\"ims-alloc-row-${p.id}\">\r\n                <td style=\"font-weight:500\">${util().sanitize(p.name)}</td>\r\n                <td style=\"font-size:12px;color:var(--ims-text-muted)\">${util().sanitize(p.sku||'\u2014')}</td>\r\n                <td>\r\n                  <select class=\"ims__select\" style=\"font-size:12px\" id=\"ims-alloc-wh-${p.id}\"\r\n                    onchange=\"window.IMS_DROPSHIP.allocUpdateAvail('${util().jsArg(p.id)}')\">\r\n                    ${_allocWarehouses.map(w=>`<option value=\"${w.id}\">${util().sanitize(w.name)}</option>`).join('')}\r\n                  </select>\r\n                </td>\r\n                <td>\r\n                  <span id=\"ims-alloc-avail-${p.id}\"\r\n                    style=\"font-weight:600;color:${avail<=0?'var(--ims-danger)':avail<=5?'var(--ims-warning)':'var(--ims-success)'}\">\r\n                    ${avail}\r\n                  </span>\r\n                </td>\r\n                <td>\r\n                  <input class=\"ims__input\" type=\"number\" min=\"1\"\r\n                    id=\"ims-alloc-qty-${p.id}\" value=\"1\"\r\n                    style=\"width:80px;font-size:13px;text-align:center\"\r\n                    oninput=\"window.IMS_DROPSHIP.allocValidateQty('${util().jsArg(p.id)}')\">\r\n                </td>\r\n                <td>\r\n                  <button class=\"ims__btn ims__btn--danger ims__btn--sm ims__btn--icon\"\r\n                    onclick=\"window.IMS_DROPSHIP.allocRemoveRow('${util().jsArg(p.id)}')\" title=\"Remove\">\r\n                    <i class=\"ti ti-trash\"></i>\r\n                  </button>\r\n                </td>\r\n              </tr>`;\r\n            }).join('')}\r\n          </tbody>\r\n        </table>\r\n      </div>\r\n      <div style=\"display:flex;justify-content:space-between;align-items:center;margin-top:12px\">\r\n        <div style=\"font-size:13px;color:var(--ims-text-muted)\">\r\n          <strong id=\"ims-alloc-total-count\">${enriched.length}</strong> product(s) to allocate\r\n        </div>\r\n      </div>`,\r\n      `<button class=\"ims__btn ims__btn--ghost\"\r\n          onclick=\"window.IMS_DROPSHIP.showAllocateForm('${util().jsArg(_allocCustomerId)}','${util().jsArg(_allocCustomerName)}')\">\r\n          <i class=\"ti ti-arrow-left\"></i> Back\r\n        </button>\r\n        <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n        <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_DROPSHIP.saveAllocationBulk()\">\r\n          <i class=\"ti ti-check\"></i> Allocate all stock\r\n        </button>`,\r\n      'xl'\r\n    );\r\n  }\r\n\r\n  function allocUpdateAvail(productId){\r\n    const whId=document.getElementById(`ims-alloc-wh-${productId}`)?.value;\r\n    const avail=_allocSelection[productId]?.stockByWh?.[whId]??0;\r\n    const el=document.getElementById(`ims-alloc-avail-${productId}`);\r\n    if(el){\r\n      el.textContent=avail;\r\n      el.style.color=avail<=0?'var(--ims-danger)':avail<=5?'var(--ims-warning)':'var(--ims-success)';\r\n    }\r\n    allocValidateQty(productId);\r\n  }\r\n\r\n  function allocValidateQty(productId){\r\n    const whId=document.getElementById(`ims-alloc-wh-${productId}`)?.value;\r\n    const qtyEl=document.getElementById(`ims-alloc-qty-${productId}`);\r\n    const avail=_allocSelection[productId]?.stockByWh?.[whId]??0;\r\n    const qty=parseInt(qtyEl?.value)||0;\r\n    if(qtyEl) qtyEl.style.borderColor=(qty>avail||qty<1)?'var(--ims-danger)':'';\r\n  }\r\n\r\n  function allocRemoveRow(productId){\r\n    document.getElementById(`ims-alloc-row-${productId}`)?.remove();\r\n    delete _allocSelection[productId];\r\n    const count=Object.keys(_allocSelection).length;\r\n    const countEl=document.getElementById('ims-alloc-total-count');\r\n    if(countEl) countEl.textContent=count;\r\n    if(count===0){\r\n      ui().toast('No products left \u2014 returning to search','info');\r\n      showAllocateForm(_allocCustomerId,_allocCustomerName);\r\n    }\r\n  }\r\n\r\n  async function saveAllocationBulk(){\r\n    const rows=Object.keys(_allocSelection);\r\n    const total=rows.length;\r\n    const today=new Date().toISOString().split('T')[0];\r\n    let errors=[],saved=0;\r\n\r\n    // Validate all rows first before touching the DB\r\n    for(const productId of rows){\r\n      const whId=document.getElementById(`ims-alloc-wh-${productId}`)?.value;\r\n      const qty=parseInt(document.getElementById(`ims-alloc-qty-${productId}`)?.value)||0;\r\n      const avail=_allocSelection[productId]?.stockByWh?.[whId]??0;\r\n      const name=_allocSelection[productId]?.name||productId;\r\n      if(!whId){errors.push(`${name}: no warehouse selected`);}\r\n      else if(qty<1){errors.push(`${name}: quantity must be at least 1`);}\r\n      else if(qty>avail){errors.push(`${name}: only ${avail} units available`);}\r\n    }\r\n    if(errors.length){\r\n      ui().toast(errors[0],'error',5000);\r\n      return;\r\n    }\r\n\r\n    // Disable button and show progress bar in modal footer\r\n    const saveBtn=document.querySelector('#ims-modal-footer .ims__btn--primary');\r\n    if(saveBtn){\r\n      saveBtn.disabled=true;\r\n      saveBtn.innerHTML=`<i class=\"ti ti-loader-2 ims__spin\"></i> Allocating...`;\r\n    }\r\n\r\n    // Inject a progress bar above the table\r\n    const tbody=document.getElementById('ims-alloc-qty-tbody');\r\n    if(tbody){\r\n      const progressHtml=`\r\n        <div id=\"ims-alloc-progress\" style=\"margin-bottom:14px\">\r\n          <div style=\"display:flex;justify-content:space-between;font-size:12px;color:var(--ims-text-muted);margin-bottom:5px\">\r\n            <span id=\"ims-alloc-progress-label\">Starting...</span>\r\n            <span id=\"ims-alloc-progress-pct\">0%</span>\r\n          </div>\r\n          <div style=\"background:var(--ims-border);border-radius:999px;height:8px;overflow:hidden\">\r\n            <div id=\"ims-alloc-progress-bar\"\r\n              style=\"height:8px;width:0%;background:var(--ims-accent);border-radius:999px;transition:width .25s\"></div>\r\n          </div>\r\n        </div>`;\r\n      tbody.closest('.ims__table-wrap').insertAdjacentHTML('beforebegin', progressHtml);\r\n    }\r\n\r\n    const setProgress=(done,label)=>{\r\n      const pct=Math.round((done/total)*100);\r\n      const bar=document.getElementById('ims-alloc-progress-bar');\r\n      const pctEl=document.getElementById('ims-alloc-progress-pct');\r\n      const labelEl=document.getElementById('ims-alloc-progress-label');\r\n      if(bar) bar.style.width=pct+'%';\r\n      if(pctEl) pctEl.textContent=pct+'%';\r\n      if(labelEl) labelEl.textContent=label;\r\n    };\r\n\r\n    for(let i=0;i<rows.length;i++){\r\n      const productId=rows[i];\r\n      const whId=document.getElementById(`ims-alloc-wh-${productId}`)?.value;\r\n      const qty=parseInt(document.getElementById(`ims-alloc-qty-${productId}`)?.value)||0;\r\n      const name=_allocSelection[productId]?.name||productId;\r\n\r\n      setProgress(i, `Allocating ${i+1} of ${total}: ${name}`);\r\n\r\n      const {error:allocErr}=await db().insert('dropship_allocations',{\r\n        customer_id:_allocCustomerId,\r\n        product_id:productId,\r\n        warehouse_id:whId,\r\n        allocated_qty:qty,\r\n        remaining_qty:qty,\r\n        allocation_date:today,\r\n        created_by:window.SM.AUTH.user?.id\r\n      });\r\n      if(allocErr){errors.push(`${name}: ${allocErr.message}`);continue;}\r\n\r\n      // Reserve stock\r\n      const {data:sl}=await db().select('stock_levels',{\r\n        eq:{product_id:productId,warehouse_id:whId},\r\n        maybeSingle:true,noCompanyFilter:true\r\n      });\r\n      if(sl) await db().update('stock_levels',sl.id,{reserved_by_allocations:(sl.reserved_by_allocations||0)+qty});\r\n\r\n      saved++;\r\n      setProgress(i+1, `Done: ${name}`);\r\n\r\n      // Dim the completed row so user sees progress visually\r\n      const row=document.getElementById(`ims-alloc-row-${productId}`);\r\n      if(row) row.style.opacity='0.4';\r\n    }\r\n\r\n    setProgress(total,'All done!');\r\n    await new Promise(r=>setTimeout(r,400)); // brief pause so user sees 100%\r\n\r\n    if(errors.length){\r\n      ui().toast(`${saved} allocated, ${errors.length} failed \u2014 ${errors[0]}`,'warning',6000);\r\n      if(saveBtn){saveBtn.disabled=false;saveBtn.innerHTML='<i class=\"ti ti-check\"></i> Allocate all stock';}\r\n    } else {\r\n      ui().closeModal();\r\n      ui().toast(`${saved} product${saved===1?'':'s'} allocated to ${_allocCustomerName}`,'success',5000);\r\n    }\r\n    _allocSelection={};\r\n    loadCustomers();\r\n  }\r\n\r\n  // kept for backwards compat (openCustomer footer button)\r\n  function checkAvailableStock(){}\r\n\r\n  async function loadAllocations(){\r\n    const content=document.getElementById('ims-ds-content');\r\n    if(!content)return;\r\n    const actions=document.getElementById('ims-ds-actions');\r\n    if(actions)actions.innerHTML='';\r\n\r\n    const {data:allocs}=await db().select('dropship_allocations',{\r\n      select:'*,dropship_customers(business_name),products(name,sku),warehouses(name)',\r\n      order:{col:'created_at',asc:false}\r\n    });\r\n    const items=allocs||[];\r\n    content.innerHTML=`\r\n      <div class=\"ims__table-wrap\">\r\n        <table class=\"ims__table\">\r\n          <thead><tr><th>Customer</th><th>Product</th><th>SKU</th><th>Warehouse</th><th>Allocated</th><th>Remaining</th><th>Sold</th><th>Date</th><th></th></tr></thead>\r\n          <tbody>${items.map(a=>`<tr>\r\n            <td><strong>${util().sanitize(a.dropship_customers?.business_name||'\u2014')}</strong></td>\r\n            <td>${util().sanitize(a.products?.name||'\u2014')}</td>\r\n            <td>${util().sanitize(a.products?.sku||'\u2014')}</td>\r\n            <td>${util().sanitize(a.warehouses?.name||'\u2014')}</td>\r\n            <td>${a.allocated_qty||0}</td>\r\n            <td style=\"font-weight:600;color:${(a.remaining_qty||0)>0?'var(--ims-success)':'var(--ims-text-muted)'}\">${a.remaining_qty||0}</td>\r\n            <td>${(a.allocated_qty||0)-(a.remaining_qty||0)}</td>\r\n            <td>${util().formatDate(a.allocation_date)}</td>\r\n            <td>\r\n              <div class=\"ims__btn-group\">\r\n                <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\"\r\n                  onclick=\"window.IMS_DROPSHIP.editAllocation('${util().jsArg(a.id)}')\"\r\n                  title=\"Edit allocation\"><i class=\"ti ti-edit\"></i></button>\r\n                <button class=\"ims__btn ims__btn--danger ims__btn--sm ims__btn--icon\"\r\n                  onclick=\"window.IMS_DROPSHIP.recallAllocation('${util().jsArg(a.id)}',${a.remaining_qty||0},'${util().jsArg(a.product_id)}','${util().jsArg(a.warehouse_id)}')\"\r\n                  title=\"Recall all remaining stock\"><i class=\"ti ti-arrow-back-up\"></i></button>\r\n              </div>\r\n            </td>\r\n          </tr>`).join('')||'<tr><td colspan=\"9\" class=\"ims__table-empty\">No allocations yet</td></tr>'}\r\n          </tbody>\r\n        </table>\r\n      </div>`;\r\n  }\r\n\r\n  async function editAllocation(allocId){\r\n    // Load allocation with related data\r\n    const {data:a}=await db().select('dropship_allocations',{\r\n      select:'*,products(name,sku),warehouses(name)',\r\n      eq:{id:allocId},maybeSingle:true,noCompanyFilter:true\r\n    });\r\n    if(!a)return;\r\n\r\n    const sold=(a.allocated_qty||0)-(a.remaining_qty||0);\r\n    const {data:whs}=await db().select('warehouses',{eq:{is_active:true}});\r\n\r\n    // Load available stock for each warehouse (excluding this allocation's own reservation)\r\n    const stockByWh={};\r\n    await Promise.all((whs||[]).map(async w=>{\r\n      const {data:sl}=await db().select('stock_levels',{\r\n        eq:{product_id:a.product_id,warehouse_id:w.id},\r\n        maybeSingle:true,noCompanyFilter:true\r\n      });\r\n      if(sl){\r\n        // Add back the current reservation so available = true free + what this allocation holds\r\n        const currentReserved = w.id===a.warehouse_id ? (a.remaining_qty||0) : 0;\r\n        stockByWh[w.id]=(sl.quantity||0)-(sl.reserved_qty||0)-(sl.reserved_by_allocations||0)+currentReserved;\r\n      } else {\r\n        stockByWh[w.id]=0;\r\n      }\r\n    }));\r\n\r\n    const whOpts=(whs||[]).map(w=>`\r\n      <option value=\"${w.id}\" ${w.id===a.warehouse_id?'selected':''}>\r\n        ${util().sanitize(w.name)} \u2014 ${stockByWh[w.id]??0} available\r\n      </option>`).join('');\r\n\r\n    const currentAvail=stockByWh[a.warehouse_id]??0;\r\n\r\n    ui().openModal(`Edit allocation: ${util().sanitize(a.products?.name||'\u2014')}`,`\r\n      <div style=\"display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-bottom:16px\">\r\n        <div class=\"ims__stat\" style=\"padding:10px\">\r\n          <div class=\"ims__stat-label\">Originally allocated</div>\r\n          <div class=\"ims__stat-value\" style=\"font-size:20px\">${a.allocated_qty||0}</div>\r\n        </div>\r\n        <div class=\"ims__stat\" style=\"padding:10px\">\r\n          <div class=\"ims__stat-label\">Already sold</div>\r\n          <div class=\"ims__stat-value\" style=\"font-size:20px;color:${sold>0?'var(--ims-text-muted)':''}\">${sold}</div>\r\n          <div class=\"ims__stat-sub\">Cannot be reduced below this</div>\r\n        </div>\r\n        <div class=\"ims__stat\" style=\"padding:10px\">\r\n          <div class=\"ims__stat-label\">Remaining (unsold)</div>\r\n          <div class=\"ims__stat-value ims__stat-value--success\" style=\"font-size:20px\">${a.remaining_qty||0}</div>\r\n        </div>\r\n      </div>\r\n\r\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:14px\">\r\n        <i class=\"ti ti-info-circle\"></i>\r\n        <span>\r\n          Changing the <strong>quantity</strong> adjusts the stock reservation automatically.\r\n          Changing the <strong>warehouse</strong> moves the reservation to the new location.\r\n          The <strong>date</strong> is for record-keeping only.\r\n        </span>\r\n      </div>\r\n\r\n      <div class=\"ims__form-grid\">\r\n        <div class=\"ims__form-group ims__form-group--full\">\r\n          <label class=\"ims__label ims__label--req\">Warehouse</label>\r\n          <select class=\"ims__select\" id=\"ims-ea-warehouse\"\r\n            onchange=\"window.IMS_DROPSHIP.editAllocUpdateAvail('${util().jsArg(allocId)}')\">\r\n            ${whOpts}\r\n          </select>\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label ims__label--req\">Total allocated quantity</label>\r\n          <input class=\"ims__input\" type=\"number\" min=\"${sold}\" id=\"ims-ea-qty\"\r\n            value=\"${a.allocated_qty||0}\"\r\n            oninput=\"window.IMS_DROPSHIP.editAllocUpdateAvail('${util().jsArg(allocId)}')\">\r\n          <span class=\"ims__input-hint\">Minimum: ${sold} (already sold). Available in selected warehouse: <strong id=\"ims-ea-avail\">${currentAvail}</strong></span>\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label ims__label--req\">Allocation date</label>\r\n          <input class=\"ims__input\" type=\"date\" id=\"ims-ea-date\"\r\n            value=\"${a.allocation_date||new Date().toISOString().split('T')[0]}\">\r\n        </div>\r\n      </div>\r\n    `,`\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n      <button class=\"ims__btn ims__btn--primary\"\r\n        onclick=\"window.IMS_DROPSHIP.saveEditAllocation('${util().jsArg(allocId)}','${util().jsArg(a.product_id)}','${util().jsArg(a.warehouse_id)}',${a.allocated_qty||0},${a.remaining_qty||0},${sold})\">\r\n        <i class=\"ti ti-check\"></i> Save changes\r\n      </button>\r\n    `,'sm');\r\n\r\n    // Store stock data for the live available check\r\n    window._editAllocStockByWh = stockByWh;\r\n  }\r\n\r\n  function editAllocUpdateAvail(){\r\n    const whId=document.getElementById('ims-ea-warehouse')?.value;\r\n    const availEl=document.getElementById('ims-ea-avail');\r\n    const qtyEl=document.getElementById('ims-ea-qty');\r\n    if(!whId||!availEl)return;\r\n    const avail=window._editAllocStockByWh?.[whId]??0;\r\n    availEl.textContent=avail;\r\n    availEl.style.color=avail<=0?'var(--ims-danger)':avail<=5?'var(--ims-warning)':'var(--ims-success)';\r\n    // Validate qty\r\n    const qty=parseInt(qtyEl?.value)||0;\r\n    if(qtyEl) qtyEl.style.borderColor=(qty>avail+qty||qty<0)?'var(--ims-danger)':'';\r\n  }\r\n\r\n  // Order numbers of open orders (goods not yet left) using this batch,\r\n  // whether it is the line's recorded batch or part of its split.\r\n  async function _batchOpenOrders(allocId){\r\n    const client=window.supabase.createClient(window.IMS_SUPABASE_URL,window.IMS_SUPABASE_ANON_KEY);\r\n    const {data:byId}=await client.from('order_items').select('order_id').eq('dropship_allocation_id',allocId);\r\n    const {data:bySplit}=await client.from('order_items').select('order_id').contains('dropship_allocation_split',[{id:allocId}]);\r\n    const ids=[...new Set([...(byId||[]),...(bySplit||[])].map(r=>r.order_id))];\r\n    if(!ids.length) return [];\r\n    const {data:ords}=await client.from('orders').select('order_number,status,restocked_at').in('id',ids);\r\n    const out=[];\r\n    for(const o of (ords||[])){\r\n      if(['collected','delivered','cancelled','refunded'].includes(o.status) || o.restocked_at) continue;\r\n      if(!(await _dropshipGoodsLeft(o.order_number))) out.push(o.order_number);\r\n    }\r\n    return out;\r\n  }\r\n\r\n  async function saveEditAllocation(allocId,productId,oldWhId,oldAllocQty,oldRemainingQty,sold){\r\n    const restore=_withBtnSpin(event,'Saving...');\r\n    try{\r\n    const newWhId=document.getElementById('ims-ea-warehouse')?.value;\r\n    const newAllocQty=parseInt(document.getElementById('ims-ea-qty')?.value)||0;\r\n    const newDate=document.getElementById('ims-ea-date')?.value;\r\n\r\n    if(!newWhId){ui().toast('Please select a warehouse','error');return;}\r\n    if(newAllocQty<sold){ui().toast(`Quantity cannot be less than ${sold} (already sold)`,'error');return;}\r\n\r\n    // A batch cannot move to another warehouse while open orders are using\r\n    // it: their units are held in the current warehouse, and would then be\r\n    // taken from the new one when collected.\r\n    if(newWhId!==oldWhId){\r\n      const inUse=await _batchOpenOrders(allocId);\r\n      if(inUse.length){\r\n        ui().toast(`This batch is being used by open orders (${inUse.slice(0,5).join(', ')}${inUse.length>5?', ...':''}). Its warehouse can't be changed until they are collected, delivered or cancelled.`,'error',10000);\r\n        return;\r\n      }\r\n    }\r\n\r\n    // New remaining = new total - sold\r\n    const newRemainingQty=newAllocQty-sold;\r\n\r\n    // Check available stock in new warehouse\r\n    // (stockByWh already adds back old reservation, so avail = true free + old reserved)\r\n    const avail=window._editAllocStockByWh?.[newWhId]??0;\r\n    if(newRemainingQty>avail){\r\n      ui().toast(`Only ${avail} units available in selected warehouse`,'error');return;\r\n    }\r\n\r\n    // 1 \u2014 Release old reservation from old warehouse\r\n    const {data:oldSl}=await db().select('stock_levels',{\r\n      eq:{product_id:productId,warehouse_id:oldWhId},\r\n      maybeSingle:true,noCompanyFilter:true\r\n    });\r\n    if(oldSl){\r\n      await db().update('stock_levels',oldSl.id,{\r\n        reserved_by_allocations:Math.max(0,(oldSl.reserved_by_allocations||0)-oldRemainingQty)\r\n      });\r\n    }\r\n\r\n    // 2 \u2014 Apply new reservation to new warehouse\r\n    const {data:newSl}=await db().select('stock_levels',{\r\n      eq:{product_id:productId,warehouse_id:newWhId},\r\n      maybeSingle:true,noCompanyFilter:true\r\n    });\r\n    if(newSl){\r\n      await db().update('stock_levels',newSl.id,{\r\n        reserved_by_allocations:(newSl.reserved_by_allocations||0)+newRemainingQty\r\n      });\r\n    }\r\n\r\n    // 3 \u2014 Update the allocation record\r\n    const {error}=await db().update('dropship_allocations',allocId,{\r\n      warehouse_id:newWhId,\r\n      allocated_qty:newAllocQty,\r\n      remaining_qty:newRemainingQty,\r\n      allocation_date:newDate||new Date().toISOString().split('T')[0]\r\n    });\r\n    if(error){ui().toast('Failed to save: '+error.message,'error');return;}\r\n\r\n    ui().closeModal();\r\n    ui().toast('Allocation updated successfully','success');\r\n    loadAllocations();\r\n    } finally { restore(); }\r\n  }\r\n\r\n  async function recallAllocation(allocId,remainingQty,productId,warehouseId){\r\n    ui().confirm(`Recall ${remainingQty} remaining units back to available stock?`,async()=>{\r\n      const {data:sl}=await db().select('stock_levels',{eq:{product_id:productId,warehouse_id:warehouseId},maybeSingle:true,noCompanyFilter:true});\r\n      if(sl){await db().update('stock_levels',sl.id,{reserved_by_allocations:Math.max(0,(sl.reserved_by_allocations||0)-remainingQty)});}\r\n      await db().update('dropship_allocations',allocId,{remaining_qty:0});\r\n      ui().toast(`${remainingQty} units returned to available stock`,'success');\r\n      loadAllocations();\r\n    },'Recall stock',false);\r\n  }\r\n\r\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\r\n  // ORDERS\r\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\r\n  async function loadOrders(filterMode=''){\r\n    const content=document.getElementById('ims-ds-content');\r\n    if(!content)return;\r\n    const actions=document.getElementById('ims-ds-actions');\r\n    if(actions)actions.innerHTML=`<button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_DROPSHIP.showNewOrder()\"><i class=\"ti ti-plus\"></i> New dropship order</button>`;\r\n\r\n    // filterMode 'self_arrange_pending' comes from dashboard card click\r\n    const isSelfArrangePending = filterMode === 'self_arrange_pending';\r\n\r\n    const search=document.getElementById('ims-ds-search')?.value?.toLowerCase()||'';\r\n    const statusF=isSelfArrangePending ? '' : (document.getElementById('ims-ds-status')?.value||'');\r\n\r\n    const _client=window.supabase.createClient(window.IMS_SUPABASE_URL,window.IMS_SUPABASE_ANON_KEY);\r\n    let _query=_client.from('orders')\r\n      .select('*,dropship_customers(business_name,delivery_method)')\r\n      .eq('fulfillment_type','dropship')\r\n      .order('order_number',{ascending:false});\r\n    if(statusF) _query=_query.eq('status',statusF);\r\n    const {data:orders}=await _query;\r\n    _allDSOrders=orders||[];\r\n    let items=_allDSOrders;\r\n\r\n    // If coming from dashboard, pre-filter to self-arrange + not yet collected\r\n    if(isSelfArrangePending){\r\n      items=items.filter(o=>o.delivery_method==='self_arrange'&&!['collected','cancelled','delivered'].includes(o.status));\r\n    } else if(search){\r\n      items=items.filter(o=>o.order_number?.toLowerCase().includes(search)||o.end_customer_name?.toLowerCase().includes(search)||o.end_postcode?.toLowerCase().includes(search)||o.dropship_customers?.business_name?.toLowerCase().includes(search));\r\n    }\r\n\r\n    const filterBanner = isSelfArrangePending ? `\r\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:12px\">\r\n        <i class=\"ti ti-filter\"></i>\r\n        <span>Showing <strong>self-arrange orders awaiting collection</strong> \u2014 courier has not yet collected.\r\n        <button class=\"ims__btn ims__btn--ghost ims__btn--sm\" style=\"margin-left:8px\" onclick=\"window.IMS_DROPSHIP.loadOrders()\">Show all orders</button></span>\r\n      </div>` : '';\r\n\r\n    content.innerHTML=`\r\n      ${filterBanner}\r\n      <div class=\"ims__filters\" style=\"margin-bottom:14px\">\r\n        <div class=\"ims__search-wrap\"><i class=\"ti ti-search\"></i><input class=\"ims__input\" type=\"text\" id=\"ims-ds-search\" placeholder=\"Order #, customer, postcode...\" oninput=\"window.IMS_DROPSHIP.filterOrders()\"></div>\r\n        <select class=\"ims__select\" id=\"ims-ds-status\" onchange=\"window.IMS_DROPSHIP.filterOrders()\">\r\n          <option value=\"\">All statuses</option>\r\n          <option value=\"received\">Received</option>\r\n          <option value=\"picking\">Picking</option>\r\n          <option value=\"packed\">Packed</option>\r\n          <option value=\"dispatched\">Dispatched</option>\r\n          <option value=\"delivered\">Delivered</option>\r\n          <option value=\"collected\">Collected</option>\r\n          <option value=\"cancelled\">Cancelled</option>\r\n        </select>\r\n      </div>\r\n      <div class=\"ims__table-wrap\">\r\n        <table class=\"ims__table\">\r\n          <thead><tr><th>Order #</th><th>Ref</th><th>Dropship customer</th><th>End customer</th><th>Postcode</th><th>Delivery</th><th>Value</th><th>Date</th><th>Status</th><th></th></tr></thead>\r\n          <tbody>${items.map(o=>{\r\n            const isSelfArrange=o.delivery_method==='self_arrange';\r\n            const pendingCollection=isSelfArrange&&!['collected','cancelled','delivered'].includes(o.status);\r\n            return`<tr${pendingCollection?' style=\"background:var(--ims-accent-bg)\"':''}>\r\n              <td><span class=\"ims__link\" onclick=\"window.IMS_DROPSHIP.openOrder('${util().jsArg(o.id)}')\">${util().sanitize(o.order_number)}</span></td>\r\n              <td style=\"font-size:12px;color:var(--ims-text-muted)\">${util().sanitize(o.external_ref||'\u2014')}</td>\r\n              <td>${util().sanitize(o.dropship_customers?.business_name||'\u2014')}</td>\r\n              <td>${util().sanitize(o.end_customer_name||'\u2014')}</td>\r\n              <td>${util().sanitize(o.end_postcode||'\u2014')}</td>\r\n              <td><span class=\"ims__pill ims__pill--${isSelfArrange?'warning':'info'}\" style=\"font-size:10px\">${isSelfArrange?'Self-arrange':'We deliver'}</span></td>\r\n              <td>${util().formatCurrency(o.total_value)}</td>\r\n              <td>${util().formatDate(o.created_at)}</td>\r\n              <td>${util().pill(o.status)}</td>\r\n              <td>\r\n                <div class=\"ims__btn-group\">\r\n                  <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_DROPSHIP.openOrder('${util().jsArg(o.id)}')\"><i class=\"ti ti-eye\"></i></button>\r\n                  ${window.SM.AUTH.isAdmin()?`<button class=\"ims__btn ims__btn--danger ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_DROPSHIP.deleteOrder('${util().jsArg(o.id)}','${util().jsArg(o.order_number)}')\" title=\"Delete order\"><i class=\"ti ti-trash\"></i></button>`:''}\r\n                  ${pendingCollection?`\r\n                    <button class=\"ims__btn ims__btn--success ims__btn--sm\"\r\n                      onclick=\"window.IMS_DROPSHIP.showCollectionModal('${util().jsArg(o.id)}','${util().jsArg(o.order_number)}','${util().jsArg(o.dropship_customers?.business_name||'')}')\">\r\n                      <i class=\"ti ti-truck-loading\"></i> Confirm collection\r\n                    </button>`:''}\r\n                </div>\r\n              </td>\r\n            </tr>`;\r\n          }).join('')||'<tr><td colspan=\"10\" class=\"ims__table-empty\">No dropship orders found</td></tr>'}\r\n          </tbody>\r\n        </table>\r\n      </div>`;\r\n  }\r\n\r\n  let _dsOrderItems=[];\r\n  let _dsActiveDeal=null; // set by checkForDSDeal() \u2014 active dropship deal for the selected customer\r\n\r\n  async function showNewOrder(preCustomerId='',preCustomerName='',preDiscount=0,preDelivery='mdf_delivers'){\r\n    _dsOrderItems=[];\r\n    _dsActiveDeal=null;\r\n    const {data:customers}=await db().select('dropship_customers',{eq:{is_active:true},order:{col:'business_name'}});\r\n    const custOpts=(customers||[]).map(c=>`<option value=\"${c.id}\" data-discount=\"${c.discount_pct||0}\" data-delivery=\"${c.delivery_method}\" ${c.id===preCustomerId?'selected':''}>${util().sanitize(c.business_name)}</option>`).join('');\r\n\r\n    ui().openModal('New dropship order',`\r\n      <div class=\"ims__form-grid\">\r\n        <div class=\"ims__form-group ims__form-group--full\">\r\n          <label class=\"ims__label ims__label--req\">Dropship customer (retailer)</label>\r\n          <select class=\"ims__select\" id=\"ims-dso-customer\" onchange=\"window.IMS_DROPSHIP.onDSCustomerChange()\">\r\n            <option value=\"\">Select customer...</option>${custOpts}\r\n          </select>\r\n        </div>\r\n        <div class=\"ims__form-group ims__form-group--full\" style=\"display:grid;grid-template-columns:1fr 1fr;gap:10px\">\r\n          <div><span class=\"ims__label\">Discount</span><div id=\"ims-dso-discount-display\" style=\"font-weight:600;color:var(--ims-success)\">${preDiscount?preDiscount+'% off wholesale':'Select customer'}</div></div>\r\n          <div><span class=\"ims__label\">Their delivery method</span><div id=\"ims-dso-delivery-display\"><span class=\"ims__pill ims__pill--${preDelivery==='mdf_delivers'?'info':'neutral'}\">${preDelivery==='mdf_delivers'?'We deliver':'Self-arrange'}</span></div></div>\r\n        </div>\r\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Retailer's order reference</label><input class=\"ims__input\" type=\"text\" id=\"ims-dso-extref\" placeholder=\"Their order number\"></div>\r\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Order date</label><input class=\"ims__input\" type=\"date\" id=\"ims-dso-orderdate\" value=\"${new Date().toISOString().split('T')[0]}\"></div>\r\n      </div>\r\n      <hr class=\"ims__divider\">\r\n      <strong style=\"font-size:13px\">End customer details (who receives the delivery)</strong>\r\n      <div class=\"ims__form-grid\" style=\"margin-top:10px\">\r\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">End customer name</label><input class=\"ims__input\" type=\"text\" id=\"ims-dso-endname\"></div>\r\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Postcode</label><input class=\"ims__input\" type=\"text\" id=\"ims-dso-endpostcode\"></div>\r\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Phone</label><input class=\"ims__input\" type=\"tel\" id=\"ims-dso-endphone\"></div>\r\n        <div class=\"ims__form-group\"><label class=\"ims__label\">Email</label><input class=\"ims__input\" type=\"email\" id=\"ims-dso-endemail\"></div>\r\n        <div class=\"ims__form-group ims__form-group--full\"><label class=\"ims__label ims__label--req\">Delivery address</label><textarea class=\"ims__textarea\" id=\"ims-dso-endaddress\" rows=\"2\"></textarea></div>\r\n        <div class=\"ims__form-group ims__form-group--full\"><label class=\"ims__label\">Notes</label><input class=\"ims__input\" type=\"text\" id=\"ims-dso-notes\" placeholder=\"Special delivery instructions\"></div>\r\n      </div>\r\n      <hr class=\"ims__divider\">\r\n      <div id=\"ims-dso-deal-banner\" class=\"ims__alert ims__alert--info\" style=\"display:none;margin-bottom:10px\"></div>\r\n      <div style=\"display:flex;align-items:center;justify-content:space-between;margin-bottom:10px\">\r\n        <strong style=\"font-size:13px\">Order items</strong>\r\n        <button class=\"ims__btn ims__btn--secondary ims__btn--sm\" onclick=\"window.IMS_DROPSHIP.addDSItem()\"><i class=\"ti ti-plus\"></i> Add item</button>\r\n      </div>\r\n      <div id=\"ims-dso-items\"><div style=\"font-size:12px;color:var(--ims-text-muted)\">No items added yet</div></div>\r\n      <div style=\"display:flex;justify-content:flex-end;align-items:center;gap:12px;margin-top:10px\">\r\n        <span style=\"font-size:13px;color:var(--ims-text-sec)\">Total:</span>\r\n        <span style=\"font-size:20px;font-weight:700\" id=\"ims-dso-total\">${util().formatCurrency(0)}</span>\r\n      </div>\r\n    `,`\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_DROPSHIP.saveDSOrder()\"><i class=\"ti ti-check\"></i> Create order</button>\r\n    `,'xl');\r\n\r\n    if(preCustomerId)onDSCustomerChange();\r\n  }\r\n\r\n  async function onDSCustomerChange(){\r\n    const sel=document.getElementById('ims-dso-customer');\r\n    if(!sel)return;\r\n    const opt=sel.options[sel.selectedIndex];\r\n    const discount=opt?.dataset?.discount||0;\r\n    const delivery=opt?.dataset?.delivery||'mdf_delivers';\r\n    const discEl=document.getElementById('ims-dso-discount-display');\r\n    const delEl=document.getElementById('ims-dso-delivery-display');\r\n    if(discEl)discEl.innerHTML=`<span style=\"font-weight:600;color:var(--ims-success)\">${discount}% off wholesale</span>`;\r\n    if(delEl)delEl.innerHTML=`<span class=\"ims__pill ims__pill--${delivery==='mdf_delivers'?'info':'neutral'}\">${delivery==='mdf_delivers'?'We deliver':'Self-arrange'}</span>`;\r\n    await checkForDSDeal(sel.value);\r\n    renderDSItems();\r\n  }\r\n\r\n  // \u2500\u2500\u2500 DROPSHIP DEALS \u2014 ORDER-FLOW INTEGRATION \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n  // Looks up any active dropship deal targeting this customer (or all\r\n  // dropship customers) and applies it to pricing. Mirrors the retail\r\n  // deals flow in ims-orders.js/ims-deals.js, but simplified: dropship\r\n  // has no platforms and no customer-type buckets \u2014 targeting is just\r\n  // \"all dropship customers\" or specific ones \u2014 and the customer's\r\n  // standing discount is always a flat percentage (discount_pct), not\r\n  // the retail dual discount_type/discount_value pair.\r\n  async function checkForDSDeal(customerId){\r\n    _dsActiveDeal=null;\r\n    if(!customerId){updateDSDealBanner();return;}\r\n    const today=new Date().toISOString().split('T')[0];\r\n    const {data:deals}=await db().select('dropship_deals',{\r\n      select:'*, dropship_deal_customers(customer_id)',\r\n      eq:{is_active:true},\r\n      lte:{valid_from:today},\r\n      gte:{valid_to:today}\r\n    });\r\n\r\n    const matches=(deals||[]).filter(d=>\r\n      d.applies_to_all_customers||(d.dropship_deal_customers||[]).some(dc=>dc.customer_id===customerId)\r\n    );\r\n\r\n    if(matches.length){\r\n      matches.sort((a,b)=>{\r\n        const aSpecific=(a.dropship_deal_customers||[]).some(dc=>dc.customer_id===customerId)?1:0;\r\n        const bSpecific=(b.dropship_deal_customers||[]).some(dc=>dc.customer_id===customerId)?1:0;\r\n        if(aSpecific!==bSpecific) return bSpecific-aSpecific;\r\n        return (b.discount_value||0)-(a.discount_value||0);\r\n      });\r\n      _dsActiveDeal=matches[0];\r\n    }\r\n    updateDSDealBanner();\r\n  }\r\n\r\n  function updateDSDealBanner(){\r\n    const banner=document.getElementById('ims-dso-deal-banner');\r\n    if(!banner)return;\r\n    if(_dsActiveDeal){\r\n      const discLabel=_dsActiveDeal.discount_type==='percentage'\r\n        ?`${_dsActiveDeal.discount_value}% off`\r\n        :`\u00A3${_dsActiveDeal.discount_value} off`;\r\n      banner.style.display='';\r\n      banner.innerHTML=`<i class=\"ti ti-tag\"></i> Deal applied: <strong>${util().sanitize(_dsActiveDeal.name)}</strong> \u2014 ${discLabel} (${_dsActiveDeal.stacking_behaviour==='stack'?'stacks with':'replaces'} standing discount)`;\r\n    } else {\r\n      banner.style.display='none';\r\n      banner.innerHTML='';\r\n    }\r\n  }\r\n\r\n  // Convenience wrapper used throughout the order form \u2014 applies the\r\n  // active deal if one exists (via calculateDSDealPrice, defined in the\r\n  // DROPSHIP DEALS admin section below \u2014 function hoisting makes it\r\n  // safe to call here regardless of declaration order), otherwise falls\r\n  // back to the customer's plain flat discount_pct (existing behaviour).\r\n  function _dsCalcPrice(wholesalePrice,discountPct){\r\n    if(!wholesalePrice||wholesalePrice<=0) return 0;\r\n    if(_dsActiveDeal){\r\n      return calculateDSDealPrice(wholesalePrice,discountPct,_dsActiveDeal).finalPrice;\r\n    }\r\n    return parseFloat((wholesalePrice*(1-discountPct/100)).toFixed(2));\r\n  }\r\n\r\n  function addDSItem(){_dsOrderItems.push({productId:'',productName:'',sku:'',qty:1,wholesalePrice:0,unitPrice:0});renderDSItems();}\r\n\r\n  async function renderDSItems(){\r\n    const container=document.getElementById('ims-dso-items');\r\n    if(!container)return;\r\n    const sel=document.getElementById('ims-dso-customer');\r\n    const discountPct=parseFloat(sel?.options[sel?.selectedIndex]?.dataset?.discount||0)||0;\r\n    const priceLabel=_dsActiveDeal?'Their price (deal applied)':`Their price (${discountPct}% off)`;\r\n\r\n    if(!_dsOrderItems.length){container.innerHTML='<div style=\"font-size:12px;color:var(--ims-text-muted)\">No items added yet</div>';updateDSTotal();return;}\r\n    container.innerHTML=`\r\n      <div style=\"display:grid;grid-template-columns:2fr 70px 120px 120px auto;gap:8px;align-items:center;margin-bottom:4px;padding:0 2px\">\r\n        <div style=\"font-size:11px;font-weight:600;color:var(--ims-text-muted)\">Product</div>\r\n        <div style=\"font-size:11px;font-weight:600;color:var(--ims-text-muted)\">Qty</div>\r\n        <div style=\"font-size:11px;font-weight:600;color:var(--ims-text-muted)\">Wholesale (\u00A3)</div>\r\n        <div style=\"font-size:11px;font-weight:600;color:var(--ims-text-muted)\">${priceLabel}</div>\r\n        <div></div>\r\n      </div>`+\r\n    _dsOrderItems.map((item,i)=>{\r\n      const theirPrice=_dsCalcPrice(item.wholesalePrice,discountPct);\r\n      return`<div style=\"display:grid;grid-template-columns:2fr 70px 120px 120px auto;gap:8px;align-items:center;margin-bottom:8px\">\r\n        <div style=\"position:relative\">\r\n          <input class=\"ims__input\" type=\"text\" placeholder=\"Product name or SKU\" value=\"${util().sanitize(item.productName)}\" autocomplete=\"off\"\r\n            oninput=\"window.IMS_DROPSHIP.updateDSItem(${i},'productName',this.value);window.IMS_DROPSHIP.searchDSProduct(${i},this.value)\">\r\n          <div id=\"ims-ds-prod-drop-${i}\" class=\"ims__ac-dropdown\"></div>\r\n        </div>\r\n                <input class=\"ims__input\" type=\"number\" min=\"1\" value=\"${item.qty}\"\r\n          oninput=\"window.IMS_DROPSHIP.updateDSItem(${i},'qty',+this.value||1)\">\r\n        <input class=\"ims__input\" type=\"number\" min=\"0\" step=\"0.01\"\r\n          id=\"ims-ds-wp-${i}\"\r\n          value=\"${item.wholesalePrice||''}\" placeholder=\"0.00\"\r\n          oninput=\"window.IMS_DROPSHIP.updateDSItem(${i},'wholesalePrice',+this.value||0)\"\r\n          style=\"${!item.wholesalePrice?'border-color:var(--ims-warning)':''}\">\r\n        <div id=\"ims-ds-their-${i}\" style=\"font-size:13px;font-weight:600;color:${_dsActiveDeal?'var(--ims-accent)':'var(--ims-success)'};padding:8px 10px;background:var(--ims-surface2);border-radius:var(--ims-radius);border:1px solid ${_dsActiveDeal?'var(--ims-accent)':'var(--ims-border)'}\">\r\n          ${_dsTheirPriceInner(theirPrice)}\r\n        </div>\r\n        <button class=\"ims__btn ims__btn--danger ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_DROPSHIP.removeDSItem(${i})\"><i class=\"ti ti-trash\"></i></button>\r\n      </div>`;\r\n    }).join('');\r\n    updateDSTotal();\r\n  }\r\n\r\n    // Content of a row's \"Their price\" cell. Shared by renderDSItems() and\r\n  // updateDSItem() so the first draw and every in-place update match.\r\n  function _dsTheirPriceInner(theirPrice){\r\n    return `${theirPrice>0?util().formatCurrency(theirPrice):'&mdash;'}\r\n          ${_dsActiveDeal&&theirPrice>0?'<div style=\"font-size:9px;font-weight:500;color:var(--ims-accent)\"><i class=\"ti ti-tag\"></i> Deal price</div>':''}`;\r\n  }\r\n\r\n  // Runs on every keystroke in the qty and wholesale boxes. It must NOT\r\n  // call renderDSItems(): that rebuilds every row, which throws the cursor\r\n  // out of the box after each character. It updates only this row's\r\n  // \"Their price\" cell, the empty-price warning and the order total.\r\n  function updateDSItem(i,field,val){\r\n    const item=_dsOrderItems[i];\r\n    if(!item) return;\r\n    item[field]=val;\r\n    if(field!=='qty'&&field!=='wholesalePrice') return;\r\n    const sel=document.getElementById('ims-dso-customer');\r\n    const discountPct=parseFloat(sel?.options[sel?.selectedIndex]?.dataset?.discount||0)||0;\r\n    const cell=document.getElementById(`ims-ds-their-${i}`);\r\n    if(cell) cell.innerHTML=_dsTheirPriceInner(_dsCalcPrice(item.wholesalePrice,discountPct));\r\n    const wp=document.getElementById(`ims-ds-wp-${i}`);\r\n    if(wp) wp.style.borderColor=item.wholesalePrice?'':'var(--ims-warning)';\r\n    updateDSTotal();\r\n  }\r\n  function removeDSItem(i){_dsOrderItems.splice(i,1);renderDSItems();}\r\n\r\n  // Search guard (as in ims-orders.js). Every keystroke starts a new search, and the answers can\r\n  // come back in any order. Each search takes a number, and only the latest\r\n  // one may update the list, so an older, slower search can never replace\r\n  // the newer results (or hide the list). Seen as a match that sometimes\r\n  // failed to appear while typing.\r\n  const _dsProdSeq={};\r\n\r\n  async function searchDSProduct(index,query){\r\n    const seq=(_dsProdSeq[index]=(_dsProdSeq[index]||0)+1);\r\n    if(!query||query.length<2){const d=document.getElementById(`ims-ds-prod-drop-${index}`);if(d)d.style.display='none';return;}\r\n    // Search by name AND by SKU\r\n    const client=window.supabase.createClient(window.IMS_SUPABASE_URL,window.IMS_SUPABASE_ANON_KEY);\r\n    const [{data:byName},{data:bySku}]=await Promise.all([\r\n      db().select('products',{ilike:{name:query},select:'id,name,sku',limit:5}),\r\n      db().select('products',{ilike:{sku:query},select:'id,name,sku',limit:5})\r\n    ]);\r\n    if(seq!==_dsProdSeq[index]) return;   // a newer search has started\r\n    const combined=[...(byName||[]),...(bySku||[])];\r\n    const products=combined.filter((p,i,arr)=>arr.findIndex(x=>x.id===p.id)===i).slice(0,8);\r\n    const drop=document.getElementById(`ims-ds-prod-drop-${index}`);\r\n    if(!drop||!products?.length){if(drop)drop.style.display='none';return;}\r\n\r\n    // Fetch all wholesale prices in one batch query\r\n    const productIds=products.map(p=>p.id);\r\n    const {data:prices}=await client\r\n      .from('product_prices')\r\n      .select('product_id,price')\r\n      .in('product_id',productIds)\r\n      .eq('price_type','wholesale')\r\n      .is('platform_id',null);\r\n    if(seq!==_dsProdSeq[index]) return;\r\n    const priceMap={};\r\n    (prices||[]).forEach(pp=>{priceMap[pp.product_id]=pp.price;});\r\n\r\n    // Customer-specific flat overrides take priority over the shared\r\n    // wholesale rate \u2014 per the confirmed pricing design, dropship\r\n    // customers should never silently share the standard wholesale\r\n    // rate for a product they have a set price for.\r\n    const custSel=document.getElementById('ims-dso-customer');\r\n    const custId=custSel?.value||null;\r\n    const customMap={};\r\n    if(custId){\r\n      const {data:custPrices}=await db().select('dropship_customer_prices',{\r\n        select:'product_id,unit_price', eq:{customer_id:custId}, in:{product_id:productIds}\r\n      });\r\n      if(seq!==_dsProdSeq[index]) return;\r\n      (custPrices||[]).forEach(cp=>{customMap[cp.product_id]=cp.unit_price;});\r\n    }\r\n\r\n    drop.innerHTML=products.map(p=>{\r\n      const wholesale=priceMap[p.id]??null;\r\n      const hasCustom=customMap[p.id]!=null;\r\n      const effectivePrice=hasCustom?customMap[p.id]:(wholesale||0);\r\n      const priceLabel=hasCustom\r\n        ?`<span style=\"color:var(--ims-accent);font-weight:600\"> \u2014 Custom: ${util().formatCurrency(customMap[p.id])}</span>`\r\n        :(wholesale!==null?' \u2014 Wholesale: '+util().formatCurrency(wholesale):'<span style=\"color:var(--ims-warning)\"> \u2014 No price set</span>');\r\n      return`<div class=\"ims__ac-item\" onmousedown=\"window.IMS_DROPSHIP.selectDSProduct(${index},${JSON.stringify({id:p.id,name:p.name,sku:p.sku,wholesale:effectivePrice}).replace(/\"/g,'&quot;')})\">\r\n        <strong>${util().sanitize(p.name)}</strong>\r\n        <span style=\"font-size:11px;color:var(--ims-text-muted);margin-left:6px\">${p.sku}${priceLabel}</span>\r\n      </div>`;\r\n    }).join('');\r\n    drop.style.display='block';\r\n  }\r\n\r\n  function selectDSProduct(index,product){\r\n    if(_dsOrderItems[index]){\r\n      _dsOrderItems[index].productId=product.id;\r\n      _dsOrderItems[index].productName=product.name;\r\n      _dsOrderItems[index].sku=product.sku;\r\n      _dsOrderItems[index].wholesalePrice=product.wholesale||0;\r\n      const sel=document.getElementById('ims-dso-customer');\r\n      const discountPct=parseFloat(sel?.options[sel?.selectedIndex]?.dataset?.discount||0)||0;\r\n      _dsOrderItems[index].unitPrice=_dsCalcPrice(product.wholesale||0,discountPct);\r\n    }\r\n    renderDSItems();\r\n    const drop=document.getElementById(`ims-ds-prod-drop-${index}`);if(drop)drop.style.display='none';\r\n  }\r\n\r\n  function updateDSTotal(){\r\n    const sel=document.getElementById('ims-dso-customer');\r\n    const discountPct=parseFloat(sel?.options[sel?.selectedIndex]?.dataset?.discount||0)||0;\r\n    const total=_dsOrderItems.reduce((s,i)=>s+((i.qty||1)*_dsCalcPrice(i.wholesalePrice,discountPct)),0);\r\n    const el=document.getElementById('ims-dso-total');if(el)el.textContent=util().formatCurrency(total);\r\n  }\r\n\r\n  // Warning box shown OVER the open form (copied from _askOverForm in\r\n  // ims-orders.js). \"Go back\" is focused, so Enter or Escape never\r\n  // proceeds by accident. With okLabel null, \"Go back\" is the only choice.\r\n  function _dsAsk({ title, message, okLabel = 'Save anyway', danger = false, reasonLabel = null }) {\r\n    return new Promise(resolve => {\r\n      const wrap = document.createElement('div');\r\n      wrap.style.cssText = 'position:fixed;inset:0;z-index:100000;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px';\r\n      wrap.innerHTML = `\r\n        <div role=\"alertdialog\" aria-modal=\"true\" style=\"background:var(--ims-surface);color:var(--ims-text);border:1px solid var(--ims-border);border-radius:var(--ims-radius);max-width:460px;width:100%;box-shadow:0 20px 50px rgba(0,0,0,.3);font-family:var(--ims-font);font-size:14px\">\r\n          <div style=\"padding:16px 18px 6px;font-weight:700;display:flex;align-items:center;gap:8px\"><i class=\"ti ti-alert-triangle\" style=\"color:var(--ims-warning)\"></i>${util().sanitize(title)}</div>\r\n          <div style=\"padding:6px 18px 14px;color:var(--ims-text-sec);line-height:1.5\">${message}</div>\r\n          ${reasonLabel ? `<div style=\"padding:0 18px 14px\"><label style=\"display:block;font-size:12px;font-weight:600;margin-bottom:6px\">${util().sanitize(reasonLabel)}</label><textarea data-act-reason rows=\"3\" class=\"ims__textarea\" style=\"width:100%\"></textarea></div>` : ''}\r\n          <div style=\"padding:12px 18px;border-top:1px solid var(--ims-border);display:flex;justify-content:flex-end;gap:8px\">\r\n            <button type=\"button\" class=\"ims__btn ims__btn--ghost\" data-act=\"cancel\">Go back</button>\r\n            ${okLabel ? `<button type=\"button\" class=\"ims__btn ims__btn--${danger ? 'danger' : 'warning'}\" data-act=\"ok\">${util().sanitize(okLabel)}</button>` : ''}\r\n          </div>\r\n        </div>`;\r\n      const cancelBtn = () => wrap.querySelector('[data-act=\"cancel\"]');\r\n      const okBtn = () => wrap.querySelector('[data-act=\"ok\"]');\r\n      const reasonBox = () => wrap.querySelector('[data-act-reason]');\r\n      const reasonText = () => (reasonBox()?.value || '').trim();\r\n      const finish = (answer) => {\r\n        document.removeEventListener('keydown', onKey, true);\r\n        wrap.remove();\r\n        resolve(answer && reasonLabel ? reasonText() : answer);\r\n      };\r\n      const onKey = (e) => {\r\n        if (e.key === 'Escape') { e.preventDefault(); e.stopPropagation(); finish(false); }\r\n        else if (e.key === 'Enter') {\r\n          if (document.activeElement === reasonBox()) return;   // new line in the reason\r\n          e.preventDefault(); e.stopPropagation(); finish(!!okBtn() && !okBtn().disabled && document.activeElement === okBtn());\r\n        }\r\n        else if (e.key === 'Tab') {\r\n          e.preventDefault(); e.stopPropagation();\r\n          const order = [reasonBox(), cancelBtn(), okBtn()].filter(el => el && !el.disabled);\r\n          const at = order.indexOf(document.activeElement);\r\n          (order[(at + 1) % order.length] || cancelBtn()).focus();\r\n        }\r\n      };\r\n      wrap.addEventListener('click', e => {\r\n        const act = e.target.closest('[data-act]')?.dataset.act;\r\n        if (act === 'ok' && okBtn()?.disabled) return;\r\n        if (act) finish(act === 'ok');\r\n      });\r\n      if (reasonLabel) {\r\n        wrap.addEventListener('input', () => { if (okBtn()) okBtn().disabled = !reasonText(); });\r\n      }\r\n      document.addEventListener('keydown', onKey, true);\r\n      // Placed inside the app container: the app's colours (--ims-surface\r\n      // and the rest, light and dark) are defined on it, not on the page,\r\n      // so a box attached to the page itself had no background at all.\r\n      (document.getElementById('ims-app') || document.body).appendChild(wrap);\r\n      if (reasonLabel && okBtn()) okBtn().disabled = true;\r\n      (reasonBox() || cancelBtn()).focus();\r\n    });\r\n  }\r\n  async function saveDSOrder(){\r\n    const g=id=>document.getElementById(id)?.value?.trim()||'';\r\n    const customerId=g('ims-dso-customer');\r\n    const endName=g('ims-dso-endname');\r\n    const endPostcode=g('ims-dso-endpostcode').toUpperCase();\r\n    const endAddress=g('ims-dso-endaddress');\r\n    const sel=document.getElementById('ims-dso-customer');\r\n    const opt=sel?.options[sel?.selectedIndex];\r\n    const discountPct=parseFloat(opt?.dataset?.discount||0)||0;\r\n    const deliveryMethod=opt?.dataset?.delivery||'mdf_delivers';\r\n\r\n    if(!customerId){ui().toast('Please select a dropship customer','error');return;}\r\n    if(!endName){ui().toast('End customer name is required','error');return;}\r\n    if(!endPostcode){ui().toast('End customer postcode is required','error');return;}\r\n    if(!endAddress){ui().toast('Delivery address is required','error');return;}\r\n    if(!_dsOrderItems.length){ui().toast('Please add at least one item','error');return;}\r\n\r\n    // Disable button and show saving state\r\n    const saveBtn=document.querySelector('#ims-modal-footer .ims__btn--primary');\r\n    if(saveBtn){saveBtn.disabled=true;saveBtn.innerHTML='<i class=\"ti ti-loader-2 ims__spin\"></i> Creating order...';}\r\n\r\n    // Show progress in modal body footer area\r\n    const progressDiv=document.createElement('div');\r\n    progressDiv.id='ims-dso-progress';\r\n    progressDiv.style.cssText='margin-top:12px;padding:10px 14px;background:var(--ims-surface2);border-radius:var(--ims-radius);border:1px solid var(--ims-border)';\r\n    progressDiv.innerHTML=`\r\n      <div style=\"display:flex;justify-content:space-between;font-size:12px;color:var(--ims-text-muted);margin-bottom:5px\">\r\n        <span id=\"ims-dso-progress-label\"><i class=\"ti ti-loader-2 ims__spin\"></i> Generating order number...</span>\r\n        <span id=\"ims-dso-progress-pct\">0%</span>\r\n      </div>\r\n      <div style=\"background:var(--ims-border);border-radius:999px;height:6px;overflow:hidden\">\r\n        <div id=\"ims-dso-progress-bar\" style=\"height:6px;width:0%;background:var(--ims-accent);border-radius:999px;transition:width .3s\"></div>\r\n      </div>`;\r\n    const modalBody=document.getElementById('ims-modal-body');\r\n    if(modalBody) modalBody.appendChild(progressDiv);\r\n\r\n    const setProgress=(pct,label)=>{\r\n      const bar=document.getElementById('ims-dso-progress-bar');\r\n      const pctEl=document.getElementById('ims-dso-progress-pct');\r\n      const labelEl=document.getElementById('ims-dso-progress-label');\r\n      if(bar) bar.style.width=pct+'%';\r\n      if(pctEl) pctEl.textContent=pct+'%';\r\n      if(labelEl) labelEl.innerHTML=label;\r\n    };\r\n\r\n    const total=_dsOrderItems.reduce((s,i)=>s+((i.qty||1)*_dsCalcPrice(i.wholesalePrice,discountPct)),0);\r\n\r\n    // Generate order number by finding the highest existing DSO number across ALL orders\r\n    const client=window.supabase.createClient(window.IMS_SUPABASE_URL,window.IMS_SUPABASE_ANON_KEY);\r\n    const {data:allDSO}=await client.from('orders')\r\n      .select('order_number')\r\n      .like('order_number','DSO-%')\r\n      .order('order_number',{ascending:false})\r\n      .limit(1);\r\n    const lastNum=allDSO?.[0]?.order_number?parseInt(allDSO[0].order_number.replace('DSO-','')||'0'):0;\r\n    const orderNumber=`DSO-${String(lastNum+1).padStart(5,'0')}`;\r\n\r\n    setProgress(20,'Saving order record...');\r\n\r\n    // Allocation check. Every dropship unit must come from this partner's\r\n    // allocation (their ring-fenced batches). If the batches do not cover\r\n    // the order, stop: nothing is saved, and the way forward is to add or\r\n    // increase an allocation. (Before, the order went through anyway and\r\n    // the units were never ring-fenced.)\r\n    const restoreSave=()=>{\r\n      if(saveBtn){saveBtn.disabled=false;saveBtn.innerHTML='<i class=\"ti ti-check\"></i> Create order';}\r\n      if(progressDiv) progressDiv.remove();\r\n    };\r\n    const noProduct=_dsOrderItems.filter(i=>!i.productId).map(i=>i.productName||'(unnamed line)');\r\n    const needed={};\r\n    _dsOrderItems.forEach(i=>{ if(i.productId){ needed[i.productId]=needed[i.productId]||{name:i.productName,qty:0}; needed[i.productId].qty+=(i.qty||1); } });\r\n    const short=[];\r\n    for(const [pid,n] of Object.entries(needed)){\r\n      const {data:batches}=await client.from('dropship_allocations').select('remaining_qty').eq('customer_id',customerId).eq('product_id',pid).gt('remaining_qty',0);\r\n      const left=(batches||[]).reduce((t,b)=>t+(b.remaining_qty||0),0);\r\n      if(left<n.qty) short.push(`<strong>${util().sanitize(n.name)}</strong>: ${n.qty} ordered, ${left} allocated`);\r\n    }\r\n    if(noProduct.length||short.length){\r\n      const partnerName=document.getElementById('ims-dso-customer')?.selectedOptions?.[0]?.textContent?.trim()||'this partner';\r\n      await _dsAsk({\r\n        title:'Not enough allocated',\r\n        message:(short.length?`<strong>${util().sanitize(partnerName)}</strong> does not have enough allocated for:<br>${short.join('<br>')}<br><br>Add or increase an allocation for them first (Dropship &gt; Allocations).`:'')+\r\n                (noProduct.length?`${short.length?'<br><br>':''}Every line must be a product from the list, so it can come from the partner's allocation. Please choose a product for: ${noProduct.map(n=>util().sanitize(n)).join(', ')}.`:''),\r\n        okLabel:null\r\n      });\r\n      restoreSave();\r\n      return;\r\n    }\r\n\r\n    // Credit limit check\r\n    const {data:custData}=await client.from('dropship_customers').select('credit_limit,business_name').eq('id',customerId).maybeSingle();\r\n    if(custData?.credit_limit>0){\r\n      const {data:openOrders}=await client.from('orders').select('total_value').eq('dropship_customer_id',customerId).eq('fulfillment_type','dropship').not('status','in','(\"collected\",\"delivered\",\"cancelled\",\"refunded\")');\r\n      const outstanding=(openOrders||[]).reduce((s,o)=>s+(o.total_value||0),0);\r\n      const remaining=custData.credit_limit-outstanding;\r\n      if(total>remaining){\r\n        const proceed=await _dsAsk({\r\n          title:'Credit limit',\r\n          message:`<strong>${util().sanitize(custData.business_name)}</strong> would go over their credit limit.<br><br>Credit limit: \u00A3${custData.credit_limit.toFixed(2)}<br>Outstanding: \u00A3${outstanding.toFixed(2)}<br>This order: \u00A3${total.toFixed(2)}<br>Over by: \u00A3${(total-remaining).toFixed(2)}`,\r\n          okLabel:'Save anyway'\r\n        });\r\n                if(!proceed){\r\n          // Put the button and progress bar back, otherwise the form is left\r\n          // stuck on \"Creating order...\" and has to be closed and redone.\r\n          if(saveBtn){saveBtn.disabled=false;saveBtn.innerHTML='<i class=\"ti ti-check\"></i> Create order';}\r\n          if(progressDiv) progressDiv.remove();\r\n          return;\r\n        }\r\n      }\r\n    }\r\n\r\n    const orderDate=g('ims-dso-orderdate')||new Date().toISOString().split('T')[0];\r\n\r\n    // Phase 2: insert into main orders table with fulfillment_type='dropship'\r\n    // This means dropship orders appear in Order Management and Logistics\r\n    const {data:order,error}=await db().insert('orders',{\r\n      order_number:       orderNumber,\r\n      fulfillment_type:   'dropship',\r\n      order_type:         'wholesale',\r\n      dropship_customer_id: customerId,\r\n      customer_name:      opt?.text||'Dropship',\r\n      status:             'received',\r\n      total_value:        total,\r\n      delivery_method:    deliveryMethod,\r\n      end_customer_name:  endName,\r\n      end_customer_phone: g('ims-dso-endphone')||null,\r\n      end_customer_email: g('ims-dso-endemail')||null,\r\n      end_address:        endAddress,\r\n      end_postcode:       endPostcode,\r\n      postcode:           endPostcode,\r\n      address:            endAddress,\r\n      notes:              g('ims-dso-notes')||null,\r\n      external_ref:       g('ims-dso-extref')||null,\r\n      created_at:         new Date(orderDate).toISOString(),\r\n      dropship_deal_id:   _dsActiveDeal?.id||null,\r\n      dropship_deal_name_snapshot: _dsActiveDeal?.name||null,\r\n      dropship_deal_discount_applied: _dsActiveDeal?1:0,\r\n      created_by:         window.SM.AUTH.user?.id\r\n    });\r\n    if(error){\r\n      ui().toast('Failed: '+error.message,'error');\r\n      if(saveBtn){saveBtn.disabled=false;saveBtn.innerHTML='<i class=\"ti ti-check\"></i> Create order';}\r\n      if(progressDiv) progressDiv.remove();\r\n      return;\r\n    }\r\n\r\n        setProgress(50,`Saving ${_dsOrderItems.length} item${_dsOrderItems.length===1?'':'s'}...`);\r\n\r\n    // Save every item line in ONE insert. Postgres runs a multi-row insert\r\n    // as a single statement, so either every line saves or none do. Before\r\n    // this, each line was saved on its own and a failure only went to the\r\n    // browser console: the order still showed as created with lines\r\n    // missing, and the allocation was still used up for the missing line.\r\n    // order_items has no company_id column, so the raw client is used.\r\n    // .select('id') returns the saved lines in the same order, so each line\r\n    // can record below which allocation its units came from.\r\n    const {data:savedLines,error:itemsError}=await client.from('order_items').insert(_dsOrderItems.map(item=>{\r\n      const unitPrice=_dsCalcPrice(item.wholesalePrice,discountPct);\r\n      return {\r\n        order_id:     order.id,\r\n        product_id:   item.productId||null,\r\n        product_name: item.productName,\r\n        sku:          item.sku||'',\r\n        quantity:     item.qty||1,\r\n        unit_price:   unitPrice,\r\n        total_price:  (item.qty||1)*unitPrice,\r\n        cost_price:   0\r\n      };\r\n    })).select('id');\r\n    if(itemsError){\r\n      // Undo the half-saved order. No allocation has been used and no\r\n      // logistics job exists yet, so removing the order row is the whole undo.\r\n      const {error:undoError}=await db().remove('orders',order.id);\r\n      if(undoError){\r\n        ui().toast(`Dropship order ${orderNumber} was created but its items could not be saved, and it could not be removed automatically. Please delete ${orderNumber} and enter it again. Reason: ${itemsError.message}`,'error',15000);\r\n        loadOrders();\r\n      } else {\r\n        ui().toast(`Order not saved. The item lines could not be saved, so nothing was recorded. Please try again. Reason: ${itemsError.message}`,'error',10000);\r\n      }\r\n      if(saveBtn){saveBtn.disabled=false;saveBtn.innerHTML='<i class=\"ti ti-check\"></i> Create order';}\r\n      if(progressDiv) progressDiv.remove();\r\n      return;\r\n    }\r\n\r\n    setProgress(65,'Updating stock allocations...');\r\n\r\n    // Use up allocations one line at a time. Doing every line at once meant\r\n    // two lines of the same product both read the same remaining figure,\r\n    // so one deduction was lost. Failures are now reported, not ignored.\r\n    const allocFailed=[];\r\n    for(const [lineIdx,item] of _dsOrderItems.entries()){\r\n      if(!item.productId) continue;\r\n      // Take the units from the partner's batches, oldest first, moving on\r\n      // to the next batch when one runs out (it used to empty the first\r\n      // batch and take nothing from the next). Re-read each line, so two\r\n      // lines of the same product carry on from each other.\r\n      const {data:batches,error:readErr}=await client.from('dropship_allocations')\r\n        .select('id,remaining_qty').eq('customer_id',customerId).eq('product_id',item.productId)\r\n        .gt('remaining_qty',0).order('created_at',{ascending:true});\r\n      if(readErr){ allocFailed.push(item.productName); continue; }\r\n      let need=item.qty||1; const split=[];\r\n      for(const bt of (batches||[])){\r\n        if(need<=0) break;\r\n        const take=Math.min(need,bt.remaining_qty||0);\r\n        if(take<=0) continue;\r\n        const {error:upErr}=await client.from('dropship_allocations').update({remaining_qty:(bt.remaining_qty||0)-take}).eq('id',bt.id);\r\n        if(upErr){ allocFailed.push(item.productName); break; }\r\n        split.push({id:bt.id,qty:take}); need-=take;\r\n      }\r\n      if(need>0) allocFailed.push(item.productName);\r\n      // Remember which batches this line used, so every later step (and\r\n      // Delete or Return) works batch by batch.\r\n      const lineId=savedLines?.[lineIdx]?.id;\r\n      if(lineId && split.length){\r\n        const {error:linkErr}=await client.from('order_items').update({dropship_allocation_id:split[0].id,dropship_allocation_split:split}).eq('id',lineId);\r\n        if(linkErr) console.warn(`[StockMaestro] ${orderNumber}: could not record the batches for ${item.productName}:`, linkErr.message);\r\n      }\r\n    }\r\n\r\n    setProgress(80,'Setting up logistics...');\r\n\r\n    let logisticsFailed=false;\r\n    if(deliveryMethod==='mdf_delivers'){\r\n      const {error:jobErr}=await db().insert('logistics_jobs',{order_id:order.id,job_type:'delivery',status:'unassigned',notes:`Dropship order ${orderNumber}. End customer: ${endName} ${endPostcode}`});\r\n      if(jobErr) logisticsFailed=true;\r\n    }\r\n\r\n    setProgress(100,'Done!');\r\n    await new Promise(r=>setTimeout(r,400));\r\n\r\n    _dsOrderItems=[];\r\n    _dsActiveDeal=null;\r\n    ui().closeModal();\r\n    ui().toast(`Dropship order ${orderNumber} created`+(deliveryMethod==='mdf_delivers'&&!logisticsFailed?' and added to the logistics queue':''),'success',5000);\r\n    if(allocFailed.length) ui().toast(`Order ${orderNumber} saved, but the stock allocation could not be updated for: ${allocFailed.join(', ')}. Please check this customer's allocations.`,'warning',12000);\r\n    if(logisticsFailed) ui().toast(`Order ${orderNumber} saved, but it could not be added to the logistics queue, so it will not show in Unassigned jobs. Please report this so it can be added.`,'warning',15000);\r\n    loadOrders();\r\n  }\r\n\r\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\r\n  // DROPSHIP DEALS\r\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\r\n  // Deliberately separate from ims-deals.js (retail/wholesale/trade\r\n  // deals) per the split-architecture decision: dropship customers\r\n  // live in a different table (dropship_customers) with a simpler\r\n  // pricing model (a single flat discount_pct, not the retail\r\n  // discount_type/discount_value pair) and simpler targeting (no\r\n  // platforms, no customer-type buckets \u2014 just all dropship customers\r\n  // or specific ones). Backed by dropship_deals / dropship_deal_customers.\r\n  async function loadDSDeals(){\r\n    const content=document.getElementById('ims-ds-content');\r\n    if(!content)return;\r\n    content.innerHTML=`<div class=\"ims__loading\"><i class=\"ti ti-loader-2 ims__spin\"></i></div>`;\r\n\r\n    const actions=document.getElementById('ims-ds-actions');\r\n    if(actions) actions.innerHTML=`<button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_DROPSHIP.showNewDSDeal()\"><i class=\"ti ti-plus\"></i> New dropship deal</button>`;\r\n\r\n    const {data:deals,error}=await db().select('dropship_deals',{\r\n      select:'*, dropship_deal_customers(customer_id)',\r\n      order:{col:'valid_from',asc:false}\r\n    });\r\n\r\n    if(error){content.innerHTML=`<div class=\"ims__coming-soon\"><i class=\"ti ti-tag\"></i><h3>Failed to load deals</h3><p>${util().sanitize(error.message)}</p></div>`;return;}\r\n\r\n    const today=new Date().toISOString().split('T')[0];\r\n    const items=deals||[];\r\n    const active=items.filter(d=>d.is_active&&d.valid_from<=today&&d.valid_to>=today);\r\n    const upcoming=items.filter(d=>d.is_active&&d.valid_from>today);\r\n    const expired=items.filter(d=>!d.is_active||d.valid_to<today);\r\n\r\n    content.innerHTML=`\r\n      <div style=\"display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:18px\">\r\n        <div class=\"ims__stat\" style=\"padding:12px\">\r\n          <div class=\"ims__stat-label\">Active deals</div>\r\n          <div class=\"ims__stat-value ims__stat-value--success\" style=\"font-size:24px\">${active.length}</div>\r\n        </div>\r\n        <div class=\"ims__stat\" style=\"padding:12px\">\r\n          <div class=\"ims__stat-label\">Upcoming</div>\r\n          <div class=\"ims__stat-value ims__stat-value--accent\" style=\"font-size:24px\">${upcoming.length}</div>\r\n        </div>\r\n        <div class=\"ims__stat\" style=\"padding:12px\">\r\n          <div class=\"ims__stat-label\">Expired</div>\r\n          <div class=\"ims__stat-value\" style=\"font-size:24px\">${expired.length}</div>\r\n        </div>\r\n      </div>\r\n      <div class=\"ims__card\">\r\n        <div class=\"ims__table-wrap\">\r\n          <table class=\"ims__table\">\r\n            <thead><tr>\r\n              <th>Deal name</th><th>Discount</th><th>Stacking</th>\r\n              <th>Targets</th><th>Valid from</th><th>Valid to</th>\r\n              <th>Status</th><th></th>\r\n            </tr></thead>\r\n            <tbody>${items.map(d=>{\r\n              const isActive=d.is_active&&d.valid_from<=today&&d.valid_to>=today;\r\n              const isUpcoming=d.is_active&&d.valid_from>today;\r\n              const statusPill=isActive\r\n                ?'<span class=\"ims__pill ims__pill--success\">Active</span>'\r\n                :isUpcoming\r\n                  ?'<span class=\"ims__pill ims__pill--accent\">Upcoming</span>'\r\n                  :'<span class=\"ims__pill ims__pill--neutral\">Expired</span>';\r\n              const discount=d.discount_type==='percentage'?`${d.discount_value}% off`:`\u00A3${d.discount_value} off`;\r\n              const targets=d.applies_to_all_customers\r\n                ?'All dropship customers'\r\n                :`${(d.dropship_deal_customers||[]).length} specific customer${(d.dropship_deal_customers||[]).length===1?'':'s'}`;\r\n              return`<tr>\r\n                <td><strong>${util().sanitize(d.name)}</strong>${d.description?`<div style=\"font-size:11px;color:var(--ims-text-muted)\">${util().sanitize(d.description)}</div>`:''}</td>\r\n                <td><span style=\"font-weight:600;color:var(--ims-accent)\">${discount}</span></td>\r\n                <td><span class=\"ims__pill ims__pill--${d.stacking_behaviour==='stack'?'info':'neutral'}\">${d.stacking_behaviour==='stack'?'Stacks':'Replaces'}</span></td>\r\n                <td style=\"font-size:12px;max-width:200px\">${targets}</td>\r\n                <td style=\"font-size:12px\">${util().formatDate(d.valid_from)}</td>\r\n                <td style=\"font-size:12px;color:${d.valid_to<today?'var(--ims-danger)':''}\">${util().formatDate(d.valid_to)}</td>\r\n                <td>${statusPill}</td>\r\n                <td><div class=\"ims__btn-group\">\r\n                  <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_DROPSHIP.editDSDeal('${util().jsArg(d.id)}')\" title=\"Edit\"><i class=\"ti ti-edit\"></i></button>\r\n                  <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_DROPSHIP.toggleDSDeal('${util().jsArg(d.id)}',${!d.is_active},'${util().jsArg(d.name)}')\" title=\"${d.is_active?'Deactivate':'Activate'}\">\r\n                    <i class=\"ti ti-${d.is_active?'eye-off':'eye'}\"></i>\r\n                  </button>\r\n                  ${window.SM.AUTH.isAdmin()?`<button class=\"ims__btn ims__btn--danger ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_DROPSHIP.deleteDSDeal('${util().jsArg(d.id)}','${util().jsArg(d.name)}')\" title=\"Delete\"><i class=\"ti ti-trash\"></i></button>`:''}\r\n                </div></td>\r\n              </tr>`;\r\n            }).join('')||'<tr><td colspan=\"8\" class=\"ims__table-empty\">No dropship deals yet \u2014 create your first deal</td></tr>'}\r\n            </tbody>\r\n          </table>\r\n        </div>\r\n      </div>`;\r\n  }\r\n\r\n  async function showNewDSDeal(){ await _openDSDealForm(null); }\r\n  async function editDSDeal(id){ await _openDSDealForm(id); }\r\n\r\n  async function _openDSDealForm(existingId){\r\n    let d=null, selCustomers=new Set();\r\n\r\n    if(existingId){\r\n      const {data:deal}=await db().select('dropship_deals',{select:'*, dropship_deal_customers(customer_id)',eq:{id:existingId},maybeSingle:true});\r\n      d=deal;\r\n      (d?.dropship_deal_customers||[]).forEach(dc=>selCustomers.add(dc.customer_id));\r\n    }\r\n\r\n    const {data:customers}=await db().select('dropship_customers',{eq:{is_active:true},order:{col:'business_name'}});\r\n    const allCustomers=customers||[];\r\n\r\n    const today=new Date().toISOString().split('T')[0];\r\n    const nextMonth=new Date(Date.now()+30*86400000).toISOString().split('T')[0];\r\n\r\n    ui().openModal(existingId?`Edit dropship deal: ${d?.name}`:'New dropship deal',`\r\n      <!-- SECTION 1: Deal details -->\r\n      <div style=\"font-size:13px;font-weight:600;color:var(--ims-text);margin-bottom:12px\"><i class=\"ti ti-tag\" style=\"color:var(--ims-accent)\"></i> Deal details</div>\r\n      <div class=\"ims__form-grid\">\r\n        <div class=\"ims__form-group ims__form-group--full\">\r\n          <label class=\"ims__label ims__label--req\">Deal name</label>\r\n          <input class=\"ims__input\" type=\"text\" id=\"ims-dsd-name\" value=\"${util().sanitize(d?.name||'')}\" placeholder=\"e.g. Q3 Volume Discount\">\r\n        </div>\r\n        <div class=\"ims__form-group ims__form-group--full\">\r\n          <label class=\"ims__label\">Description</label>\r\n          <input class=\"ims__input\" type=\"text\" id=\"ims-dsd-desc\" value=\"${util().sanitize(d?.description||'')}\" placeholder=\"Internal note about this deal\">\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label ims__label--req\">Discount type</label>\r\n          <select class=\"ims__select\" id=\"ims-dsd-dtype\" onchange=\"window.IMS_DROPSHIP.onDSDealDiscountTypeChange()\">\r\n            <option value=\"percentage\" ${(d?.discount_type||'percentage')==='percentage'?'selected':''}>Percentage off (%)</option>\r\n            <option value=\"fixed_amount\" ${d?.discount_type==='fixed_amount'?'selected':''}>Fixed amount off (\u00A3)</option>\r\n          </select>\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label ims__label--req\">Discount value</label>\r\n          <input class=\"ims__input\" type=\"number\" step=\"0.01\" min=\"0\" id=\"ims-dsd-dvalue\"\r\n            value=\"${d?.discount_value||''}\"\r\n            placeholder=\"${(d?.discount_type||'percentage')==='percentage'?'e.g. 10 for 10% off':'e.g. 50 for \u00A350 off'}\"\r\n            oninput=\"window.IMS_DROPSHIP.updateDSDealPreview()\">\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label ims__label--req\">Stacking behaviour</label>\r\n          <select class=\"ims__select\" id=\"ims-dsd-stack\" onchange=\"window.IMS_DROPSHIP.updateDSDealPreview()\">\r\n            <option value=\"replace\" ${(d?.stacking_behaviour||'replace')==='replace'?'selected':''}>Replace customer's standing discount</option>\r\n            <option value=\"stack\" ${d?.stacking_behaviour==='stack'?'selected':''}>Stack on top of standing discount</option>\r\n          </select>\r\n          <span class=\"ims__input-hint\">\r\n            Replace: deal discount used instead of the customer's standing % off wholesale.<br>\r\n            Stack: deal discount applied after the standing discount.\r\n          </span>\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label ims__label--req\">Status</label>\r\n          <select class=\"ims__select\" id=\"ims-dsd-active\">\r\n            <option value=\"true\" ${(d?.is_active!==false)?'selected':''}>Active</option>\r\n            <option value=\"false\" ${d?.is_active===false?'selected':''}>Inactive (draft)</option>\r\n          </select>\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label ims__label--req\">Valid from</label>\r\n          <input class=\"ims__input\" type=\"date\" id=\"ims-dsd-from\" value=\"${d?.valid_from||today}\">\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label ims__label--req\">Valid to</label>\r\n          <input class=\"ims__input\" type=\"date\" id=\"ims-dsd-to\" value=\"${d?.valid_to||nextMonth}\">\r\n        </div>\r\n      </div>\r\n\r\n      <hr class=\"ims__divider\">\r\n\r\n      <!-- SECTION 2: Customer targeting -->\r\n      <div style=\"font-size:13px;font-weight:600;color:var(--ims-text);margin-bottom:12px\"><i class=\"ti ti-users\" style=\"color:var(--ims-accent)\"></i> Customer targeting</div>\r\n      <div style=\"margin-bottom:10px\">\r\n        <label style=\"display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer;margin-bottom:8px\">\r\n          <input type=\"checkbox\" id=\"ims-dsd-all-cust\" ${d?.applies_to_all_customers?'checked':''}\r\n            onchange=\"window.IMS_DROPSHIP.onDSDealAllCustomersChange()\">\r\n          <strong>Apply to ALL dropship customers</strong>\r\n        </label>\r\n      </div>\r\n      <div id=\"ims-dsd-cust-detail\" style=\"${d?.applies_to_all_customers?'opacity:0.4;pointer-events:none':''}\">\r\n        <div style=\"font-size:12px;font-weight:600;color:var(--ims-text-sec);margin-bottom:8px\">Specific dropship customers:</div>\r\n        <div style=\"max-height:220px;overflow-y:auto;border:1px solid var(--ims-border);border-radius:var(--ims-radius);padding:8px\">\r\n          ${allCustomers.length?allCustomers.map(c=>`\r\n            <label style=\"display:flex;align-items:center;gap:8px;padding:5px 4px;cursor:pointer;font-size:13px;border-bottom:1px solid var(--ims-border)\">\r\n              <input type=\"checkbox\" class=\"ims-dsd-cust-cb\" value=\"${c.id}\"\r\n                ${selCustomers.has(c.id)?'checked':''}>\r\n              <span>${util().sanitize(c.business_name)}</span>\r\n            </label>`).join('')\r\n          :'<div style=\"font-size:12px;color:var(--ims-text-muted);padding:8px\">No dropship customers found</div>'}\r\n        </div>\r\n      </div>\r\n\r\n      <!-- Price preview -->\r\n      <hr class=\"ims__divider\">\r\n      <div style=\"font-size:13px;font-weight:600;color:var(--ims-text);margin-bottom:10px\"><i class=\"ti ti-calculator\" style=\"color:var(--ims-accent)\"></i> Price preview</div>\r\n      <div style=\"display:grid;grid-template-columns:1fr 1fr;gap:10px;align-items:end\">\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label\">Example wholesale price (\u00A3)</label>\r\n          <input class=\"ims__input\" type=\"number\" step=\"0.01\" id=\"ims-dsd-preview-price\" value=\"100\" oninput=\"window.IMS_DROPSHIP.updateDSDealPreview()\">\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label\">Customer standing discount (%)</label>\r\n          <input class=\"ims__input\" type=\"number\" step=\"0.01\" id=\"ims-dsd-preview-standing\" value=\"0\" oninput=\"window.IMS_DROPSHIP.updateDSDealPreview()\">\r\n        </div>\r\n      </div>\r\n      <div id=\"ims-dsd-preview\" style=\"background:var(--ims-surface2);border-radius:var(--ims-radius);padding:12px;font-size:13px;margin-top:8px\">\r\n        Enter values above to see price calculation\r\n      </div>\r\n    `,`\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_DROPSHIP.saveDSDeal('${util().jsArg(existingId||'')}')\"><i class=\"ti ti-check\"></i> ${existingId?'Save changes':'Create deal'}</button>\r\n    `,'xl');\r\n\r\n    setTimeout(()=>updateDSDealPreview(),100);\r\n  }\r\n\r\n  function onDSDealDiscountTypeChange(){\r\n    const type=document.getElementById('ims-dsd-dtype')?.value;\r\n    const input=document.getElementById('ims-dsd-dvalue');\r\n    if(input) input.placeholder=type==='percentage'?'e.g. 10 for 10% off':'e.g. 50 for \u00A350 off';\r\n    updateDSDealPreview();\r\n  }\r\n\r\n  function onDSDealAllCustomersChange(){\r\n    const checked=document.getElementById('ims-dsd-all-cust')?.checked;\r\n    const detail=document.getElementById('ims-dsd-cust-detail');\r\n    if(detail){detail.style.opacity=checked?'0.4':'1';detail.style.pointerEvents=checked?'none':'';}\r\n  }\r\n\r\n  // Pure calculation \u2014 given a wholesale price, the customer's flat\r\n  // standing discount %, and a deal record, returns the final price\r\n  // plus a line-item breakdown (mirrors ims-deals.js's calculateDealPrice).\r\n  function calculateDSDealPrice(wholesalePrice,customerDiscountPct,deal){\r\n    let afterStanding=wholesalePrice;\r\n    const breakdown=[];\r\n    breakdown.push({label:'Wholesale price',amount:wholesalePrice,type:'base'});\r\n\r\n    if(deal.stacking_behaviour==='stack'&&customerDiscountPct>0){\r\n      const disc=wholesalePrice*customerDiscountPct/100;\r\n      afterStanding=wholesalePrice-disc;\r\n      breakdown.push({label:`Standing discount (${customerDiscountPct}%)`,amount:-disc,type:'standing'});\r\n    }\r\n\r\n    let finalPrice=afterStanding;\r\n    if(deal.discount_type==='percentage'){\r\n      const disc=afterStanding*deal.discount_value/100;\r\n      finalPrice=afterStanding-disc;\r\n      breakdown.push({label:`Deal: ${deal.name} (${deal.discount_value}% ${deal.stacking_behaviour==='stack'?'stacked':'replaces standing'})`,amount:-disc,type:'deal'});\r\n    } else {\r\n      finalPrice=afterStanding-deal.discount_value;\r\n      breakdown.push({label:`Deal: ${deal.name} (\u00A3${deal.discount_value} off ${deal.stacking_behaviour==='stack'?'stacked':'replaces standing'})`,amount:-deal.discount_value,type:'deal'});\r\n    }\r\n\r\n    finalPrice=Math.max(0,finalPrice);\r\n    breakdown.push({label:'Customer pays',amount:finalPrice,type:'final'});\r\n    return{finalPrice:parseFloat(finalPrice.toFixed(2)),breakdown};\r\n  }\r\n\r\n  function updateDSDealPreview(){\r\n    const preview=document.getElementById('ims-dsd-preview');\r\n    if(!preview)return;\r\n    const base=parseFloat(document.getElementById('ims-dsd-preview-price')?.value)||100;\r\n    const standing=parseFloat(document.getElementById('ims-dsd-preview-standing')?.value)||0;\r\n    const dtype=document.getElementById('ims-dsd-dtype')?.value||'percentage';\r\n    const dvalue=parseFloat(document.getElementById('ims-dsd-dvalue')?.value)||0;\r\n    const stack=document.getElementById('ims-dsd-stack')?.value||'replace';\r\n\r\n    const result=calculateDSDealPrice(base,standing,{discount_type:dtype,discount_value:dvalue,stacking_behaviour:stack,name:'This deal'});\r\n    const fmt=v=>`\u00A3${v.toFixed(2)}`;\r\n    preview.innerHTML=result.breakdown.map(line=>{\r\n      const isFinal=line.type==='final';\r\n      const color=line.type==='deal'?'var(--ims-accent)':line.type==='standing'?'var(--ims-text-sec)':isFinal?'var(--ims-success)':'inherit';\r\n      return `<div style=\"display:flex;justify-content:space-between;padding:${isFinal?'6px':'4px'} 0;${isFinal?'font-size:15px;font-weight:700':'border-bottom:1px solid var(--ims-border)'};color:${color}\"><span>${line.label}</span><span>${fmt(line.amount)}</span></div>`;\r\n    }).join('');\r\n  }\r\n\r\n  async function saveDSDeal(existingId){\r\n    const restore=_withBtnSpin(event,'Saving...');\r\n    try{\r\n    const g=id=>document.getElementById(id)?.value?.trim()||'';\r\n    const name=g('ims-dsd-name');\r\n    if(!name){ui().toast('Deal name is required','error');return;}\r\n    const dvalue=parseFloat(g('ims-dsd-dvalue'));\r\n    if(!dvalue||dvalue<=0){ui().toast('Please enter a valid discount value','error');return;}\r\n    const from=g('ims-dsd-from'), to=g('ims-dsd-to');\r\n    if(!from||!to){ui().toast('Valid from and valid to dates are required','error');return;}\r\n    if(to<from){ui().toast('Valid to must be after valid from','error');return;}\r\n\r\n    const allCust=document.getElementById('ims-dsd-all-cust')?.checked||false;\r\n    const specificCustomers=[...document.querySelectorAll('.ims-dsd-cust-cb:checked')].map(cb=>cb.value);\r\n    if(!allCust&&!specificCustomers.length){ui().toast('Select \"All dropship customers\" or at least one specific customer','error');return;}\r\n\r\n    const dealData={\r\n      name,\r\n      description:g('ims-dsd-desc')||null,\r\n      discount_type:g('ims-dsd-dtype')||'percentage',\r\n      discount_value:dvalue,\r\n      stacking_behaviour:g('ims-dsd-stack')||'replace',\r\n      applies_to_all_customers:allCust,\r\n      valid_from:from,\r\n      valid_to:to,\r\n      is_active:document.getElementById('ims-dsd-active')?.value==='true',\r\n      created_by:window.SM.AUTH.user?.id\r\n    };\r\n\r\n    // dropship_deal_customers has no company_id column \u2014 db().insert()\r\n    // would try to inject one and fail, so a raw client is required for\r\n    // that child table (matching how deal_customers is handled).\r\n    const client=window.supabase.createClient(window.IMS_SUPABASE_URL,window.IMS_SUPABASE_ANON_KEY);\r\n\r\n    let dealId=existingId;\r\n    if(existingId){\r\n      const {error}=await db().update('dropship_deals',existingId,dealData);\r\n      if(error){ui().toast('Failed: '+error.message,'error');return;}\r\n      await client.from('dropship_deal_customers').delete().eq('deal_id',existingId);\r\n    } else {\r\n      const {data:newDeal,error}=await db().insert('dropship_deals',dealData);\r\n      if(error){ui().toast('Failed: '+error.message,'error');return;}\r\n      if(!newDeal?.id){ui().toast('Deal created but ID not returned','error');return;}\r\n      dealId=newDeal.id;\r\n    }\r\n\r\n    if(!allCust&&specificCustomers.length){\r\n      await Promise.all(specificCustomers.map(custId=>\r\n        client.from('dropship_deal_customers').insert({deal_id:dealId,customer_id:custId})\r\n      ));\r\n    }\r\n\r\n    ui().closeModal();\r\n    ui().toast(`Dropship deal \"${name}\" ${existingId?'updated':'created'}`,'success');\r\n    loadDSDeals();\r\n    } finally { restore(); }\r\n  }\r\n\r\n  async function toggleDSDeal(id,newActive,name){\r\n    await db().update('dropship_deals',id,{is_active:newActive});\r\n    ui().toast(`\"${name}\" ${newActive?'activated':'deactivated'}`,'success');\r\n    loadDSDeals();\r\n  }\r\n\r\n  async function deleteDSDeal(id,name){\r\n    ui().confirm(\r\n      `Delete dropship deal \"${name}\"? This cannot be undone. Orders that used this deal will keep their discount records.`,\r\n      async()=>{\r\n        const client=window.supabase.createClient(window.IMS_SUPABASE_URL,window.IMS_SUPABASE_ANON_KEY);\r\n        await client.from('dropship_deal_customers').delete().eq('deal_id',id);\r\n        const {error}=await db().remove('dropship_deals',id);\r\n        if(error){ui().toast('Failed: '+error.message,'error');return;}\r\n        ui().toast(`Dropship deal \"${name}\" deleted`,'success');\r\n        loadDSDeals();\r\n      },\r\n      'Delete deal',\r\n      true\r\n    );\r\n  }\r\n\r\n  async function openOrder(id){\r\n    const {data:o}=await db().select('orders',{\r\n      select:'*,dropship_customers(business_name,discount_pct,delivery_method),order_items(*)',\r\n      eq:{id},maybeSingle:true,noCompanyFilter:true\r\n    });\r\n    if(!o)return;\r\n    const pendingCollection=o.delivery_method==='self_arrange'&&!['collected','cancelled','delivered'].includes(o.status);\r\n    ui().openModal(`Dropship Order: ${o.order_number}`,`\r\n      <div style=\"display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px\">\r\n        <div><span class=\"ims__label\">Dropship customer</span><div style=\"font-weight:600\">${util().sanitize(o.dropship_customers?.business_name||'\u2014')}</div></div>\r\n        <div><span class=\"ims__label\">Retailer ref</span><div>${util().sanitize(o.external_ref||'\u2014')}</div></div>\r\n        <div><span class=\"ims__label\">End customer</span><div style=\"font-weight:600\">${util().sanitize(o.end_customer_name||'\u2014')}</div></div>\r\n        <div><span class=\"ims__label\">End postcode</span><div>${util().sanitize(o.end_postcode||'\u2014')}</div></div>\r\n        <div style=\"grid-column:1/-1\"><span class=\"ims__label\">Delivery address</span><div>${util().sanitize(o.end_address||'\u2014')}</div></div>\r\n        <div><span class=\"ims__label\">Delivery method</span><div><span class=\"ims__pill ims__pill--${o.delivery_method==='mdf_delivers'?'info':'neutral'}\">${o.delivery_method==='mdf_delivers'?'MDF London delivers':'Customer self-arranges'}</span></div></div>\r\n        <div><span class=\"ims__label\">Status</span><div>${util().pill(o.status)}</div></div>\r\n        <div><span class=\"ims__label\">Order value</span><div style=\"font-weight:700;font-size:18px\">${util().formatCurrency(o.total_value)}</div></div>\r\n        ${o.collected_by?`\r\n          <div><span class=\"ims__label\">Collected by</span><div>${util().sanitize(o.collected_by)}</div></div>\r\n          <div><span class=\"ims__label\">Vehicle reg</span><div>${util().sanitize(o.collection_vehicle||'\u2014')}</div></div>\r\n          <div><span class=\"ims__label\">Collected at</span><div>${util().formatDate(o.collected_at)}</div></div>`:''}\r\n        ${o.notes?`<div style=\"grid-column:1/-1\"><span class=\"ims__label\">Notes</span><div>${util().sanitize(o.notes)}</div></div>`:''}\r\n      </div>\r\n      <hr class=\"ims__divider\">\r\n      <strong style=\"font-size:13px\">Items</strong>\r\n      <table class=\"ims__table\" style=\"margin-top:8px\">\r\n        <thead><tr><th>Product</th><th>SKU</th><th>Qty</th><th>Unit price</th><th>Total</th></tr></thead>\r\n        <tbody>${(o.order_items||[]).map(i=>`<tr>\r\n          <td>${util().sanitize(i.product_name||'\u2014')}</td>\r\n          <td>${util().sanitize(i.sku||'\u2014')}</td>\r\n          <td>${i.quantity}</td>\r\n          <td>${util().formatCurrency(i.unit_price)}</td>\r\n          <td>${util().formatCurrency(i.total_price)}</td>\r\n        </tr>`).join('')}\r\n        <tr><td colspan=\"4\" style=\"text-align:right;font-weight:600\">Total</td><td style=\"font-weight:700\">${util().formatCurrency(o.total_value)}</td></tr>\r\n        </tbody>\r\n      </table>\r\n    `,`\r\n      <div style=\"display:flex;gap:8px;align-items:center;flex-wrap:wrap\">\r\n        ${['collected','cancelled','delivered','refunded'].includes(o.status) ? `\r\n          <div style=\"font-size:12px;color:var(--ims-text-muted);padding:6px 10px;background:var(--ims-surface2);border-radius:var(--ims-radius);border:1px solid var(--ims-border)\">\r\n            <i class=\"ti ti-lock\" style=\"font-size:11px\"></i>\r\n            Order is <strong>${o.status}</strong> \u2014 status is final and cannot be changed\r\n          </div>` : `\r\n          <select class=\"ims__select\" id=\"ims-dso-status-sel\" style=\"font-size:12px;width:auto\">\r\n            <option value=\"\">Update status...</option>\r\n            <option>picking</option>\r\n            <option>packed</option>\r\n            ${o.delivery_method==='mdf_delivers'?'<option>dispatched</option><option>delivered</option>':''}\r\n            <option>cancelled</option>\r\n          </select>\r\n          <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_DROPSHIP.updateOrderStatus('${util().jsArg(o.id)}')\">Update</button>`}\r\n        ${pendingCollection?`\r\n          <button class=\"ims__btn ims__btn--success\"\r\n            onclick=\"window.IMS_DROPSHIP.showCollectionModal('${util().jsArg(o.id)}','${util().jsArg(o.order_number)}','${util().jsArg(o.dropship_customers?.business_name||'')}')\">\r\n            <i class=\"ti ti-truck-loading\"></i> Confirm collection\r\n          </button>`:''}\r\n        ${['collected','delivered'].includes(o.status) ? `\r\n          <button class=\"ims__btn ims__btn--warning\" onclick=\"window.IMS_DROPSHIP.showDropshipReturn('${util().jsArg(o.id)}','${util().jsArg(o.order_number)}','${util().jsArg(o.dropship_customers?.business_name||'')}')\"><i class=\"ti ti-arrow-back-up\"></i> Process return</button>\r\n          <button class=\"ims__btn ims__btn--secondary\" onclick=\"window.IMS_DROPSHIP.showDropshipRefundNoReturn('${util().jsArg(o.id)}','${util().jsArg(o.order_number)}','${util().jsArg(o.dropship_customers?.business_name||'')}',${o.total_value||0})\"><i class=\"ti ti-currency-pound\"></i> Refund (no return)</button>` : ''}\r\n        ${window.SM.AUTH.isAdmin()?`<button class=\"ims__btn ims__btn--danger\" onclick=\"window.IMS_DROPSHIP.deleteOrder('${util().jsArg(o.id)}','${util().jsArg(o.order_number)}')\"><i class=\"ti ti-trash\"></i> Delete order</button>`:''}\r\n        <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Close</button>\r\n      </div>\r\n    `,'xl');\r\n  }\r\n\r\n  async function updateOrderStatus(orderId){\r\n    const sel=document.getElementById('ims-dso-status-sel');\r\n    if(!sel?.value)return;\r\n    // Prevent setting to collected via status dropdown \u2014 must use Confirm Collection button\r\n    if(sel.value==='collected'){ui().toast('Use the Confirm Collection button to mark as collected','warning');return;}\r\n    const updates={status:sel.value};\r\n    if(sel.value==='dispatched')updates.dispatched_at=new Date().toISOString();\r\n    if(sel.value==='delivered')updates.delivered_at=new Date().toISOString();\r\n    await db().update('orders',orderId,updates);\r\n    ui().closeModal();ui().toast('Order status updated','success');loadOrders();\r\n  }\r\n\r\n  // \u2500\u2500\u2500 COURIER COLLECTION CONFIRMATION \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n  // Called when courier arrives to collect a self-arrange order.\r\n  // Requires columns on dropship_orders:\r\n  //   collected_by text, collection_vehicle text, collected_at timestamptz\r\n  // Run this migration if not already done:\r\n  //   ALTER TABLE dropship_orders ADD COLUMN IF NOT EXISTS collected_by text;\r\n  //   ALTER TABLE dropship_orders ADD COLUMN IF NOT EXISTS collection_vehicle text;\r\n  //   ALTER TABLE dropship_orders ADD COLUMN IF NOT EXISTS collected_at timestamptz;\r\n  //   ALTER TABLE dropship_orders ADD COLUMN IF NOT EXISTS collection_notes text;\r\n\r\n  async function showCollectionModal(orderId, orderNumber, customerName){\r\n    const now = new Date();\r\n    const dateStr = now.toISOString().split('T')[0];\r\n    const timeStr = now.toTimeString().slice(0,5);\r\n\r\n    // Load order items so we can show what's being collected\r\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\r\n    const {data:items} = await client\r\n      .from('dropship_order_items')\r\n      .select('product_name,sku,quantity')\r\n      .eq('order_id', orderId);\r\n\r\n    ui().openModal(`Confirm collection: ${orderNumber}`,`\r\n      <div class=\"ims__alert ims__alert--warning\" style=\"margin-bottom:16px\">\r\n        <i class=\"ti ti-truck-loading\"></i>\r\n        <span>A courier is collecting this order on behalf of <strong>${util().sanitize(customerName)}</strong>. Complete the details below before confirming \u2014 this cannot be undone.</span>\r\n      </div>\r\n\r\n      ${items?.length ? `\r\n        <div style=\"margin-bottom:16px\">\r\n          <div style=\"font-size:12px;font-weight:600;color:var(--ims-text-muted);margin-bottom:6px\">ITEMS BEING COLLECTED</div>\r\n          <div style=\"border:1px solid var(--ims-border);border-radius:var(--ims-radius);overflow:hidden\">\r\n            ${items.map((item,i)=>`\r\n              <div style=\"display:flex;justify-content:space-between;align-items:center;padding:8px 12px;${i<items.length-1?'border-bottom:1px solid var(--ims-border)':''}\">\r\n                <div>\r\n                  <div style=\"font-size:13px;font-weight:500\">${util().sanitize(item.product_name||'\u2014')}</div>\r\n                  <div style=\"font-size:11px;color:var(--ims-text-muted)\">${util().sanitize(item.sku||'')}</div>\r\n                </div>\r\n                <div style=\"font-weight:600;color:var(--ims-accent)\">\u00D7${item.quantity}</div>\r\n              </div>`).join('')}\r\n          </div>\r\n        </div>` : ''}\r\n\r\n      <div class=\"ims__form-grid\">\r\n        <div class=\"ims__form-group ims__form-group--full\">\r\n          <label class=\"ims__label ims__label--req\">Collected by (driver/courier name)</label>\r\n          <input class=\"ims__input\" type=\"text\" id=\"ims-col-by\"\r\n            placeholder=\"e.g. John Smith \u2014 Panther Logistics\">\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label\">Vehicle registration</label>\r\n          <input class=\"ims__input\" type=\"text\" id=\"ims-col-vehicle\"\r\n            placeholder=\"e.g. AB12 CDE\" style=\"text-transform:uppercase\">\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label ims__label--req\">Collection date</label>\r\n          <input class=\"ims__input\" type=\"date\" id=\"ims-col-date\" value=\"${dateStr}\">\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label ims__label--req\">Collection time</label>\r\n          <input class=\"ims__input\" type=\"time\" id=\"ims-col-time\" value=\"${timeStr}\">\r\n        </div>\r\n        <div class=\"ims__form-group ims__form-group--full\">\r\n          <label class=\"ims__label\">Notes</label>\r\n          <input class=\"ims__input\" type=\"text\" id=\"ims-col-notes\"\r\n            placeholder=\"e.g. 2 boxes, driver checked contents, left copy of POD\">\r\n        </div>\r\n      </div>\r\n\r\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-top:4px\">\r\n        <i class=\"ti ti-info-circle\"></i>\r\n        <span>Stock will remain reserved \u2014 it has already left your warehouse. The allocation <strong>remaining qty</strong> will not change on collection (it reduces when orders are placed).</span>\r\n      </div>\r\n    `,`\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n      <button class=\"ims__btn ims__btn--success\"\r\n        onclick=\"window.IMS_DROPSHIP.confirmCollection('${util().jsArg(orderId)}','${util().jsArg(orderNumber)}')\">\r\n        <i class=\"ti ti-circle-check\"></i> Confirm collected\r\n      </button>\r\n    `,'lg');\r\n\r\n    // Auto-focus driver name\r\n    setTimeout(()=>document.getElementById('ims-col-by')?.focus(), 150);\r\n  }\r\n\r\n  // \u2500\u2500\u2500 DROPSHIP STOCK OUT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n  // The one place that takes stock out for a dropship order, whether the\r\n  // partner collects it (confirmCollection below) or our van delivers it\r\n  // (ims-logistics.js calls this too), so the two can never disagree.\r\n  //\r\n  // Dropship stock is set aside by an allocation, which adds to\r\n  // reserved_by_allocations in the allocation's own warehouse. So when the\r\n  // goods leave: on-hand (quantity) and reserved_by_allocations both go\r\n  // down, in that same warehouse. reserved_qty belongs to normal orders\r\n  // and is never touched here. (The old collection code reduced it, which\r\n  // took reservations away from normal orders and made stock look more\r\n  // available than it really was.)\r\n  //\r\n  // Returns { skipped, problems }. skipped = already done for this order.\r\n  // problems = product names whose stock could not be updated.\r\n  // The batches a line's units came from, as [{alloc, qty}]. New lines\r\n  // record their split across batches (dropship_allocation_split). Older\r\n  // lines have at most one batch recorded, or none, and keep the earlier\r\n  // behaviour: to take stock out, the recorded batch or else the partner's\r\n  // latest batch; to give units back, _allocationForLine's choice.\r\n  async function _lineParts(client, customerId, item, mode){\r\n    const qty=item.quantity||0;\r\n    const split=Array.isArray(item.dropship_allocation_split)?item.dropship_allocation_split.filter(p=>p&&p.id&&p.qty>0):[];\r\n    if(split.length){\r\n      const {data:rows}=await client.from('dropship_allocations').select('id,warehouse_id,allocated_qty,remaining_qty').in('id',split.map(p=>p.id));\r\n      return split.map(p=>({alloc:(rows||[]).find(r=>r.id===p.id)||null, qty:p.qty}));\r\n    }\r\n    if(mode==='giveback') return [{alloc:await _allocationForLine(client, customerId, item), qty}];\r\n    let alloc=null;\r\n    if(item.dropship_allocation_id){\r\n      ({data:alloc}=await client.from('dropship_allocations').select('id,warehouse_id').eq('id',item.dropship_allocation_id).maybeSingle());\r\n    }\r\n    if(!alloc && customerId){\r\n      ({data:alloc}=await client.from('dropship_allocations').select('id,warehouse_id')\r\n        .eq('customer_id',customerId).eq('product_id',item.product_id)\r\n        .order('created_at',{ascending:false}).limit(1).maybeSingle());\r\n    }\r\n    return [{alloc, qty}];\r\n  }\r\n\r\n  async function deductDropshipStock(orderId, orderNumber, reason){\r\n    // A 'sale' movement for this order means the stock has already been\r\n    // taken out once. Never do it twice.\r\n    const {data:already}=await db().select('stock_movements',{eq:{reference:orderNumber,movement_type:'sale'},limit:1,noCompanyFilter:true});\r\n    if(already?.length) return {skipped:true,problems:[]};\r\n\r\n    const client=window.supabase.createClient(window.IMS_SUPABASE_URL,window.IMS_SUPABASE_ANON_KEY);\r\n    const {data:ord}=await client.from('orders').select('dropship_customer_id').eq('id',orderId).maybeSingle();\r\n    const {data:items}=await client.from('order_items').select('product_id,product_name,quantity,dropship_allocation_id,dropship_allocation_split').eq('order_id',orderId);\r\n    const problems=[];\r\n\r\n    // One line (and one batch) at a time, so nothing reads a figure another\r\n    // step is about to change.\r\n    for(const item of (items||[])){\r\n      if(!item.product_id) continue;\r\n      const label=item.product_name||item.product_id;\r\n      const parts=await _lineParts(client, ord?.dropship_customer_id, item, 'deduct');\r\n      for(const part of parts){\r\n        const qty=part.qty;\r\n        let sl=null, fromAllocation=false;\r\n        if(part.alloc?.warehouse_id){\r\n          const {data}=await db().select('stock_levels',{eq:{product_id:item.product_id,warehouse_id:part.alloc.warehouse_id},maybeSingle:true,noCompanyFilter:true});\r\n          sl=data; fromAllocation=true;\r\n        } else {\r\n          // No batch on record. Only safe to guess the warehouse when the\r\n          // product is held in exactly one.\r\n          const {data:rows}=await db().select('stock_levels',{eq:{product_id:item.product_id},noCompanyFilter:true});\r\n          if((rows||[]).length===1) sl=rows[0];\r\n        }\r\n        if(!sl){ problems.push(label); continue; }\r\n\r\n        const updates={quantity:Math.max(0,(sl.quantity||0)-qty)};\r\n        if(fromAllocation) updates.reserved_by_allocations=Math.max(0,(sl.reserved_by_allocations||0)-qty);\r\n        const {error:upErr}=await db().update('stock_levels',sl.id,updates);\r\n        if(upErr){ problems.push(label); continue; }\r\n\r\n        await db().insert('stock_movements',{\r\n          product_id:item.product_id, warehouse_id:sl.warehouse_id||null,\r\n          movement_type:'sale', quantity:-qty,\r\n          reference:orderNumber||null, reason,\r\n          user_id:window.SM.AUTH.user?.id\r\n        });\r\n      }\r\n    }\r\n    return {skipped:false,problems};\r\n  }\r\n\r\n  // \u2500\u2500\u2500 DROPSHIP STOCK RULES (shared) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n  // A dropship order's units belong to the partner's allocation until they\r\n  // physically leave:\r\n  //   created            allocation remaining - qty (in saveDSOrder)\r\n  //   left (collected or delivered)\r\n  //                      on-hand - qty, partner reservation - qty\r\n  //                      (deductDropshipStock above)\r\n  //   deleted before leaving\r\n  //                      allocation remaining + qty, to the same batch\r\n  //   returned after leaving\r\n  //                      on-hand + qty, partner reservation + qty,\r\n  //                      allocation remaining + qty (they can sell it again)\r\n  //   lost, case closed  on-hand - qty, partner reservation - qty\r\n  //   parcel found       the exact reverse of whatever had happened\r\n  // Normal orders' \"reserved\" (reserved_qty) is never touched by any of it.\r\n\r\n  // Have this order's goods physically left (a 'sale' or 'write_off'\r\n  // stock movement exists)?\r\n  async function _dropshipGoodsLeft(orderNumber){\r\n    const {data}=await db().select('stock_movements',{eq:{reference:orderNumber},in:{movement_type:['sale','write_off']},limit:1,noCompanyFilter:true});\r\n    return !!data?.length;\r\n  }\r\n\r\n  // The allocation a line's units came from: the one recorded on the line,\r\n  // or for older orders (created before that was recorded) a best guess.\r\n  // Allocations are used oldest first, so recent orders drew from the batch\r\n  // currently in use (the oldest one that still has units). The guess is\r\n  // that batch if it has room to take the units back, otherwise the newest\r\n  // batch with room. (The old Delete used the oldest batch, which is\r\n  // usually an old, used-up one.)\r\n  async function _allocationForLine(client, customerId, item){\r\n    if(item.dropship_allocation_id){\r\n      const {data}=await client.from('dropship_allocations').select('id,warehouse_id,allocated_qty,remaining_qty').eq('id',item.dropship_allocation_id).maybeSingle();\r\n      if(data) return data;\r\n    }\r\n    if(!customerId||!item.product_id) return null;\r\n    const {data:rows}=await client.from('dropship_allocations')\r\n      .select('id,warehouse_id,allocated_qty,remaining_qty,created_at')\r\n      .eq('customer_id',customerId).eq('product_id',item.product_id)\r\n      .order('created_at',{ascending:true});\r\n    const qty=item.quantity||0;\r\n    const room=a=>a.allocated_qty==null?qty:(a.allocated_qty||0)-(a.remaining_qty||0);\r\n    const list=rows||[];\r\n    const current=list.find(a=>(a.remaining_qty||0)>0);\r\n    if(current && room(current)>0) return current;\r\n    const newestFirst=[...list].reverse();\r\n    return newestFirst.find(a=>room(a)>=qty)||newestFirst.find(a=>room(a)>0)||null;\r\n  }\r\n\r\n  // How many of qty units the allocation can take back (never above what\r\n  // was allocated).\r\n  function _roomIn(alloc, qty){\r\n    if(alloc.allocated_qty==null) return qty;\r\n    return Math.max(0,Math.min(qty,(alloc.allocated_qty||0)-(alloc.remaining_qty||0)));\r\n  }\r\n\r\n  // Returns and \"parcel found\": puts the order's units back, once only\r\n  // (claims the same \"already restocked\" stamp smartRestock uses).\r\n  // Returns the number of lines put back.\r\n  async function restoreDropshipStock(orderId, orderNumber, reason){\r\n    const client=window.supabase.createClient(window.IMS_SUPABASE_URL,window.IMS_SUPABASE_ANON_KEY);\r\n    const {data:ord}=await client.from('orders').select('dropship_customer_id,restocked_at').eq('id',orderId).maybeSingle();\r\n    if(!ord||ord.restocked_at) return 0;\r\n    const {data:items}=await client.from('order_items').select('product_id,product_name,quantity,dropship_allocation_id,dropship_allocation_split').eq('order_id',orderId);\r\n    if(!(items||[]).some(i=>i.product_id)) return 0;\r\n\r\n    const authClient=window.supabase.createClient(window.IMS_SUPABASE_URL,window.IMS_SUPABASE_ANON_KEY,\r\n      {global:{headers:{Authorization:`Bearer ${window.SM.AUTH.session?.access_token}`}}});\r\n    const {data:claimed,error:stampErr}=await authClient.from('orders')\r\n      .update({restocked_at:new Date().toISOString()})\r\n      .eq('id',orderId).is('restocked_at',null).select('id');\r\n    if(stampErr){ ui().toast(`Stock for ${orderNumber} was not updated: ${stampErr.message}`,'error',8000); return 0; }\r\n    if(!claimed?.length) return 0;\r\n\r\n    const left=await _dropshipGoodsLeft(orderNumber);\r\n    let processed=0; const problems=[];\r\n    for(const item of items){\r\n      if(!item.product_id) continue;\r\n      const label=item.product_name||item.product_id;\r\n      // Batch by batch: each part goes back to the batch (and warehouse) it\r\n      // came from.\r\n      const parts=await _lineParts(client, ord.dropship_customer_id, item, 'giveback');\r\n      let lineOk=true;\r\n      for(const part of parts){\r\n        const alloc=part.alloc, qty=part.qty;\r\n        if(!alloc){ problems.push(label); lineOk=false; continue; }\r\n        const give=_roomIn(alloc, qty);\r\n        if(left){\r\n          // The goods had left, so they come back onto the shelf. Units the\r\n          // batch can take back are ring-fenced for the partner again.\r\n          const {data:sl}=await db().select('stock_levels',{eq:{product_id:item.product_id,warehouse_id:alloc.warehouse_id},maybeSingle:true,noCompanyFilter:true});\r\n          if(!sl){ problems.push(label); lineOk=false; continue; }\r\n          const {error:upErr}=await db().update('stock_levels',sl.id,{\r\n            quantity:(sl.quantity||0)+qty,\r\n            reserved_by_allocations:(sl.reserved_by_allocations||0)+give\r\n          });\r\n          if(upErr){ problems.push(label); lineOk=false; continue; }\r\n          await db().insert('stock_movements',{\r\n            product_id:item.product_id, warehouse_id:alloc.warehouse_id, movement_type:'return', quantity:qty,\r\n            reference:orderNumber||null, reason:`${reason}: back on the shelf and in the partner's allocation`,\r\n            user_id:window.SM.AUTH.user?.id\r\n          });\r\n        }\r\n        if(give>0){\r\n          const {error:aErr}=await client.from('dropship_allocations').update({remaining_qty:(alloc.remaining_qty||0)+give}).eq('id',alloc.id);\r\n          if(aErr){ problems.push(label); lineOk=false; continue; }\r\n        }\r\n      }\r\n      if(lineOk) processed++;\r\n    }\r\n    if(problems.length) ui().toast(`${orderNumber}: stock could not be put back for ${problems.join(', ')}. Please check stock levels and allocations.`,'warning',10000);\r\n    return processed;\r\n  }\r\n\r\n  // Lost, case closed (claim settled or rejected, or closed without a\r\n  // claim): the units are gone, so they leave the shelf and the partner's\r\n  // reservation. Skipped if they already left or were put back.\r\n  // Returns { done, problems }, like writeOffOrderStock in ims-logistics.js.\r\n  async function writeOffDropshipStock(orderId, orderNumber, reason){\r\n    if(await _dropshipGoodsLeft(orderNumber)) return {done:0,problems:[]};\r\n    const client=window.supabase.createClient(window.IMS_SUPABASE_URL,window.IMS_SUPABASE_ANON_KEY);\r\n    const {data:ord}=await client.from('orders').select('dropship_customer_id,restocked_at').eq('id',orderId).maybeSingle();\r\n    if(!ord||ord.restocked_at) return {done:0,problems:[]};\r\n    const {data:items}=await client.from('order_items').select('product_id,product_name,quantity,dropship_allocation_id,dropship_allocation_split').eq('order_id',orderId);\r\n    let done=0; const problems=[];\r\n    for(const item of (items||[])){\r\n      if(!item.product_id) continue;\r\n      const label=item.product_name||item.product_id;\r\n      // Batch by batch, in each batch's own warehouse.\r\n      const parts=await _lineParts(client, ord.dropship_customer_id, item, 'deduct');\r\n      let lineOk=true;\r\n      for(const part of parts){\r\n        const qty=part.qty, whId=part.alloc?.warehouse_id||null;\r\n        if(!whId){ problems.push(label); lineOk=false; continue; }\r\n        const {data:sl}=await db().select('stock_levels',{eq:{product_id:item.product_id,warehouse_id:whId},maybeSingle:true,noCompanyFilter:true});\r\n        if(!sl){ problems.push(label); lineOk=false; continue; }\r\n        const {error:upErr}=await db().update('stock_levels',sl.id,{\r\n          quantity:Math.max(0,(sl.quantity||0)-qty),\r\n          reserved_by_allocations:Math.max(0,(sl.reserved_by_allocations||0)-qty)\r\n        });\r\n        if(upErr){ problems.push(label); lineOk=false; continue; }\r\n        await db().insert('stock_movements',{\r\n          product_id:item.product_id, warehouse_id:whId, movement_type:'write_off', quantity:-qty,\r\n          reference:orderNumber||null, reason, user_id:window.SM.AUTH.user?.id\r\n        });\r\n      }\r\n      if(lineOk) done++;\r\n    }\r\n    return {done,problems};\r\n  }\r\n\r\n  async function confirmCollection(orderId, orderNumber){\r\n    const collectedBy  = document.getElementById('ims-col-by')?.value?.trim();\r\n    const vehicle      = document.getElementById('ims-col-vehicle')?.value?.trim().toUpperCase();\r\n    const dateVal      = document.getElementById('ims-col-date')?.value;\r\n    const timeVal      = document.getElementById('ims-col-time')?.value||'00:00';\r\n    const notes        = document.getElementById('ims-col-notes')?.value?.trim();\r\n\r\n    if(!collectedBy){ ui().toast('Please enter who collected the order','error'); return; }\r\n    if(!dateVal){ ui().toast('Please enter the collection date','error'); return; }\r\n\r\n    const collectedAt = new Date(`${dateVal}T${timeVal}:00`).toISOString();\r\n\r\n    const {error} = await db().update('orders', orderId, {\r\n      status:             'collected',\r\n      collected_by:       collectedBy,\r\n      collection_vehicle: vehicle||null,\r\n      collected_at:       collectedAt,\r\n      collection_notes:   notes||null\r\n    });\r\n\r\n    if(error){\r\n      // If columns don't exist yet, fall back to just status update\r\n      if(error.message?.includes('column')){\r\n        await db().update('orders', orderId, {\r\n          status:'collected',\r\n          collected_at: collectedAt\r\n        });\r\n        ui().closeModal();\r\n        ui().toast(`Order ${orderNumber} marked as collected. Run the SQL migration to store full collection details.`,'warning',7000);\r\n      } else {\r\n        ui().toast('Failed: '+error.message,'error');\r\n        return;\r\n      }\r\n    } else {\r\n      ui().closeModal();\r\n      ui().toast(`Order ${orderNumber} confirmed collected by ${collectedBy}`,'success',5000);\r\n    }\r\n\r\n    // Take the stock out: on-hand and the partner's allocation\r\n    // reservation, in the allocation's warehouse. See deductDropshipStock\r\n    // above. It also logs the 'sale' movement that smartRestock relies on\r\n    // if this order is ever returned, and will not run twice.\r\n    const stockResult=await deductDropshipStock(orderId,orderNumber,'Dropship order collected');\r\n    if(stockResult.problems.length){\r\n      ui().toast(`Order ${orderNumber} collected, but stock could not be updated for: ${stockResult.problems.join(', ')}. Please adjust these in Inventory.`,'warning',15000);\r\n    }\r\n    loadOrders();\r\n    if(window.IMS_DASHBOARD?.load)window.IMS_DASHBOARD.load();\r\n  }\r\n\r\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\r\n  // RETURNS & REFUNDS\r\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\r\n  // Previously, once a dropship order reached collected/delivered its\r\n  // status was permanently locked \u2014 there was no return path at all. These\r\n  // two actions cover the two real scenarios:\r\n  //  - A genuine return: goods come back, restock via smartRestock (which\r\n  //    correctly handles both MDF-delivered and self-collected orders now\r\n  //    that both log a 'sale' movement), and the charge is removed from\r\n  //    the customer's account \u2014 either voided outright if never invoiced,\r\n  //    or reversed with a credit note if it has been.\r\n  //  - A refund without return: customer keeps the item, no restock, but\r\n  //    the charge still needs reversing the same way.\r\n\r\n  function showDropshipReturn(orderId, orderNumber, customerName){\r\n    const todayStr = new Date().toISOString().split('T')[0];\r\n    ui().openModal(`Process return \u2014 ${orderNumber}`, `\r\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:14px\">\r\n        <i class=\"ti ti-info-circle\"></i>\r\n        <span>Restocks the item(s) and removes the charge from <strong>${util().sanitize(customerName||'the customer')}</strong>'s account \u2014 voids the order if it hasn't been invoiced yet, or issues a credit note if it has.</span>\r\n      </div>\r\n      <div class=\"ims__form-group\" style=\"margin-bottom:10px\">\r\n        <label class=\"ims__label ims__label--req\">Date returned</label>\r\n        <input class=\"ims__input\" type=\"date\" id=\"ims-dsret-date\" value=\"${todayStr}\" max=\"${todayStr}\">\r\n      </div>\r\n      <div class=\"ims__form-group\">\r\n        <label class=\"ims__label\">Reason / notes</label>\r\n        <textarea class=\"ims__textarea\" id=\"ims-dsret-notes\" rows=\"2\" placeholder=\"Reason for return...\"></textarea>\r\n      </div>\r\n    `,`\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n      <button class=\"ims__btn ims__btn--success\" onclick=\"window.IMS_DROPSHIP.confirmDropshipReturn('${util().jsArg(orderId)}','${util().jsArg(orderNumber)}')\"><i class=\"ti ti-arrow-back-up\"></i> Confirm return</button>\r\n    `,'sm');\r\n  }\r\n\r\n  async function confirmDropshipReturn(orderId, orderNumber){\r\n    const dateVal = document.getElementById('ims-dsret-date')?.value;\r\n    const notes   = document.getElementById('ims-dsret-notes')?.value?.trim()||'';\r\n    if(!dateVal){ ui().toast('Please select the date returned','error'); return; }\r\n\r\n    const { data: ord } = await db().select('orders', {\r\n      select:'total_value,invoice_id,order_number', eq:{id:orderId}, maybeSingle:true, noCompanyFilter:true\r\n    });\r\n    if(!ord){ ui().toast('Order not found','error'); return; }\r\n    const reasonText = `Dropship return \u2014 ${ord.order_number||orderNumber}${notes?' \u2014 '+notes:''}`;\r\n\r\n    // Restock \u2014 smartRestock (ims-logistics.js) checks whether stock was\r\n    // ever actually deducted for this order, whether it was MDF-delivered\r\n    // via Logistics or self-collected (both now log a 'sale' movement),\r\n    // and does the right thing either way.\r\n    await window.IMS_LOGISTICS.smartRestock(orderId, ord.order_number||orderNumber, 'Dropship return');\r\n\r\n    // Remove the charge from the customer's account \u2014 voids if never\r\n    // invoiced, issues a credit note against the batch invoice if it has.\r\n    const noteNum = await window.IMS_ACCOUNTS.reverseOrderInvoice(orderId, ord.total_value||0, dateVal, reasonText);\r\n\r\n    await db().update('orders', orderId, {\r\n      status:'refunded', refunded_at:new Date(dateVal).toISOString(),\r\n      return_reason:`Dropship return${notes?' \u2014 '+notes:''}`\r\n    });\r\n\r\n    // Only record a standalone expense here if there was nothing to credit\r\n    // (order was never invoiced) \u2014 otherwise reverseOrderInvoice already\r\n    // recorded the correct expense against the credit note.\r\n    if(!noteNum){\r\n      // One entry, as a reduction of sales (standard practice, as in Xero\r\n      // and Sage).\r\n      await db().insert('transactions', {\r\n        date:dateVal, type:'income', category:'Sales returns and refunds',\r\n        description:reasonText, amount:-(ord.total_value||0), vat_amount:0, reference:ord.order_number||orderNumber\r\n      });\r\n    }\r\n\r\n    ui().closeModal();\r\n    ui().toast(`${orderNumber} \u2014 return processed, stock updated${noteNum?', credit note '+noteNum+' issued':' (order was not yet invoiced \u2014 nothing to credit)'}`,'success',7000);\r\n    loadOrders();\r\n  }\r\n\r\n  function showDropshipRefundNoReturn(orderId, orderNumber, customerName, totalValue){\r\n    const todayStr = new Date().toISOString().split('T')[0];\r\n    ui().openModal(`Refund without return \u2014 ${orderNumber}`, `\r\n      <div class=\"ims__alert ims__alert--warning\" style=\"margin-bottom:14px\">\r\n        <i class=\"ti ti-alert-triangle\"></i>\r\n        <span>Customer keeps the item \u2014 <strong>no stock will be restocked</strong>. This still removes the charge from <strong>${util().sanitize(customerName||'the customer')}</strong>'s account.</span>\r\n      </div>\r\n      <div class=\"ims__form-grid\">\r\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Refund amount (\u00A3)</label><input class=\"ims__input\" type=\"number\" step=\"0.01\" min=\"0\" id=\"ims-dsrnr-amount\" value=\"${(totalValue||0).toFixed(2)}\"></div>\r\n        <div class=\"ims__form-group\"><label class=\"ims__label ims__label--req\">Date</label><input class=\"ims__input\" type=\"date\" id=\"ims-dsrnr-date\" value=\"${todayStr}\" max=\"${todayStr}\"></div>\r\n        <div class=\"ims__form-group ims__form-group--full\"><label class=\"ims__label ims__label--req\">Reason</label><input class=\"ims__input\" type=\"text\" id=\"ims-dsrnr-reason\" placeholder=\"e.g. Goodwill gesture, minor cosmetic fault...\"></div>\r\n      </div>\r\n    `,`\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n      <button class=\"ims__btn ims__btn--success\" onclick=\"window.IMS_DROPSHIP.confirmDropshipRefundNoReturn('${util().jsArg(orderId)}','${util().jsArg(orderNumber)}')\"><i class=\"ti ti-currency-pound\"></i> Confirm refund</button>\r\n    `,'sm');\r\n  }\r\n\r\n  async function confirmDropshipRefundNoReturn(orderId, orderNumber){\r\n    const amount = parseFloat(document.getElementById('ims-dsrnr-amount')?.value)||0;\r\n    const dateVal = document.getElementById('ims-dsrnr-date')?.value;\r\n    const reason = document.getElementById('ims-dsrnr-reason')?.value?.trim();\r\n    if(!amount||amount<=0){ ui().toast('Please enter a valid amount','error'); return; }\r\n    if(!dateVal){ ui().toast('Please select a date','error'); return; }\r\n    if(!reason){ ui().toast('Please enter a reason','error'); return; }\r\n    const reasonText = `Refund without return \u2014 ${orderNumber} \u2014 ${reason}`;\r\n\r\n    // No smartRestock call \u2014 the customer is keeping the item.\r\n    const noteNum = await window.IMS_ACCOUNTS.reverseOrderInvoice(orderId, amount, dateVal, reasonText);\r\n\r\n    await db().update('orders', orderId, {\r\n      status:'refunded', refunded_at:new Date(dateVal).toISOString(),\r\n      return_reason:reasonText\r\n    });\r\n\r\n    if(!noteNum){\r\n      // One entry, as a reduction of sales (standard practice, as in Xero\r\n      // and Sage).\r\n      await db().insert('transactions', {\r\n        date:dateVal, type:'income', category:'Sales returns and refunds',\r\n        description:reasonText, amount:-amount, vat_amount:0, reference:orderNumber\r\n      });\r\n    }\r\n\r\n    ui().closeModal();\r\n    ui().toast(`Refund of ${util().formatCurrency(amount)} processed \u2014 customer kept the item${noteNum?', credit note '+noteNum+' issued':''}`,'success',7000);\r\n    loadOrders();\r\n  }\r\n\r\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\r\n  // FORTNIGHTLY INVOICES\r\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\r\n  async function loadInvoices(){\r\n    const content=document.getElementById('ims-ds-content');\r\n    if(!content)return;\r\n    const actions=document.getElementById('ims-ds-actions');\r\n    if(actions)actions.innerHTML=`<button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_DROPSHIP.generateInvoices()\"><i class=\"ti ti-file-invoice\"></i> Generate fortnightly invoices</button>`;\r\n\r\n    // Dropship invoices now live in the shared invoices table\r\n    // (source_module='dropship'), not the retired dropship_invoices \u2014\r\n    // customer_name/address/postcode are stored directly on each\r\n    // invoice row (snapshotted at generation time), so no join needed.\r\n    const {data:invoices}=await db().select('invoices',{\r\n      eq:{source_module:'dropship'},\r\n      order:{col:'created_at',asc:false}\r\n    });\r\n    const items=invoices||[];\r\n    content.innerHTML=`\r\n      <div class=\"ims__table-wrap\">\r\n        <table class=\"ims__table\">\r\n          <thead><tr><th>Invoice #</th><th>Customer</th><th>Invoice date</th><th>Total</th><th>Due date</th><th>Status</th><th></th></tr></thead>\r\n          <tbody>${items.map(inv=>`<tr>\r\n            <td><strong>${util().sanitize(inv.invoice_number)}</strong></td>\r\n            <td>${util().sanitize(inv.customer_name||'\u2014')}</td>\r\n            <td style=\"font-size:12px\">${util().formatDate(inv.invoice_date)}</td>\r\n            <td style=\"font-weight:600\">${util().formatCurrency(inv.gross_amount)}</td>\r\n            <td style=\"color:${inv.due_date&&new Date(inv.due_date)<new Date()&&inv.status!=='paid'?'var(--ims-danger)':''}\">${inv.due_date?util().formatDate(inv.due_date):'\u2014'}</td>\r\n            <td>${util().pill(inv.status)}</td>\r\n            <td><div class=\"ims__btn-group\">\r\n              ${inv.status==='draft'?`<button class=\"ims__btn ims__btn--secondary ims__btn--sm\" onclick=\"window.IMS_DROPSHIP.emailInvoice('${util().jsArg(inv.id)}')\"><i class=\"ti ti-send\"></i> Send</button>`:''}\r\n              ${['sent','overdue','partially_paid'].includes(inv.status)?`<button class=\"ims__btn ims__btn--success ims__btn--sm\" onclick=\"window.IMS_ACCOUNTS.markInvoicePaid('${util().jsArg(inv.id)}',${(inv.gross_amount||0)-(inv.paid_amount||0)})\"><i class=\"ti ti-check\"></i> ${inv.status==='partially_paid'?'Record payment':'Mark paid'}</button>`:''}\r\n              <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_ACCOUNTS.openInvoice('${util().jsArg(inv.id)}')\" title=\"View\"><i class=\"ti ti-eye\"></i></button>\r\n              <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_ACCOUNTS.printInvoice('${util().jsArg(inv.id)}')\" title=\"Print\"><i class=\"ti ti-printer\"></i></button>\r\n            </div></td>\r\n          </tr>`).join('')||'<tr><td colspan=\"7\" class=\"ims__table-empty\">No invoices yet \u2014 click Generate to create fortnightly invoices</td></tr>'}\r\n          </tbody>\r\n        </table>\r\n      </div>`;\r\n  }\r\n\r\n  async function generateInvoices(){\r\n    const {data:customers}=await db().select('dropship_customers',{eq:{is_active:true},order:{col:'business_name'}});\r\n    if(!customers?.length){ui().toast('No active dropship customers','warning');return;}\r\n    const custOpts='<option value=\"all\">All active customers</option>'+\r\n      customers.map(c=>`<option value=\"${c.id}\">${util().sanitize(c.business_name)}</option>`).join('');\r\n\r\n    // Build fortnightly periods going back 6 months \u2014 newest first\r\n    // Each month = 2 periods: 1st-15th and 16th-last day of month\r\n    const periods=[];\r\n    const now=new Date();\r\n    for(let monthOffset=0;monthOffset<6;monthOffset++){\r\n      const refDate=new Date(now.getFullYear(),now.getMonth()-monthOffset,1);\r\n      const y=refDate.getFullYear();\r\n      const m=String(refDate.getMonth()+1).padStart(2,'0');\r\n      const lastDay=new Date(y,refDate.getMonth()+1,0).getDate(); // true last day of month\r\n      const monthLabel=refDate.toLocaleDateString('en-GB',{month:'long',year:'numeric'});\r\n\r\n      // Second half: 16th to last day \u2014 add this first (most recent within month)\r\n      const s2=`${y}-${m}-16`;\r\n      const e2=`${y}-${m}-${String(lastDay).padStart(2,'0')}`;\r\n      if(new Date(s2)<=now){\r\n        periods.push({s:s2,e:e2,label:`16 \u2014 ${lastDay} ${monthLabel}`});\r\n      }\r\n\r\n      // First half: 1st to 15th\r\n      const s1=`${y}-${m}-01`;\r\n      const e1=`${y}-${m}-15`;\r\n      if(new Date(s1)<=now){\r\n        periods.push({s:s1,e:e1,label:`01 \u2014 15 ${monthLabel}`});\r\n      }\r\n    }\r\n\r\n    ui().openModal('Generate fortnightly invoices',`\r\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-bottom:14px\">\r\n        <i class=\"ti ti-info-circle\"></i>\r\n        <span>Select one or more fortnightly periods and the customer. An invoice will be generated per period per customer covering all orders in that range.</span>\r\n      </div>\r\n      <div class=\"ims__form-group\" style=\"margin-bottom:14px\">\r\n        <label class=\"ims__label\">Customer</label>\r\n        <select class=\"ims__select\" id=\"ims-gi-customer\">${custOpts}</select>\r\n      </div>\r\n      <label style=\"display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer;margin-bottom:14px\">\r\n        <input type=\"checkbox\" id=\"ims-gi-novat\">\r\n        Generate without VAT (zero-rated invoice)\r\n      </label>\r\n      <div class=\"ims__form-grid\" style=\"margin-bottom:14px\">\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label\">Account ref (optional)</label>\r\n          <input class=\"ims__input\" type=\"text\" id=\"ims-gi-accref\" placeholder=\"e.g. HAPPY01\">\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label\">Carriage net (\u00A3)</label>\r\n          <input class=\"ims__input\" type=\"number\" step=\"0.01\" min=\"0\" id=\"ims-gi-carriage\" value=\"0\">\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label\">Total packages (optional)</label>\r\n          <input class=\"ims__input\" type=\"number\" min=\"0\" id=\"ims-gi-packages\">\r\n        </div>\r\n        <div class=\"ims__form-group\">\r\n          <label class=\"ims__label\">Incoterms (optional)</label>\r\n          <input class=\"ims__input\" type=\"text\" id=\"ims-gi-incoterms\" placeholder=\"e.g. DAP\">\r\n        </div>\r\n      </div>\r\n      <div class=\"ims__label\" style=\"margin-bottom:8px\">Select billing period(s)</div>\r\n      <div style=\"border:1px solid var(--ims-border);border-radius:var(--ims-radius);overflow:hidden\">\r\n        ${periods.map((p,i)=>`\r\n          <label style=\"display:flex;align-items:center;gap:10px;padding:10px 14px;cursor:pointer;\r\n            border-bottom:${i<periods.length-1?'1px solid var(--ims-border)':'none'};\r\n            background:var(--ims-surface)\"\r\n            onmouseenter=\"this.style.background='var(--ims-surface2)'\"\r\n            onmouseleave=\"this.style.background='var(--ims-surface)'\">\r\n            <input type=\"checkbox\" value=\"${p.s}|${p.e}\"\r\n              style=\"width:16px;height:16px;accent-color:var(--ims-accent);flex-shrink:0\">\r\n            <span style=\"font-size:13px\">${p.label}</span>\r\n          </label>`).join('')}\r\n      </div>\r\n    `,`\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_DROPSHIP.runGenerateInvoices()\">\r\n        <i class=\"ti ti-file-invoice\"></i> Generate invoices\r\n      </button>\r\n    `,'sm');\r\n  }\r\n\r\n  function setInvoicePeriod(){}  // no longer needed, kept for safety\r\n\r\n  async function runGenerateInvoices(){\r\n    const custFilter=document.getElementById('ims-gi-customer')?.value;\r\n    const checked=[...document.querySelectorAll('#ims-modal-body input[type=checkbox]:checked')];\r\n    if(!checked.length){ui().toast('Please select at least one period','error');return;}\r\n\r\n    const {data:allCustomers}=await db().select('dropship_customers',{eq:{is_active:true}});\r\n    const customers=custFilter==='all'?allCustomers:(allCustomers||[]).filter(c=>c.id===custFilter);\r\n    if(!customers?.length){ui().toast('No customers found','warning');return;}\r\n\r\n    const noVat=document.getElementById('ims-gi-novat')?.checked||false;\r\n    const accountRef=document.getElementById('ims-gi-accref')?.value?.trim()||null;\r\n    const carriageAmount=parseFloat(document.getElementById('ims-gi-carriage')?.value)||0;\r\n    const totalPackages=document.getElementById('ims-gi-packages')?.value?parseInt(document.getElementById('ims-gi-packages').value):null;\r\n    const incoterms=document.getElementById('ims-gi-incoterms')?.value?.trim()||null;\r\n\r\n    ui().closeModal();\r\n    let created=0,skipped=0;\r\n\r\n    // Dropship invoices now live in the same shared invoices/invoice_lines\r\n    // tables Accounts uses (source_module='dropship' distinguishes their\r\n    // origin) rather than the old, separate dropship_invoices table \u2014\r\n    // one true invoicing system for the whole app, per the confirmed\r\n    // migration/standardization plan.\r\n    const client=window.supabase.createClient(window.IMS_SUPABASE_URL,window.IMS_SUPABASE_ANON_KEY);\r\n\r\n    for(const chk of checked){\r\n      const [pStart,pEnd]=chk.value.split('|');\r\n      for(const c of customers){\r\n        // invoices has no customer_id column at all \u2014 Accounts stores\r\n        // customer identity as plain snapshotted text fields\r\n        // (customer_name/address/postcode/email/vat_number), never a\r\n        // foreign key. Matching on name+date+source instead.\r\n        const {data:existing}=await db().select('invoices',{\r\n          eq:{source_module:'dropship',customer_name:c.business_name,invoice_date:pStart},maybeSingle:true\r\n        });\r\n        if(existing){skipped++;continue;}\r\n\r\n        const {data:allOrders}=await db().select('orders',{\r\n          select:'id,total_value,status',\r\n          eq:{dropship_customer_id:c.id,fulfillment_type:'dropship'},\r\n          gte:{created_at:pStart+'T00:00:00'},\r\n          lte:{created_at:pEnd+'T23:59:59'}\r\n        });\r\n        // Exclude cancelled/refunded orders \u2014 these should never be charged\r\n        // to the customer, whether they were caught before invoicing or\r\n        // returned/refunded after the fact (see confirmDropshipReturn /\r\n        // confirmDropshipRefundNoReturn below, both of which set 'refunded').\r\n        const orders=(allOrders||[]).filter(o=>!['cancelled','refunded'].includes(o.status));\r\n        if(!orders?.length){skipped++;continue;}\r\n\r\n        const orderIds=orders.map(o=>o.id);\r\n        const {data:orderItems}=await client.from('order_items')\r\n          .select('order_id,product_id,product_name,sku,quantity,unit_price,total_price,products(hs_tariff_code,country_of_origin,unit_weight_kg)')\r\n          .in('order_id',orderIds);\r\n\r\n        const netTotal=(orderItems||[]).reduce((s,it)=>s+(it.total_price||0),0);\r\n        const vatRate=noVat?0:(window.SM.AUTH.company?.vat_rate||20)/100;\r\n        const vatAmt=noVat?0:parseFloat((netTotal*vatRate).toFixed(2));\r\n        const grossTotal=parseFloat((netTotal+vatAmt+carriageAmount).toFixed(2));\r\n\r\n        const {data:lastInv}=await db().select('invoices',{\r\n          select:'invoice_number',eq:{source_module:'dropship'},order:{col:'created_at',asc:false},limit:1\r\n        });\r\n        const num=lastInv?.[0]?.invoice_number?parseInt(lastInv[0].invoice_number.split('-').pop()||0)+1:1;\r\n        const invoiceNumber=`DSI-${String(num).padStart(5,'0')}`;\r\n\r\n        const dueDate=new Date(pEnd);\r\n        dueDate.setDate(dueDate.getDate()+14);\r\n\r\n        const {data:inv,error}=await db().insert('invoices',{\r\n          invoice_type:'sales',\r\n          source_module:'dropship',\r\n          customer_name:c.business_name,\r\n          customer_address:c.address||null,\r\n          customer_postcode:c.postcode||null,\r\n          customer_email:c.email||null,\r\n          customer_vat_number:c.vat_number||null,\r\n          eori_no:c.eori_no||null,\r\n          account_ref:accountRef||c.account_ref||null,\r\n          invoice_date:pStart,\r\n          due_date:dueDate.toISOString().split('T')[0],\r\n          net_amount:parseFloat(netTotal.toFixed(2)),\r\n          vat_rate:noVat?0:(window.SM.AUTH.company?.vat_rate||20),\r\n          vat_amount:vatAmt,\r\n          carriage_amount:carriageAmount,\r\n          total_packages:totalPackages,\r\n          incoterms:incoterms,\r\n          gross_amount:grossTotal,\r\n          currency:'GBP',\r\n          status:'draft',\r\n          invoice_number:invoiceNumber\r\n        });\r\n\r\n        if(error){\r\n          console.error('[Dropship invoice generation] Insert failed for',c.business_name,pStart,'\u2014',error.message);\r\n          ui().toast(`Failed for ${c.business_name}: ${error.message}`,'error',8000);\r\n          skipped++;\r\n          continue;\r\n        }\r\n\r\n        if(!error&&inv){\r\n          await Promise.all((orderItems||[]).map((it,idx)=>\r\n            client.from('invoice_lines').insert({\r\n              invoice_id:inv.id,\r\n              description:it.product_name,\r\n              product_code:it.sku,\r\n              quantity:it.quantity,\r\n              unit_price:it.unit_price,\r\n              net_amount:it.total_price,\r\n              vat_rate:noVat?0:(window.SM.AUTH.company?.vat_rate||20),\r\n              vat_amount:noVat?0:parseFloat((it.total_price*vatRate).toFixed(2)),\r\n              gross_amount:noVat?it.total_price:parseFloat((it.total_price*(1+vatRate)).toFixed(2)),\r\n              hs_tariff_code:it.products?.hs_tariff_code||null,\r\n              country_of_origin:it.products?.country_of_origin||null,\r\n              unit_weight_kg:it.products?.unit_weight_kg||null,\r\n              sort_order:idx\r\n            })\r\n          ));\r\n          await Promise.all(orders.map(o=>client.from('orders').update({invoice_id:inv.id}).eq('id',o.id)));\r\n          created++;\r\n        }\r\n      }\r\n    }\r\n    ui().toast(`${created} invoice(s) generated${skipped>0?`, ${skipped} skipped`:''}`,'success',5000);\r\n    loadInvoices();\r\n  }\r\n\r\n  async function emailInvoice(id){\r\n    const {data:inv}=await db().select('invoices',{\r\n      eq:{id},maybeSingle:true,noCompanyFilter:true\r\n    });\r\n    if(!inv)return;\r\n    // customer_email is snapshotted directly on the invoice at\r\n    // generation time \u2014 no customer_id column exists to look back\r\n    // through to dropship_customers.\r\n    const company=window.SM.AUTH.company;\r\n    const body=`Dear ${inv.customer_name||'Customer'},\\n\\nPlease find attached your invoice dated ${util().formatDate(inv.invoice_date)}.\\n\\nInvoice number: ${inv.invoice_number}\\nTotal amount: ${util().formatCurrency(inv.gross_amount)} (incl. VAT ${util().formatCurrency(inv.vat_amount)})\\nDue date: ${inv.due_date?util().formatDate(inv.due_date):'14 days'}\\n\\nPlease transfer payment to:\\nBank: ${company?.bank_name||'\u2014'}\\nAccount: ${company?.bank_account||'\u2014'}\\nSort code: ${company?.bank_sort_code||'\u2014'}\\n\\nKind regards,\\n${company?.name||'MDF London Ltd'}\\n${company?.email||''}`;\r\n\r\n    ui().openModal(`Email invoice: ${inv.invoice_number}`,`\r\n      <div class=\"ims__form-group\" style=\"margin-bottom:10px\">\r\n        <label class=\"ims__label\">To</label>\r\n        <input class=\"ims__input\" type=\"email\" id=\"ims-inv-email-to\" value=\"${util().sanitize(inv.customer_email||'')}\">\r\n      </div>\r\n      <div class=\"ims__form-group\">\r\n        <label class=\"ims__label\">Message</label>\r\n        <textarea class=\"ims__textarea\" id=\"ims-inv-email-body\" rows=\"12\">${body}</textarea>\r\n      </div>\r\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-top:8px\"><i class=\"ti ti-info-circle\"></i>\r\n        <span>Copy this email and send from your mail client. SMTP sending will be available in a future update.</span>\r\n      </div>\r\n    `,`\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_DROPSHIP.confirmEmailSent('${util().jsArg(id)}')\"><i class=\"ti ti-check\"></i> Mark as sent</button>\r\n    `,'lg');\r\n  }\r\n\r\n  async function confirmEmailSent(id){\r\n    await db().update('invoices',id,{status:'sent',sent_at:new Date().toISOString()});\r\n    ui().closeModal();ui().toast('Invoice marked as sent','success');loadInvoices();\r\n  }\r\n\r\n  // markPaid() removed \u2014 dropship invoices live in the shared invoices\r\n  // table, so payment is now recorded through window.IMS_ACCOUNTS.markInvoicePaid,\r\n  // the same flow Accounts uses. That function properly accumulates paid_amount\r\n  // (supports partial payment), records an income transaction, and captures\r\n  // payment date/method/reference \u2014 none of which this bare status flip did.\r\n\r\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\r\n  // WEEKLY REPORT\r\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\r\n  async function loadReports(){\r\n    const content=document.getElementById('ims-ds-content');\r\n    if(!content)return;\r\n    const actions=document.getElementById('ims-ds-actions');\r\n    if(actions)actions.innerHTML='';\r\n    const {data:customers}=await db().select('dropship_customers',{eq:{is_active:true},order:{col:'business_name'}});\r\n    const custOpts=(customers||[]).map(c=>`<option value=\"${c.id}\">${util().sanitize(c.business_name)}</option>`).join('');\r\n    const weekAgo=new Date(Date.now()-7*86400000).toISOString().split('T')[0];\r\n    const today=new Date().toISOString().split('T')[0];\r\n    content.innerHTML=`\r\n      <div class=\"ims__card\" style=\"margin-bottom:14px\">\r\n        <div class=\"ims__form-grid\">\r\n          <div class=\"ims__form-group ims__form-group--full\">\r\n            <label class=\"ims__label ims__label--req\">Select dropship customer</label>\r\n            <select class=\"ims__select\" id=\"ims-dsr-customer\"><option value=\"\">Choose customer...</option>${custOpts}</select>\r\n          </div>\r\n          <div class=\"ims__form-group\"><label class=\"ims__label\">Week from</label><input class=\"ims__input\" type=\"date\" id=\"ims-dsr-from\" value=\"${weekAgo}\"></div>\r\n          <div class=\"ims__form-group\"><label class=\"ims__label\">Week to</label><input class=\"ims__input\" type=\"date\" id=\"ims-dsr-to\" value=\"${today}\"></div>\r\n        </div>\r\n        <div class=\"ims__btn-group\" style=\"margin-top:10px\">\r\n          <button class=\"ims__btn ims__btn--primary\" onclick=\"window.IMS_DROPSHIP.generateWeeklyReport()\"><i class=\"ti ti-chart-bar\"></i> Generate report</button>\r\n        </div>\r\n      </div>\r\n      <div id=\"ims-dsr-output\"></div>`;\r\n  }\r\n\r\n  async function generateWeeklyReport(){\r\n    const customerId=document.getElementById('ims-dsr-customer')?.value;\r\n    const from=document.getElementById('ims-dsr-from')?.value;\r\n    const to=document.getElementById('ims-dsr-to')?.value;\r\n    const output=document.getElementById('ims-dsr-output');\r\n    if(!customerId){ui().toast('Please select a customer','error');return;}\r\n    if(!output)return;\r\n    output.innerHTML=`<div class=\"ims__loading\"><i class=\"ti ti-loader-2 ims__spin\"></i></div>`;\r\n\r\n    const client=window.supabase.createClient(window.IMS_SUPABASE_URL,window.IMS_SUPABASE_ANON_KEY);\r\n\r\n    const {data:customer}=await db().select('dropship_customers',{eq:{id:customerId},maybeSingle:true,noCompanyFilter:true});\r\n    const {data:allocs}=await db().select('dropship_allocations',{\r\n      select:'allocated_qty,remaining_qty,allocation_date,products(id,name,sku)',\r\n      eq:{customer_id:customerId},noCompanyFilter:true\r\n    });\r\n\r\n    const {data:orders}=await client\r\n      .from('orders')\r\n      .select('id,order_number,external_ref,end_customer_name,end_customer_phone,end_address,end_postcode,status,total_value,delivery_method,delivered_at,collected_at,created_at')\r\n      .eq('fulfillment_type','dropship')\r\n      .eq('dropship_customer_id',customerId)\r\n      .gte('created_at',from+'T00:00:00')\r\n      .lte('created_at',to+'T23:59:59')\r\n      .order('created_at',{ascending:true});\r\n\r\n    const orderIds=(orders||[]).map(o=>o.id);\r\n    let orderItems=[];\r\n    if(orderIds.length){\r\n      const {data:items}=await client\r\n        .from('order_items')\r\n        .select('order_id,product_name,sku,quantity')\r\n        .in('order_id',orderIds);\r\n      orderItems=items||[];\r\n    }\r\n    const itemsByOrder={};\r\n    orderItems.forEach(i=>{\r\n      if(!itemsByOrder[i.order_id])itemsByOrder[i.order_id]=[];\r\n      itemsByOrder[i.order_id].push(i);\r\n    });\r\n    const enrichedOrders=(orders||[]).map(o=>({...o,items:itemsByOrder[o.id]||[]}));\r\n\r\n    const {data:invoice}=await db().select('dropship_invoices',{\r\n      select:'invoice_number,period_start,period_end,total_value,status,due_date',\r\n      eq:{customer_id:customerId,status:'draft'},\r\n      order:{col:'created_at',asc:false},\r\n      limit:1,noCompanyFilter:true\r\n    });\r\n\r\n    const orderList=enrichedOrders;\r\n    const allocationList=allocs||[];\r\n    const totalOrders=orderList.length;\r\n    const delivered=orderList.filter(o=>['delivered','collected'].includes(o.status)).length;\r\n    const inProgress=orderList.filter(o=>!['delivered','collected','cancelled'].includes(o.status)).length;\r\n    const totalValue=orderList.reduce((s,o)=>s+(o.total_value||0),0);\r\n\r\n    const soldInPeriodIds=(orders||[]).filter(o=>['collected','delivered'].includes(o.status)).map(o=>o.id);\r\n    let periodItems=[];\r\n    if(soldInPeriodIds.length){\r\n      const {data:pi}=await client.from('order_items').select('sku,product_name,quantity').in('order_id',soldInPeriodIds);\r\n      periodItems=pi||[];\r\n    }\r\n    const soldBySkU={};\r\n    periodItems.forEach(i=>{const sku=i.sku||i.product_name;soldBySkU[sku]=(soldBySkU[sku]||0)+(i.quantity||0);});\r\n\r\n    const {data:priorOrders}=await client.from('orders')\r\n      .select('id')\r\n      .eq('fulfillment_type','dropship')\r\n      .eq('dropship_customer_id',customerId)\r\n      .in('status',['collected','delivered'])\r\n      .lt('created_at',from+'T00:00:00');\r\n    const priorOrderIds=(priorOrders||[]).map(o=>o.id);\r\n    let priorItems=[];\r\n    if(priorOrderIds.length){\r\n      const {data:pi}=await client.from('order_items').select('sku,product_name,quantity').in('order_id',priorOrderIds);\r\n      priorItems=pi||[];\r\n    }\r\n    const soldBeforePeriod={};\r\n    priorItems.forEach(i=>{const sku=i.sku||i.product_name;soldBeforePeriod[sku]=(soldBeforePeriod[sku]||0)+(i.quantity||0);});\r\n\r\n    const allocByProduct={};\r\n    allocationList.forEach(a=>{\r\n      const key=a.products?.sku||a.products?.id;\r\n      if(!key)return;\r\n      if(!allocByProduct[key])allocByProduct[key]={name:a.products?.name,sku:a.products?.sku,totalAllocated:0};\r\n      allocByProduct[key].totalAllocated+=(a.allocated_qty||0);\r\n    });\r\n    Object.values(allocByProduct).forEach(p=>{\r\n      p.opening=Math.max(0,p.totalAllocated-(soldBeforePeriod[p.sku]||0));\r\n    });\r\n\r\n    const allocTotalAlloc=Object.values(allocByProduct).reduce((s,p)=>s+(p.opening||0),0);\r\n    const allocTotalSold=Object.values(allocByProduct).reduce((s,p)=>s+(soldBySkU[p.sku]||0),0);\r\n    const allocTotalRemain=allocTotalAlloc-allocTotalSold;\r\n\r\n    output.innerHTML=`\r\n      <div class=\"ims__card\" style=\"margin-bottom:14px\">\r\n        <div class=\"ims__card-header\">\r\n          <div class=\"ims__card-title\"><i class=\"ti ti-chart-bar\"></i>Weekly Dropship Report \u2014 ${util().sanitize(customer?.business_name||'')}</div>\r\n          <div class=\"ims__btn-group\">\r\n            <button class=\"ims__btn ims__btn--secondary ims__btn--sm\" onclick=\"window.IMS_DROPSHIP.printWeeklyReport('${util().jsArg(customerId)}','${util().jsArg(from)}','${util().jsArg(to)}')\"><i class=\"ti ti-printer\"></i> Print</button>\r\n            <button class=\"ims__btn ims__btn--secondary ims__btn--sm\" onclick=\"window.IMS_DROPSHIP.exportWeeklyReport()\"><i class=\"ti ti-download\"></i> Export CSV</button>\r\n            <button class=\"ims__btn ims__btn--primary ims__btn--sm\" onclick=\"window.IMS_DROPSHIP.emailWeeklyReport('${util().jsArg(customerId)}','${util().jsArg(from)}','${util().jsArg(to)}')\"><i class=\"ti ti-send\"></i> Email report</button>\r\n          </div>\r\n        </div>\r\n        <div style=\"font-size:12px;color:var(--ims-text-muted);margin-bottom:12px\">Period: ${util().formatDate(from)} \u2014 ${util().formatDate(to)}</div>\r\n\r\n        <div style=\"display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-bottom:16px\">\r\n          <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Total orders</div><div class=\"ims__stat-value\" style=\"font-size:20px\">${totalOrders}</div></div>\r\n          <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Delivered</div><div class=\"ims__stat-value ims__stat-value--success\" style=\"font-size:20px\">${delivered}</div></div>\r\n          <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">In progress</div><div class=\"ims__stat-value\" style=\"font-size:20px\">${inProgress}</div></div>\r\n          <div class=\"ims__stat\" style=\"padding:10px\"><div class=\"ims__stat-label\">Week revenue</div><div class=\"ims__stat-value\" style=\"font-size:16px\">${util().formatCurrency(totalValue)}</div></div>\r\n        </div>\r\n\r\n        <strong style=\"font-size:13px;display:block;margin-bottom:8px\">Orders this week (${totalOrders})</strong>\r\n        <table class=\"ims__table\" style=\"margin-bottom:16px\">\r\n          <thead><tr><th>Order #</th><th>Ref</th><th>End customer</th><th>Postcode</th><th>Product</th><th>Qty</th><th>Status</th><th>Collected</th></tr></thead>\r\n          <tbody>${orderList.map(o=>`<tr>\r\n            <td>${util().sanitize(o.order_number)}</td>\r\n            <td>${util().sanitize(o.external_ref||'\u2014')}</td>\r\n            <td>${util().sanitize(o.end_customer_name||'\u2014')}</td>\r\n            <td>${util().sanitize(o.end_postcode||'\u2014')}</td>\r\n            <td style=\"font-size:11px\">${(o.items||[]).map(i=>util().sanitize(i.product_name||'\u2014')).join(', ')||'\u2014'}</td>\r\n            <td style=\"text-align:center\">${(o.items||[]).reduce((s,i)=>s+(i.quantity||0),0)||1}</td>\r\n            <td>${util().pill(o.status)}</td>\r\n            <td>${o.collected_at?util().formatDate(o.collected_at):o.delivered_at?util().formatDate(o.delivered_at):'\u2014'}</td>\r\n          </tr>`).join('')||'<tr><td colspan=\"9\" class=\"ims__table-empty\">No orders in this period</td></tr>'}\r\n          </tbody>\r\n        </table>\r\n\r\n        <strong style=\"font-size:13px;display:block;margin-bottom:8px\">Stock allocation summary</strong>\r\n        <table class=\"ims__table\" style=\"margin-bottom:16px\">\r\n          <thead><tr><th>Product</th><th>SKU</th><th>Total allocated</th><th>Sold/delivered</th><th>Remaining</th></tr></thead>\r\n          <tbody>${Object.values(allocByProduct).map(p=>`<tr>\r\n            <td>${util().sanitize(p.name||'\u2014')}</td>\r\n            <td>${util().sanitize(p.sku||'\u2014')}</td>\r\n            <td>${p.opening}</td>\r\n            <td>${soldBySkU[p.sku]||0}</td>\r\n            <td style=\"font-weight:600;color:${Math.max(0,p.opening-(soldBySkU[p.sku]||0))>0?'var(--ims-success)':'var(--ims-text-muted)'}\">${Math.max(0,p.opening-(soldBySkU[p.sku]||0))}</td>\r\n          </tr>`).join('')||'<tr><td colspan=\"5\" class=\"ims__table-empty\">No stock allocated</td></tr>'}\r\n          <tr style=\"font-weight:600;border-top:2px solid var(--ims-border);background:var(--ims-surface2)\">\r\n            <td>Totals</td>\r\n            <td></td>\r\n            <td>${allocTotalAlloc}</td>\r\n            <td>${allocTotalSold}</td>\r\n            <td style=\"color:${allocTotalRemain>0?'var(--ims-success)':'var(--ims-text-muted)'}\">${allocTotalRemain}</td>\r\n          </tr>\r\n          </tbody>\r\n        </table>\r\n\r\n        ${invoice && invoice.invoice_number ? `\r\n          <strong style=\"font-size:13px;display:block;margin-bottom:8px\">Current fortnightly invoice</strong>\r\n          <div class=\"ims__alert ims__alert--${invoice.status==='paid'?'success':invoice.status==='sent'?'info':'warning'}\">\r\n            <i class=\"ti ti-file-invoice\"></i>\r\n            <span><strong>${invoice.invoice_number}</strong> | Period: ${util().formatDate(invoice.period_start)} \u2014 ${util().formatDate(invoice.period_end)} | Total: <strong>${util().formatCurrency(invoice.total_value)}</strong> | Due: ${invoice.due_date?util().formatDate(invoice.due_date):'\u2014'} | Status: ${invoice.status}</span>\r\n          </div>` : '<div class=\"ims__alert ims__alert--info\"><i class=\"ti ti-info-circle\"></i><span>No current fortnightly invoice \u2014 click Invoices tab to generate.</span></div>'}\r\n      </div>`;\r\n\r\n    window._dsReportData={customer,orders:orderList,allocs:allocByProduct,soldBySkU,from,to};\r\n  }\r\n\r\n  async function emailWeeklyReport(customerId,from,to){\r\n    const {data:customer}=await db().select('dropship_customers',{eq:{id:customerId},maybeSingle:true,noCompanyFilter:true});\r\n    const company=window.SM.AUTH.company;\r\n    const body=`Dear ${util().sanitize(customer?.business_name||'Customer')},\\n\\nPlease find below your summary dropship report for the period ${util().formatDate(from)} to ${util().formatDate(to)}.\\n\\nFor full details please log into the portal or contact us directly.\\n\\nKind regards,\\n${company?.name||'MDF London Ltd'}\\n${company?.email||''}`;\r\n\r\n    ui().openModal('Email summary report',`\r\n      <div class=\"ims__form-group\" style=\"margin-bottom:10px\">\r\n        <label class=\"ims__label\">To</label>\r\n        <input class=\"ims__input\" type=\"email\" id=\"ims-wkr-email-to\" value=\"${util().sanitize(customer?.email||'')}\">\r\n      </div>\r\n      <div class=\"ims__form-group\">\r\n        <label class=\"ims__label\">Message</label>\r\n        <textarea class=\"ims__textarea\" id=\"ims-wkr-email-body\" rows=\"10\">${body}</textarea>\r\n      </div>\r\n      <div class=\"ims__alert ims__alert--info\" style=\"margin-top:8px\"><i class=\"ti ti-info-circle\"></i>\r\n        <span>Copy this email and send from your mail client, attaching the printed report PDF. Full SMTP sending coming in next update.</span>\r\n      </div>\r\n    `,`\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n      <button class=\"ims__btn ims__btn--primary\" onclick=\"window.SM.UI.closeModal();window.IMS_DROPSHIP.printWeeklyReport('${util().jsArg(customerId)}','${util().jsArg(from)}','${util().jsArg(to)}')\"><i class=\"ti ti-printer\"></i> Close & print report</button>\r\n    `,'lg');\r\n  }\r\n\r\n  async function printWeeklyReport(customerId,from,to){\r\n    const report=window._dsReportData;\r\n    if(!report){ui().toast('Generate the report first','warning');return;}\r\n    const {customer,orders,allocs,soldBySkU}=report;\r\n    const now=new Date().toLocaleDateString('en-GB');\r\n\r\n    const orderRows=orders.map(o=>[\r\n      util().sanitize(o.order_number||'\u2014'),\r\n      util().sanitize(o.external_ref||'\u2014'),\r\n      util().sanitize(o.end_customer_name||'\u2014'),\r\n      util().sanitize(o.end_postcode||'\u2014'),\r\n      util().sanitize((o.items||[]).map(i=>i.product_name||'\u2014').join(', ')||'\u2014'),\r\n      String((o.items||[]).reduce((s,i)=>s+(i.quantity||0),0)||1),\r\n      util().sanitize(o.status||'\u2014'),\r\n      o.collected_at?util().formatDate(o.collected_at):o.delivered_at?util().formatDate(o.delivered_at):'\u2014'\r\n    ]);\r\n    const orderTotalsRow=[\r\n      '<td>Report total</td>','<td></td>','<td></td>','<td></td>','<td></td>',\r\n      `<td class=\"r\">${orders.length}</td>`,'<td></td>','<td></td>'\r\n    ];\r\n    const orderTableHtml=window.PRINT.table({\r\n      colWidths:['10%','10%','20%','10%','25%','5%','10%','10%'],\r\n      columns:[\r\n        {label:'Order #'},{label:'Ref'},{label:'End customer'},{label:'Postcode'},\r\n        {label:'Product'},{label:'Qty',align:'r'},{label:'Status'},{label:'Collected'}\r\n      ],\r\n      rows:orderRows,\r\n      totalsRow:orderTotalsRow\r\n    });\r\n\r\n    const allocList=Object.values(allocs);\r\n    const allocRows=allocList.map(p=>{\r\n      const sold=soldBySkU?.[p.sku]||0;\r\n      const remaining=Math.max(0,p.opening-sold);\r\n      return [\r\n        util().sanitize(p.name||'\u2014'),\r\n        util().sanitize(p.sku||'\u2014'),\r\n        String(p.opening),\r\n        String(sold),\r\n        String(remaining)\r\n      ];\r\n    });\r\n    const allocTotalAlloc=allocList.reduce((s,p)=>s+(p.opening||0),0);\r\n    const allocTotalSold=allocList.reduce((s,p)=>s+(soldBySkU?.[p.sku]||0),0);\r\n    const allocTotalRemain=allocTotalAlloc-allocTotalSold;\r\n    const allocTotalsRow=[\r\n      '<td>Totals</td>','<td></td>',\r\n      `<td class=\"r\">${allocTotalAlloc}</td>`,\r\n      `<td class=\"r\">${allocTotalSold}</td>`,\r\n      `<td class=\"r\">${allocTotalRemain}</td>`\r\n    ];\r\n    const allocTableHtml=window.PRINT.table({\r\n      colWidths:['35%','25%','13%','13%','14%'],\r\n      columns:[\r\n        {label:'Product'},{label:'SKU'},{label:'Allocated',align:'r'},\r\n        {label:'Sold',align:'r'},{label:'Remaining',align:'r'}\r\n      ],\r\n      rows:allocRows,\r\n      totalsRow:allocTotalsRow\r\n    });\r\n\r\n    const headerHtml=window.PRINT.header({\r\n      title:'Dropship Activity Report',\r\n      docRef:`Period: ${util().formatDate(from)} to ${util().formatDate(to)}`,\r\n      rightLabel:'',\r\n      rightName:customer?.business_name||'\u2014',\r\n      rightLines:[\r\n        util().sanitize(customer?.address||''),\r\n        util().sanitize(customer?.postcode||''),\r\n        util().sanitize(customer?.email||''),\r\n        `Date: ${now}`\r\n      ]\r\n    });\r\n\r\n    const page=`\r\n      ${headerHtml}\r\n      <div class=\"st\">Orders \u2014 ${util().sanitize(util().formatDate(from))} to ${util().sanitize(util().formatDate(to))}</div>\r\n      <hr class=\"rule\">\r\n      ${orderTableHtml}\r\n      <hr class=\"rule-dbl\">\r\n      <div class=\"st\" style=\"margin-top:12px\">Stock Allocation Summary</div>\r\n      <hr class=\"rule\">\r\n      ${allocTableHtml}\r\n      <hr class=\"rule-dbl\">\r\n      ${window.PRINT.pageFooter(['StockMaestro \u00A9 2026 ABSA Digital',`Dropship Report \u2014 ${customer?.business_name||''} \u2014 ${from} to ${to}`],1,1)}\r\n    `;\r\n\r\n    window.PRINT.renderDocument([page],`Dropship Report \u2014 ${customer?.business_name} \u2014 ${from} to ${to}`);\r\n  }\r\n\r\n  function exportWeeklyReport(){\r\n    const report=window._dsReportData;\r\n    if(!report){ui().toast('Generate the report first','warning');return;}\r\n    const {customer,orders,allocs,from,to}=report;\r\n    const headers=['Order #','End Customer','Address','Postcode','Phone','Delivery Method','Value','Status','Delivered Date'];\r\n    const rows=(orders||[]).map(o=>[o.order_number,o.end_customer_name,o.end_address,o.end_postcode,o.end_customer_phone||'',o.delivery_method==='mdf_delivers'?'MDF Delivers':'Self-arrange',o.total_value,o.status,o.delivered_at?util().formatDate(o.delivered_at):o.collected_at?util().formatDate(o.collected_at):'']);\r\n    util().exportCSV(headers,rows,`dropship_report_${customer?.business_name?.replace(/\\s/g,'_')}_${from}_to_${to}`);\r\n  }\r\n\r\n  let _allDSOrders=[];\r\n\r\n  function renderOrderRows(items){\r\n    const tbody=document.querySelector('#ims-ds-content tbody');\r\n    if(!tbody)return;\r\n    tbody.innerHTML=items.map(o=>{\r\n      const isSelfArrange=o.delivery_method==='self_arrange';\r\n      const pendingCollection=isSelfArrange&&!['collected','cancelled','delivered'].includes(o.status);\r\n      return`<tr${pendingCollection?' style=\"background:var(--ims-accent-bg)\"':''}>\r\n        <td><span class=\"ims__link\" onclick=\"window.IMS_DROPSHIP.openOrder('${util().jsArg(o.id)}')\">${util().sanitize(o.order_number)}</span></td>\r\n        <td style=\"font-size:12px;color:var(--ims-text-muted)\">${util().sanitize(o.external_ref||'\u2014')}</td>\r\n        <td>${util().sanitize(o.dropship_customers?.business_name||'\u2014')}</td>\r\n        <td>${util().sanitize(o.end_customer_name||'\u2014')}</td>\r\n        <td>${util().sanitize(o.end_postcode||'\u2014')}</td>\r\n        <td><span class=\"ims__pill ims__pill--${isSelfArrange?'warning':'info'}\" style=\"font-size:10px\">${isSelfArrange?'Self-arrange':'We deliver'}</span></td>\r\n        <td>${util().formatCurrency(o.total_value)}</td>\r\n        <td>${util().formatDate(o.created_at)}</td>\r\n        <td>${util().pill(o.status)}</td>\r\n        <td><div class=\"ims__btn-group\">\r\n          <button class=\"ims__btn ims__btn--secondary ims__btn--sm ims__btn--icon\" onclick=\"window.IMS_DROPSHIP.openOrder('${util().jsArg(o.id)}')\"><i class=\"ti ti-eye\"></i></button>\r\n          ${pendingCollection?`<button class=\"ims__btn ims__btn--success ims__btn--sm\" onclick=\"window.IMS_DROPSHIP.showCollectionModal('${util().jsArg(o.id)}','${util().jsArg(o.order_number)}','${util().jsArg(o.dropship_customers?.business_name||'')}')\"><i class=\"ti ti-truck-loading\"></i> Confirm collection</button>`:''}\r\n        </div></td>\r\n      </tr>`;\r\n    }).join('')||'<tr><td colspan=\"10\" class=\"ims__table-empty\">No dropship orders found</td></tr>';\r\n  }\r\n\r\n  function filterOrders(){\r\n    const search=document.getElementById('ims-ds-search')?.value?.toLowerCase()||'';\r\n    const statusF=document.getElementById('ims-ds-status')?.value||'';\r\n    let items=_allDSOrders;\r\n    if(statusF)items=items.filter(o=>o.status===statusF);\r\n    if(search)items=items.filter(o=>\r\n      o.order_number?.toLowerCase().includes(search)||\r\n      o.end_customer_name?.toLowerCase().includes(search)||\r\n      o.end_postcode?.toLowerCase().includes(search)||\r\n      o.dropship_customers?.business_name?.toLowerCase().includes(search)\r\n    );\r\n    renderOrderRows(items);\r\n  }\r\n\r\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\r\n  window.addEventListener('ims:panel',e=>{\r\n    if(e.detail.panel==='dropship'){initTabs();loadCustomers();}\r\n  });\r\n\r\n  async function deleteOrder(orderId, orderNumber) {\r\n    if (!window.SM.AUTH.isAdmin()) { ui().toast('Admin access required', 'error'); return; }\r\n    // Once the goods have left (collected, delivered or written off),\r\n    // deleting the order would erase a real sale and its stock history.\r\n    if (await _dsCannotDelete(orderId, orderNumber)) return;\r\n\r\n    ui().openModal('Delete order', `\r\n      <div class=\"ims__alert ims__alert--danger\" style=\"margin-bottom:16px\">\r\n        <i class=\"ti ti-alert-triangle\"></i>\r\n        <span>You are about to permanently delete order <strong>${util().sanitize(orderNumber)}</strong>. This cannot be undone.</span>\r\n      </div>\r\n      <div style=\"font-size:13px;color:var(--ims-text-muted)\">\r\n        This will permanently delete the order and:<br><br>\r\n        &bull; Give its units back to the partner's allocation<br>\r\n        &bull; Reverse any financial transactions<br>\r\n        &bull; Remove it from any manifests<br>\r\n        &bull; Delete its activity log and logistics jobs\r\n      </div>\r\n    `, `\r\n      <button class=\"ims__btn ims__btn--ghost\" onclick=\"window.SM.UI.closeModal()\">Cancel</button>\r\n      <button class=\"ims__btn ims__btn--danger\" onclick=\"window.IMS_DROPSHIP.confirmDeleteOrder('${util().jsArg(orderId)}','${util().jsArg(orderNumber)}')\">\r\n        <i class=\"ti ti-trash\"></i> Yes, delete order\r\n      </button>\r\n    `, 'sm');\r\n  }\r\n\r\n  // True (with a message) if this order can no longer be deleted because\r\n  // its goods have already left.\r\n  async function _dsCannotDelete(orderId, orderNumber) {\r\n    const { data: o } = await db().select('orders', { select: 'status', eq: { id: orderId }, maybeSingle: true, noCompanyFilter: true });\r\n    const left = ['collected', 'delivered'].includes(o?.status) || await _dropshipGoodsLeft(orderNumber);\r\n    if (left) {\r\n      ui().toast(`${orderNumber} cannot be deleted: its goods have already left. If they come back, use Process return instead.`, 'warning', 9000);\r\n      return true;\r\n    }\r\n    return false;\r\n  }\r\n\r\n  async function confirmDeleteOrder(orderId, orderNumber) {\r\n    const client = window.supabase.createClient(window.IMS_SUPABASE_URL, window.IMS_SUPABASE_ANON_KEY);\r\n    ui().closeModal();\r\n    // Checked again here, in case the order was collected meanwhile.\r\n    if (await _dsCannotDelete(orderId, orderNumber)) return;\r\n\r\n    const { data: order } = await db().select('orders', {\r\n      select: 'status, dropship_customer_id, invoice_id',\r\n      eq: { id: orderId }, maybeSingle: true, noCompanyFilter: true\r\n    });\r\n\r\n    const { data: items } = await client.from('order_items')\r\n      .select('product_id, product_name, quantity, dropship_allocation_id, dropship_allocation_split')\r\n      .eq('order_id', orderId);\r\n\r\n    ui().toast('Deleting order, please wait...', 'info', 5000);\r\n\r\n    // 1 - Give the units back to the allocation they came from. Nothing\r\n    // else about stock changes: the goods never left, and a dropship order\r\n    // never adds to normal orders' \"reserved\" (the old code wrongly reduced\r\n    // it, and put units back into the partner's oldest batch). One line at\r\n    // a time, so two lines of the same product cannot overwrite each other.\r\n    const allocProblems = [];\r\n    for (const item of (items || [])) {\r\n      if (!item.product_id || !order?.dropship_customer_id) continue;\r\n      // Batch by batch: each part goes back to the batch it came from.\r\n      const parts = await _lineParts(client, order.dropship_customer_id, item, 'giveback');\r\n      for (const part of parts) {\r\n        const alloc = part.alloc;\r\n        const give = alloc ? _roomIn(alloc, part.qty) : 0;\r\n        if (!alloc || give <= 0) { allocProblems.push(item.product_name || item.product_id); continue; }\r\n        const { error: aErr } = await client.from('dropship_allocations')\r\n          .update({ remaining_qty: (alloc.remaining_qty || 0) + give }).eq('id', alloc.id);\r\n        if (aErr) allocProblems.push(item.product_name || item.product_id);\r\n      }\r\n    }\r\n    if (allocProblems.length) {\r\n      ui().toast(`${orderNumber}: units could not be given back to the allocation for ${allocProblems.join(', ')}. Please check this partner's allocations.`, 'warning', 10000);\r\n    }\r\n\r\n    // 3 \u2014 Delete transactions\r\n    await client.from('transactions').delete().eq('related_id', orderId);\r\n    await client.from('transactions').delete().eq('reference', orderNumber);\r\n\r\n    // 4 \u2014 Delete AR entry\r\n    await client.from('accounts_receivable').delete().eq('order_id', orderId);\r\n\r\n    // 5 \u2014 Unlink from invoice and recalculate total\r\n    if (order?.invoice_id) {\r\n      await client.from('orders').update({ invoice_id: null }).eq('id', orderId);\r\n      const { data: remainingOrders } = await client.from('orders').select('total_value').eq('invoice_id', order.invoice_id);\r\n      const newNet = (remainingOrders || []).reduce((s, o) => s + (o.total_value || 0), 0);\r\n      const vatRate = (window.SM.AUTH.company?.vat_rate || 20) / 100;\r\n      const newVat = parseFloat((newNet * vatRate).toFixed(2));\r\n      await client.from('dropship_invoices').update({\r\n        total_value: parseFloat((newNet + newVat).toFixed(2)),\r\n        vat_amount: newVat\r\n      }).eq('id', order.invoice_id);\r\n    }\r\n\r\n    // 6 \u2014 Remove from manifest\r\n    await client.from('manifest_items').delete().eq('order_id', orderId);\r\n\r\n    // 7 \u2014 Delete logistics job\r\n    await client.from('logistics_jobs').delete().eq('order_id', orderId);\r\n\r\n    // 8 \u2014 Delete activity log\r\n    await client.from('order_activity_log').delete().eq('order_id', orderId);\r\n\r\n    // 9 \u2014 Delete COD transactions\r\n    await client.from('cod_transactions').delete().eq('order_id', orderId);\r\n\r\n    // 10 \u2014 Delete order items\r\n    await client.from('order_items').delete().eq('order_id', orderId);\r\n\r\n    // 11 \u2014 Delete the order\r\n    await db().remove('orders', orderId);\r\n\r\n    ui().toast(`Order ${orderNumber} deleted \u2014 all records reversed`, 'success', 5000);\r\n    loadOrders();\r\n  }\r\n\r\n  window.IMS_DROPSHIP={\r\n    loadCustomers,openCustomer,showCustomerForm,saveCustomer,deleteCustomer,confirmDeleteCustomer,\r\n        showCustomerPricing,editCustomPrice,clearCustomPriceEdit,saveCustomPrice,deleteCustomPrice,\r\n    showAllocateForm,renderAllocSearch,allocToggleProduct,allocConfirmSelection,\r\n    allocUpdateAvail,allocValidateQty,allocRemoveRow,saveAllocationBulk,\r\n    checkAvailableStock,\r\n    loadAllocations,editAllocation,editAllocUpdateAvail,saveEditAllocation,recallAllocation,\r\n    loadOrders,filterOrders,renderOrderRows,showNewOrder,deleteOrder,confirmDeleteOrder,onDSCustomerChange,addDSItem,\r\n        updateDSItem,updateDSTotal,removeDSItem,searchDSProduct,selectDSProduct,\r\n        saveDSOrder,openOrder,updateOrderStatus,showCollectionModal,confirmCollection,deductDropshipStock,\r\n        restoreDropshipStock,writeOffDropshipStock,\r\n    showDropshipReturn,confirmDropshipReturn,showDropshipRefundNoReturn,confirmDropshipRefundNoReturn,\r\n    loadInvoices,generateInvoices,setInvoicePeriod,runGenerateInvoices,emailInvoice,\r\n    confirmEmailSent,\r\n    loadReports,generateWeeklyReport,emailWeeklyReport,\r\n    printWeeklyReport,exportWeeklyReport,\r\n    loadDSDeals,showNewDSDeal,editDSDeal,saveDSDeal,toggleDSDeal,deleteDSDeal,\r\n    onDSDealDiscountTypeChange,onDSDealAllCustomersChange,updateDSDealPreview\r\n  };\r\n})();\r\n"],
  "mappings": "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",
  "names": []
}
