[FIX] point_of_sale: ensure QR code loads in auto-printed receipts

Prior to this commit, enabling auto receipt printing resulted in the QR
code not being printed on the receipt. This was due to the QR image
being fetched post printing. This commit addresses the issue by first
loading the QR code image, then sending it to the printer, ensuring its
presence on the printed receipt.

opw-3763169

closes odoo/odoo#155354

Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com>
This commit is contained in:
Pedram (pebr)
2024-03-01 10:29:38 +00:00
parent deae7b7247
commit ce1fef9113
3 changed files with 42 additions and 23 deletions
@@ -1,4 +1,5 @@
/** @odoo-module **/
import { loadAllImages } from "@point_of_sale/utils";
export const printerService = {
dependencies: ["renderer"],
@@ -36,6 +37,8 @@ export class PrinterService {
}
async print(component, props, options) {
const el = await this.renderer.toHtml(component, props);
// Load all images before printing
await loadAllImages(el);
return await this.printHtml(el, options);
}
is = () => Boolean(this.device?.printReceipt);
@@ -6,6 +6,7 @@ import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
import { useService } from "@web/core/utils/hooks";
import { Component, useState } from "@odoo/owl";
import { usePos } from "@point_of_sale/app/store/pos_hook";
import { loadImage } from "@point_of_sale/utils";
export class PartnerDetailsEdit extends Component {
static template = "point_of_sale.PartnerDetailsEdit";
@@ -92,7 +93,14 @@ export class PartnerDetailsEdit extends Component {
});
} else {
const imageUrl = await getDataURLFromFile(file);
const loadedImage = await this._loadImage(imageUrl);
const loadedImage = await loadImage(imageUrl, {
onError: () => {
this.popup.add(ErrorPopup, {
title: _t("Loading Image Error"),
body: _t("Encountered error when loading image. Please try again."),
});
}
});
if (loadedImage) {
const resizedImage = await this._resizeImage(loadedImage, 800, 600);
this.changes.image_1920 = resizedImage.toDataURL();
@@ -118,28 +126,6 @@ export class PartnerDetailsEdit extends Component {
ctx.drawImage(img, 0, 0, width, height);
return canvas;
}
/**
* Loading image is converted to a Promise to allow await when
* loading an image. It resolves to the loaded image if successful,
* else, resolves to false.
*
* [Source](https://stackoverflow.com/questions/45788934/how-to-turn-this-callback-into-a-promise-using-async-await)
*/
_loadImage(url) {
return new Promise((resolve) => {
const img = new Image();
img.addEventListener("load", () => resolve(img));
img.addEventListener("error", () => {
this.popup.add(ErrorPopup, {
title: _t("Loading Image Error"),
body: _t("Encountered error when loading image. Please try again."),
});
resolve(false);
});
img.src = url;
});
}
isFieldCommercialAndPartnerIsChild(field) {
return (
this.pos.isChildPartner(this.props.partner) &&
+30
View File
@@ -66,3 +66,33 @@ export function random5Chars() {
export function qrCodeSrc(url, { size = 200 } = {}) {
return `/report/barcode/QR/${encodeURIComponent(url)}?width=${size}&height=${size}`;
}
/**
* Loading image is converted to a Promise to allow await when
* loading an image. It resolves to the loaded image if successful,
* else, resolves to false.
*
* [Source](https://stackoverflow.com/questions/45788934/how-to-turn-this-callback-into-a-promise-using-async-await)
*/
export function loadImage(url, options = {}) {
return new Promise((resolve, reject) => {
const img = new Image();
img.addEventListener("load", () => resolve(img));
img.addEventListener("error", () => {
if (options.onError) {
options.onError();
}
reject(new Error(`Failed to load image at ${url}`));
});
img.src = url;
});
}
/**
* Load all images in the given element.
* @param {HTMLElement} el
*/
export function loadAllImages(el) {
const images = el.querySelectorAll("img");
return Promise.all(Array.from(images).map(img => loadImage(img.src)));
}