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