forked from alaguraj/odoo-testing-addons
Print rendered POS receipt through QZ
This commit is contained in:
parent
bbc7603c5b
commit
b5f450bbf7
@ -21,6 +21,10 @@ function getBillingPrinterName(config) {
|
||||
return config?.qz_billing_printer_name || config?.qz_printer_name || "";
|
||||
}
|
||||
|
||||
function paperWidthMm(config) {
|
||||
return String(config?.qz_paper_width || DEFAULT_COLUMNS) === "48" ? 80 : 58;
|
||||
}
|
||||
|
||||
function cleanText(value) {
|
||||
return String(value ?? "")
|
||||
.normalize("NFKD")
|
||||
@ -132,6 +136,65 @@ function bytesToBase64(bytes) {
|
||||
return btoa(binary);
|
||||
}
|
||||
|
||||
function absoluteUrl(value) {
|
||||
if (!value || value.startsWith("data:") || value.startsWith("blob:")) {
|
||||
return value;
|
||||
}
|
||||
return new URL(value, window.location.origin).href;
|
||||
}
|
||||
|
||||
function collectPrintableStyles() {
|
||||
return Array.from(document.querySelectorAll("link[rel='stylesheet'], style"))
|
||||
.map((node) => {
|
||||
if (node.tagName === "LINK") {
|
||||
return `<link rel="stylesheet" href="${absoluteUrl(node.getAttribute("href"))}">`;
|
||||
}
|
||||
return node.outerHTML;
|
||||
})
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
function buildHtmlReceipt(receiptElement, pos) {
|
||||
const config = pos?.config || {};
|
||||
const widthMm = paperWidthMm(config);
|
||||
const clone = receiptElement.cloneNode(true);
|
||||
for (const node of clone.querySelectorAll("[src]")) {
|
||||
node.setAttribute("src", absoluteUrl(node.getAttribute("src")));
|
||||
}
|
||||
for (const node of clone.querySelectorAll("[href]")) {
|
||||
node.setAttribute("href", absoluteUrl(node.getAttribute("href")));
|
||||
}
|
||||
|
||||
return `<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<base href="${window.location.origin}/">
|
||||
${collectPrintableStyles()}
|
||||
<style>
|
||||
@page { size: ${widthMm}mm auto; margin: 0; }
|
||||
html, body {
|
||||
width: ${widthMm}mm;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #fff;
|
||||
}
|
||||
body {
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
.pos-receipt {
|
||||
width: ${widthMm}mm !important;
|
||||
max-width: ${widthMm}mm !important;
|
||||
box-sizing: border-box;
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>${clone.outerHTML}</body>
|
||||
</html>`;
|
||||
}
|
||||
|
||||
class EscPosBuilder {
|
||||
constructor(columns) {
|
||||
this.columns = columns;
|
||||
@ -448,6 +511,31 @@ patch(ReceiptScreen.prototype, {
|
||||
await qz.websocket.connect({ retries: 2, delay: 1 });
|
||||
}
|
||||
|
||||
const receiptElement = this.el?.querySelector?.(".pos-receipt");
|
||||
if (receiptElement) {
|
||||
const widthMm = paperWidthMm(this.pos.config);
|
||||
const config = qz.configs.create(printerName, {
|
||||
copies: 1,
|
||||
margins: 0,
|
||||
units: "mm",
|
||||
size: { width: widthMm },
|
||||
rasterize: true,
|
||||
scaleContent: true,
|
||||
spool: { size: 1 },
|
||||
});
|
||||
await qz.print(config, [{
|
||||
type: "pixel",
|
||||
format: "html",
|
||||
flavor: "plain",
|
||||
data: buildHtmlReceipt(receiptElement, this.pos),
|
||||
}]);
|
||||
|
||||
if (this.currentOrder) {
|
||||
this.currentOrder._printed = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const config = qz.configs.create(printerName, {
|
||||
encoding: "CP437",
|
||||
copies: 1,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user