diff --git a/addons/laundry_management/static/src/js/laundry_receipt_details.js b/addons/laundry_management/static/src/js/laundry_receipt_details.js new file mode 100644 index 0000000..ae79fa7 --- /dev/null +++ b/addons/laundry_management/static/src/js/laundry_receipt_details.js @@ -0,0 +1,83 @@ +/** @odoo-module + * + * LaundryReceiptDetails — read-only receipt block. + * Reads from pos.laundryContext (live) for fresh prints, falls back + * to the order's persisted primitives for re-prints / backend prints. + */ +import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/hooks/pos_hook"; + +export class LaundryReceiptDetails extends Component { + static template = "laundry_management.LaundryReceiptDetails"; + static props = { + order: { type: Object, optional: true }, + }; + + setup() { + this.pos = usePos(); + } + + get order() { + return this.props.order; + } + + /** Live context first, persisted primitives as fallback. */ + get ctx() { + const order = this.order; + if (!order) return null; + const live = this.pos?.laundryContext?.get(order.uuid); + if (live && (live.type_id || live.attribute_ids?.length || live.is_delivery)) { + return live; + } + return { + type_id: order.laundry_order_type_id || false, + attribute_ids: order.laundry_order_attribute_ids || [], + is_delivery: !!order.laundry_is_delivery, + delivery_address: order.laundry_delivery_address || "", + delivery_scheduled_at: order.laundry_delivery_scheduled_at || "", + }; + } + + get orderType() { + const id = this.ctx?.type_id; + if (!id) return null; + return this.pos?.models?.["laundry.order.type"]?.get(id) || null; + } + + get attributes() { + const ids = this.ctx?.attribute_ids || []; + const model = this.pos?.models?.["laundry.order.attribute"]; + if (!model) return []; + return ids.map((id) => model.get(id)).filter(Boolean); + } + + get isDelivery() { + return !!this.ctx?.is_delivery; + } + + get deliveryAddress() { + return this.ctx?.delivery_address || ""; + } + + get deliveryScheduledAt() { + const v = this.ctx?.delivery_scheduled_at; + if (!v) return ""; + try { + const d = new Date(v.replace(" ", "T")); + if (!isNaN(d.getTime())) { + return d.toLocaleString(); + } + } catch (_e) { + // ignore + } + return String(v); + } + + get isUrgent() { + return this.orderType?.priority === "urgent"; + } + + get hasContent() { + return !!(this.orderType || this.attributes.length || this.isDelivery); + } +}