Tower: upload laundry_management 19.0.19.0.4 (via marketplace)

This commit is contained in:
2026-05-01 15:00:37 +00:00
parent 70d43d34ca
commit 284e2939f5

View File

@@ -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;
},
});