From 1067cbf02d7bab763f753ea7449adff6d977c322 Mon Sep 17 00:00:00 2001 From: Felipe Paloschi Date: Tue, 3 Nov 2020 17:42:39 -0300 Subject: [PATCH 1/3] Change NFCe emission flow to avoid paid POS Orders with failed NFCe --- br_account/models/account_tax.py | 1 - br_point_of_sale/models/invoice_eletronic.py | 399 +++++++++++-- br_point_of_sale/models/pos_order.py | 575 +++++++++---------- br_point_of_sale/static/src/js/main.js | 42 +- br_point_of_sale/static/src/js/models.js | 1 - br_point_of_sale/static/src/js/screens.js | 35 +- 6 files changed, 691 insertions(+), 362 deletions(-) diff --git a/br_account/models/account_tax.py b/br_account/models/account_tax.py index 6b650ee8b..e3c98de6c 100644 --- a/br_account/models/account_tax.py +++ b/br_account/models/account_tax.py @@ -376,7 +376,6 @@ def compute_all(self, price_unit, currency=None, quantity=1.0, price_unit, currency, quantity, product, partner) res['price_without_tax'] = round(price_unit * quantity, 2) return res - price_base = price_unit * quantity taxes = self.sum_taxes(price_base) total_included = total_excluded = price_base diff --git a/br_point_of_sale/models/invoice_eletronic.py b/br_point_of_sale/models/invoice_eletronic.py index 87040fb2e..f05b87994 100644 --- a/br_point_of_sale/models/invoice_eletronic.py +++ b/br_point_of_sale/models/invoice_eletronic.py @@ -3,64 +3,78 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import re +import logging + +from datetime import datetime +from random import SystemRandom from odoo import api, fields, models +_logger = logging.getLogger(__name__) + class InvoiceEletronic(models.Model): - _inherit = 'invoice.eletronic' + _inherit = "invoice.eletronic" pos_order_id = fields.Many2one( - 'pos.order', string=u'Pedido POS', readonly=True) - customer_cpf = fields.Char(string='CPF') + "pos.order", string="Pedido POS", readonly=True + ) + pos_reference = fields.Char(string="POS Reference") + customer_cpf = fields.Char(string="CPF") def _get_variables_msg(self): variables = super(InvoiceEletronic, self)._get_variables_msg() - variables.update({ - 'order': self.pos_order_id, - 'eletronic': self - }) + variables.update({"order": self.pos_order_id, "eletronic": self}) return variables @api.multi def _prepare_eletronic_invoice_values(self): - vals = super(InvoiceEletronic, self)\ - ._prepare_eletronic_invoice_values() - if self.model != '65': + vals = super( + InvoiceEletronic, self + )._prepare_eletronic_invoice_values() + if self.model != "65": return vals - vals['pag'][0]['tPag'] = self.metodo_pagamento - vals['pag'][0]['vPag'] = "%.02f" % self.valor_pago - vals['pag'][0]['vTroco'] = "%.02f" % self.troco or '0.00' + vals["pag"][0]["tPag"] = self.metodo_pagamento + vals["pag"][0]["vPag"] = "%.02f" % self.valor_pago + vals["pag"][0]["vTroco"] = "%.02f" % self.troco or "0.00" if self.customer_cpf: - vals.update({ - 'dest': { - 'tipo': 'person', - 'cnpj_cpf': re.sub('[^0-9]', '', self.customer_cpf), - 'xNome': u'NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO -\ - SEM VALOR FISCAL' if self.ambiente == 'homologacao' else None, - 'enderDest': None, - 'indIEDest': '9' - } - }) + vals.update( + { + "dest": { + "tipo": "person", + "cnpj_cpf": re.sub("[^0-9]", "", self.customer_cpf), + "xNome": u"NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO -\ + SEM VALOR FISCAL" + if self.ambiente == "homologacao" + else None, + "enderDest": None, + "indIEDest": "9", + } + } + ) return vals def _compute_legal_information(self): super(InvoiceEletronic, self)._compute_legal_information - fiscal_ids = self.pos_order_id.fiscal_position_id.\ - fiscal_observation_ids.filtered(lambda x: x.tipo == 'fiscal') - obs_ids = self.pos_order_id.fiscal_position_id.\ - fiscal_observation_ids.filtered(lambda x: x.tipo == 'observacao') + fiscal_ids = self.pos_order_id.fiscal_position_id.fiscal_observation_ids.filtered( + lambda x: x.tipo == "fiscal" + ) + obs_ids = self.pos_order_id.fiscal_position_id.fiscal_observation_ids.filtered( + lambda x: x.tipo == "observacao" + ) - prod_obs_ids = self.env['br_account.fiscal.observation'].browse() + prod_obs_ids = self.env["br_account.fiscal.observation"].browse() for item in self.pos_order_id.lines: prod_obs_ids |= item.product_id.fiscal_observation_ids - fiscal_ids |= prod_obs_ids.filtered(lambda x: x.tipo == 'fiscal') - obs_ids |= prod_obs_ids.filtered(lambda x: x.tipo == 'observacao') + fiscal_ids |= prod_obs_ids.filtered(lambda x: x.tipo == "fiscal") + obs_ids |= prod_obs_ids.filtered(lambda x: x.tipo == "observacao") fiscal = self._compute_msg(fiscal_ids) + ( - self.invoice_id.fiscal_comment or '') + self.invoice_id.fiscal_comment or "" + ) observacao = self._compute_msg(obs_ids) + ( - self.invoice_id.comment or '') + self.invoice_id.comment or "" + ) if self.informacoes_legais: self.informacoes_legais += fiscal else: @@ -69,3 +83,324 @@ def _compute_legal_information(self): self.informacoes_complementares += observacao else: self.informacoes_complementares = observacao + + def create_from_ui(self, orders): + # Keep only new orders + submitted_references = [o["name"] for o in orders] + existing_edocs = self.search( + [("pos_reference", "in", submitted_references)] + ) + + error_edocs = self.env["invoice.eletronic"] + done_edocs = self.env["invoice.eletronic"] + + for edoc in existing_edocs: + if edoc.state in ["error", "cancel"]: + error_edocs += edoc + else: + done_edocs += edoc + + existing_references = set([o.pos_reference for o in done_edocs]) + + edocs_to_save = [ + o for o in orders if o["name"] not in existing_references + ] + + edoc_ids = done_edocs.ids or [] + error_edocs.unlink() + + for edoc_data in edocs_to_save: + if edoc_data.get("to_invoice"): + continue + edoc_id = self.create(self._prepare_edoc_fields(edoc_data)) + edoc_id.validate_invoice() + edoc_id.action_post_validate() + edoc_ids.append(edoc_id.id) + + return edoc_ids + + def get_approximate_taxes(self, product, price): + ncm = product.fiscal_classification_id + + tributos_estimados_federais = price * (ncm.federal_nacional / 100) + tributos_estimados_estaduais = price * (ncm.estadual_imposto / 100) + tributos_estimados_municipais = price * (ncm.municipal_imposto / 100) + + return "%.02f" % ( + tributos_estimados_federais + + tributos_estimados_estaduais + + tributos_estimados_municipais + ) + + def get_total_tributes(self, eletronic_item_values): + trib = [] + for item in eletronic_item_values: + val = item[2].get("tributos_estimados") + if val: + trib.append(float(val)) + return sum(trib) + + def _prepare_tax_context(self, vals): + return { + "icms_st_aliquota_mva": vals.get("icms_st_aliquota_mva"), + "icms_aliquota_reducao_base": vals.get( + "icms_aliquota_reducao_base" + ), + "icms_st_aliquota_reducao_base": vals.get( + "icms_st_aliquota_reducao_base" + ), + "icms_base_calculo": vals.get("icms_base_calculo"), + "pis_base_calculo": vals.get("pis_base_calculo"), + "cofins_base_calculo": vals.get("cofins_base_calculo"), + } + + def _prepare_edoc_item_fields( + self, line, fiscal_pos, partner, company, pricelist + ): + if not line: + return + line_vals = line[2] + product = self.env["product.product"].browse( + line_vals.get("product_id") + ) + tax_values = fiscal_pos.map_tax_extra_values( + company, product, partner + ) + + empty = self.env["account.tax"] + tax_ids = ( + tax_values.get("tax_icms_id", empty) + + tax_values.get("tax_icms_st_id", empty) + + tax_values.get("tax_ipi_id", empty) + + tax_values.get("tax_pis_id", empty) + + tax_values.get("tax_cofins_id", empty) + + tax_values.get("tax_ii_id", empty) + + tax_values.get("tax_issqn_id", empty) + ) + + vals = { + "name": line_vals.get("name"), + "product_id": product.id, + "tipo_produto": product.fiscal_type, + "cfop": tax_values["cfop_id"].code + if tax_values.get("cfop_id", False) + else False, + "cest": product.cest + or product.fiscal_classification_id.cest + or "", + "uom_id": product.uom_id.id, + "ncm": product.fiscal_classification_id.code, + "quantidade": line_vals.get("qty"), + "preco_unitario": line_vals.get("price_unit"), + "valor_bruto": line_vals.get("price_subtotal_incl"), + "valor_liquido": line_vals.get("price_subtotal"), + "origem": product.origin, + "tributos_estimados": self.get_approximate_taxes( + product, line_vals.get("price_subtotal") + ), + # - ICMS - + "icms_cst": tax_values.get("icms_cst_normal", False) + or tax_values.get("icms_csosn_simples", False), + "icms_tipo_base": "3", + "icms_aliquota_reducao_base": tax_values.get( + "icms_aliquota_reducao_base", False + ), + # - ICMS ST - + "icms_st_aliquota": 0, + "icms_st_aliquota_mva": 0, + "icms_st_aliquota_reducao_base": tax_values.get( + "icms_st_aliquota_reducao_base", False + ), + "icms_st_base_calculo": 0, + "icms_st_valor": 0, + # - Simples Nacional - + "icms_aliquota_credito": 0, + "icms_valor_credito": 0, + # - II - + "ii_base_calculo": 0, + "ii_valor_despesas": 0, + "ii_valor": 0, + "ii_valor_iof": 0, + # - IPI - + "ipi_cst": tax_values.get("ipi_cst", False), + # - PIS - + "pis_cst": tax_values.get("pis_cst", False), + # - COFINS - + "cofins_cst": tax_values.get("cofins_cst", False), + # - ISSQN - + "issqn_codigo": 0, + "issqn_aliquota": 0, + "issqn_base_calculo": 0, + "issqn_valor": 0, + "issqn_valor_retencao": 0.00, + } + + taxes_ids = tax_ids.filtered( + lambda tax: tax.company_id.id == company.id + ) + if fiscal_pos: + taxes_ids = fiscal_pos.map_tax(taxes_ids, product, partner) + price = line_vals.get("price_unit") * ( + 1 - (line_vals.get("discount") or 0.0) / 100.0 + ) + taxes = {"taxes": []} + if taxes_ids: + ctx = self._prepare_tax_context(vals) + taxes_ids = taxes_ids.with_context(**ctx) + taxes = taxes_ids.compute_all( + price, + pricelist.currency_id, + line_vals.get("qty"), + product=product, + partner=partner or False, + ) + for tax in taxes["taxes"]: + tax_id = self.env["account.tax"].browse(tax["id"]) + if tax_id.domain == "icms": + vals.update( + { + "icms_aliquota": tax_id.amount, + "icms_base_calculo": tax.get("base", 0.00), + "icms_valor": tax.get("amount", 0.00), + } + ) + if tax_id.domain == "ipi": + vals.update( + { + "ipi_aliquota": tax_id.amount, + "ipi_base_calculo": tax.get("base", 0.00), + "ipi_valor": tax.get("amount", 0.00), + } + ) + if tax_id.domain == "pis": + vals.update( + { + "pis_aliquota": tax_id.amount, + "pis_base_calculo": tax.get("base", 0.00), + "pis_valor": tax.get("amount", 0.00), + } + ) + if tax_id.domain == "cofins": + vals.update( + { + "cofins_aliquota": tax_id.amount, + "cofins_base_calculo": tax.get("base", 0.00), + "cofins_valor": tax.get("amount", 0.00), + } + ) + line[2] = vals + return line + + def _prepare_edoc_fields(self, ui_order): + fiscal_position = self.env["account.fiscal.position"].browse( + ui_order["fiscal_position_id"] + ) + partner = self.env["res.partner"].browse(ui_order["partner_id"]) + company = self.env.user.company_id + pricelist = self.env["product.pricelist"].browse( + ui_order["pricelist_id"] + ) + pos_session = self.env["pos.session"].browse( + ui_order["pos_session_id"] + ) + + journal = self.env["account.journal"].browse( + ui_order.get("statement_ids")[0][2].get("journal_id") + ) + + if pos_session.sequence_number <= ui_order["sequence_number"]: + pos_session.write( + {"sequence_number": ui_order["sequence_number"] + 1} + ) + pos_session.refresh() + + numero = ( + fiscal_position.product_serie_id.internal_sequence_id.next_by_id() + ) + + vals = { + "pos_reference": ui_order["name"], + "code": ui_order.get("sequence_number"), + "name": u"Documento Eletrônico: nº %d" + % ui_order.get("sequence_number"), + "company_id": company.id, + "schedule_user_id": ui_order.get("user_id"), + "date_order": ui_order["creation_date"], + "pricelist_id": ui_order["pricelist_id"], + "state": "draft", + "tipo_operacao": "saida", + "model": "65", + "ind_dest": "1", + "ind_ie_dest": "9", + "ambiente": "homologacao" + if company.tipo_ambiente == "2" + else "producao", + "serie": fiscal_position.product_serie_id.id, + "numero": numero, + "numero_nfe": numero, + "numero_controle": "".join( + [str(SystemRandom().randrange(9)) for i in range(8)] + ), + "data_emissao": datetime.now(), + "data_fatura": datetime.now(), + "finalidade_emissao": "1", + "partner_id": ui_order.get("partner_id"), + "customer_cpf": ui_order.get("customer_cpf", ""), + "payment_term_id": None, + "fiscal_position_id": fiscal_position.id, + "ind_final": fiscal_position.ind_final, + "ind_pres": fiscal_position.ind_pres, + "metodo_pagamento": journal.metodo_pagamento, + "troco": abs( + sum( + payment[2].get("amount") + for payment in ui_order.get("statement_ids") + if payment[2].get("amount") < 0 + ) + ), + "valor_pago": sum( + payment[2].get("amount") + for payment in ui_order.get("statement_ids") + if payment[2].get("amount") > 0 + ), + "eletronic_item_ids": [ + self._prepare_edoc_item_fields( + line, fiscal_position, partner, company, pricelist + ) + for line in ui_order["lines"] + ] + if ui_order["lines"] + else False, + } + + base_icms = 0 + for pos_line in vals.get("eletronic_item_ids"): + base_icms += pos_line[2].get("icms_base_calculo") + + vals.update( + { + "valor_estimado_tributos": self.get_total_tributes( + vals.get("eletronic_item_ids") + ), + "valor_icms": sum( + line[2].get("icms_valor", 0) + for line in vals.get("eletronic_item_ids") + ), + "valor_pis": sum( + line[2].get("pis_valor", 0) + for line in vals.get("eletronic_item_ids") + ), + "valor_cofins": sum( + line[2].get("cofins_valor", 0) + for line in vals.get("eletronic_item_ids") + ), + "valor_ii": 0, + "valor_bruto": ui_order["amount_total"] + - ui_order["amount_tax"], + "valor_desconto": ui_order["amount_tax"], + "valor_final": ui_order["amount_total"], + "valor_bc_icms": base_icms, + "valor_bc_icmsst": 0, + } + ) + return vals diff --git a/br_point_of_sale/models/pos_order.py b/br_point_of_sale/models/pos_order.py index f33fa68ef..958053543 100644 --- a/br_point_of_sale/models/pos_order.py +++ b/br_point_of_sale/models/pos_order.py @@ -10,38 +10,48 @@ class PosOrder(models.Model): - _inherit = 'pos.order' + _inherit = "pos.order" @api.multi def _compute_nfe_number(self): for item in self: - docs = self.env['invoice.eletronic'].search( - [('pos_order_id', '=', item.id)]) + docs = self.env["invoice.eletronic"].search( + [("pos_order_id", "=", item.id)] + ) if docs: item.nfe_number = docs[0].numero item.nfe_exception_number = docs[0].numero - item.nfe_exception = (docs[0].state in ('error', 'denied')) - item.sending_nfe = docs[0].state == 'draft' - item.nfe_status = '%s - %s' % ( - docs[0].codigo_retorno, docs[0].mensagem_retorno) + item.nfe_exception = docs[0].state in ("error", "denied") + item.sending_nfe = docs[0].state == "draft" + item.nfe_status = "%s - %s" % ( + docs[0].codigo_retorno, + docs[0].mensagem_retorno, + ) ambiente_nfe = fields.Selection( - string="Ambiente NFe", related="company_id.tipo_ambiente", - readonly=True) + string="Ambiente NFe", + related="company_id.tipo_ambiente", + readonly=True, + ) sending_nfe = fields.Boolean( - string="Enviando NFe?", compute="_compute_nfe_number") + string="Enviando NFe?", compute="_compute_nfe_number" + ) nfe_exception = fields.Boolean( - string="Problemas na NFe?", compute="_compute_nfe_number") + string="Problemas na NFe?", compute="_compute_nfe_number" + ) nfe_status = fields.Char( - string="Mensagem NFe", compute="_compute_nfe_number") + string="Mensagem NFe", compute="_compute_nfe_number" + ) nfe_number = fields.Integer( - string=u"Número NFe", compute="_compute_nfe_number") + string=u"Número NFe", compute="_compute_nfe_number" + ) nfe_exception_number = fields.Integer( - string=u"Número NFe", compute="_compute_nfe_number") + string=u"Número NFe", compute="_compute_nfe_number" + ) numero_controle = fields.Integer() customer_cpf = fields.Char(string="CPF cliente") - @api.depends('statement_ids', 'lines') + @api.depends("statement_ids", "lines") def _compute_amount_taxes(self): for order in self: order.total_icms = sum(line.valor_icms for line in order.lines) @@ -51,402 +61,343 @@ def _compute_amount_taxes(self): @api.model def _order_fields(self, ui_order): res = super(PosOrder, self)._order_fields(ui_order) - res.update({'customer_cpf': ui_order['customer_cpf'] or False}) + res.update({"customer_cpf": ui_order["customer_cpf"] or False}) return res def action_preview_danfe(self): - docs = self.env['invoice.eletronic'].search( - [('pos_order_id', '=', self.id)]) + docs = self.env["invoice.eletronic"].search( + [("pos_order_id", "=", self.id)] + ) if not docs: - raise UserError(u'Não existe um E-Doc relacionado à este pedido') + raise UserError(u"Não existe um E-Doc relacionado à este pedido") for doc in docs: - if doc.state == 'draft': + if doc.state == "draft": raise UserError( - 'Nota Fiscal de consumidor na fila de envio. Aguarde!') + "Nota Fiscal de consumidor na fila de envio. Aguarde!" + ) - action = self.env.ref('br_nfe.report_br_nfe_danfe').report_action(docs) + action = self.env.ref("br_nfe.report_br_nfe_danfe").report_action( + docs + ) return action @api.model def _process_order(self, pos_order): - num_controle = int(''.join([str(SystemRandom().randrange(9)) - for i in range(8)])) + num_controle = int( + "".join([str(SystemRandom().randrange(9)) for i in range(8)]) + ) res = super(PosOrder, self)._process_order(pos_order) res.numero_controle = str(num_controle) + edoc_id = self.env["invoice.eletronic"].search( + [ + ("pos_reference", "=", res.pos_reference), + ("state", "=", "done"), + ], + limit=1, + ) + + if edoc_id: + edoc_id.write({'pos_order_id': res.id}) + if not res.fiscal_position_id: - res.fiscal_position_id = \ + res.fiscal_position_id = ( res.session_id.config_id.default_fiscal_position_id.id + ) - res.numero = \ - res.fiscal_position_id.product_serie_id.\ - internal_sequence_id.next_by_id() + res.numero = ( + res.fiscal_position_id.product_serie_id.internal_sequence_id.next_by_id() + ) for line in res.lines: values = line.order_id.fiscal_position_id.map_tax_extra_values( - line.company_id, line.product_id, - line.order_id.partner_id) - - empty = self.env['account.tax'].browse() - tax_ids = values.get('tax_icms_id', empty) | \ - values.get('tax_icms_st_id', empty) | \ - values.get('tax_icms_inter_id', empty) | \ - values.get('tax_icms_intra_id', empty) | \ - values.get('tax_icms_fcp_id', empty) | \ - values.get('tax_ipi_id', empty) | \ - values.get('tax_pis_id', empty) | \ - values.get('tax_cofins_id', empty) | \ - values.get('tax_ii_id', empty) | \ - values.get('tax_issqn_id', empty) + line.company_id, line.product_id, line.order_id.partner_id + ) + + empty = self.env["account.tax"].browse() + tax_ids = ( + values.get("tax_icms_id", empty) + | values.get("tax_icms_st_id", empty) + | values.get("tax_icms_inter_id", empty) + | values.get("tax_icms_intra_id", empty) + | values.get("tax_icms_fcp_id", empty) + | values.get("tax_ipi_id", empty) + | values.get("tax_pis_id", empty) + | values.get("tax_cofins_id", empty) + | values.get("tax_ii_id", empty) + | values.get("tax_issqn_id", empty) + ) other_taxes = line.tax_ids.filtered(lambda x: not x.domain) tax_ids |= other_taxes - line.update({ - 'tax_ids': [(6, None, [x.id for x in tax_ids if x])] - }) + line.update( + {"tax_ids": [(6, None, [x.id for x in tax_ids if x])]} + ) for key, value in values.items(): if value and key in line._fields: line.update({key: value}) - foo = self._prepare_edoc_vals(res) - eletronic = self.env['invoice.eletronic'].create(foo) - eletronic.validate_invoice() - eletronic.action_post_validate() return res - def _prepare_edoc_item_vals(self, pos_line): - vals = { - 'name': pos_line.name, - 'product_id': pos_line.product_id.id, - 'tipo_produto': pos_line.product_id.fiscal_type, - 'cfop': pos_line.cfop_id.code, - 'cest': pos_line.product_id.cest or - pos_line.product_id.fiscal_classification_id.cest or '', - 'uom_id': pos_line.product_id.uom_id.id, - 'ncm': pos_line.product_id.fiscal_classification_id.code, - 'quantidade': pos_line.qty, - 'preco_unitario': pos_line.price_unit, - 'valor_bruto': pos_line.price_subtotal_incl, - 'valor_liquido': pos_line.price_subtotal, - 'origem': pos_line.product_id.origin, - 'tributos_estimados': pos_line.get_approximate_taxes(), - # - ICMS - - 'icms_cst': pos_line.icms_cst_normal or \ - pos_line.icms_csosn_simples, - 'icms_aliquota': pos_line.aliquota_icms, - 'icms_tipo_base': '3', - 'icms_aliquota_reducao_base': pos_line.icms_aliquota_reducao_base, - 'icms_base_calculo': pos_line.base_icms, - 'icms_valor': pos_line.valor_icms, - # - ICMS ST - - 'icms_st_aliquota': 0, - 'icms_st_aliquota_mva': 0, - 'icms_st_aliquota_reducao_base': pos_line.\ - icms_st_aliquota_reducao_base, - 'icms_st_base_calculo': 0, - 'icms_st_valor': 0, - # - Simples Nacional - - 'icms_aliquota_credito': 0, - 'icms_valor_credito': 0, - # - II - - 'ii_base_calculo': 0, - 'ii_valor_despesas': 0, - 'ii_valor': 0, - 'ii_valor_iof': 0, - # - IPI - - 'ipi_cst': pos_line.ipi_cst, - 'ipi_aliquota': pos_line.aliquota_ipi, - 'ipi_base_calculo': pos_line.base_ipi, - 'ipi_valor': pos_line.valor_ipi, - # - PIS - - 'pis_cst': pos_line.pis_cst, - 'pis_aliquota': pos_line.aliquota_pis, - 'pis_base_calculo': pos_line.base_pis, - 'pis_valor': pos_line.valor_pis, - # - COFINS - - 'cofins_cst': pos_line.cofins_cst, - 'cofins_aliquota': pos_line.aliquota_cofins, - 'cofins_base_calculo': pos_line.base_cofins, - 'cofins_valor': pos_line.valor_cofins, - # - ISSQN - - 'issqn_codigo': 0, - 'issqn_aliquota': 0, - 'issqn_base_calculo': 0, - 'issqn_valor': 0, - 'issqn_valor_retencao': 0.00, - - } - return vals - - def _prepare_edoc_vals(self, pos): - vals = { - 'pos_order_id': pos.id, - 'code': pos.sequence_number, - 'name': u'Documento Eletrônico: nº %d' % pos.sequence_number, - 'company_id': pos.company_id.id, - 'schedule_user_id': pos.user_id.id, - 'state': 'draft', - 'tipo_operacao': 'saida', - 'model': '65', - 'ind_dest': '1', - 'ind_ie_dest': '9', - 'ambiente': 'homologacao' - if pos.company_id.tipo_ambiente == '2' else 'producao', - 'serie': pos.fiscal_position_id.product_serie_id.id, - 'numero': pos.numero, - 'numero_nfe': pos.numero, - 'numero_controle': pos.numero_controle, - 'data_emissao': datetime.now(), - 'data_fatura': datetime.now(), - 'finalidade_emissao': '1', - 'partner_id': pos.partner_id.id, - 'customer_cpf': pos.customer_cpf, - 'payment_term_id': None, - 'fiscal_position_id': pos.fiscal_position_id.id, - 'ind_final': pos.fiscal_position_id.ind_final, - 'ind_pres': pos.fiscal_position_id.ind_pres, - 'metodo_pagamento': pos.statement_ids[0].journal_id. - metodo_pagamento, - 'troco': abs(sum( - payment.amount for payment in - pos.statement_ids if payment.amount < 0)), - 'valor_pago': sum( - payment.amount for payment in - pos.statement_ids if payment.amount > 0) - } - - base_icms = 0 - base_cofins = 0 - base_pis = 0 - eletronic_items = [] - for pos_line in pos.lines: - eletronic_items.append((0, 0, - self._prepare_edoc_item_vals(pos_line))) - base_icms += pos_line.base_icms - base_pis += pos_line.base_pis - base_cofins += pos_line.base_cofins - - vals['valor_estimado_tributos'] = \ - self.get_total_tributes(eletronic_items) - vals['eletronic_item_ids'] = eletronic_items - vals['valor_icms'] = pos.total_icms - vals['valor_pis'] = pos.total_pis - vals['valor_cofins'] = pos.total_cofins - vals['valor_ii'] = 0 - vals['valor_bruto'] = pos.amount_total - pos.amount_tax - vals['valor_desconto'] = pos.amount_tax - vals['valor_final'] = pos.amount_total - vals['valor_bc_icms'] = base_icms - vals['valor_bc_icmsst'] = 0 - return vals - - def get_total_tributes(self, values): - trib = [] - for item in values: - val = item[2].get('tributos_estimados') - if val: - trib.append(float(val)) - return sum(trib) - @api.multi def _compute_total_edocs(self): for item in self: - item.total_edocs = self.env['invoice.eletronic'].search_count( - [('pos_order_id', '=', item.id)]) + item.total_edocs = self.env["invoice.eletronic"].search_count( + [("pos_order_id", "=", item.id)] + ) - total_edocs = fields.Integer(string="Total NFe", - compute=_compute_total_edocs) + total_edocs = fields.Integer( + string="Total NFe", compute=_compute_total_edocs + ) @api.multi def action_view_edocs(self): if self.total_edocs == 1: - edoc = self.env['invoice.eletronic'].search( - [('pos_order_id', '=', self.id)], limit=1) - dummy, act_id = self.env['ir.model.data'].get_object_reference( - 'br_account_einvoice', 'action_sped_base_eletronic_doc') - dummy, view_id = self.env['ir.model.data'].get_object_reference( - 'br_account_einvoice', 'br_account_invoice_eletronic_form') - vals = self.env['ir.actions.act_window'].browse(act_id).read()[0] - vals['view_id'] = (view_id, u'sped.eletronic.doc.form') - vals['views'][1] = (view_id, u'form') - vals['views'] = [vals['views'][1], vals['views'][0]] - vals['res_id'] = edoc.id - vals['search_view'] = False + edoc = self.env["invoice.eletronic"].search( + [("pos_order_id", "=", self.id)], limit=1 + ) + dummy, act_id = self.env["ir.model.data"].get_object_reference( + "br_account_einvoice", "action_sped_base_eletronic_doc" + ) + dummy, view_id = self.env["ir.model.data"].get_object_reference( + "br_account_einvoice", "br_account_invoice_eletronic_form" + ) + vals = self.env["ir.actions.act_window"].browse(act_id).read()[0] + vals["view_id"] = (view_id, u"sped.eletronic.doc.form") + vals["views"][1] = (view_id, u"form") + vals["views"] = [vals["views"][1], vals["views"][0]] + vals["res_id"] = edoc.id + vals["search_view"] = False return vals else: - dummy, act_id = self.env['ir.model.data'].get_object_reference( - 'br_account_einvoice', 'action_sped_base_eletronic_doc') - vals = self.env['ir.actions.act_window'].browse(act_id).read()[0] + dummy, act_id = self.env["ir.model.data"].get_object_reference( + "br_account_einvoice", "action_sped_base_eletronic_doc" + ) + vals = self.env["ir.actions.act_window"].browse(act_id).read()[0] return vals @api.model def _amount_line_tax(self, line, fiscal_position_id): taxes = line.tax_ids.filtered( - lambda t: t.company_id.id == line.order_id.company_id.id) + lambda t: t.company_id.id == line.order_id.company_id.id + ) if fiscal_position_id: taxes = fiscal_position_id.map_tax( - taxes, line.product_id, line.order_id.partner_id) + taxes, line.product_id, line.order_id.partner_id + ) price = line.price_unit * (1 - (line.discount or 0.0) / 100.0) taxes = taxes.compute_all( - price, line.order_id.pricelist_id.currency_id, line.qty, + price, + line.order_id.pricelist_id.currency_id, + line.qty, product=line.product_id, - partner=line.order_id.partner_id or False) - return taxes['total_included'] - taxes['total_excluded'] + partner=line.order_id.partner_id or False, + ) + return taxes["total_included"] - taxes["total_excluded"] total_icms = fields.Float( - string='ICMS', compute=_compute_amount_taxes, store=True) + string="ICMS", compute=_compute_amount_taxes, store=True + ) total_pis = fields.Float( - string='PIS', compute=_compute_amount_taxes, store=True) + string="PIS", compute=_compute_amount_taxes, store=True + ) total_cofins = fields.Float( - string='COFINS', compute=_compute_amount_taxes, store=True) + string="COFINS", compute=_compute_amount_taxes, store=True + ) class PosOrderLine(models.Model): - _inherit = 'pos.order.line' + _inherit = "pos.order.line" def _prepare_tax_context(self): return { - 'icms_st_aliquota_mva': self.icms_st_aliquota_mva, - 'icms_aliquota_reducao_base': self.icms_aliquota_reducao_base, - 'icms_st_aliquota_reducao_base': - self.icms_st_aliquota_reducao_base, - 'icms_base_calculo': self.base_icms, - 'pis_base_calculo': self.base_pis, - 'cofins_base_calculo': self.base_cofins, + "icms_st_aliquota_mva": self.icms_st_aliquota_mva, + "icms_aliquota_reducao_base": self.icms_aliquota_reducao_base, + "icms_st_aliquota_reducao_base": self.icms_st_aliquota_reducao_base, + "icms_base_calculo": self.base_icms, + "pis_base_calculo": self.base_pis, + "cofins_base_calculo": self.base_cofins, } def get_approximate_taxes(self): ncm = self.product_id.fiscal_classification_id tributos_estimados_federais = self.price_subtotal * ( - ncm.federal_nacional / 100) - tributos_estimados_estaduais = \ - self.price_subtotal * (ncm.estadual_imposto / 100) - tributos_estimados_municipais = \ - self.price_subtotal * (ncm.municipal_imposto / 100) + ncm.federal_nacional / 100 + ) + tributos_estimados_estaduais = self.price_subtotal * ( + ncm.estadual_imposto / 100 + ) + tributos_estimados_municipais = self.price_subtotal * ( + ncm.municipal_imposto / 100 + ) return "%.02f" % ( - tributos_estimados_federais + - tributos_estimados_estaduais + - tributos_estimados_municipais) + tributos_estimados_federais + + tributos_estimados_estaduais + + tributos_estimados_municipais + ) - @api.depends('price_unit', 'tax_ids', 'qty', 'discount', 'product_id') + @api.depends("price_unit", "tax_ids", "qty", "discount", "product_id") def _compute_amount_and_taxes(self): for line in self: currency = line.order_id.pricelist_id.currency_id values = line.order_id.fiscal_position_id.map_tax_extra_values( - line.company_id, line.product_id, line.order_id.partner_id) - tax_ids = [values.get('tax_icms_id', False), - values.get('tax_icms_st_id', False), - values.get('tax_ipi_id', False), - values.get('tax_pis_id', False), - values.get('tax_cofins_id', False), - values.get('tax_ii_id', False), - values.get('tax_issqn_id', False)] - - line.update({ - 'tax_ids': [(6, None, [x.id for x in tax_ids if x])] - }) - line.cfop_id = values['cfop_id'].code if values.get( - 'cfop_id', False) else False - line.icms_cst_normal = values.get('icms_cst_normal', False) - line.icms_csosn_simples = values.get('icms_csosn_simples', False) - line.icms_st_aliquota_mva = values.get('icms_st_aliquota_mva', - False) - line.aliquota_icms_proprio = values.get('aliquota_icms_proprio', - False) - line.incluir_ipi_base = values.get('incluir_ipi_base', False) + line.company_id, line.product_id, line.order_id.partner_id + ) + tax_ids = [ + values.get("tax_icms_id", False), + values.get("tax_icms_st_id", False), + values.get("tax_ipi_id", False), + values.get("tax_pis_id", False), + values.get("tax_cofins_id", False), + values.get("tax_ii_id", False), + values.get("tax_issqn_id", False), + ] + + line.update( + {"tax_ids": [(6, None, [x.id for x in tax_ids if x])]} + ) + line.cfop_id = ( + values["cfop_id"].code + if values.get("cfop_id", False) + else False + ) + line.icms_cst_normal = values.get("icms_cst_normal", False) + line.icms_csosn_simples = values.get("icms_csosn_simples", False) + line.icms_st_aliquota_mva = values.get( + "icms_st_aliquota_mva", False + ) + line.aliquota_icms_proprio = values.get( + "aliquota_icms_proprio", False + ) + line.incluir_ipi_base = values.get("incluir_ipi_base", False) line.icms_aliquota_reducao_base = values.get( - 'icms_aliquota_reducao_base', False) + "icms_aliquota_reducao_base", False + ) line.icms_st_aliquota_reducao_base = values.get( - 'icms_st_aliquota_reducao_base', False) - line.ipi_cst = values.get('ipi_cst', False) or u'99' - line.ipi_reducao_bc = values.get('ipi_reducao_bc', False) - line.ipi_cst = values.get('ipi_cst', False) - line.pis_cst = values.get('pis_cst', False) - line.cofins_cst = values.get('cofins_cst', False) + "icms_st_aliquota_reducao_base", False + ) + line.ipi_cst = values.get("ipi_cst", False) or u"99" + line.ipi_reducao_bc = values.get("ipi_reducao_bc", False) + line.ipi_cst = values.get("ipi_cst", False) + line.pis_cst = values.get("pis_cst", False) + line.cofins_cst = values.get("cofins_cst", False) line.valor_bruto = line.qty * line.price_unit line.valor_desconto = line.valor_bruto * line.discount / 100 taxes_ids = line.tax_ids.filtered( - lambda tax: tax.company_id.id == line.order_id. - company_id.id) + lambda tax: tax.company_id.id == line.order_id.company_id.id + ) fiscal_position_id = line.order_id.fiscal_position_id if fiscal_position_id: taxes_ids = fiscal_position_id.map_tax( - taxes_ids, line.product_id, - line.order_id.partner_id) + taxes_ids, line.product_id, line.order_id.partner_id + ) price = line.price_unit * (1 - (line.discount or 0.0) / 100.0) - taxes = {'taxes': []} + taxes = {"taxes": []} if taxes_ids: ctx = line._prepare_tax_context() taxes_ids = taxes_ids.with_context(**ctx) taxes = taxes_ids.compute_all( - price, currency, line.qty, product=line.product_id, - partner=line.order_id.partner_id or False) - for tax in taxes['taxes']: - tax_id = self.env['account.tax'].browse(tax['id']) - if tax_id.domain == 'icms': - line.valor_icms = tax.get('amount', 0.00) - line.base_icms = tax.get('base', 0.00) + price, + currency, + line.qty, + product=line.product_id, + partner=line.order_id.partner_id or False, + ) + for tax in taxes["taxes"]: + tax_id = self.env["account.tax"].browse(tax["id"]) + if tax_id.domain == "icms": + line.valor_icms = tax.get("amount", 0.00) + line.base_icms = tax.get("base", 0.00) line.aliquota_icms = tax_id.amount - if tax_id.domain == 'ipi': - line.valor_ipi = tax.get('amount', 0.00) - line.base_ipi = tax.get('base', 0.00) + if tax_id.domain == "ipi": + line.valor_ipi = tax.get("amount", 0.00) + line.base_ipi = tax.get("base", 0.00) line.aliquota_ipi = tax_id.amount - if tax_id.domain == 'pis': - line.valor_pis = tax.get('amount', 0.00) - line.base_pis = tax.get('base', 0.00) + if tax_id.domain == "pis": + line.valor_pis = tax.get("amount", 0.00) + line.base_pis = tax.get("base", 0.00) line.aliquota_pis = tax_id.amount - if tax_id.domain == 'cofins': - line.valor_cofins = tax.get('amount', 0.00) - line.base_cofins = tax.get('base', 0.00) + if tax_id.domain == "cofins": + line.valor_cofins = tax.get("amount", 0.00) + line.base_cofins = tax.get("base", 0.00) line.aliquota_cofins = tax_id.amount - cfop_id = fields.Many2one('br_account.cfop', string="CFOP") + cfop_id = fields.Many2one("br_account.cfop", string="CFOP") icms_cst_normal = fields.Char(string="CST ICMS", size=5) icms_csosn_simples = fields.Char(string="CSOSN ICMS", size=5) - icms_st_aliquota_mva = fields.Float(string=u'Alíquota MVA (%)', - digits=dp.get_precision('Account')) + icms_st_aliquota_mva = fields.Float( + string=u"Alíquota MVA (%)", digits=dp.get_precision("Account") + ) aliquota_icms_proprio = fields.Float( - string=u'Alíquota ICMS Próprio (%)', - digits=dp.get_precision('Account')) + string=u"Alíquota ICMS Próprio (%)", + digits=dp.get_precision("Account"), + ) icms_aliquota_reducao_base = fields.Float( - string=u'Redução Base ICMS (%)', digits=dp.get_precision('Account')) + string=u"Redução Base ICMS (%)", digits=dp.get_precision("Account") + ) icms_st_aliquota_reducao_base = fields.Float( - string=u'Redução Base ICMS ST(%)', digits=dp.get_precision('Account')) - ipi_cst = fields.Char(string='CST IPI', size=5) - pis_cst = fields.Char(string='CST PIS', size=5) - cofins_cst = fields.Char(string='CST COFINS', size=5) + string=u"Redução Base ICMS ST(%)", digits=dp.get_precision("Account") + ) + ipi_cst = fields.Char(string="CST IPI", size=5) + pis_cst = fields.Char(string="CST PIS", size=5) + cofins_cst = fields.Char(string="CST COFINS", size=5) valor_desconto = fields.Float( - string='Vlr. Desc. (-)', store=True, - digits=dp.get_precision('Sale Price')) + string="Vlr. Desc. (-)", + store=True, + digits=dp.get_precision("Sale Price"), + ) valor_bruto = fields.Float( - string='Vlr. Bruto', store=True, compute=_compute_amount_and_taxes, - digits=dp.get_precision('Sale Price')) - valor_icms = fields.Float(string='Valor ICMS', store=True, - digits=dp.get_precision('Sale Price'), - compute=_compute_amount_and_taxes) - valor_ipi = fields.Float(string='Valor IPI', store=True, - digits=dp.get_precision('Sale Price'), - compute=_compute_amount_and_taxes) - valor_pis = fields.Float(string='Valor PIS', store=True, - digits=dp.get_precision('Sale Price'), - compute=_compute_amount_and_taxes) - valor_cofins = fields.Float(string='Valor COFINS', store=True, - digits=dp.get_precision('Sale Price'), - compute=_compute_amount_and_taxes) - base_icms = fields.Float(string='Base ICMS', store=True, - compute=_compute_amount_and_taxes) - base_ipi = fields.Float(string='Base IPI', store=True, - compute=_compute_amount_and_taxes) - base_pis = fields.Float(string='Base PIS', store=True, - compute=_compute_amount_and_taxes) - base_cofins = fields.Float(string='Base COFINS', store=True, - compute=_compute_amount_and_taxes) - aliquota_icms = fields.Float(compute=_compute_amount_and_taxes, store=True) + string="Vlr. Bruto", + store=True, + compute=_compute_amount_and_taxes, + digits=dp.get_precision("Sale Price"), + ) + valor_icms = fields.Float( + string="Valor ICMS", + store=True, + digits=dp.get_precision("Sale Price"), + compute=_compute_amount_and_taxes, + ) + valor_ipi = fields.Float( + string="Valor IPI", + store=True, + digits=dp.get_precision("Sale Price"), + compute=_compute_amount_and_taxes, + ) + valor_pis = fields.Float( + string="Valor PIS", + store=True, + digits=dp.get_precision("Sale Price"), + compute=_compute_amount_and_taxes, + ) + valor_cofins = fields.Float( + string="Valor COFINS", + store=True, + digits=dp.get_precision("Sale Price"), + compute=_compute_amount_and_taxes, + ) + base_icms = fields.Float( + string="Base ICMS", store=True, compute=_compute_amount_and_taxes + ) + base_ipi = fields.Float( + string="Base IPI", store=True, compute=_compute_amount_and_taxes + ) + base_pis = fields.Float( + string="Base PIS", store=True, compute=_compute_amount_and_taxes + ) + base_cofins = fields.Float( + string="Base COFINS", store=True, compute=_compute_amount_and_taxes + ) + aliquota_icms = fields.Float( + compute=_compute_amount_and_taxes, store=True + ) aliquota_ipi = fields.Float(compute=_compute_amount_and_taxes, store=True) aliquota_pis = fields.Float(compute=_compute_amount_and_taxes, store=True) - aliquota_cofins = fields.Float(compute=_compute_amount_and_taxes, store=True) + aliquota_cofins = fields.Float( + compute=_compute_amount_and_taxes, store=True + ) diff --git a/br_point_of_sale/static/src/js/main.js b/br_point_of_sale/static/src/js/main.js index 77542174d..4676d54f9 100644 --- a/br_point_of_sale/static/src/js/main.js +++ b/br_point_of_sale/static/src/js/main.js @@ -2,45 +2,57 @@ odoo.define('br_point_of_sale', function (require) { "use strict"; var models = require('point_of_sale.models'); - var _super_order = models.PosModel.prototype; var rpc = require('web.rpc'); var session = require('web.session'); + var models = require('point_of_sale.models'); + var _super_posorder = models.Order.prototype; - let search_nfce = (pos_order_ids, fields) => { + let search_nfce = (edoc_ids, fields) => { return rpc.query({ model: 'invoice.eletronic', method: 'search_read', fields: fields, - domain: [['pos_order_id', 'in', pos_order_ids]] + domain: [['id', 'in', edoc_ids]] }) } models.PosModel = models.PosModel.extend({ - _save_to_server: function (order, opts) { - var self = this - return _super_order._save_to_server.apply(this, arguments).done((result) => self.get_nfce(result)); + create_invoice_eletronic: function(pos_order) { + var self = this; + var args = [0, [_super_posorder.export_as_JSON.call(pos_order)]] + + return rpc.query({ + model: 'invoice.eletronic', + method: 'create_from_ui', + args: args, + kwargs: {context: session.user_context}, + }, { + timeout: 7500, + }).then( edoc_ids => self.get_nfce(edoc_ids)); }, - get_nfce: function (pos_order_ids) { - if (!pos_order_ids.length) { - return; + get_nfce: function (edoc_ids) { + if (!edoc_ids.length) { + return (new $.Deferred()).reject(); } let self = this; - self.cronSendNfe() - .then(function() { - self.checkNfe(self, pos_order_ids); + return self.cronSendNfe().then(function() { + return self.checkNfe(self, edoc_ids); }); }, - checkNfe: function(self, pos_order_ids) + checkNfe: function(self, edoc_ids) { let inv_fields = ['state', 'pos_order_id', 'codigo_retorno', 'mensagem_retorno', 'id']; - search_nfce(pos_order_ids, inv_fields).then(function (einvoices) { + var def = $.Deferred(); + search_nfce(edoc_ids, inv_fields).then(function (einvoices) { let einvoice = einvoices[0]; if (einvoice.state == 'done') { self.print_nfce(einvoice.id); + def.resolve(); } else if (['error', 'cancel'].indexOf(einvoice.state) > -1) { - alert('NFC-e Rejeitada: ' + einvoice.codigo_retorno + ' - ' + einvoice.mensagem_retorno); + def.reject('NFC-e Rejeitada: ' + einvoice.codigo_retorno + ' - ' + einvoice.mensagem_retorno); } }); + return def; }, print_nfce: function (einvoice_id) { diff --git a/br_point_of_sale/static/src/js/models.js b/br_point_of_sale/static/src/js/models.js index ca85c9141..8b5e103f1 100644 --- a/br_point_of_sale/static/src/js/models.js +++ b/br_point_of_sale/static/src/js/models.js @@ -13,7 +13,6 @@ odoo.define('br_point_of_sale.models', function (require) { export_as_JSON: function() { var vals = _super_posorder.export_as_JSON.call(this); vals["customer_cpf"] = this.get_client_cpf(); - console.log(vals); return vals; }, set_client_cpf: function(customerCpf){ diff --git a/br_point_of_sale/static/src/js/screens.js b/br_point_of_sale/static/src/js/screens.js index 7eb85f93b..795c3b922 100644 --- a/br_point_of_sale/static/src/js/screens.js +++ b/br_point_of_sale/static/src/js/screens.js @@ -48,7 +48,7 @@ odoo.define('br_point_of_sale.screens', function (require) { }; }, renderElement: function(){ - this._super() + this._super(); var self = this; this.$('.js_customer_cpf').ready(function($) { @@ -67,5 +67,38 @@ odoo.define('br_point_of_sale.screens', function (require) { } }) }, + finalize_validation: function() { + var self = this; + var order = this.pos.get_order(); + order.initialize_validation_date(); + this.pos.create_invoice_eletronic(order) + .done( result => self.finalize_pos_order()) + .fail( reason => alert(reason)); + }, + finalize_pos_order: function() { + var self = this; + var order = this.pos.get_order(); + if (order.is_paid_with_cash() && this.pos.config.iface_cashdrawer) { + + this.pos.proxy.open_cashbox(); + } + order.initialize_validation_date(); + order.finalized = true; + + if (order.is_to_invoice()) { + var invoiced = this.pos.push_and_invoice_order(order); + this.invoicing = true; + + invoiced.fail(this._handleFailedPushForInvoice.bind(this, order, false)); + + invoiced.done(function(){ + self.invoicing = false; + self.gui.show_screen('receipt'); + }); + } else { + this.pos.push_order(order); + this.gui.show_screen('receipt'); + } + } }); }); From 8896e0af5601e0efd9a8129aa0de746f3147d895 Mon Sep 17 00:00:00 2001 From: Fabio Luna Date: Wed, 4 Nov 2020 18:47:07 -0300 Subject: [PATCH 2/3] [FIX] br_pos_nfce Add a default value to get the "icms base calculo". --- br_point_of_sale/models/invoice_eletronic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/br_point_of_sale/models/invoice_eletronic.py b/br_point_of_sale/models/invoice_eletronic.py index f05b87994..d3d77f20b 100644 --- a/br_point_of_sale/models/invoice_eletronic.py +++ b/br_point_of_sale/models/invoice_eletronic.py @@ -375,7 +375,7 @@ def _prepare_edoc_fields(self, ui_order): base_icms = 0 for pos_line in vals.get("eletronic_item_ids"): - base_icms += pos_line[2].get("icms_base_calculo") + base_icms += pos_line[2].get("icms_base_calculo") or 0 vals.update( { From 52a1c354b9dca31c7d36be23bc812ccc6a5d7ec0 Mon Sep 17 00:00:00 2001 From: Felipe Paloschi Date: Fri, 6 Nov 2020 12:11:01 -0300 Subject: [PATCH 3/3] Improve errors messages in NFCe --- br_point_of_sale/static/src/js/main.js | 3 +-- br_point_of_sale/static/src/js/screens.js | 8 +++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/br_point_of_sale/static/src/js/main.js b/br_point_of_sale/static/src/js/main.js index 4676d54f9..383d795dc 100644 --- a/br_point_of_sale/static/src/js/main.js +++ b/br_point_of_sale/static/src/js/main.js @@ -19,8 +19,7 @@ odoo.define('br_point_of_sale', function (require) { models.PosModel = models.PosModel.extend({ create_invoice_eletronic: function(pos_order) { var self = this; - var args = [0, [_super_posorder.export_as_JSON.call(pos_order)]] - + var args = [0, [pos_order.export_as_JSON()]] return rpc.query({ model: 'invoice.eletronic', method: 'create_from_ui', diff --git a/br_point_of_sale/static/src/js/screens.js b/br_point_of_sale/static/src/js/screens.js index 795c3b922..8644d701e 100644 --- a/br_point_of_sale/static/src/js/screens.js +++ b/br_point_of_sale/static/src/js/screens.js @@ -73,7 +73,13 @@ odoo.define('br_point_of_sale.screens', function (require) { order.initialize_validation_date(); this.pos.create_invoice_eletronic(order) .done( result => self.finalize_pos_order()) - .fail( reason => alert(reason)); + .fail( reason => { + if(reason.data.type == "xhrtimeout") { + alert("Não foi possível conectar ao servidor!"); + } else { + alert(reason.data.name); + } + }) }, finalize_pos_order: function() { var self = this;