// Ported from legacy henza_admin/src/store/invoiceCart/invoiceCart.js // // The basket behind the branch-allocation ("فاکتور") screen. Structurally a copy // of the order cart, with two deliberate differences: // // 1. STORAGE KEY — legacy wrote BOTH carts to 'admin_cart_items', so building an // allocation clobbered a half-finished order and vice versa. Verified in // legacy: store/cart/cart.js:27 and store/invoiceCart/invoiceCart.js:27 use // the same key. This cart gets its own key instead; reproducing silent data // loss would be worse than the deviation. Recorded in docs/ADMIN-PORT-PLAN.md. // // 2. No re-hydrate fetch — the allocation screen only needs product ids, so // there is no variant/stock refresh to perform. import { defineStore } from 'pinia'; import { isBranch } from '../utils'; const cartKey = isBranch() ? 'branch_invoice_items' : 'admin_invoice_items'; export interface InvoiceCartItem { pid: string; vid?: string; qty: number; product: Record; } export const useInvoiceCartStore = defineStore('invoiceCart', { state: () => ({ items: [] as InvoiceCartItem[], }), actions: { /** legacy mutation INIT — also persists */ setItems(res: InvoiceCartItem[]) { this.items = res; localStorage.setItem(cartKey, JSON.stringify(res)); }, /** legacy mutation ADD_TO_CART, including its out-of-stock guard */ add(data: InvoiceCartItem) { const index = this.items.findIndex((i) => i.pid == data.pid && i.vid == data.vid); const variants = (data.product?.variants_all ?? []) as { id: string; qty?: number; is_pre_order?: boolean; }[]; const variant = variants.filter((x) => x.id === data.vid)[0]; // legacy: when a variant was named, it must be in stock or a pre-order. // The allocation screen adds whole products (no vid), which legacy let // through only because `variant` was undefined — preserved. if (data.vid && variant && !variant.is_pre_order && variant.qty === 0) return; if (index == -1) { this.items.push(data); } else { this.items[index].product = data.product; this.items[index].qty = data.qty; } this.setItems(this.items); }, remove(item: { pid: string; vid?: string }) { const index = this.items.findIndex((v) => v.pid == item.pid && v.vid == item.vid); if (index > -1) this.items.splice(index, 1); this.setItems(this.items); }, updateItemQuantity(payload: { index: number; quantity: number }) { this.items[payload.index].qty = payload.quantity; this.setItems(this.items); }, clear() { this.items = []; this.setItems(this.items); }, /** Rehydrate from localStorage on mount. */ init() { try { this.items = JSON.parse(localStorage.getItem(cartKey) ?? '[]') || []; } catch { this.items = []; } }, }, });