Tower: upload laundry_management 19.0.19.0.4 (via marketplace)
This commit is contained in:
@@ -0,0 +1,94 @@
|
|||||||
|
/** @odoo-module */
|
||||||
|
import { Component } from "@odoo/owl";
|
||||||
|
import { Dialog } from "@web/core/dialog/dialog";
|
||||||
|
|
||||||
|
// Sort priority: cash first, then bank, then others
|
||||||
|
const JOURNAL_ORDER = { cash: 0, bank: 1 };
|
||||||
|
|
||||||
|
export class LaundrySettlementReceipt extends Component {
|
||||||
|
static components = { Dialog };
|
||||||
|
static template = "laundry_management.SettlementReceipt";
|
||||||
|
static props = {
|
||||||
|
partnerName: { type: String },
|
||||||
|
settledTotal: { type: Number },
|
||||||
|
remainingDue: { type: Number },
|
||||||
|
payments: { type: Array },
|
||||||
|
settledOrders: { type: Array },
|
||||||
|
close: { type: Function },
|
||||||
|
};
|
||||||
|
|
||||||
|
get dateTime() {
|
||||||
|
return new Date().toLocaleString();
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt(value) {
|
||||||
|
return parseFloat(value || 0).toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Group payments by method name, merge duplicates, sort cash → bank → other. */
|
||||||
|
get groupedPayments() {
|
||||||
|
const map = {};
|
||||||
|
for (const p of this.props.payments) {
|
||||||
|
// Use method_name (from settlement_pos_pm_id) when available,
|
||||||
|
// fall back to journal_name for legacy payments without it.
|
||||||
|
const key = p.method_name || p.journal_name;
|
||||||
|
const jtype = p.journal_type || "other";
|
||||||
|
if (!map[key]) {
|
||||||
|
map[key] = { name: key, amount: 0, _type: jtype };
|
||||||
|
}
|
||||||
|
map[key].amount += p.amount;
|
||||||
|
}
|
||||||
|
return Object.values(map).sort(
|
||||||
|
(a, b) => (JOURNAL_ORDER[a._type] ?? 2) - (JOURNAL_ORDER[b._type] ?? 2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Group settled orders by name, merge duplicates. */
|
||||||
|
get groupedOrders() {
|
||||||
|
const map = {};
|
||||||
|
for (const o of this.props.settledOrders) {
|
||||||
|
const key = o.name;
|
||||||
|
if (!map[key]) {
|
||||||
|
map[key] = { name: key, applied: 0, remaining_on_order: 0 };
|
||||||
|
}
|
||||||
|
map[key].applied += o.applied;
|
||||||
|
map[key].remaining_on_order = o.remaining_on_order;
|
||||||
|
}
|
||||||
|
return Object.values(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
printReceipt() {
|
||||||
|
const receiptEl = document.querySelector(".settlement-receipt-content");
|
||||||
|
if (!receiptEl) return;
|
||||||
|
const printWindow = window.open("", "_blank", "width=300,height=600");
|
||||||
|
if (!printWindow) return;
|
||||||
|
printWindow.document.write(`
|
||||||
|
<html><head><title>Settlement Receipt</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: monospace; font-size: 12px; width: 280px;
|
||||||
|
margin: 0 auto; padding: 10px; }
|
||||||
|
.text-center { text-align: center; }
|
||||||
|
.fw-bold { font-weight: bold; }
|
||||||
|
.fs-5 { font-size: 16px; }
|
||||||
|
.mt-2 { margin-top: 8px; }
|
||||||
|
.mb-1 { margin-bottom: 4px; }
|
||||||
|
.mb-2 { margin-bottom: 8px; }
|
||||||
|
.border-top { border-top: 1px dashed #000; padding-top: 6px; }
|
||||||
|
.border-bottom { border-bottom: 1px dashed #000; padding-bottom: 6px; }
|
||||||
|
.d-flex { display: flex; }
|
||||||
|
.justify-content-between { justify-content: space-between; }
|
||||||
|
table { width: 100%; border-collapse: collapse; }
|
||||||
|
td, th { padding: 2px 0; }
|
||||||
|
.text-end { text-align: right; }
|
||||||
|
.text-muted { color: #666; }
|
||||||
|
.small { font-size: 11px; }
|
||||||
|
</style></head><body>
|
||||||
|
${receiptEl.innerHTML}
|
||||||
|
</body></html>
|
||||||
|
`);
|
||||||
|
printWindow.document.close();
|
||||||
|
printWindow.focus();
|
||||||
|
printWindow.print();
|
||||||
|
printWindow.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user