Add QZ raw receipt fallback text
This commit is contained in:
parent
3f1e8bd7e9
commit
0333967c90
@ -4,6 +4,7 @@ import { patch } from "@web/core/utils/patch";
|
|||||||
import { ReceiptScreen } from "@point_of_sale/app/screens/receipt_screen/receipt_screen";
|
import { ReceiptScreen } from "@point_of_sale/app/screens/receipt_screen/receipt_screen";
|
||||||
|
|
||||||
const RECEIPT_COLUMNS = 42;
|
const RECEIPT_COLUMNS = 42;
|
||||||
|
const NEWLINE = "\r\n";
|
||||||
|
|
||||||
function normalizeReceiptText(text) {
|
function normalizeReceiptText(text) {
|
||||||
return (text || "")
|
return (text || "")
|
||||||
@ -34,20 +35,87 @@ function wrapLine(line, width = RECEIPT_COLUMNS) {
|
|||||||
return wrapped;
|
return wrapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildEscPosReceipt(receiptElement) {
|
function money(value, currency) {
|
||||||
|
const amount = Number(value || 0).toFixed(2);
|
||||||
|
return currency?.symbol ? `${currency.symbol}${amount}` : amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
function leftRight(left, right, width = RECEIPT_COLUMNS) {
|
||||||
|
const cleanLeft = String(left || "");
|
||||||
|
const cleanRight = String(right || "");
|
||||||
|
const space = Math.max(1, width - cleanLeft.length - cleanRight.length);
|
||||||
|
return `${cleanLeft}${" ".repeat(space)}${cleanRight}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildReceiptLinesFromOrder(order) {
|
||||||
|
const currency = order?.pos?.currency;
|
||||||
|
const lines = [];
|
||||||
|
const company = order?.pos?.company;
|
||||||
|
const client = order?.get_partner?.();
|
||||||
|
|
||||||
|
if (company?.name) {
|
||||||
|
lines.push(company.name);
|
||||||
|
}
|
||||||
|
if (company?.phone) {
|
||||||
|
lines.push(company.phone);
|
||||||
|
}
|
||||||
|
lines.push("-".repeat(RECEIPT_COLUMNS));
|
||||||
|
|
||||||
|
const receiptNumber = order?.name || order?.uid || "";
|
||||||
|
if (receiptNumber) {
|
||||||
|
lines.push(`Receipt: ${receiptNumber}`);
|
||||||
|
}
|
||||||
|
lines.push(new Date().toLocaleString());
|
||||||
|
if (client?.name) {
|
||||||
|
lines.push(`Customer: ${client.name}`);
|
||||||
|
}
|
||||||
|
lines.push("-".repeat(RECEIPT_COLUMNS));
|
||||||
|
|
||||||
|
for (const orderline of order?.get_orderlines?.() || []) {
|
||||||
|
const product = orderline.get_product?.();
|
||||||
|
const name = product?.display_name || product?.name || "";
|
||||||
|
const qty = orderline.get_quantity?.() || 0;
|
||||||
|
const total = orderline.get_price_with_tax?.() ?? orderline.get_display_price?.() ?? 0;
|
||||||
|
for (const wrapped of wrapLine(name, RECEIPT_COLUMNS)) {
|
||||||
|
lines.push(wrapped);
|
||||||
|
}
|
||||||
|
lines.push(leftRight(` ${qty} x`, money(total, currency)));
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.push("-".repeat(RECEIPT_COLUMNS));
|
||||||
|
lines.push(leftRight("TOTAL", money(order?.get_total_with_tax?.(), currency)));
|
||||||
|
const tax = order?.get_total_tax?.();
|
||||||
|
if (tax) {
|
||||||
|
lines.push(leftRight("Tax", money(tax, currency)));
|
||||||
|
}
|
||||||
|
const change = order?.get_change?.();
|
||||||
|
if (change) {
|
||||||
|
lines.push(leftRight("Change", money(change, currency)));
|
||||||
|
}
|
||||||
|
lines.push("-".repeat(RECEIPT_COLUMNS));
|
||||||
|
lines.push("Thank you");
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildReceiptLines(receiptElement, order) {
|
||||||
|
const domLines = normalizeReceiptText(receiptElement?.innerText || "");
|
||||||
|
if (domLines.length > 1) {
|
||||||
|
return domLines;
|
||||||
|
}
|
||||||
|
return buildReceiptLinesFromOrder(order);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildEscPosReceipt(receiptElement, order) {
|
||||||
const ESC = "\x1B";
|
const ESC = "\x1B";
|
||||||
const GS = "\x1D";
|
const GS = "\x1D";
|
||||||
const lines = normalizeReceiptText(receiptElement.innerText);
|
const lines = buildReceiptLines(receiptElement, order);
|
||||||
const body = lines.flatMap((line) => wrapLine(line)).join("\n");
|
const body = lines.flatMap((line) => wrapLine(line)).join(NEWLINE);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
ESC + "@", // Initialize printer
|
ESC + "@", // Initialize printer
|
||||||
ESC + "a" + "\x01", // Center
|
|
||||||
ESC + "E" + "\x01", // Bold on
|
|
||||||
body,
|
|
||||||
ESC + "E" + "\x00", // Bold off
|
|
||||||
ESC + "a" + "\x00", // Left align
|
ESC + "a" + "\x00", // Left align
|
||||||
"\n\n\n",
|
body,
|
||||||
|
NEWLINE + NEWLINE + NEWLINE,
|
||||||
GS + "V" + "\x00", // Full cut on Epson-compatible printers
|
GS + "V" + "\x00", // Full cut on Epson-compatible printers
|
||||||
].join("");
|
].join("");
|
||||||
}
|
}
|
||||||
@ -76,16 +144,9 @@ patch(ReceiptScreen.prototype, {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const printData = buildEscPosReceipt(receiptElement);
|
const printData = buildEscPosReceipt(receiptElement, this.currentOrder);
|
||||||
|
|
||||||
await qz.print(config, [
|
await qz.print(config, [printData]);
|
||||||
{
|
|
||||||
type: "raw",
|
|
||||||
format: "command",
|
|
||||||
flavor: "plain",
|
|
||||||
data: printData,
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (this.currentOrder) {
|
if (this.currentOrder) {
|
||||||
this.currentOrder._printed = true;
|
this.currentOrder._printed = true;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user