Refactor receipt printing and template rendering logic

- Updated the `ReceiptInterface` to await the `printImageBuffer` method for proper asynchronous handling.
- Modified the `renderTemplateJPG` method in `SocketClient` to accept an image type parameter and improved error handling for template download failures.
- Enhanced the response handling to correctly parse and return image data based on the content type.
This commit is contained in:
Tom Butcher 2026-08-19 18:19:49 +01:00
parent 75fa9e2270
commit bec253cde8
2 changed files with 94 additions and 37 deletions

View File

@ -142,7 +142,7 @@ export default class ReceiptInterface {
const imageBuffer = Buffer.isBuffer(image)
? Buffer.from(image)
: Buffer.from(image);
this.receiptPrinter.printImageBuffer(imageBuffer);
await this.receiptPrinter.printImageBuffer(imageBuffer);
this.receiptPrinter.cut();
}
@ -168,21 +168,24 @@ export default class ReceiptInterface {
`Deploying job ${documentJob._id} to receipt printer ${this.name}`
);
const jpgObj =
await this.documentPrinterClient.socketClient.renderTemplateJPG({
_id: documentTemplate._id,
content: documentTemplate.content,
object: object,
width: 512,
});
const imageObj =
await this.documentPrinterClient.socketClient.renderTemplateJPG(
{
_id: documentTemplate._id,
content: documentTemplate.content,
object: object,
width: 512,
},
"png",
);
if (!jpgObj || !jpgObj.images) {
if (!imageObj || !imageObj.images) {
throw new Error(
jpgObj?.error || "Failed to render document template to image"
imageObj?.error || "Failed to render document template to image"
);
}
this.images.set(documentJob._id, jpgObj.images);
this.images.set(documentJob._id, imageObj.images);
return { success: true };
}

View File

@ -1,6 +1,7 @@
import log4js from "log4js";
import { WebSocketScanner } from "../network/websocketScanner.js";
import { io } from "socket.io-client";
import axios from "axios";
// Load configuration
import { loadConfig, saveConfig } from "../config.js";
import { getDeviceInfo } from "../utils.js";
@ -510,34 +511,87 @@ export class SocketClient {
});
}
async renderTemplatePDF(templateData) {
logger.debug("Rendering template PDF...", templateData);
return new Promise((resolve, reject) => {
this.socket.emit("renderTemplatePDF", templateData, (result) => {
if (result && result.error) {
logger.error("Failed to render template PDF:", result.error);
reject(new Error(result.error));
} else {
logger.trace("Template PDF rendered successfully.");
resolve(result);
}
});
});
getApiUrl() {
return this.fileManager.getApiUrl();
}
async renderTemplateJPG(templateData) {
logger.debug("Rendering template JPG...", templateData);
return new Promise((resolve, reject) => {
this.socket.emit("renderTemplateJPG", templateData, (result) => {
if (result && result.error) {
logger.error("Failed to render template JPG:", result.error);
reject(new Error(result.error));
} else {
logger.trace("Template JPG rendered successfully.");
resolve(result);
}
});
});
getApiHeaders() {
return {
"X-Auth-Code": config.host.authCode,
"X-Host-Id": config.host.id || this.id,
};
}
parseTemplateDownloadError(error) {
const data = error?.response?.data;
if (data instanceof ArrayBuffer || Buffer.isBuffer(data)) {
try {
const parsed = JSON.parse(Buffer.from(data).toString("utf8"));
return parsed?.error || error.message;
} catch (parseError) {
return error.message;
}
}
return data?.error || error.message;
}
async renderTemplatePDF(templateData) {
logger.debug("Rendering template PDF...", templateData);
try {
const response = await axios.post(
`${this.getApiUrl()}/documenttemplates/${templateData._id}/download`,
{
content: templateData.content,
object: templateData.object,
},
{
params: { type: "pdf" },
responseType: "arraybuffer",
headers: this.getApiHeaders(),
},
);
logger.trace("Template PDF rendered successfully.");
return { pdf: Buffer.from(response.data) };
} catch (error) {
const message = this.parseTemplateDownloadError(error);
logger.error("Failed to render template PDF:", message);
throw new Error(message);
}
}
async renderTemplateJPG(templateData, type = "jpeg") {
logger.debug(`Rendering template ${type.toUpperCase()}...`, templateData);
try {
const response = await axios.post(
`${this.getApiUrl()}/documenttemplates/${templateData._id}/download`,
{
content: templateData.content,
object: templateData.object,
width: templateData.width,
},
{
params: { type },
responseType: "arraybuffer",
headers: this.getApiHeaders(),
},
);
const contentType = response.headers["content-type"] || "";
if (contentType.includes("application/json")) {
const payload = JSON.parse(Buffer.from(response.data).toString("utf8"));
logger.trace("Template JPG rendered successfully.");
return {
images: (payload.images || []).map((image) =>
Buffer.from(image, "base64"),
),
};
}
logger.trace("Template JPG rendered successfully.");
return { images: [Buffer.from(response.data)] };
} catch (error) {
const message = this.parseTemplateDownloadError(error);
logger.error("Failed to render template JPG:", message);
throw new Error(message);
}
}
async subscribeToObjectActions({ objectType, _id }) {