From 6e0bbecd4ed321207da1b37e38528c26139124f1 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 3 Nov 2022 09:51:43 +0100 Subject: [PATCH] [FIX] l10n_es_pos: offline simplified number In 2967122efbbe6445b239d07cb43e874c2647c1ba the behavior of the simplified sequence was change to gather via rpc for each ticket validation. For the case of offline the planned fallback was to set the unique ID given by Odoo. This change fallbacks to the former behavior for that case allowing to obtain the proper sequence even offline. The main drawback will be that concurrent users in the same session could collide their sequence numbers if they happen to be offline. Anyway, that would be easily fixed just by separating such cashiers in separate configs. As a solution to that, a different technique should be used (longpoll for multi sessions or something like that) --- l10n_es_pos/readme/ROADMAP.rst | 9 +++-- l10n_es_pos/static/src/js/PaymentScreen.js | 8 ++--- l10n_es_pos/static/src/js/models.js | 42 ++++++++++++++-------- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/l10n_es_pos/readme/ROADMAP.rst b/l10n_es_pos/readme/ROADMAP.rst index d4aabf87e23..c18448cdb17 100644 --- a/l10n_es_pos/readme/ROADMAP.rst +++ b/l10n_es_pos/readme/ROADMAP.rst @@ -1,2 +1,7 @@ -No se comprueba el límite en operaciones separadas para un mismo cliente, algo -que Hacienda proscribe. +* No se comprueba el límite en operaciones separadas para un mismo cliente, algo + que Hacienda proscribe. +* El soporte para usuarios concurrentes sobre una misma sesión es limitado y solo es + fiable si ambos puestos están online. En el caso de que cualquiera de ellos estuviese + offline, se correría el riesgo de solapar la secuencia de factura simplificada. Se + recomienda que en estos casos se añada mejor una configuración de punto de venta + adicional. diff --git a/l10n_es_pos/static/src/js/PaymentScreen.js b/l10n_es_pos/static/src/js/PaymentScreen.js index eb3f84ebac2..a4c15c5ab98 100644 --- a/l10n_es_pos/static/src/js/PaymentScreen.js +++ b/l10n_es_pos/static/src/js/PaymentScreen.js @@ -12,12 +12,12 @@ odoo.define("l10n_es_pos.PaymentScreen", function (require) { const L10nEsPosPaymentScreen = (PaymentScreen) => class extends PaymentScreen { - async validateOrder(isForceValidate) { - var below_limit = + async _finalizeValidation() { + const below_limit = this.currentOrder.get_total_with_tax() <= this.env.pos.config.l10n_es_simplified_invoice_limit; if (this.env.pos.config.iface_l10n_es_simplified_invoice) { - var order = this.currentOrder; + const order = this.currentOrder; if (below_limit && !order.to_invoice) { await order.set_simple_inv_number(); } else { @@ -25,7 +25,7 @@ odoo.define("l10n_es_pos.PaymentScreen", function (require) { order.to_invoice = true; } } - super.validateOrder(isForceValidate); + super._finalizeValidation(); } }; diff --git a/l10n_es_pos/static/src/js/models.js b/l10n_es_pos/static/src/js/models.js index bc3d1ee64d3..d8593a0f7f9 100644 --- a/l10n_es_pos/static/src/js/models.js +++ b/l10n_es_pos/static/src/js/models.js @@ -13,11 +13,14 @@ odoo.define("l10n_es_pos.models", function (require) { initialize: function () { pos_super.initialize.apply(this, arguments); this.pushed_simple_invoices = []; - - this.own_simplified_invoice_prefix = ""; // Unique UUID return this; }, get_simple_inv_next_number: function () { + // If we had pending orders to sync we want to avoid getting the next number + // from the DB as we'd be ovelaping the sequence. + if (this.env.pos.db.get_orders().length) { + return Promise.reject({message: {code: "pending_orders"}}); + } return this.rpc({ method: "search_read", domain: [["id", "=", this.config_id]], @@ -70,24 +73,33 @@ odoo.define("l10n_es_pos.models", function (require) { return total; }, set_simple_inv_number: function () { - const self = this; return this.pos .get_simple_inv_next_number() - .then(function (configs) { - const config = configs[0]; - self.pos.config.l10n_es_simplified_invoice_number = + .then(([config]) => { + // We'll get the number from DB only when we're online. Otherwise + // the sequence will run on the client side until the orders are + // synced. + this.pos.config.l10n_es_simplified_invoice_number = config.l10n_es_simplified_invoice_number; + }) + .catch((error) => { + // We'll only consider network errors (XmlHttpRequestError) or + // forced rejections to resync invoice numbers + if ( + error.message && + ![-32098, "pending_orders"].includes(error.message.code) + ) { + throw error; + } + }) + .finally(() => { const simplified_invoice_number = - self.pos.config.l10n_es_simplified_invoice_prefix + - self.pos.get_padding_simple_inv( - config.l10n_es_simplified_invoice_number + this.pos.config.l10n_es_simplified_invoice_prefix + + this.pos.get_padding_simple_inv( + this.pos.config.l10n_es_simplified_invoice_number ); - self.l10n_es_unique_id = simplified_invoice_number; - self.is_simplified_invoice = true; - }) - .catch(function () { - self.l10n_es_unique_id = self.uid; - self.is_simplified_invoice = true; + this.l10n_es_unique_id = simplified_invoice_number; + this.is_simplified_invoice = true; }); }, get_base_by_tax: function () {