Tower: upload laundry_management 19.0.19.0.4 (via marketplace)
This commit is contained in:
166
addons/laundry_management/static/src/js/payment_screen_patch.js
Normal file
166
addons/laundry_management/static/src/js/payment_screen_patch.js
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
/** @odoo-module
|
||||||
|
*
|
||||||
|
* PaymentScreen patch — minimal laundry behaviors:
|
||||||
|
* 1. Settlement orders: hide pay-later methods, custom validateOrder
|
||||||
|
* that calls settle_laundry_dues_rpc and bypasses normal sync.
|
||||||
|
* 2. Legacy laundry orders: trigger order-type popup at payment time
|
||||||
|
* (NOT on add-line). Block payment if type is required and missing.
|
||||||
|
*
|
||||||
|
* STRICT CONTRACT:
|
||||||
|
* - Does NOT touch order.lines, pricing, taxes
|
||||||
|
* - Does NOT override PosOrder.setup
|
||||||
|
* - Selections stored as primitives only (handled in pos_store_patch.js)
|
||||||
|
* - For non-laundry orders, super.validateOrder runs unchanged.
|
||||||
|
*/
|
||||||
|
import { patch } from "@web/core/utils/patch";
|
||||||
|
import { _t } from "@web/core/l10n/translation";
|
||||||
|
import { PaymentScreen } from "@point_of_sale/app/screens/payment_screen/payment_screen";
|
||||||
|
import { AlertDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
||||||
|
import { LaundrySettlementReceipt } from "@laundry_management/js/settlement_receipt";
|
||||||
|
|
||||||
|
function isSettlementOrder(order) {
|
||||||
|
return (
|
||||||
|
order &&
|
||||||
|
order.lines &&
|
||||||
|
order.lines.some(
|
||||||
|
(line) => line.product_id?.product_tmpl_id?.is_laundry_settlement
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
patch(PaymentScreen.prototype, {
|
||||||
|
setup() {
|
||||||
|
super.setup(...arguments);
|
||||||
|
// For settlement orders, hide Customer Account / pay-later methods.
|
||||||
|
if (isSettlementOrder(this.currentOrder)) {
|
||||||
|
this.payment_methods_from_config =
|
||||||
|
this.payment_methods_from_config.filter(
|
||||||
|
(pm) => !pm.split_transactions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-payment gate for the legacy laundry order-type flow.
|
||||||
|
* - true → continue with payment
|
||||||
|
* - false → block payment
|
||||||
|
*
|
||||||
|
* Skipped for: feature disabled, settlement orders, non-laundry orders,
|
||||||
|
* and orders that already have a type. If required + missing, opens the
|
||||||
|
* popup; blocks if the user closes/cancels.
|
||||||
|
*/
|
||||||
|
async beforePaymentFlow(order) {
|
||||||
|
const pos = this.pos;
|
||||||
|
const config = pos.config;
|
||||||
|
if (!order || !config?.enable_laundry_order_type) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (isSettlementOrder(order)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!pos.orderHasLaundryServiceLine(order)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (order.laundry_order_type_id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
await pos.runLaundryOrderTypeFlow(order);
|
||||||
|
if (config.require_laundry_order_type && !order.laundry_order_type_id) {
|
||||||
|
pos.notification.add(
|
||||||
|
_t("Order type is required to proceed to payment."),
|
||||||
|
{ type: "warning" }
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
async validateOrder(isForceValidate) {
|
||||||
|
const order = this.currentOrder;
|
||||||
|
|
||||||
|
// ── Settlement validation — bypass normal POS sync ──
|
||||||
|
if (isSettlementOrder(order)) {
|
||||||
|
return this._validateSettlementOrder(order);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Legacy laundry order-type gate ──
|
||||||
|
const allowed = await this.beforePaymentFlow(order);
|
||||||
|
if (!allowed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.validateOrder(isForceValidate);
|
||||||
|
},
|
||||||
|
|
||||||
|
async _validateSettlementOrder(order) {
|
||||||
|
const paymentLines = order.payment_ids
|
||||||
|
.filter((pl) => pl.getAmount() > 0)
|
||||||
|
.map((pl) => ({
|
||||||
|
pos_payment_method_id: pl.payment_method_id.id,
|
||||||
|
amount: pl.getAmount(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (paymentLines.length === 0) {
|
||||||
|
this.notification.add(
|
||||||
|
_t("Please add at least one payment."),
|
||||||
|
{ type: "warning" }
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const partnerId = order.partner_id?.id;
|
||||||
|
if (!partnerId) {
|
||||||
|
this.notification.add(_t("No customer selected."), {
|
||||||
|
type: "danger",
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sessionId = this.pos.session?.id || null;
|
||||||
|
|
||||||
|
let response;
|
||||||
|
try {
|
||||||
|
this.ui.block();
|
||||||
|
response = await this.pos.data.call(
|
||||||
|
"res.partner",
|
||||||
|
"settle_laundry_dues_rpc",
|
||||||
|
[partnerId, paymentLines, sessionId]
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
this.dialog.add(AlertDialog, {
|
||||||
|
title: _t("Settlement Failed"),
|
||||||
|
body:
|
||||||
|
err?.data?.message ||
|
||||||
|
err?.message ||
|
||||||
|
_t("Unknown error."),
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
this.ui.unblock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
order.payment_ids.some(
|
||||||
|
(pl) => pl.payment_method_id.is_cash_count && pl.getAmount() > 0
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
this.pos.hardwareProxy.openCashbox();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dialog.add(LaundrySettlementReceipt, {
|
||||||
|
partnerName: order.partner_id.name,
|
||||||
|
settledTotal: response.settled_total || 0,
|
||||||
|
remainingDue: response.remaining_due || 0,
|
||||||
|
payments: response.payments || [],
|
||||||
|
settledOrders: response.settled_orders || [],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.pos._lastSettlementMethodId =
|
||||||
|
paymentLines[0]?.pos_payment_method_id || null;
|
||||||
|
|
||||||
|
this.pos.removeOrder(order, false);
|
||||||
|
this.pos.addNewOrder();
|
||||||
|
this.pos.navigate("ProductScreen");
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user