feat: enhance basic receipt layout with double-height printing and conditional header skipping
This commit is contained in:
parent
e667ef3bac
commit
d1df33bdb2
@ -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
|
||||
@ -279,14 +288,24 @@ export class EscPosGenerator {
|
||||
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 }));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user