From d1df33bdb2586d4379a3459adfc8fd11ae93730e Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Mon, 1 Jun 2026 15:09:38 +0700 Subject: [PATCH] feat: enhance basic receipt layout with double-height printing and conditional header skipping --- static/src/js/escpos_generator.js | 71 ++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/static/src/js/escpos_generator.js b/static/src/js/escpos_generator.js index 77bd744..f96e857 100755 --- a/static/src/js/escpos_generator.js +++ b/static/src/js/escpos_generator.js @@ -209,13 +209,13 @@ export class EscPosGenerator { cmds.push(...this.initialize()); // ── Header ──────────────────────────────────────────────────────── - if (receiptData.headerData) { + // On basic receipt (table checker): skip company header, print only minimal info + if (!receiptData.isBasicReceipt && receiptData.headerData) { const h = receiptData.headerData; if (h.companyName) { cmds.push(...this.addLine(h.companyName, { align: 'center', bold: true, width: 2, height: 2 })); } if (h.address) { - // Long addresses should wrap — print as-is (printer wraps automatically) cmds.push(...this.addLine(h.address, { align: 'center' })); } if (h.phone) { @@ -230,12 +230,20 @@ export class EscPosGenerator { // ── Order info ──────────────────────────────────────────────────── if (receiptData.orderData) { const o = receiptData.orderData; - if (o.orderName) cmds.push(...this.addLine(`Order: ${o.orderName}`)); - if (o.date) cmds.push(...this.addLine(`Date: ${o.date}`)); - if (o.cashier) cmds.push(...this.addLine(`Cashier: ${o.cashier}`)); - // Table name — printed after cashier, matching pos_restaurant ReceiptHeader - if (o.tableName) cmds.push(...this.addLine(o.tableName, { bold: true, align: 'center' })); - if (o.customer) cmds.push(...this.addLine(`Customer: ${o.customer}`)); + if (receiptData.isBasicReceipt) { + // Basic receipt (table checker): all info at double height for readability + if (o.orderName) cmds.push(...this.addLine(`Order: ${o.orderName}`, { height: 2, bold: true })); + if (o.date) cmds.push(...this.addLine(o.date, { height: 2 })); + if (o.cashier) cmds.push(...this.addLine(`By: ${o.cashier}`, { height: 2 })); + if (o.tableName) cmds.push(...this.addLine(o.tableName, { bold: true, height: 2, align: 'center' })); + if (o.customer) cmds.push(...this.addLine(`Cust: ${o.customer}`, { height: 2 })); + } else { + if (o.orderName) cmds.push(...this.addLine(`Order: ${o.orderName}`)); + if (o.date) cmds.push(...this.addLine(`Date: ${o.date}`)); + if (o.cashier) cmds.push(...this.addLine(`Cashier: ${o.cashier}`)); + if (o.tableName) cmds.push(...this.addLine(o.tableName, { bold: true, align: 'center' })); + if (o.customer) cmds.push(...this.addLine(`Customer: ${o.customer}`)); + } cmds.push(...this.addLine(this.divider())); } @@ -248,15 +256,16 @@ export class EscPosGenerator { if (receiptData.isBasicReceipt) { // ── Basic receipt / table checker ────────────────────────── - // Show only qty + product name (no price/total), matching - // Odoo's basic_receipt behaviour (vals.price = false). - // Format: "2 Mie Ayam Geprek" - const qtyLabel = qtyStr.padEnd(3); - const nameMaxLen = W - qtyLabel.length; + // Show only qty + product name (no price/total), at double-width + // double-height for maximum readability on 58mm paper. + // At width=2, each char is 2x wide, so effective cols = W/2 = 16 + const halfW = Math.floor(W / 2); + const qtyLabel = qtyStr.padEnd(2) + ' '; + const nameMaxLen = halfW - qtyLabel.length; const displayName = name.length > nameMaxLen ? name.substring(0, nameMaxLen - 1) + '.' : name; - cmds.push(...this.addLine(qtyLabel + displayName, { bold: true, height: 2 })); + cmds.push(...this.addLine(qtyLabel + displayName, { bold: true, width: 2, height: 2 })); } else { // ── Full receipt ─────────────────────────────────────────── // Line 1: product name @@ -278,15 +287,25 @@ export class EscPosGenerator { const subName = String(sub.productName || ''); const subQty = sub.quantity || 0; const subQtyStr = subQty % 1 === 0 ? subQty.toFixed(0) : subQty.toFixed(2); - - // Format: " - 1x Mie Goreng" - const prefix = ` - ${subQtyStr}x `; - const maxSubLen = W - prefix.length; - - const displayName = subName.length > maxSubLen - ? subName.substring(0, maxSubLen - 1) + '.' - : subName; - cmds.push(...this.addLine(prefix + displayName, { bold: true })); + + if (receiptData.isBasicReceipt) { + // Double-height sub-lines on basic receipt + const halfW = Math.floor(W / 2); + const prefix = ` ${subQtyStr}x `; + const maxSubLen = halfW - prefix.length; + const displaySub = subName.length > maxSubLen + ? subName.substring(0, maxSubLen - 1) + '.' + : subName; + cmds.push(...this.addLine(prefix + displaySub, { height: 2 })); + } else { + // Format: " - 1x Mie Goreng" + const prefix = ` - ${subQtyStr}x `; + const maxSubLen = W - prefix.length; + const displaySub = subName.length > maxSubLen + ? subName.substring(0, maxSubLen - 1) + '.' + : subName; + cmds.push(...this.addLine(prefix + displaySub, { bold: true })); + } }); } @@ -323,7 +342,11 @@ export class EscPosGenerator { wrappedLines.forEach((l, i) => { const prefix = i === 0 ? '* ' : ' '; - cmds.push(...this.addLine(prefix + l, { bold: true })); + if (receiptData.isBasicReceipt) { + cmds.push(...this.addLine(prefix + l, { bold: true, height: 2 })); + } else { + cmds.push(...this.addLine(prefix + l, { bold: true })); + } }); } });