// The making charge («اجرت») the server will charge this customer for each // variant — fetched from /customer/me/wage-quote, which runs the same formula // that prices the order (MON-08, owner ruling 2026-10-08). The app shows this // figure, never one it computes itself, so what is shown is what is charged. // // Requests are batched: many cards asking at once become one call. import { defineStore } from 'pinia' import { ref, watch } from 'vue' import { api, type WageQuote } from '../api/client' import { useSessionStore } from './session' export const useWageQuoteStore = defineStore('wageQuotes', () => { const session = useSessionStore() const quotes = ref>({}) const pending = new Set() const inFlight = new Set() let timer: ReturnType | null = null // A different customer has a different percent: never reuse another's quotes. watch( () => session.token, () => { quotes.value = {} pending.clear() inFlight.clear() }, ) async function flush() { timer = null const ids = [...pending].slice(0, 200) ids.forEach((id) => { pending.delete(id) inFlight.add(id) }) if (pending.size) timer = setTimeout(flush, 0) if (!ids.length) return try { const rows = await api.getWageQuotes(ids) const next = { ...quotes.value } for (const r of rows) next[r.variantId] = r quotes.value = next } catch (e) { console.warn('wage quote failed', e) } finally { ids.forEach((id) => inFlight.delete(id)) } } /** Asks for a variant's quote (idempotent; safe to call from a computed). */ function request(variantId: string) { if (!session.token || quotes.value[variantId] || pending.has(variantId) || inFlight.has(variantId)) return pending.add(variantId) if (!timer) timer = setTimeout(flush, 30) } /** The charged percent, or null while it is still loading. */ function finalPercent(variantId: string): number | null { const q = quotes.value[variantId] return q ? parseFloat(q.finalPercent) : null } return { quotes, request, finalPercent } })