From e7c67653e4ea32bf83885314870b86ba9dc092c7 Mon Sep 17 00:00:00 2001 From: Alaguraj0361 Date: Thu, 7 May 2026 16:58:11 +0530 Subject: [PATCH] enabled multi-printer configuration for billing and kitchen printers --- .../dine360_qz_printer/models/pos_config.py | 3 +- .../models/res_config_settings.py | 3 +- .../static/src/js/qz_wrapper.js | 89 ++++++++++++++++++- .../views/pos_config_views.xml | 16 +++- 4 files changed, 103 insertions(+), 8 deletions(-) diff --git a/addons/dine360_qz_printer/models/pos_config.py b/addons/dine360_qz_printer/models/pos_config.py index 66174d4..56d40d4 100644 --- a/addons/dine360_qz_printer/models/pos_config.py +++ b/addons/dine360_qz_printer/models/pos_config.py @@ -4,7 +4,8 @@ class PosConfig(models.Model): _inherit = 'pos.config' use_qz_printer = fields.Boolean("Use QZ Tray Printer", help="Print directly using QZ Tray locally") - qz_printer_name = fields.Char("QZ Printer Name", help="Name of the printer mapped in QZ Tray") + qz_billing_printer_name = fields.Char("Billing Printer Name", help="Name of the billing printer mapped in QZ Tray") + qz_kitchen_printer_name = fields.Char("Kitchen Printer Name", help="Name of the kitchen printer mapped in QZ Tray") qz_paper_width = fields.Selection( [('42', '58mm / 42 columns'), ('48', '80mm / 48 columns')], string="QZ Receipt Width", diff --git a/addons/dine360_qz_printer/models/res_config_settings.py b/addons/dine360_qz_printer/models/res_config_settings.py index 035a086..48a1d53 100644 --- a/addons/dine360_qz_printer/models/res_config_settings.py +++ b/addons/dine360_qz_printer/models/res_config_settings.py @@ -5,7 +5,8 @@ class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' use_qz_printer = fields.Boolean(related='pos_config_id.use_qz_printer', readonly=False) - qz_printer_name = fields.Char(related='pos_config_id.qz_printer_name', readonly=False) + qz_billing_printer_name = fields.Char(related='pos_config_id.qz_billing_printer_name', readonly=False) + qz_kitchen_printer_name = fields.Char(related='pos_config_id.qz_kitchen_printer_name', readonly=False) qz_paper_width = fields.Selection(related='pos_config_id.qz_paper_width', readonly=False) qz_print_logo = fields.Boolean(related='pos_config_id.qz_print_logo', readonly=False) qz_enable_cutter = fields.Boolean(related='pos_config_id.qz_enable_cutter', readonly=False) diff --git a/addons/dine360_qz_printer/static/src/js/qz_wrapper.js b/addons/dine360_qz_printer/static/src/js/qz_wrapper.js index ffb3274..566e6ee 100644 --- a/addons/dine360_qz_printer/static/src/js/qz_wrapper.js +++ b/addons/dine360_qz_printer/static/src/js/qz_wrapper.js @@ -3,6 +3,7 @@ import { patch } from "@web/core/utils/patch"; import { ReceiptScreen } from "@point_of_sale/app/screens/receipt_screen/receipt_screen"; import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup"; +import { PosStore } from "@point_of_sale/app/store/pos_store"; const ESC = 0x1b; const GS = 0x1d; @@ -355,7 +356,7 @@ async function buildEscPosReceipt(order, pos) { patch(ReceiptScreen.prototype, { async printReceipt() { - if (this.pos.config.use_qz_printer && this.pos.config.qz_printer_name) { + if (this.pos.config.use_qz_printer && this.pos.config.qz_billing_printer_name) { try { if (!window.qz) { console.error("QZ Tray library not loaded."); @@ -366,7 +367,7 @@ patch(ReceiptScreen.prototype, { await qz.websocket.connect({ retries: 2, delay: 1 }); } - const config = qz.configs.create(this.pos.config.qz_printer_name, { + const config = qz.configs.create(this.pos.config.qz_billing_printer_name, { encoding: "CP437", copies: 1, spool: { size: 1 }, @@ -395,3 +396,87 @@ patch(ReceiptScreen.prototype, { return super.printReceipt(...arguments); }, }); + +async function buildEscPosKitchenTicket(order, pos, changes) { + const config = pos?.config || {}; + const columns = columnsFromConfig(config); + const builder = new EscPosBuilder(columns); + + builder.init(); + builder.align("center"); + builder.bold(true); + builder.size("doubleHeight"); + builder.line("KITCHEN ORDER"); + builder.size("normal"); + builder.line(""); + + builder.align("left"); + if (order.name) builder.line(`Order: ${order.name}`); + if (order.table?.name) builder.line(`Table: ${order.table.name}`); + if (order.customer_count) builder.line(`Guests: ${order.customer_count}`); + builder.line(`Time: ${new Date().toLocaleTimeString()}`); + builder.separator("="); + + for (const category of Object.values(changes.categories || {})) { + if (category.name) { + builder.bold(true); + builder.line(category.name.toUpperCase()); + builder.bold(false); + } + for (const line of category.orderlines || []) { + const qty = line.quantity; + const qtyText = Number.isInteger(qty) ? String(qty) : qty.toFixed(2).replace(/\.?0+$/, ""); + addWrappedLine(builder, `${qtyText} x ${line.name}`); + if (line.note) { + addWrappedLine(builder, `Note: ${line.note}`, "", 2); + } + } + builder.line(""); + } + + builder.feed(END_FEED_LINES); + if (config.qz_enable_cutter !== false) { + builder.cut(config.qz_cut_mode || "partial"); + } + builder.feed(1); + return bytesToBase64(builder.bytes); +} + +patch(PosStore.prototype, { + async sendOrderToPrinter(order) { + if (this.config.use_qz_printer && this.config.qz_kitchen_printer_name) { + const changes = order.computeChanges(); + if (Object.keys(changes.categories).length > 0) { + try { + if (!window.qz) { + console.error("QZ Tray library not loaded."); + return false; + } + if (!qz.websocket.isActive()) { + await qz.websocket.connect({ retries: 2, delay: 1 }); + } + + const config = qz.configs.create(this.config.qz_kitchen_printer_name, { + encoding: "CP437", + copies: 1, + spool: { size: 1 }, + }); + const payload = await buildEscPosKitchenTicket(order, this, changes); + await qz.print(config, [{ + type: "raw", + format: "command", + flavor: "base64", + data: payload, + }]); + order.saved_quantity = order.get_orderlines().reduce((acc, line) => acc + line.get_quantity(), 0); + return true; + } catch (err) { + console.error("QZ Tray Kitchen Print Error:", err); + // Fallback or show error + } + } + return true; + } + return super.sendOrderToPrinter(...arguments); + }, +}); diff --git a/addons/dine360_qz_printer/views/pos_config_views.xml b/addons/dine360_qz_printer/views/pos_config_views.xml index e798595..1b3d3cf 100644 --- a/addons/dine360_qz_printer/views/pos_config_views.xml +++ b/addons/dine360_qz_printer/views/pos_config_views.xml @@ -11,8 +11,12 @@
-
+
+