summaryrefslogtreecommitdiff
path: root/addons/point_of_sale/static/src/js/printers.js
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/point_of_sale/static/src/js/printers.js
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/point_of_sale/static/src/js/printers.js')
-rw-r--r--addons/point_of_sale/static/src/js/printers.js172
1 files changed, 172 insertions, 0 deletions
diff --git a/addons/point_of_sale/static/src/js/printers.js b/addons/point_of_sale/static/src/js/printers.js
new file mode 100644
index 00000000..20ea4454
--- /dev/null
+++ b/addons/point_of_sale/static/src/js/printers.js
@@ -0,0 +1,172 @@
+odoo.define('point_of_sale.Printer', function (require) {
+"use strict";
+
+var Session = require('web.Session');
+var core = require('web.core');
+const { Gui } = require('point_of_sale.Gui');
+var _t = core._t;
+
+// IMPROVEMENT: This is too much. We can get away from this class.
+class PrintResult {
+ constructor({ successful, message }) {
+ this.successful = successful;
+ this.message = message;
+ }
+}
+
+class PrintResultGenerator {
+ IoTActionError() {
+ return new PrintResult({
+ successful: false,
+ message: {
+ title: _t('Connection to IoT Box failed'),
+ body: _t('Please check if the IoT Box is still connected.'),
+ },
+ });
+ }
+ IoTResultError() {
+ return new PrintResult({
+ successful: false,
+ message: {
+ title: _t('Connection to the printer failed'),
+ body: _t('Please check if the printer is still connected.'),
+ },
+ });
+ }
+ Successful() {
+ return new PrintResult({
+ successful: true,
+ });
+ }
+}
+
+var PrinterMixin = {
+ init: function() {
+ this.receipt_queue = [];
+ this.printResultGenerator = new PrintResultGenerator();
+ },
+
+ /**
+ * Add the receipt to the queue of receipts to be printed and process it.
+ * We clear the print queue if printing is not successful.
+ * @param {String} receipt: The receipt to be printed, in HTML
+ * @returns {PrintResult}
+ */
+ print_receipt: async function(receipt) {
+ if (receipt) {
+ this.receipt_queue.push(receipt);
+ }
+ let image, sendPrintResult;
+ while (this.receipt_queue.length > 0) {
+ receipt = this.receipt_queue.shift();
+ image = await this.htmlToImg(receipt);
+ try {
+ sendPrintResult = await this.send_printing_job(image);
+ } catch (error) {
+ // Error in communicating to the IoT box.
+ this.receipt_queue.length = 0;
+ return this.printResultGenerator.IoTActionError();
+ }
+ // rpc call is okay but printing failed because
+ // IoT box can't find a printer.
+ if (!sendPrintResult || sendPrintResult.result === false) {
+ this.receipt_queue.length = 0;
+ return this.printResultGenerator.IoTResultError();
+ }
+ }
+ return this.printResultGenerator.Successful();
+ },
+
+ /**
+ * Generate a jpeg image from a canvas
+ * @param {DOMElement} canvas
+ */
+ process_canvas: function (canvas) {
+ return canvas.toDataURL('image/jpeg').replace('data:image/jpeg;base64,','');
+ },
+
+ /**
+ * Renders the html as an image to print it
+ * @param {String} receipt: The receipt to be printed, in HTML
+ */
+ htmlToImg: function (receipt) {
+ var self = this;
+ $('.pos-receipt-print').html(receipt);
+ var promise = new Promise(function (resolve, reject) {
+ self.receipt = $('.pos-receipt-print>.pos-receipt');
+ html2canvas(self.receipt[0], {
+ onparsed: function(queue) {
+ queue.stack.ctx.height = Math.ceil(self.receipt.outerHeight() + self.receipt.offset().top);
+ },
+ onrendered: function (canvas) {
+ $('.pos-receipt-print').empty();
+ resolve(self.process_canvas(canvas));
+ },
+ letterRendering: true,
+ })
+ });
+ return promise;
+ },
+
+ _onIoTActionResult: function (data){
+ if (this.pos && (data === false || data.result === false)) {
+ Gui.showPopup('ErrorPopup',{
+ 'title': _t('Connection to the printer failed'),
+ 'body': _t('Please check if the printer is still connected.'),
+ });
+ }
+ },
+
+ _onIoTActionFail: function () {
+ if (this.pos) {
+ Gui.showPopup('ErrorPopup',{
+ 'title': _t('Connection to IoT Box failed'),
+ 'body': _t('Please check if the IoT Box is still connected.'),
+ });
+ }
+ },
+}
+
+var Printer = core.Class.extend(PrinterMixin, {
+ init: function (url, pos) {
+ PrinterMixin.init.call(this, arguments);
+ this.pos = pos;
+ this.connection = new Session(undefined, url || 'http://localhost:8069', { use_cors: true});
+ },
+
+ /**
+ * Sends a command to the connected proxy to open the cashbox
+ * (the physical box where you store the cash). Updates the status of
+ * the printer with the answer from the proxy.
+ */
+ open_cashbox: function () {
+ var self = this;
+ return this.connection.rpc('/hw_proxy/default_printer_action', {
+ data: {
+ action: 'cashbox'
+ }
+ }).then(self._onIoTActionResult.bind(self))
+ .guardedCatch(self._onIoTActionFail.bind(self));
+ },
+
+ /**
+ * Sends the printing command the connected proxy
+ * @param {String} img : The receipt to be printed, as an image
+ */
+ send_printing_job: function (img) {
+ return this.connection.rpc('/hw_proxy/default_printer_action', {
+ data: {
+ action: 'print_receipt',
+ receipt: img,
+ }
+ });
+ },
+});
+
+return {
+ PrinterMixin: PrinterMixin,
+ Printer: Printer,
+ PrintResult,
+ PrintResultGenerator,
+}
+});