From ddb9d1a3988c6708c1a1c9c1444664f36ead8a5c Mon Sep 17 00:00:00 2001 From: Luiz Felipe do Divino Date: Thu, 2 Feb 2023 16:28:01 -0300 Subject: [PATCH 1/3] [FIX] Check if fiscal document type selected at pos.config --- .../js/Screens/PaymentScreen/PaymentScreen.js | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/l10n_br_pos/static/src/js/Screens/PaymentScreen/PaymentScreen.js b/l10n_br_pos/static/src/js/Screens/PaymentScreen/PaymentScreen.js index 4877ddedc895..97dd1e3d3410 100644 --- a/l10n_br_pos/static/src/js/Screens/PaymentScreen/PaymentScreen.js +++ b/l10n_br_pos/static/src/js/Screens/PaymentScreen/PaymentScreen.js @@ -41,16 +41,20 @@ odoo.define("l10n_br_pos.PaymentScreen", function (require) { async _isOrderValid(isForceValidate) { var result = super._isOrderValid(isForceValidate); - var order = this.env.pos.get_order(); - const valid_cpf_cnpj = this.check_valid_cpf_cnpj(order); - if (valid_cpf_cnpj) { - result = await order.document_send(this); - return result; + if (this.env.pos.config.simplified_document_type) { + var order = this.env.pos.get_order(); + const valid_cpf_cnpj = this.check_valid_cpf_cnpj(order); + if (valid_cpf_cnpj) { + result = await order.document_send(this); + } else { + Gui.showPopup("ErrorPopup", { + title: _t("Invalid CNPJ / CPF !"), + body: _t("Enter a valid CNPJ / CPF number"), + }); + } } - Gui.showPopup("ErrorPopup", { - title: _t("Invalid CNPJ / CPF !"), - body: _t("Enter a valid CNPJ / CPF number"), - }); + + return result; } }; From f0b69bbc411806c8ca7177fe4829bab8792af584 Mon Sep 17 00:00:00 2001 From: Luiz Felipe do Divino Date: Thu, 2 Feb 2023 16:28:41 -0300 Subject: [PATCH 2/3] [ADD] NFC-e proccess at POS --- l10n_br_pos/static/src/js/models.js | 2 +- l10n_br_pos_nfce/__init__.py | 1 + l10n_br_pos_nfce/__manifest__.py | 1 + l10n_br_pos_nfce/models/__init__.py | 2 + l10n_br_pos_nfce/models/pos_config.py | 13 +++ l10n_br_pos_nfce/models/pos_order.py | 30 ++++++ .../static/src/js/Screens/PaymentScreen.js | 26 ++++++ l10n_br_pos_nfce/static/src/js/models.js | 91 ++++++++++++++++++- l10n_br_pos_nfce/views/pos_config_view.xml | 15 +++ l10n_br_pos_nfce/views/pos_template.xml | 4 + 10 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 l10n_br_pos_nfce/models/__init__.py create mode 100644 l10n_br_pos_nfce/models/pos_config.py create mode 100644 l10n_br_pos_nfce/models/pos_order.py create mode 100644 l10n_br_pos_nfce/static/src/js/Screens/PaymentScreen.js create mode 100644 l10n_br_pos_nfce/views/pos_config_view.xml diff --git a/l10n_br_pos/static/src/js/models.js b/l10n_br_pos/static/src/js/models.js index d7b8d32474ae..7e446b91131e 100644 --- a/l10n_br_pos/static/src/js/models.js +++ b/l10n_br_pos/static/src/js/models.js @@ -384,7 +384,6 @@ odoo.define("l10n_br_pos.models", function (require) { label: "Iniciando Processo de Transmissão", }); this.state_edoc = SITUACAO_EDOC_A_ENVIAR; - this._document_status_popup(); var result = false; var processor_result = null; // Verifica se os campos do documento fiscal são válidos @@ -393,6 +392,7 @@ odoo.define("l10n_br_pos.models", function (require) { // Obtem o responsável pelo envio do documento fiscal; var processor = await this._document_get_processor(); if (processor) { + this._document_status_popup(); // Efetivamente envia o documento fiscal processor_result = await processor.send_order(this); // Valida se foi emitido corretamente e salva os dados do resulto diff --git a/l10n_br_pos_nfce/__init__.py b/l10n_br_pos_nfce/__init__.py index e69de29bb2d1..0650744f6bc6 100644 --- a/l10n_br_pos_nfce/__init__.py +++ b/l10n_br_pos_nfce/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/l10n_br_pos_nfce/__manifest__.py b/l10n_br_pos_nfce/__manifest__.py index 8f6f28392d63..a64b3797165d 100644 --- a/l10n_br_pos_nfce/__manifest__.py +++ b/l10n_br_pos_nfce/__manifest__.py @@ -16,6 +16,7 @@ ], "data": [ "views/pos_template.xml", + "views/pos_config_view.xml", ], "demo": [], "installable": True, diff --git a/l10n_br_pos_nfce/models/__init__.py b/l10n_br_pos_nfce/models/__init__.py new file mode 100644 index 000000000000..234b311eae09 --- /dev/null +++ b/l10n_br_pos_nfce/models/__init__.py @@ -0,0 +1,2 @@ +from . import pos_config +from . import pos_order diff --git a/l10n_br_pos_nfce/models/pos_config.py b/l10n_br_pos_nfce/models/pos_config.py new file mode 100644 index 000000000000..70a7130e2aaa --- /dev/null +++ b/l10n_br_pos_nfce/models/pos_config.py @@ -0,0 +1,13 @@ +# Copyright (C) 2023 Renato Lima - Akretion +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from odoo import api, fields, models + + +class PosConfig(models.Model): + _inherit = "pos.config" + + nfce_document_serie_id = fields.Many2one( + string="Document Serie", + comodel_name="l10n_br_fiscal.document.serie", + ) diff --git a/l10n_br_pos_nfce/models/pos_order.py b/l10n_br_pos_nfce/models/pos_order.py new file mode 100644 index 000000000000..afa574d48943 --- /dev/null +++ b/l10n_br_pos_nfce/models/pos_order.py @@ -0,0 +1,30 @@ +# Copyright (C) 2023 Renato Lima - Akretion +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from odoo import api, fields, models + + +class PosOrder(models.Model): + _inherit = "pos.order" + + def _prepare_invoice_vals(self): + vals = super(PosOrder, self)._prepare_invoice_vals() + + pos_config_id = self.session_id.config_id + + vals.update({ + "document_type_id": pos_config_id.simplified_document_type_id.id, + "fiscal_operation_id": pos_config_id.out_pos_fiscal_operation_id.id, + "ind_pres": "1", + "document_serie_id": pos_config_id.nfce_document_serie_id.id, + "partner_id": pos_config_id.partner_id.id, + }) + + return vals + + def _generate_pos_order_invoice(self): + res = super(PosOrder, self)._generate_pos_order_invoice() + + self.account_move.fiscal_document_id.action_document_confirm() + + return res diff --git a/l10n_br_pos_nfce/static/src/js/Screens/PaymentScreen.js b/l10n_br_pos_nfce/static/src/js/Screens/PaymentScreen.js new file mode 100644 index 000000000000..aadb73a4043b --- /dev/null +++ b/l10n_br_pos_nfce/static/src/js/Screens/PaymentScreen.js @@ -0,0 +1,26 @@ +/* +Copyright (C) 2016-Today KMEE (https://kmee.com.br) +@author: Luis Felipe Mileo +@author: Luiz Felipe do Divino +@author: Gabriel Cardoso + License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +*/ + +odoo.define("l10n_br_pos_nfce.PaymentScreen", function (require) { + "use strict"; + + const PaymentScreen = require("point_of_sale.PaymentScreen"); + const Registries = require("point_of_sale.Registries"); + + const L10nBrPosNFCePaymentScreen = (PaymentScreen) => + class extends PaymentScreen { + toggleIsToInvoice() { + if (!this.document_type === "65") { + super.toggleIsToInvoice(); + } + } + }; + Registries.Component.extend(PaymentScreen, L10nBrPosNFCePaymentScreen); + + return L10nBrPosNFCePaymentScreen; +}); diff --git a/l10n_br_pos_nfce/static/src/js/models.js b/l10n_br_pos_nfce/static/src/js/models.js index f8b6704dd0e0..dfbc49986c45 100644 --- a/l10n_br_pos_nfce/static/src/js/models.js +++ b/l10n_br_pos_nfce/static/src/js/models.js @@ -4,7 +4,96 @@ Copyright (C) 2022-Today KMEE (https://kmee.com.br) License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). */ -odoo.define("l10n_br_pos.models", function () { +odoo.define("l10n_br_pos_nfce.models", function (require) { "use strict"; + const models = require("point_of_sale.models"); + + var _super_order = models.Order.prototype; + models.Order = models.Order.extend({ + initialize: function (attributes, options) { + // CORE METHODS + _super_order.initialize.apply(this, arguments, options); + if (this.document_type === "65") { + this.to_invoice = true; + } + }, + async document_send(component) { + if (this.document_type !== "65") { + return _super_order.document_send.apply(this, arguments); + } + if (!this.get_client()) { + const anonimous_partner = this.pos.db.get_partner_by_id( + this.pos.config.partner_id[0] + ); + this.set_client(anonimous_partner); + component.trigger("close-popup"); + } + + return true; + }, + }); + + var _super_posmodel = models.PosModel.prototype; + models.PosModel = models.PosModel.extend({ + push_and_invoice_order(order) { + if (!this.document_type === "65") { + return _super_posmodel.push_and_invoice_order.call(this); + } + var self = this; + var invoiced = new Promise(function (resolveInvoiced, rejectInvoiced) { + if (!order.get_client()) { + rejectInvoiced({ + code: 400, + message: "Missing Customer", + data: {}, + }); + } else { + var order_id = self.db.add_order(order.export_as_JSON()); + + self.flush_mutex.exec(function () { + var done = new Promise(function (resolveDone, rejectDone) { + // Send the order to the server + // we have a 30 seconds timeout on this push. + // FIXME: if the server takes more than 30 seconds to accept the order, + // the client will believe it wasn't successfully sent, and very bad + // things will happen as a duplicate will be sent next time + // so we must make sure the server detects and ignores duplicated orders + + var transfer = self._flush_orders( + [self.db.get_order(order_id)], + {timeout: 30000, to_invoice: true} + ); + + transfer.catch(function (error) { + rejectInvoiced(error); + rejectDone(); + }); + + transfer.then(function (order_server_id) { + if (order_server_id.length) { + resolveInvoiced(order_server_id); + resolveDone(); + } else { + // The order has been pushed separately in batch when + // the connection came back. + // The user has to go to the backend to print the invoice + rejectInvoiced({ + code: 401, + message: "Backend Invoice", + data: {order: order}, + }); + rejectDone(); + } + }); + + return done; + }); + }); + } + }); + + return invoiced; + }, + }); }); diff --git a/l10n_br_pos_nfce/views/pos_config_view.xml b/l10n_br_pos_nfce/views/pos_config_view.xml new file mode 100644 index 000000000000..fd1a27a581a3 --- /dev/null +++ b/l10n_br_pos_nfce/views/pos_config_view.xml @@ -0,0 +1,15 @@ + + + + + pos.config.form (in l10n_br_pos_nfce) + pos.config + + + + + + + + + diff --git a/l10n_br_pos_nfce/views/pos_template.xml b/l10n_br_pos_nfce/views/pos_template.xml index 0d5aa5a6e846..d5cf1abddd1c 100644 --- a/l10n_br_pos_nfce/views/pos_template.xml +++ b/l10n_br_pos_nfce/views/pos_template.xml @@ -25,6 +25,10 @@