From fe1b692f4f14fba1b17abe303cd89fba7553ab8c Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Mon, 1 Jun 2026 08:49:26 +0700 Subject: [PATCH] feat: truncate long cashier names to first and last name, apply bold formatting to receipt items, and reduce paper feed length --- static/src/js/escpos_generator.js | 13 +++++++------ static/src/js/pos_receipt_printer.js | 21 +++++++++++++++++++-- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/static/src/js/escpos_generator.js b/static/src/js/escpos_generator.js index eec9f99..4a4b927 100755 --- a/static/src/js/escpos_generator.js +++ b/static/src/js/escpos_generator.js @@ -255,12 +255,12 @@ export class EscPosGenerator { const displayName = name.length > nameMaxLen ? name.substring(0, nameMaxLen - 1) + '.' : name; - cmds.push(...this.addLine(qtyLabel + displayName)); + cmds.push(...this.addLine(qtyLabel + displayName, { bold: true, height: 2 })); } else { // ── Full receipt ─────────────────────────────────────────── // Line 1: product name const displayName = name.length > W ? name.substring(0, W - 1) + '.' : name; - cmds.push(...this.addLine(displayName)); + cmds.push(...this.addLine(displayName, { bold: true, height: 2 })); // Line 2: qty x unitPrice = total (right-aligned) const priceStr = this.formatAmount(line.price || 0); @@ -268,14 +268,15 @@ export class EscPosGenerator { const middle = `${qtyStr}x ${priceStr}`; let itemLine = middle + totalStr.padStart(W - middle.length); if (itemLine.length > W) itemLine = totalStr.padStart(W); - cmds.push(...this.addLine(itemLine)); + cmds.push(...this.addLine(itemLine, { bold: true, height: 2 })); } // Note line (customer note / kitchen note) — shown on both modes if (line.note) { const noteText = `* ${line.note}`; cmds.push(...this.addLine( - noteText.length > W ? noteText.substring(0, W - 1) + '.' : noteText + noteText.length > W ? noteText.substring(0, W - 1) + '.' : noteText, + { bold: true } )); } }); @@ -336,8 +337,8 @@ export class EscPosGenerator { } } - // Feed and cut - cmds.push(...this.feedAndCut(4)); + // Feed and cut (reduced feed to 1 line to prevent footer white spaces on integrated Android/iMin printers) + cmds.push(...this.feedAndCut(1)); return new Uint8Array(cmds); } diff --git a/static/src/js/pos_receipt_printer.js b/static/src/js/pos_receipt_printer.js index 359ea56..69f6004 100755 --- a/static/src/js/pos_receipt_printer.js +++ b/static/src/js/pos_receipt_printer.js @@ -17,6 +17,22 @@ import { EscPosGraphics } from "./escpos_graphics"; * Ensures sale completion is never blocked by print errors. */ +const formatFirstLastName = (name) => { + if (!name) return ""; + let temp = name.trim(); + let prefix = ""; + const prefixMatch = temp.match(/^(served\s+by:?|order\s+taker:?|kasir:?)\s*/i); + if (prefixMatch) { + prefix = prefixMatch[0]; + temp = temp.substring(prefix.length).trim(); + } + const parts = temp.split(/\s+/); + if (parts.length <= 2) { + return name; + } + return prefix + parts[0] + " " + parts[parts.length - 1]; +}; + // Singleton instances for the POS session let bluetoothManager = null; let escposGenerator = null; @@ -680,7 +696,7 @@ patch(PosPrinterService.prototype, { const orderData = { orderName: order.pos_reference || order.name || '', date: dateStr || new Date().toLocaleString(), - cashier: (typeof order.getCashierName === 'function' ? order.getCashierName() : '') || '', + cashier: formatFirstLastName((typeof order.getCashierName === 'function' ? order.getCashierName() : '') || ''), customer: order.partner_id?.name || null, tableName, }; @@ -823,7 +839,7 @@ patch(PosPrinterService.prototype, { const orderData = { orderName: getText('.pos-receipt-vat') || getText('.pos-receipt-order-name') || getText('.order-name') || getText('.pos-receipt-order-data') || '', date: getText('#order-date') || getText('.pos-receipt-date') || new Date().toLocaleString(), - cashier: getText('.cashier') || getText('.pos-receipt-cashier') || '', + cashier: formatFirstLastName(getText('.cashier') || getText('.pos-receipt-cashier') || ''), customer: getText('.pos-receipt-customer') || getText('.customer') || null }; @@ -1073,6 +1089,7 @@ patch(PosPrinterService.prototype, { } else if (pos.user) { cashierName = pos.user.name || ''; } + cashierName = formatFirstLastName(cashierName); console.log('[BluetoothPrint] Cashier name:', cashierName); // Get customer info - try multiple ways