From 9bfd81b153fb8be3951f3ec38177eb1eac5fe351 Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Thu, 18 Jun 2026 16:45:06 +0700 Subject: [PATCH] fix: resolve pop-up blocker issues by initializing print window synchronously before async operations --- static/src/app/closing_receipt_patch.js | 64 ++++++++++++++++++------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/static/src/app/closing_receipt_patch.js b/static/src/app/closing_receipt_patch.js index 9292163..58318f1 100644 --- a/static/src/app/closing_receipt_patch.js +++ b/static/src/app/closing_receipt_patch.js @@ -100,8 +100,30 @@ patch(ClosePosPopup.prototype, { async closeSession() { this.pos._resetConnectedCashier(); + // ── Open print window synchronously to avoid pop-up blocker ────────── + let printWindow = null; + try { + printWindow = window.open("", "_blank", "width=400,height=600"); + if (!printWindow) { + const notification = this.pos?.env?.services?.notification; + if (notification) { + notification.add( + _t("Pop-up blocked. Please allow pop-ups for this site to print the closing receipt."), + { type: "warning" } + ); + } else { + alert("Pop-up blocked. Please allow pop-ups for this site to print the closing receipt."); + } + } else { + printWindow.document.write("

Closing Session, please wait...

"); + } + } catch (e) { + console.error("[pos_closing_receipt] Failed to open print window", e); + } + const syncSuccess = await this.pos.pushOrdersWithClosingPopup(); if (!syncSuccess) { + if (printWindow) printWindow.close(); return; } @@ -117,6 +139,7 @@ patch(ClosePosPopup.prototype, { } ); if (!response.successful) { + if (printWindow) printWindow.close(); return this.handleClosingError(response); } } @@ -129,6 +152,7 @@ patch(ClosePosPopup.prototype, { ); } catch (error) { if (!error.data && error.data?.message !== "This session is already closed.") { + if (printWindow) printWindow.close(); throw error; } } @@ -166,11 +190,12 @@ patch(ClosePosPopup.prototype, { ); if (!response.successful) { + if (printWindow) printWindow.close(); return this.handleClosingError(response); } // ── Print AFTER closing session on server ──────────────────────── - await this._printClosingReceipt(receiptData); + await this._printClosingReceipt(receiptData, printWindow); // Mark session closed locally this.pos.session.state = "closed"; @@ -178,6 +203,7 @@ patch(ClosePosPopup.prototype, { // ── Navigate away ──────────────────────────────────────────────── this.pos.router.close(); } catch (error) { + if (printWindow) printWindow.close(); if (error instanceof ConnectionLostError) { throw error; } else { @@ -188,7 +214,7 @@ patch(ClosePosPopup.prototype, { } }, - async _printClosingReceipt(receiptData) { + async _printClosingReceipt(receiptData, printWindow) { console.log("[pos_closing_receipt] Initiating closing receipt print..."); if (this.pos.env.services.ui) { console.log("[pos_closing_receipt] Blocking UI during print..."); @@ -325,17 +351,7 @@ patch(ClosePosPopup.prototype, { `; - const printWindow = window.open("", "_blank", "width=400,height=600"); if (!printWindow) { - const notification = this.pos?.env?.services?.notification; - if (notification) { - notification.add( - _t("Pop-up blocked. Please allow pop-ups for this site and try again to print closing receipt."), - { type: "warning" } - ); - } else { - alert("Pop-up blocked. Please allow pop-ups for this site and try again to print closing receipt."); - } return; } printWindow.document.open(); @@ -435,6 +451,23 @@ patch(Navbar.prototype, { const pos = this.pos; const formatCurrency = (val, hasSymbol = true) => safeFormatCurrency(val, pos, hasSymbol); + // ── Open print window synchronously to avoid pop-up blocker ────────── + let printWindow = null; + try { + printWindow = window.open("", "_blank", "width=400,height=600"); + if (!printWindow) { + this.notification.add( + _t("Pop-up blocked. Please allow pop-ups for this site and try again."), + { type: "warning" } + ); + return; + } else { + printWindow.document.write("

Fetching Closing Summary...

"); + } + } catch (e) { + console.error("[pos_closing_receipt] Failed to open print window", e); + } + // ── 1. Fetch the last closed session for this config ───────────────── let sessionData; try { @@ -444,6 +477,7 @@ patch(Navbar.prototype, { [this.pos.config.id] ); if (!result) { + if (printWindow) printWindow.close(); this.notification.add(_t("No closed session found to reprint."), { type: "warning", }); @@ -451,6 +485,7 @@ patch(Navbar.prototype, { } sessionData = result; } catch (err) { + if (printWindow) printWindow.close(); console.error("[pos_closing_receipt] Could not fetch last session:", err); this.notification.add(_t("Failed to fetch session data."), { type: "danger" }); return; @@ -600,12 +635,7 @@ patch(Navbar.prototype, { `; - const printWindow = window.open("", "_blank", "width=400,height=600"); if (!printWindow) { - this.notification.add( - _t("Pop-up blocked. Please allow pop-ups for this site and try again."), - { type: "warning" } - ); return; } printWindow.document.open();