feat: improve closing receipt print styling and add PrinterService patch for reliable UI handling

This commit is contained in:
Suherdy Yacob 2026-06-03 09:15:20 +07:00
parent 81cbebb9bb
commit 36f9830c08
3 changed files with 71 additions and 3 deletions

View File

@ -0,0 +1,29 @@
.pos-closing-receipt-print {
width: 512px;
font-size: 22px;
color: #000000;
}
.pos-closing-receipt-print .pos-receipt {
padding-left: 20px !important;
padding-right: 20px !important;
box-sizing: border-box !important;
}
@media print {
iframe.pos-print-iframe {
display: block !important;
position: fixed !important;
left: -9999px !important;
top: -9999px !important;
width: 0 !important;
height: 0 !important;
border: 0 !important;
}
.pos-closing-receipt-print .pos-receipt {
padding-left: 20px !important;
padding-right: 20px !important;
box-sizing: border-box !important;
}
}

View File

@ -7,7 +7,7 @@
(printer service with webPrintFallback: true).
-->
<t t-name="pos_closing_receipt.ClosingReceipt">
<div class="pos-receipt-print">
<div class="pos-closing-receipt-print">
<div class="pos-receipt" style="font-family: 'Courier New', Courier, monospace; font-size: 18px; width: 100%; max-width: 320px; margin: 0 auto; padding: 12px;">
<!-- ===== HEADER ===== -->

View File

@ -8,6 +8,28 @@ import { Component } from "@odoo/owl";
import { parseFloat } from "@web/views/fields/parsers";
import { ConnectionLostError } from "@web/core/network/rpc";
import { _t } from "@web/core/l10n/translation";
import { PrinterService } from "@point_of_sale/app/services/printer_service";
import { waitImages } from "@point_of_sale/utils";
// Patch PrinterService.printWeb to return a promise that resolves only after print dialog is closed
patch(PrinterService.prototype, {
async printWeb(el) {
console.log("[pos_closing_receipt] Patched printWeb called");
await this.renderer.whenMounted({
el,
callback: async (elClone) => {
console.log("[pos_closing_receipt] printWeb whenMounted callback started. Awaiting images...");
await waitImages(elClone);
console.log("[pos_closing_receipt] Images loaded. Invoking window.print...");
window.print(elClone);
console.log("[pos_closing_receipt] window.print has returned.");
},
});
console.log("[pos_closing_receipt] Patched printWeb fully resolved and returning true.");
return true;
}
});
// ─────────────────────────────────────────────────────────────────────────────
// ClosingReceipt OWL Component
@ -137,12 +159,29 @@ patch(ClosePosPopup.prototype, {
},
async _printClosingReceipt(receiptData) {
console.log("[pos_closing_receipt] Initiating closing receipt print...");
if (this.pos.env.services.ui) {
console.log("[pos_closing_receipt] Blocking UI during print...");
this.pos.env.services.ui.block();
}
try {
await this.printer.print(ClosingReceipt, receiptData, {
const printResult = await this.printer.print(ClosingReceipt, receiptData, {
webPrintFallback: true,
});
console.log("[pos_closing_receipt] Print operation resolved with result:", printResult);
// Explicit safety delay to let printer buffers flush (especially for Bluetooth/JSPM)
const delayMs = 1500;
console.log(`[pos_closing_receipt] Applying safety buffer delay of ${delayMs}ms...`);
await new Promise((resolve) => setTimeout(resolve, delayMs));
console.log("[pos_closing_receipt] Safety buffer complete.");
} catch (err) {
console.warn("[pos_closing_receipt] Failed to print closing receipt:", err);
console.error("[pos_closing_receipt] CRITICAL: Failed to print closing receipt:", err);
} finally {
if (this.pos.env.services.ui) {
console.log("[pos_closing_receipt] Unblocking UI.");
this.pos.env.services.ui.unblock();
}
}
},