diff --git a/addons/laundry_management/static/src/js/laundry_context_store.js b/addons/laundry_management/static/src/js/laundry_context_store.js new file mode 100644 index 0000000..47305b5 --- /dev/null +++ b/addons/laundry_management/static/src/js/laundry_context_store.js @@ -0,0 +1,72 @@ +/** @odoo-module + * + * LaundryContextStore — small reactive store, owned by PosStore, that + * holds the per-order laundry context (type / attributes / delivery) + * keyed by order uuid. + * + * Why a separate store? + * The POS related-models engine wraps records in a field-aware proxy. + * Writing custom properties (not declared in _load_pos_data_fields) + * directly on the order does NOT trigger OWL reactivity, so the + * context panel never re-renders after the popup confirms. + * + * Exposing the fields via _load_pos_data_fields is proven to crash + * POS at boot (`lines is undefined` in _computeAllPrices), so the + * only safe path is to keep these values OUTSIDE the engine, in a + * plain OWL reactive object that components can subscribe to. + * + * Contract: + * pos.laundryContext.get(uuid) → reactive object with keys: + * { type_id, attribute_ids, + * is_delivery, delivery_address, + * delivery_scheduled_at } + * pos.laundryContext.set(uuid, patch) + * pos.laundryContext.clear(uuid) + * + * Persistence is independent: the same values are mirrored on the + * order as primitives (set in pos_store_patch.js) and shipped to the + * backend via PosOrder.serializeForORM (see pos_order_patch.js). + */ +import { reactive } from "@odoo/owl"; + +function emptyContext() { + return { + type_id: false, + attribute_ids: [], + is_delivery: false, + delivery_address: false, + delivery_scheduled_at: false, + }; +} + +export class LaundryContextStore { + constructor() { + this.byUuid = reactive({}); + } + + get(uuid) { + if (!uuid) { + return emptyContext(); + } + if (!this.byUuid[uuid]) { + this.byUuid[uuid] = emptyContext(); + } + return this.byUuid[uuid]; + } + + set(uuid, patch) { + if (!uuid || !patch) { + return; + } + const cur = this.get(uuid); + for (const key of Object.keys(patch)) { + cur[key] = patch[key]; + } + } + + clear(uuid) { + if (uuid && this.byUuid[uuid]) { + delete this.byUuid[uuid]; + } + } +}