From 284e2939f5562daabfabd6ec53e3ddfec9aac5b4 Mon Sep 17 00:00:00 2001 From: git_admin Date: Fri, 1 May 2026 15:00:37 +0000 Subject: [PATCH] Tower: upload laundry_management 19.0.19.0.4 (via marketplace) --- .../static/src/js/pos_order_patch.js.bak | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 addons/laundry_management/static/src/js/pos_order_patch.js.bak diff --git a/addons/laundry_management/static/src/js/pos_order_patch.js.bak b/addons/laundry_management/static/src/js/pos_order_patch.js.bak new file mode 100644 index 0000000..a592a82 --- /dev/null +++ b/addons/laundry_management/static/src/js/pos_order_patch.js.bak @@ -0,0 +1,83 @@ +/** @odoo-module + * + * PosOrder JS-side patch for the laundry order-type / attributes feature. + * + * Why this patch exists: + * The two relational laundry fields on `pos.order` + * - laundry_order_type_id (Many2one → laundry.order.type) + * - laundry_order_attribute_ids (Many2many → laundry.order.attribute) + * are NOT exposed via _load_pos_data_fields anymore. Including them was + * breaking the POS relational engine during order initialization + * (TypeError: lines is undefined → _computeAllPrices crash). + * + * So instead of round-tripping them through the relational engine, we: + * 1. Store them as plain JS attributes on the order instance + * (assigned by runLaundryOrderTypeFlow in pos_store_patch.js). + * 2. Inject them into the sync_from_ui payload via serializeForORM + * as standard ORM commands (integer id for M2O, [(6,0,ids)] for M2M). + * 3. The backend pos.order columns still exist; sync writes the values + * normally and _maybe_create_laundry_order propagates them onward. + * + * The 3 SCALAR laundry fields (laundry_is_delivery, ..._address, + * ..._scheduled_at) remain in _load_pos_data_fields and round-trip + * normally through the relational engine. We only set safe defaults + * for them here so consumers never hit `undefined`. + * + * Setup runs with (...args) so super gets the exact arguments the + * framework passed, and all writes happen AFTER super.setup so we never + * interfere with base initialization. + */ +import { patch } from "@web/core/utils/patch"; +import { PosOrder } from "@point_of_sale/app/models/pos_order"; + +patch(PosOrder.prototype, { + setup(...args) { + super.setup(...args); + + // Scalar field defaults (these ARE in _load_pos_data_fields). + if (this.laundry_is_delivery === undefined) { + this.laundry_is_delivery = false; + } + if (this.laundry_delivery_address === undefined) { + this.laundry_delivery_address = false; + } + if (this.laundry_delivery_scheduled_at === undefined) { + this.laundry_delivery_scheduled_at = false; + } + + // Relational field shadows (NOT in _load_pos_data_fields — pure JS). + // Plain attributes only, never relational records, so the engine + // does not see them as relational writes. + if (this.laundry_order_type_id === undefined) { + this.laundry_order_type_id = false; + } + if (this.laundry_order_attribute_ids === undefined) { + this.laundry_order_attribute_ids = []; + } + }, + + serializeForORM(opts = {}) { + const data = super.serializeForORM(opts); + + // Many2one → just the integer id (or false to clear). + const typeRec = this.laundry_order_type_id; + if (typeRec && typeof typeRec === "object" && typeRec.id) { + data.laundry_order_type_id = typeRec.id; + } else if (typeof typeRec === "number") { + data.laundry_order_type_id = typeRec; + } else { + data.laundry_order_type_id = false; + } + + // Many2many → standard ORM "set" command [(6, 0, [ids])]. + const attrs = Array.isArray(this.laundry_order_attribute_ids) + ? this.laundry_order_attribute_ids + : []; + const attrIds = attrs + .map((a) => (a && typeof a === "object" ? a.id : a)) + .filter((id) => Number.isInteger(id)); + data.laundry_order_attribute_ids = [[6, 0, attrIds]]; + + return data; + }, +});