Tower: upload laundry_management 19.0.19.0.4 (via marketplace)
This commit is contained in:
133
addons/laundry_management/static/src/js/pos_order_patch.js
Normal file
133
addons/laundry_management/static/src/js/pos_order_patch.js
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/** @odoo-module
|
||||||
|
*
|
||||||
|
* PosOrder patch — laundry context fields.
|
||||||
|
*
|
||||||
|
* Two responsibilities:
|
||||||
|
* 1. setup(): seed primitive defaults on the reactive proxy so that
|
||||||
|
* OWL components (panel, receipt) which read these slots track
|
||||||
|
* future writes and re-render. Without seeding, assigning a fresh
|
||||||
|
* property after first render does NOT trigger reactivity.
|
||||||
|
* No fields are pulled from the loader — pure in-memory defaults.
|
||||||
|
*
|
||||||
|
* 2. serializeForORM(): inject the laundry slots into the sync_from_ui
|
||||||
|
* payload so the backend pos.order columns are populated, exactly
|
||||||
|
* like `general_customer_note`.
|
||||||
|
* - laundry_order_type_id → integer id (Many2one)
|
||||||
|
* - laundry_order_attribute_ids → [[6, 0, ids]] (Many2many "set")
|
||||||
|
* - laundry_is_delivery → boolean
|
||||||
|
* - laundry_delivery_address → string | false
|
||||||
|
* - laundry_delivery_scheduled_at → string | false
|
||||||
|
*
|
||||||
|
* NOTE: this patch does NOT touch order.lines, pricing, taxes, or any
|
||||||
|
* relational field exposed by _load_pos_data_fields.
|
||||||
|
*/
|
||||||
|
import { patch } from "@web/core/utils/patch";
|
||||||
|
import { PosOrder } from "@point_of_sale/app/models/pos_order";
|
||||||
|
|
||||||
|
function pickId(v) {
|
||||||
|
if (!v) return false;
|
||||||
|
if (typeof v === "number") return v;
|
||||||
|
if (typeof v === "object" && Number.isInteger(v.id)) return v.id;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function pickIds(arr) {
|
||||||
|
if (!Array.isArray(arr)) return [];
|
||||||
|
const out = [];
|
||||||
|
const seen = new Set();
|
||||||
|
for (const v of arr) {
|
||||||
|
const id = pickId(v);
|
||||||
|
if (id && !seen.has(id)) {
|
||||||
|
seen.add(id);
|
||||||
|
out.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeDateTime(value) {
|
||||||
|
if (!value || typeof value !== "string") return false;
|
||||||
|
|
||||||
|
let v = value;
|
||||||
|
|
||||||
|
// Remove timezone like +03:00 or -03:00
|
||||||
|
const tzMatch = v.match(/([+-]\d{2}:\d{2})$/);
|
||||||
|
if (tzMatch) {
|
||||||
|
v = v.replace(tzMatch[0], "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove Z
|
||||||
|
if (v.endsWith("Z")) {
|
||||||
|
v = v.slice(0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove milliseconds
|
||||||
|
if (v.includes(".")) {
|
||||||
|
v = v.split(".")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace T with space
|
||||||
|
v = v.replace("T", " ");
|
||||||
|
|
||||||
|
// Ensure seconds exist
|
||||||
|
if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(v)) {
|
||||||
|
v += ":00";
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
patch(PosOrder.prototype, {
|
||||||
|
setup(...args) {
|
||||||
|
super.setup(...args);
|
||||||
|
// Seed defaults on the reactive proxy. Assigning after first
|
||||||
|
// render only triggers OWL reactivity if the key already exists
|
||||||
|
// on the proxy at observation time.
|
||||||
|
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 = [];
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
initState(...args) {
|
||||||
|
super.initState(...args);
|
||||||
|
// Reactive flag for POS Mode system: when true, the order is a
|
||||||
|
// dedicated settlement context — products cannot be added,
|
||||||
|
// quantities cannot be edited, line cannot be deleted.
|
||||||
|
// Seeded here so OWL reactivity tracks future writes.
|
||||||
|
if (this.uiState && !("is_laundry_settle_due" in this.uiState)) {
|
||||||
|
this.uiState.is_laundry_settle_due = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
serializeForORM(opts = {}) {
|
||||||
|
const data = super.serializeForORM(opts);
|
||||||
|
|
||||||
|
const typeId = pickId(this.laundry_order_type_id);
|
||||||
|
data.laundry_order_type_id = typeId || false;
|
||||||
|
|
||||||
|
const attrIds = pickIds(this.laundry_order_attribute_ids);
|
||||||
|
data.laundry_order_attribute_ids = [[6, 0, attrIds]];
|
||||||
|
|
||||||
|
data.laundry_is_delivery = !!this.laundry_is_delivery;
|
||||||
|
data.laundry_delivery_address = this.laundry_delivery_address || false;
|
||||||
|
// ABSOLUTE GUARANTEE: nothing with a "T", ".000", or timezone reaches
|
||||||
|
// the backend. Run the full normalizer even if upstream already did;
|
||||||
|
// normalize(normalize(x)) === normalize(x), so this is a zero-cost net.
|
||||||
|
data.laundry_delivery_scheduled_at =
|
||||||
|
normalizeDateTime(this.laundry_delivery_scheduled_at) || false;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user