From 7f053439f8e30adf51f10df763a0433f27055401 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Fri, 3 Jul 2020 08:58:46 -0300 Subject: [PATCH 01/81] [ADD] Module l10n_br_nfse_ginfes --- l10n_br_nfse_ginfes/README.rst | 92 +++++++++++ l10n_br_nfse_ginfes/__init__.py | 1 + l10n_br_nfse_ginfes/__manifest__.py | 27 ++++ l10n_br_nfse_ginfes/models/__init__.py | 1 + l10n_br_nfse_ginfes/models/document.py | 153 ++++++++++++++++++ l10n_br_nfse_ginfes/readme/CONFIGURE.rst | 1 + l10n_br_nfse_ginfes/readme/CONTRIBUTORS.rst | 2 + l10n_br_nfse_ginfes/readme/DESCRIPTION.rst | 1 + l10n_br_nfse_ginfes/readme/INSTALL.rst | 4 + l10n_br_nfse_ginfes/readme/ROADMAP.rst | 0 l10n_br_nfse_ginfes/readme/USAGE.rst | 1 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/src/img/itajuba.png | Bin 0 -> 31499 bytes 13 files changed, 283 insertions(+) create mode 100644 l10n_br_nfse_ginfes/README.rst create mode 100644 l10n_br_nfse_ginfes/__init__.py create mode 100644 l10n_br_nfse_ginfes/__manifest__.py create mode 100644 l10n_br_nfse_ginfes/models/__init__.py create mode 100644 l10n_br_nfse_ginfes/models/document.py create mode 100644 l10n_br_nfse_ginfes/readme/CONFIGURE.rst create mode 100644 l10n_br_nfse_ginfes/readme/CONTRIBUTORS.rst create mode 100644 l10n_br_nfse_ginfes/readme/DESCRIPTION.rst create mode 100644 l10n_br_nfse_ginfes/readme/INSTALL.rst create mode 100644 l10n_br_nfse_ginfes/readme/ROADMAP.rst create mode 100644 l10n_br_nfse_ginfes/readme/USAGE.rst create mode 100644 l10n_br_nfse_ginfes/static/description/icon.png create mode 100644 l10n_br_nfse_ginfes/static/src/img/itajuba.png diff --git a/l10n_br_nfse_ginfes/README.rst b/l10n_br_nfse_ginfes/README.rst new file mode 100644 index 000000000000..5bc82d9d91a9 --- /dev/null +++ b/l10n_br_nfse_ginfes/README.rst @@ -0,0 +1,92 @@ +========= +Edoc Nfse +========= + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fl10n--brazil-lightgray.png?logo=github + :target: https://github.com/OCA/l10n-brazil/tree/12.0-l10n_br_nfse/l10n_br_nfse + :alt: OCA/l10n-brazil +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/l10n-brazil-12-0-l10n_br_nfse/l10n-brazil-12-0-l10n_br_nfse-l10n_br_nfse + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/124/12.0-l10n_br_nfse + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Este módulo permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e). + +**Table of contents** + +.. contents:: + :local: + +Installation +============ + +* Este módulo tem uma depedencia do pacote python erpbrasil.edoc +* Este módulo tem uma depedencia do pacote python erpbrasil.assinatura +* Este módulo tem uma depedencia do pacote python erpbrasil.transmissao +* Este módulo tem uma depedencia do pacote python erpbrasil.base + +Configuration +============= + +Após a instalação do módulo deve ser configurado na empresa o processador de documentos eletrônicos como erpbrasil.edoc. + +Usage +===== + + + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* KMEE + +Contributors +~~~~~~~~~~~~ + +* Luis Felipe Mileo +* Gabriel Cardoso de Faria + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/l10n-brazil `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/l10n_br_nfse_ginfes/__init__.py b/l10n_br_nfse_ginfes/__init__.py new file mode 100644 index 000000000000..0650744f6bc6 --- /dev/null +++ b/l10n_br_nfse_ginfes/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py new file mode 100644 index 000000000000..a6d3f6a78b4d --- /dev/null +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -0,0 +1,27 @@ +# Copyright 2019 KMEE INFORMATICA LTDA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + 'name': 'Edoc Nfse Ginfes', + 'summary': """ + NFS-E""", + 'version': '12.0.1.0.0', + 'license': 'AGPL-3', + 'author': 'KMEE, Odoo Community Association (OCA)', + 'website': 'https://github.com/OCA/l10n-brazil', + 'external_dependencies': { + 'python': [ + 'erpbrasil.edoc', + 'erpbrasil.assinatura', + 'erpbrasil.transmissao', + 'erpbrasil.base', + ], + }, + 'depends': [ + 'l10n_br_nfse', + ], + 'data': [ + ], + 'demo': [ + ], +} diff --git a/l10n_br_nfse_ginfes/models/__init__.py b/l10n_br_nfse_ginfes/models/__init__.py new file mode 100644 index 000000000000..9c01ea2470e4 --- /dev/null +++ b/l10n_br_nfse_ginfes/models/__init__.py @@ -0,0 +1 @@ +from . import document diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py new file mode 100644 index 000000000000..e99ec46ede55 --- /dev/null +++ b/l10n_br_nfse_ginfes/models/document.py @@ -0,0 +1,153 @@ +# Copyright 2019 KMEE INFORMATICA LTDA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from nfselib.ginfes.v3_01.tipos_v03 import ( + ListaRpsType, + tcCpfCnpj, + tcDadosServico, + tcDadosTomador, + tcEndereco, + tcIdentificacaoPrestador, + tcIdentificacaoRps, + tcIdentificacaoTomador, + tcInfRps, + tcLoteRps, + tcRps, + tcValores, +) +from nfselib.ginfes.v3_01.servico_enviar_lote_rps_envio_v03 import \ + EnviarLoteRpsEnvio + +from odoo import api, fields, models, _ +from odoo.addons.l10n_br_fiscal.constants.fiscal import ( + MODELO_FISCAL_NFSE, + SITUACAO_EDOC_AUTORIZADA, + TAX_FRAMEWORK_SIMPLES_ALL, +) + +from odoo.addons.l10n_br_nfse.models.res_company import PROCESSADOR + + +def fiter_processador_edoc_nfse_ginfes(record): + if (record.processador_edoc == PROCESSADOR and + record.document_type_id.code in [ + MODELO_FISCAL_NFSE, + ]): + return True + return False + + +def fiter_provedor_ginfes(record): + if record.company_id.provedor_nfse == 'ginfes': + return True + return False + + +class Document(models.Model): + + _inherit = 'l10n_br_fiscal.document' + + + def _serialize(self, edocs): + edocs = super(Document, self)._serialize(edocs) + for record in self.filtered( + fiter_processador_edoc_nfse_ginfes).filtered( + fiter_provedor_ginfes): + edocs.append(record.serialize_nfse_ginfes()) + return edocs + + def _serialize_dados_servico(self): + self.line_ids.ensure_one() + dados = self._prepare_dados_servico() + return tcDadosServico( + Valores=tcValores( + ValorServicos=dados['valor_servicos'], + ValorDeducoes=dados['valor_deducoes'], + ValorPis=dados['valor_pis'], + ValorCofins=dados['valor_cofins'], + ValorInss=dados['valor_inss'], + ValorIr=dados['valor_ir'], + ValorCsll=dados['valor_csll'], + IssRetido=dados['iss_retido'], + ValorIss=dados['valor_iss'], + ValorIssRetido=dados['valor_iss_retido'], + OutrasRetencoes=dados['outras_retencoes'], + BaseCalculo=dados['base_calculo'], + Aliquota=dados['aliquota'], + ValorLiquidoNfse=dados['valor_liquido_nfse'], + ), + ItemListaServico=dados['item_lista_servico'], + CodigoCnae=dados['codigo_cnae'], + CodigoTributacaoMunicipio=dados['codigo_tributacao_municipio'], + Discriminacao=dados['discriminacao'], + CodigoMunicipio=dados['codigo_municipio'], + ) + + def _serialize_dados_tomador(self): + dados = self._prepare_dados_tomador() + return tcDadosTomador( + IdentificacaoTomador=tcIdentificacaoTomador( + CpfCnpj=tcCpfCnpj( + Cnpj=dados['cnpj'], + Cpf=dados['cpf'], + ), + InscricaoMunicipal=dados['inscricao_municipal'] + ), + RazaoSocial=dados['razao_social'], + Endereco=tcEndereco( + Endereco=dados['endereco'], + Numero=dados['numero'], + Complemento=dados['complemento'], + Bairro=dados['bairro'], + CodigoMunicipio=dados['codigo_municipio'], + Uf=dados['uf'], + Cep=dados['cep'], + ) or None, + ) + + def _serialize_rps(self, dados): + + return tcRps( + InfRps=tcInfRps( + Id=dados['id'], + IdentificacaoRps=tcIdentificacaoRps( + Numero=dados['numero'], + Serie=dados['serie'], + Tipo=dados['tipo'], + ), + DataEmissao=dados['data_emissao'], + NaturezaOperacao=dados['natureza_operacao'], + RegimeEspecialTributacao=dados['regime_especial_tributacao'], + OptanteSimplesNacional=dados['optante_simples_nacional'], + IncentivadorCultural=dados['incentivador_cultural'], + Status=dados['status'], + RpsSubstituido=dados['rps_substitiuido'], + Servico=self._serialize_dados_servico(), + Prestador=tcIdentificacaoPrestador( + Cnpj=dados['cnpj'], + InscricaoMunicipal=dados['inscricao_municipal'], + ), + Tomador=self._serialize_dados_tomador(), + IntermediarioServico=dados['intermediario_servico'], + ConstrucaoCivil=dados['construcao_civil'], + ) + ) + + def _serialize_lote_rps(self): + dados = self._prepare_lote_rps() + return tcLoteRps( + Cnpj=dados['cnpj'], + InscricaoMunicipal=dados['inscricao_municipal'], + QuantidadeRps='1', + ListaRps=ListaRpsType( + Rps=[self._serialize_rps(dados)] + ) + ) + + def serialize_nfse_ginfes(self): + # numero_lote = 14 + lote_rps = EnviarLoteRpsEnvio( + LoteRps=self._serialize_lote_rps() + ) + return lote_rps diff --git a/l10n_br_nfse_ginfes/readme/CONFIGURE.rst b/l10n_br_nfse_ginfes/readme/CONFIGURE.rst new file mode 100644 index 000000000000..5d5408311049 --- /dev/null +++ b/l10n_br_nfse_ginfes/readme/CONFIGURE.rst @@ -0,0 +1 @@ +Após a instalação do módulo deve ser configurado na empresa o processador de documentos eletrônicos como erpbrasil.edoc. diff --git a/l10n_br_nfse_ginfes/readme/CONTRIBUTORS.rst b/l10n_br_nfse_ginfes/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000000..b21b70ea05a7 --- /dev/null +++ b/l10n_br_nfse_ginfes/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Luis Felipe Mileo +* Gabriel Cardoso de Faria diff --git a/l10n_br_nfse_ginfes/readme/DESCRIPTION.rst b/l10n_br_nfse_ginfes/readme/DESCRIPTION.rst new file mode 100644 index 000000000000..1220b52313c8 --- /dev/null +++ b/l10n_br_nfse_ginfes/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Este módulo permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e). diff --git a/l10n_br_nfse_ginfes/readme/INSTALL.rst b/l10n_br_nfse_ginfes/readme/INSTALL.rst new file mode 100644 index 000000000000..a46265414864 --- /dev/null +++ b/l10n_br_nfse_ginfes/readme/INSTALL.rst @@ -0,0 +1,4 @@ +* Este módulo tem uma depedencia do pacote python erpbrasil.edoc +* Este módulo tem uma depedencia do pacote python erpbrasil.assinatura +* Este módulo tem uma depedencia do pacote python erpbrasil.transmissao +* Este módulo tem uma depedencia do pacote python erpbrasil.base diff --git a/l10n_br_nfse_ginfes/readme/ROADMAP.rst b/l10n_br_nfse_ginfes/readme/ROADMAP.rst new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/l10n_br_nfse_ginfes/readme/USAGE.rst b/l10n_br_nfse_ginfes/readme/USAGE.rst new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/l10n_br_nfse_ginfes/readme/USAGE.rst @@ -0,0 +1 @@ + diff --git a/l10n_br_nfse_ginfes/static/description/icon.png b/l10n_br_nfse_ginfes/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/l10n_br_nfse_ginfes/static/src/img/itajuba.png b/l10n_br_nfse_ginfes/static/src/img/itajuba.png new file mode 100644 index 0000000000000000000000000000000000000000..b327d17fa2afc8b4270397e3aa4a13bd2ce61062 GIT binary patch literal 31499 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 Date: Fri, 3 Jul 2020 12:16:00 -0300 Subject: [PATCH 02/81] [IMP] l10n_br_ginfes readme and manifest --- l10n_br_nfse_ginfes/README.rst | 21 +- l10n_br_nfse_ginfes/__manifest__.py | 2 +- .../static/description/index.html | 439 ++++++++++++++++++ 3 files changed, 451 insertions(+), 11 deletions(-) create mode 100644 l10n_br_nfse_ginfes/static/description/index.html diff --git a/l10n_br_nfse_ginfes/README.rst b/l10n_br_nfse_ginfes/README.rst index 5bc82d9d91a9..382d83a44d38 100644 --- a/l10n_br_nfse_ginfes/README.rst +++ b/l10n_br_nfse_ginfes/README.rst @@ -1,6 +1,6 @@ -========= -Edoc Nfse -========= +================ +Edoc Nfse Ginfes +================ .. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! @@ -14,18 +14,18 @@ Edoc Nfse :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fl10n--brazil-lightgray.png?logo=github - :target: https://github.com/OCA/l10n-brazil/tree/12.0-l10n_br_nfse/l10n_br_nfse + :target: https://github.com/OCA/l10n-brazil/tree/12.0/l10n_br_nfse_ginfes :alt: OCA/l10n-brazil .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/l10n-brazil-12-0-l10n_br_nfse/l10n-brazil-12-0-l10n_br_nfse-l10n_br_nfse + :target: https://translation.odoo-community.org/projects/l10n-brazil-12-0/l10n-brazil-12-0-l10n_br_nfse_ginfes :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/124/12.0-l10n_br_nfse + :target: https://runbot.odoo-community.org/runbot/124/12.0 :alt: Try me on Runbot -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| -Este módulo permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e). +Este módulo permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e) pelo sistema Ginfes. **Table of contents** @@ -56,7 +56,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -73,6 +73,7 @@ Contributors * Luis Felipe Mileo * Gabriel Cardoso de Faria +* Luis Otavio Malta Conceição Maintainers ~~~~~~~~~~~ @@ -87,6 +88,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/l10n-brazil `_ project on GitHub. +This module is part of the `OCA/l10n-brazil `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index a6d3f6a78b4d..e95011683250 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -4,7 +4,7 @@ { 'name': 'Edoc Nfse Ginfes', 'summary': """ - NFS-E""", + NFS-E Ginfes""", 'version': '12.0.1.0.0', 'license': 'AGPL-3', 'author': 'KMEE, Odoo Community Association (OCA)', diff --git a/l10n_br_nfse_ginfes/static/description/index.html b/l10n_br_nfse_ginfes/static/description/index.html new file mode 100644 index 000000000000..3a61b894e8a5 --- /dev/null +++ b/l10n_br_nfse_ginfes/static/description/index.html @@ -0,0 +1,439 @@ + + + + + + +Edoc Nfse Ginfes + + + +
+

Edoc Nfse Ginfes

+ + +

Beta License: AGPL-3 OCA/l10n-brazil Translate me on Weblate Try me on Runbot

+

Este módulo permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e).

+

Table of contents

+ +
+

Installation

+
    +
  • Este módulo tem uma depedencia do pacote python erpbrasil.edoc
  • +
  • Este módulo tem uma depedencia do pacote python erpbrasil.assinatura
  • +
  • Este módulo tem uma depedencia do pacote python erpbrasil.transmissao
  • +
  • Este módulo tem uma depedencia do pacote python erpbrasil.base
  • +
+
+
+

Configuration

+

Após a instalação do módulo deve ser configurado na empresa o processador de documentos eletrônicos como erpbrasil.edoc.

+
+
+

Usage

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • KMEE
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/l10n-brazil project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + From dd8305aa56690a400cbe4131f6026d610d391751 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Mon, 20 Jul 2020 16:05:01 -0300 Subject: [PATCH 03/81] [ADD] NFSe Ginfes test --- l10n_br_nfse_ginfes/__init__.py | 1 + l10n_br_nfse_ginfes/tests/__init__.py | 1 + .../tests/nfse/001_50_nfse.xml | 1 + .../tests/test_fiscal_document_nfse_ginfes.py | 142 ++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 l10n_br_nfse_ginfes/tests/__init__.py create mode 100644 l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml create mode 100644 l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py diff --git a/l10n_br_nfse_ginfes/__init__.py b/l10n_br_nfse_ginfes/__init__.py index 0650744f6bc6..0ee8b5073e26 100644 --- a/l10n_br_nfse_ginfes/__init__.py +++ b/l10n_br_nfse_ginfes/__init__.py @@ -1 +1,2 @@ from . import models +from . import tests diff --git a/l10n_br_nfse_ginfes/tests/__init__.py b/l10n_br_nfse_ginfes/tests/__init__.py new file mode 100644 index 000000000000..333821c2330f --- /dev/null +++ b/l10n_br_nfse_ginfes/tests/__init__.py @@ -0,0 +1 @@ +from . import test_fiscal_document_nfse_ginfes diff --git a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml new file mode 100644 index 000000000000..1c347f6af8de --- /dev/null +++ b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml @@ -0,0 +1 @@ +595943150001573517215000112020-06-04T13:58:4611121100.0.0.0.0.0.0.20.0.0.0.0.100.1056311900[ODOO_DEV] Customized Odoo Development3132404595943150001573517281493979000189Cliente 1 SPRua Samuel Morse135Brooklin3550308SP4576060 diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py new file mode 100644 index 000000000000..efa4b9615c21 --- /dev/null +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -0,0 +1,142 @@ +# Copyright 2020 KMEE INFORMATICA LTDA +# Gabriel Cardoso de Faria +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from base64 import b64encode +from xmldiff import main +import os +import logging +from OpenSSL import crypto + +from odoo.tests.common import TransactionCase, Form +from odoo.tests import tagged +from datetime import datetime, timedelta +from odoo.tools import config +from odoo import fields +from odoo.tools.misc import format_date +from odoo.addons import l10n_br_nfse_ginfes + +_logger = logging.getLogger(__name__) + + +class TestFiscalDocumentNFSeGinfes(TransactionCase): + + def setUp(self): + super(TestFiscalDocumentNFSeGinfes, self).setUp() + + self.nfse_same_state = self.env.ref( + 'l10n_br_nfse.demo_nfse_same_state' + ) + + self.company_ginfes.processador_edoc = 'erpbrasil_edoc' + self.company_ginfes.partner_id.inscr_mun = '35172' + self.company_ginfes.partner_id.inscr_est = '' + self.company_ginfes.partner_id.state_id = self.env.ref( + 'base.state_br_mg') + self.company_ginfes.partner_id.city_id = self.env.ref( + 'l10n_br_base.city_3132404') + self.company_ginfes = self.env.ref( + 'l10n_br_fiscal.empresa_simples_nacional') + self.company_ginfes.icms_regulation_id = self.env.ref( + 'l10n_br_fiscal.tax_icms_regulation').id + self.company_ginfes.city_taxation_code_id = self.env.ref( + 'l10n_br_fiscal.city_taxation_code_itajuba').id + self.company_ginfes.document_type_id = self.env.ref( + 'l10n_br_fiscal.document_SE') + + self.cert_country = "BR" + self.cert_issuer_a = "EMISSOR A TESTE" + self.cert_issuer_b = "EMISSOR B TESTE" + self.cert_subject_valid = "CERTIFICADO VALIDO TESTE" + self.cert_date_exp = fields.Datetime.today() + timedelta(days=365) + self.cert_subject_invalid = "CERTIFICADO INVALIDO TESTE" + self.cert_passwd = "123456" + self.cert_name = "{} - {} - {} - Valid: {}".format( + "NF-E", + "A1", + self.cert_subject_valid, + format_date(self.env, self.cert_date_exp), + ) + self.certificate_model = self.env["l10n_br_fiscal.certificate"] + + self.certificate_valid = self._create_certificate( + valid=True, passwd=self.cert_passwd, issuer=self.cert_issuer_a, + country=self.cert_country, subject=self.cert_subject_valid) + + cert = self.certificate_model.create( + { + 'type': 'nf-e', + 'subtype': 'a1', + 'password': self.cert_passwd, + 'file': self.certificate_valid + } + ) + + self.company_ginfes.certificate_nfe_id = cert + self.nfse_same_state.company_id = self.company_ginfes.id + + def _create_certificate(self, valid=True, passwd=None, issuer=None, + country=None, subject=None): + """Creating a fake certificate""" + + key = crypto.PKey() + key.generate_key(crypto.TYPE_RSA, 2048) + + cert = crypto.X509() + + cert.get_issuer().C = country + cert.get_issuer().CN = issuer + + cert.get_subject().C = country + cert.get_subject().CN = subject + + cert.set_serial_number(2009) + + if valid: + time_before = 0 + time_after = 365 * 24 * 60 * 60 + else: + time_before = -1 * (365 * 24 * 60 * 60) + time_after = 0 + + cert.gmtime_adj_notBefore(time_before) + cert.gmtime_adj_notAfter(time_after) + cert.set_pubkey(key) + cert.sign(key, 'md5') + + p12 = crypto.PKCS12() + p12.set_privatekey(key) + p12.set_certificate(cert) + + return b64encode(p12.export(passwd)) + + def test_nfse_ginfes(self): + """ Test NFS-e same state. """ + + self.nfse_same_state._onchange_document_serie_id() + self.nfse_same_state._onchange_partner_id() + self.nfse_same_state._onchange_fiscal_operation_id() + self.nfse_same_state._onchange_company_id() + self.nfse_same_state.rps_number = 50 + self.nfse_same_state.date = datetime.strptime( + '2020-06-04T11:58:46', '%Y-%m-%dT%H:%M:%S') + + for line in self.nfse_same_state.line_ids: + line._onchange_product_id_fiscal() + line._onchange_commercial_quantity() + line._onchange_ncm_id() + line._onchange_fiscal_operation_id() + line._onchange_fiscal_operation_line_id() + line._onchange_fiscal_taxes() + + self.nfse_same_state.action_document_confirm() + + xml_path = os.path.join( + l10n_br_nfse_ginfes.__path__[0], 'tests', 'nfse', + '001_50_nfse.xml') + output = os.path.join(config['data_dir'], 'filestore', + self.cr.dbname, self.nfse_same_state.file_xml_id.store_fname) + _logger.info("XML file saved at %s" % (output,)) + + diff = main.diff_files(xml_path, output) + _logger.info("Diff with expected XML (if any): %s" % (diff,)) + assert len(diff) == 0 From 75d2a2d42e37e1bc1f691e7616cd9a2ee07266e3 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Tue, 21 Jul 2020 08:22:02 -0300 Subject: [PATCH 04/81] [FIX] Company Ginfes definition order --- l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py index efa4b9615c21..aebc66a06c3d 100644 --- a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -26,6 +26,8 @@ def setUp(self): self.nfse_same_state = self.env.ref( 'l10n_br_nfse.demo_nfse_same_state' ) + self.company_ginfes = self.env.ref( + 'l10n_br_fiscal.empresa_simples_nacional') self.company_ginfes.processador_edoc = 'erpbrasil_edoc' self.company_ginfes.partner_id.inscr_mun = '35172' @@ -34,8 +36,6 @@ def setUp(self): 'base.state_br_mg') self.company_ginfes.partner_id.city_id = self.env.ref( 'l10n_br_base.city_3132404') - self.company_ginfes = self.env.ref( - 'l10n_br_fiscal.empresa_simples_nacional') self.company_ginfes.icms_regulation_id = self.env.ref( 'l10n_br_fiscal.tax_icms_regulation').id self.company_ginfes.city_taxation_code_id = self.env.ref( From 7f04fd05dd969902e98ef8397c56e30b14042731 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Tue, 21 Jul 2020 08:22:26 -0300 Subject: [PATCH 05/81] [FIX] Flake8 --- l10n_br_nfse_ginfes/models/document.py | 5 +---- .../tests/test_fiscal_document_nfse_ginfes.py | 9 ++++----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index e99ec46ede55..384d7ec28882 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -19,11 +19,9 @@ from nfselib.ginfes.v3_01.servico_enviar_lote_rps_envio_v03 import \ EnviarLoteRpsEnvio -from odoo import api, fields, models, _ +from odoo import models from odoo.addons.l10n_br_fiscal.constants.fiscal import ( MODELO_FISCAL_NFSE, - SITUACAO_EDOC_AUTORIZADA, - TAX_FRAMEWORK_SIMPLES_ALL, ) from odoo.addons.l10n_br_nfse.models.res_company import PROCESSADOR @@ -48,7 +46,6 @@ class Document(models.Model): _inherit = 'l10n_br_fiscal.document' - def _serialize(self, edocs): edocs = super(Document, self)._serialize(edocs) for record in self.filtered( diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py index aebc66a06c3d..1e8c3d3920b5 100644 --- a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -7,13 +7,12 @@ import logging from OpenSSL import crypto -from odoo.tests.common import TransactionCase, Form -from odoo.tests import tagged +from odoo.tests.common import TransactionCase from datetime import datetime, timedelta from odoo.tools import config from odoo import fields from odoo.tools.misc import format_date -from odoo.addons import l10n_br_nfse_ginfes +from ... import l10n_br_nfse_ginfes _logger = logging.getLogger(__name__) @@ -133,8 +132,8 @@ def test_nfse_ginfes(self): xml_path = os.path.join( l10n_br_nfse_ginfes.__path__[0], 'tests', 'nfse', '001_50_nfse.xml') - output = os.path.join(config['data_dir'], 'filestore', - self.cr.dbname, self.nfse_same_state.file_xml_id.store_fname) + output = os.path.join(config['data_dir'], 'filestore', self.cr.dbname, + self.nfse_same_state.file_xml_id.store_fname) _logger.info("XML file saved at %s" % (output,)) diff = main.diff_files(xml_path, output) From a19df18eb82df594e2fecd584d8babd17415efbb Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Tue, 21 Jul 2020 10:44:22 -0300 Subject: [PATCH 06/81] [FIX] Nfselib dependecies --- l10n_br_nfse_ginfes/__manifest__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index e95011683250..c8c4e0dc3f81 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -15,6 +15,7 @@ 'erpbrasil.assinatura', 'erpbrasil.transmissao', 'erpbrasil.base', + 'nfselib', ], }, 'depends': [ From 71f6c7c825b730388295d711eb17f00dfcf0c031 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Wed, 22 Jul 2020 07:40:06 -0300 Subject: [PATCH 07/81] [ADD] Contributors --- l10n_br_nfse_ginfes/readme/CONTRIBUTORS.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/l10n_br_nfse_ginfes/readme/CONTRIBUTORS.rst b/l10n_br_nfse_ginfes/readme/CONTRIBUTORS.rst index b21b70ea05a7..72e4abef82ed 100644 --- a/l10n_br_nfse_ginfes/readme/CONTRIBUTORS.rst +++ b/l10n_br_nfse_ginfes/readme/CONTRIBUTORS.rst @@ -1,2 +1,3 @@ * Luis Felipe Mileo * Gabriel Cardoso de Faria +* Luis Otavio Malta Conceição From 6d5d9f27d98acfdda5fa6e89df8a681a60df8c1f Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Wed, 22 Jul 2020 07:41:12 -0300 Subject: [PATCH 08/81] [FIX] Update nfse xml test --- .../tests/nfse/001_50_nfse.xml | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml index 1c347f6af8de..4182e31bfb5f 100644 --- a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml +++ b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml @@ -1 +1,66 @@ -595943150001573517215000112020-06-04T13:58:4611121100.0.0.0.0.0.0.20.0.0.0.0.100.1056311900[ODOO_DEV] Customized Odoo Development3132404595943150001573517281493979000189Cliente 1 SPRua Samuel Morse135Brooklin3550308SP4576060 + + + 59594315000157 + 35172 + 1 + + + + + 50 + 001 + 1 + + 2020-06-04T13:58:46 + 1 + 1 + 1 + 2 + 1 + + + 100.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 2 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 100.00 + + 105 + 6311900 + [ODOO_DEV] Customized Odoo Development + 3132404 + + + 59594315000157 + 35172 + + + + + 81493979000189 + + + Cliente 1 SP + + Rua Samuel Morse + 135 + Brooklin + 3550308 + SP + 4576060 + + + + + + + From 7572cb06c765c27d39ebc82472d0c4d15e646b81 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Wed, 22 Jul 2020 12:25:28 -0300 Subject: [PATCH 09/81] [ADD] l10n_br_nfse_ginfes readme --- l10n_br_nfse_ginfes/README.rst | 9 +++++---- l10n_br_nfse_ginfes/readme/CONFIGURE.rst | 2 +- l10n_br_nfse_ginfes/readme/DESCRIPTION.rst | 2 +- l10n_br_nfse_ginfes/readme/INSTALL.rst | 1 + l10n_br_nfse_ginfes/readme/USAGE.rst | 2 +- l10n_br_nfse_ginfes/static/description/index.html | 7 +++++-- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/l10n_br_nfse_ginfes/README.rst b/l10n_br_nfse_ginfes/README.rst index 382d83a44d38..2c78090fbce6 100644 --- a/l10n_br_nfse_ginfes/README.rst +++ b/l10n_br_nfse_ginfes/README.rst @@ -23,9 +23,9 @@ Edoc Nfse Ginfes :target: https://runbot.odoo-community.org/runbot/124/12.0 :alt: Try me on Runbot -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| -Este módulo permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e) pelo sistema Ginfes. +Esse módulo completa o documento criado pelo l10n_br_nfse para permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e) pelo sistema GINFES. **Table of contents** @@ -39,16 +39,17 @@ Installation * Este módulo tem uma depedencia do pacote python erpbrasil.assinatura * Este módulo tem uma depedencia do pacote python erpbrasil.transmissao * Este módulo tem uma depedencia do pacote python erpbrasil.base +* Este módulo tem uma depedencia do pacote python nfselib Configuration ============= -Após a instalação do módulo deve ser configurado na empresa o processador de documentos eletrônicos como erpbrasil.edoc. +É apenas necessário a instalação e configuração do módulo l10n_br_nfse. Usage ===== - +Após ser criado uma Nota Fiscal de Serviço Eletrônicas (NFS-e) é possível confirmá-la e transmiti-la. Bug Tracker =========== diff --git a/l10n_br_nfse_ginfes/readme/CONFIGURE.rst b/l10n_br_nfse_ginfes/readme/CONFIGURE.rst index 5d5408311049..a827a70c7ee1 100644 --- a/l10n_br_nfse_ginfes/readme/CONFIGURE.rst +++ b/l10n_br_nfse_ginfes/readme/CONFIGURE.rst @@ -1 +1 @@ -Após a instalação do módulo deve ser configurado na empresa o processador de documentos eletrônicos como erpbrasil.edoc. +É apenas necessário a instalação e configuração do módulo l10n_br_nfse. diff --git a/l10n_br_nfse_ginfes/readme/DESCRIPTION.rst b/l10n_br_nfse_ginfes/readme/DESCRIPTION.rst index 1220b52313c8..025d04716349 100644 --- a/l10n_br_nfse_ginfes/readme/DESCRIPTION.rst +++ b/l10n_br_nfse_ginfes/readme/DESCRIPTION.rst @@ -1 +1 @@ -Este módulo permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e). +Esse módulo completa o documento criado pelo l10n_br_nfse para permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e) pelo sistema GINFES. diff --git a/l10n_br_nfse_ginfes/readme/INSTALL.rst b/l10n_br_nfse_ginfes/readme/INSTALL.rst index a46265414864..e2c08a6648de 100644 --- a/l10n_br_nfse_ginfes/readme/INSTALL.rst +++ b/l10n_br_nfse_ginfes/readme/INSTALL.rst @@ -2,3 +2,4 @@ * Este módulo tem uma depedencia do pacote python erpbrasil.assinatura * Este módulo tem uma depedencia do pacote python erpbrasil.transmissao * Este módulo tem uma depedencia do pacote python erpbrasil.base +* Este módulo tem uma depedencia do pacote python nfselib diff --git a/l10n_br_nfse_ginfes/readme/USAGE.rst b/l10n_br_nfse_ginfes/readme/USAGE.rst index 8b137891791f..f217aefe6260 100644 --- a/l10n_br_nfse_ginfes/readme/USAGE.rst +++ b/l10n_br_nfse_ginfes/readme/USAGE.rst @@ -1 +1 @@ - +Após ser criado uma Nota Fiscal de Serviço Eletrônicas (NFS-e) é possível confirmá-la e transmiti-la. diff --git a/l10n_br_nfse_ginfes/static/description/index.html b/l10n_br_nfse_ginfes/static/description/index.html index 3a61b894e8a5..4d78fd8c547d 100644 --- a/l10n_br_nfse_ginfes/static/description/index.html +++ b/l10n_br_nfse_ginfes/static/description/index.html @@ -368,7 +368,7 @@

Edoc Nfse Ginfes

!! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/l10n-brazil Translate me on Weblate Try me on Runbot

-

Este módulo permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e).

+

Esse módulo completa o documento criado pelo l10n_br_nfse para permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e) pelo sistema GINFES.

Table of contents

    @@ -391,14 +391,16 @@

    Installation

  • Este módulo tem uma depedencia do pacote python erpbrasil.assinatura
  • Este módulo tem uma depedencia do pacote python erpbrasil.transmissao
  • Este módulo tem uma depedencia do pacote python erpbrasil.base
  • +
  • Este módulo tem uma depedencia do pacote python nfselib

Configuration

-

Após a instalação do módulo deve ser configurado na empresa o processador de documentos eletrônicos como erpbrasil.edoc.

+

É apenas necessário a instalação e configuração do módulo l10n_br_nfse.

Usage

+

Após ser criado uma Nota Fiscal de Serviço Eletrônicas (NFS-e) é possível confirmá-la e transmiti-la.

Bug Tracker

@@ -421,6 +423,7 @@

Contributors

From c1d88a4f57b80ad6fed7e15dbd5d0bc34b7161f1 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Thu, 30 Jul 2020 11:43:34 -0300 Subject: [PATCH 10/81] [ADD] NFS-e Ginfes Cancel --- l10n_br_nfse_ginfes/models/document.py | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 384d7ec28882..ba31ec7f1678 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -2,6 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import xml.etree.ElementTree as ET from nfselib.ginfes.v3_01.tipos_v03 import ( ListaRpsType, tcCpfCnpj, @@ -148,3 +149,35 @@ def serialize_nfse_ginfes(self): LoteRps=self._serialize_lote_rps() ) return lote_rps + + def cancelar_documento(self): + for record in self.filtered(fiter_processador_edoc_nfse_ginfes): + processador = record._processador_erpbrasil_nfse() + processo = processador.cancela_documento() + + if processo.webservice == 'CancelarNfseV3': + mensagem_completa = '' + situacao = True + retorno = ET.fromstring(processo.retorno) + + sucesso = retorno.findall( + ".//{http://www.ginfes.com.br/tipos_v03.xsd}Sucesso") + if not sucesso: + mensagem_erro = retorno.findall( + ".//{http://www.ginfes.com.br/tipos_v03.xsd}Mensagem")[ + 0].text + correcao = retorno.findall( + ".//{http://www.ginfes.com.br/tipos_v03.xsd}Correcao")[ + 0].text + codigo = retorno.findall( + ".//{http://www.ginfes.com.br/tipos_v03.xsd}Codigo")[ + 0].text + mensagem_completa += ( + codigo + ' - ' + + mensagem_erro + + ' - Correção: ' + + correcao + '\n' + ) + situacao = False + + return situacao, mensagem_completa From f0dee76716e5fd59935ced4ffe1b08e3daa09d04 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Fri, 31 Jul 2020 10:21:04 -0300 Subject: [PATCH 11/81] [REF] Move doc_number to cancela_documento --- l10n_br_nfse_ginfes/models/document.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index ba31ec7f1678..6f77c89184b5 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -153,7 +153,7 @@ def serialize_nfse_ginfes(self): def cancelar_documento(self): for record in self.filtered(fiter_processador_edoc_nfse_ginfes): processador = record._processador_erpbrasil_nfse() - processo = processador.cancela_documento() + processo = processador.cancela_documento(doc_numero=self.number) if processo.webservice == 'CancelarNfseV3': mensagem_completa = '' From 84ad337cd4b75721daef8c5cb4c4958966aaba22 Mon Sep 17 00:00:00 2001 From: Marcel Savegnago Date: Sat, 1 Aug 2020 17:39:52 -0300 Subject: [PATCH 12/81] =?UTF-8?q?[ADD]=20l10n=5Fbr=5Fnfse:=20adicionado=20?= =?UTF-8?q?campo=20de=20selecao=20do=20provedor=20nfse=20e=20removendo=20r?= =?UTF-8?q?eferencias=20a=20ginfes=20do=20m=C3=B3dulo=20base?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- l10n_br_nfse_ginfes/models/__init__.py | 1 + l10n_br_nfse_ginfes/models/res_company.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 l10n_br_nfse_ginfes/models/res_company.py diff --git a/l10n_br_nfse_ginfes/models/__init__.py b/l10n_br_nfse_ginfes/models/__init__.py index 9c01ea2470e4..166dd3bd2493 100644 --- a/l10n_br_nfse_ginfes/models/__init__.py +++ b/l10n_br_nfse_ginfes/models/__init__.py @@ -1 +1,2 @@ from . import document +from . import res_company diff --git a/l10n_br_nfse_ginfes/models/res_company.py b/l10n_br_nfse_ginfes/models/res_company.py new file mode 100644 index 000000000000..91dc8b38348e --- /dev/null +++ b/l10n_br_nfse_ginfes/models/res_company.py @@ -0,0 +1,15 @@ +# Copyright 2020 - TODAY, Marcel Savegnago - Escodoo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models, _ + + +class ResCompany(models.Model): + + _inherit = 'res.company' + + provedor_nfse = fields.Selection( + selection_add=[ + ('ginfes', 'Ginfes'), + ] + ) From d7359fb686e8100f8a41acfbd8256fd2748c4726 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Mon, 3 Aug 2020 09:40:55 -0300 Subject: [PATCH 13/81] [ADD] NFS-e Ginfes document view --- l10n_br_nfse_ginfes/__manifest__.py | 1 + l10n_br_nfse_ginfes/views/document_view.xml | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 l10n_br_nfse_ginfes/views/document_view.xml diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index c8c4e0dc3f81..e154b35e4eb0 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -22,6 +22,7 @@ 'l10n_br_nfse', ], 'data': [ + 'views/document_view.xml', ], 'demo': [ ], diff --git a/l10n_br_nfse_ginfes/views/document_view.xml b/l10n_br_nfse_ginfes/views/document_view.xml new file mode 100644 index 000000000000..df907594ced5 --- /dev/null +++ b/l10n_br_nfse_ginfes/views/document_view.xml @@ -0,0 +1,18 @@ + + + + + + + l10n_br_nfse_ginfes.document.form.inherit + l10n_br_fiscal.document + + + + + + + From 443a1549fce4e97e5731d4f6289989af23280ef2 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Mon, 3 Aug 2020 10:15:57 -0300 Subject: [PATCH 14/81] [FIX] Test Company Ginfes provedor --- l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py index 1e8c3d3920b5..3faf20bae228 100644 --- a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -29,6 +29,7 @@ def setUp(self): 'l10n_br_fiscal.empresa_simples_nacional') self.company_ginfes.processador_edoc = 'erpbrasil_edoc' + self.company_ginfes.provedor_nfse = 'ginfes' self.company_ginfes.partner_id.inscr_mun = '35172' self.company_ginfes.partner_id.inscr_est = '' self.company_ginfes.partner_id.state_id = self.env.ref( From b72c9fadb90945ab4ee3186ba1527e88875a29bf Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Mon, 3 Aug 2020 10:40:26 -0300 Subject: [PATCH 15/81] [FIX] Flake8 --- l10n_br_nfse_ginfes/models/document.py | 8 +++----- l10n_br_nfse_ginfes/models/res_company.py | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 6f77c89184b5..87490e8ea259 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -173,11 +173,9 @@ def cancelar_documento(self): ".//{http://www.ginfes.com.br/tipos_v03.xsd}Codigo")[ 0].text mensagem_completa += ( - codigo + ' - ' + - mensagem_erro + - ' - Correção: ' + - correcao + '\n' - ) + codigo + ' - ' + mensagem_erro + + ' - Correção: ' + correcao + '\n' + ) situacao = False return situacao, mensagem_completa diff --git a/l10n_br_nfse_ginfes/models/res_company.py b/l10n_br_nfse_ginfes/models/res_company.py index 91dc8b38348e..51785e6dfe3f 100644 --- a/l10n_br_nfse_ginfes/models/res_company.py +++ b/l10n_br_nfse_ginfes/models/res_company.py @@ -1,7 +1,7 @@ # Copyright 2020 - TODAY, Marcel Savegnago - Escodoo # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models, _ +from odoo import fields, models class ResCompany(models.Model): From e9ff27e9443e174d2d8353eec7e5ef1b83b67547 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Mon, 3 Aug 2020 14:07:55 -0300 Subject: [PATCH 16/81] [REF] Cancel namespace in findall xml --- l10n_br_nfse_ginfes/models/document.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 87490e8ea259..14c1d77dc6a1 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -159,19 +159,16 @@ def cancelar_documento(self): mensagem_completa = '' situacao = True retorno = ET.fromstring(processo.retorno) + nsmap = {'tipo': 'http://www.ginfes.com.br/tipos_v03.xsd'} - sucesso = retorno.findall( - ".//{http://www.ginfes.com.br/tipos_v03.xsd}Sucesso") + sucesso = retorno.findall(".//tipo:Sucesso", namespaces=nsmap) if not sucesso: mensagem_erro = retorno.findall( - ".//{http://www.ginfes.com.br/tipos_v03.xsd}Mensagem")[ - 0].text + ".//tipo:Mensagem", namespaces=nsmap)[0].text correcao = retorno.findall( - ".//{http://www.ginfes.com.br/tipos_v03.xsd}Correcao")[ - 0].text + ".//tipo:Correcao", namespaces=nsmap)[0].text codigo = retorno.findall( - ".//{http://www.ginfes.com.br/tipos_v03.xsd}Codigo")[ - 0].text + ".//tipo:Codigo", namespaces=nsmap)[0].text mensagem_completa += ( codigo + ' - ' + mensagem_erro + ' - Correção: ' + correcao + '\n' From df2442b56068aa76b5b321974da6cd4465320ec9 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Mon, 3 Aug 2020 14:08:15 -0300 Subject: [PATCH 17/81] [ADD] Consulta NFS-e por RPS --- l10n_br_nfse_ginfes/models/document.py | 86 +++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 14c1d77dc6a1..d8018e6d1733 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -3,6 +3,8 @@ import xml.etree.ElementTree as ET +from datetime import datetime +from erpbrasil.base import misc from nfselib.ginfes.v3_01.tipos_v03 import ( ListaRpsType, tcCpfCnpj, @@ -20,7 +22,8 @@ from nfselib.ginfes.v3_01.servico_enviar_lote_rps_envio_v03 import \ EnviarLoteRpsEnvio -from odoo import models +from odoo import models, _ +from odoo.exceptions import ValidationError from odoo.addons.l10n_br_fiscal.constants.fiscal import ( MODELO_FISCAL_NFSE, ) @@ -176,3 +179,84 @@ def cancelar_documento(self): situacao = False return situacao, mensagem_completa + + def action_consultar_nfse_rps(self): + for record in self.filtered(fiter_processador_edoc_nfse_ginfes): + processador = record._processador_erpbrasil_nfse() + processo = processador.consulta_nfse_rps( + self.rps_number, self.document_serie, self.rps_type) + + retorno = ET.fromstring(processo.retorno) + nsmap = {'consulta': 'http://www.ginfes.com.br/servico_consultar_nfse_rps_resposta_v03.xsd', + 'tipo': 'http://www.ginfes.com.br/tipos_v03.xsd'} + if processo.webservice == 'ConsultarNfsePorRpsV3': + enviado = retorno.findall( + ".//consulta:CompNfse", namespaces=nsmap) + nao_encontrado = retorno.findall( + ".//tipo:MensagemRetorno", namespaces=nsmap) + + if enviado: + # NFS-e já foi enviada + + cancelada = retorno.findall( + ".//tipo:NfseCancelamento",namespaces=nsmap) + + if cancelada: + # NFS-e enviada foi cancelada + + data = retorno.findall( + ".//tipo:DataHora", namespaces=nsmap)[0].text + data = datetime.strptime(data, '%Y-%m-%dT%H:%M:%S').\ + strftime("%m/%d/%Y") + mensagem = _('NFS-e cancelada em ' + data) + raise ValidationError(_(mensagem)) + + else: + numero = retorno.findall(".//tipo:InfNfse/tipo:Numero", + namespaces=nsmap)[0].text + cnpj_prestador = retorno.findall( + ".//tipo:IdentificacaoPrestador/tipo:Cnpj", + namespaces=nsmap)[0].text + razao_social_prestador = retorno.findall( + ".//tipo:PrestadorServico/tipo:RazaoSocial", + namespaces=nsmap)[0].text + + varibles_error = [] + + if numero != self.number: + varibles_error.append('Número') + if cnpj_prestador != misc.punctuation_rm( + self.company_cnpj_cpf): + varibles_error.append('CNPJ do prestador') + if razao_social_prestador != self.company_legal_name: + varibles_error.append('Razão Social de pestrador') + + if varibles_error: + mensagem = 'Os seguintes campos não condizem com' \ + ' o provedor NFS-e: \n' + mensagem += '\n'.join(varibles_error) + raise ValidationError(_(mensagem)) + else: + # TODO: Mensagem de sucesso + pass + + elif nao_encontrado: + # NFS-e não foi enviada + + mensagem_erro = retorno.findall( + ".//tipo:Mensagem", namespaces=nsmap)[0].text + correcao = retorno.findall( + ".//tipo:Correcao", namespaces=nsmap)[0].text + codigo = retorno.findall( + ".//tipo:Codigo", namespaces=nsmap)[0].text + mensagem = ( + codigo + ' - ' + mensagem_erro + + ' - Correção: ' + correcao + '\n' + ) + + raise ValidationError(_(mensagem)) + + else: + mensagem = _('Erro desconhecido.') + raise ValidationError(_(mensagem)) + From 9d9e993cd5bb2a63f544140ed7b7172906f0f3b9 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Tue, 4 Aug 2020 07:50:09 -0300 Subject: [PATCH 18/81] [FIX] Flake8 --- l10n_br_nfse_ginfes/models/document.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index d8018e6d1733..fb3ab181e065 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -173,9 +173,8 @@ def cancelar_documento(self): codigo = retorno.findall( ".//tipo:Codigo", namespaces=nsmap)[0].text mensagem_completa += ( - codigo + ' - ' + mensagem_erro + - ' - Correção: ' + correcao + '\n' - ) + codigo + ' - ' + mensagem_erro + + ' - Correção: ' + correcao + '\n') situacao = False return situacao, mensagem_completa @@ -187,7 +186,8 @@ def action_consultar_nfse_rps(self): self.rps_number, self.document_serie, self.rps_type) retorno = ET.fromstring(processo.retorno) - nsmap = {'consulta': 'http://www.ginfes.com.br/servico_consultar_nfse_rps_resposta_v03.xsd', + nsmap = {'consulta': 'http://www.ginfes.com.br/servico_consultar_' + 'nfse_rps_resposta_v03.xsd', 'tipo': 'http://www.ginfes.com.br/tipos_v03.xsd'} if processo.webservice == 'ConsultarNfsePorRpsV3': enviado = retorno.findall( @@ -199,7 +199,7 @@ def action_consultar_nfse_rps(self): # NFS-e já foi enviada cancelada = retorno.findall( - ".//tipo:NfseCancelamento",namespaces=nsmap) + ".//tipo:NfseCancelamento", namespaces=nsmap) if cancelada: # NFS-e enviada foi cancelada @@ -226,7 +226,7 @@ def action_consultar_nfse_rps(self): if numero != self.number: varibles_error.append('Número') if cnpj_prestador != misc.punctuation_rm( - self.company_cnpj_cpf): + self.company_cnpj_cpf): varibles_error.append('CNPJ do prestador') if razao_social_prestador != self.company_legal_name: varibles_error.append('Razão Social de pestrador') @@ -259,4 +259,3 @@ def action_consultar_nfse_rps(self): else: mensagem = _('Erro desconhecido.') raise ValidationError(_(mensagem)) - From 4f47cc7b70815dd03d1016735209516101ccf2e6 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Wed, 5 Aug 2020 07:28:11 -0300 Subject: [PATCH 19/81] [REF] action_consultar_nfse_rps return message --- l10n_br_nfse_ginfes/models/document.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index fb3ab181e065..66cbfebbbe84 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -209,7 +209,7 @@ def action_consultar_nfse_rps(self): data = datetime.strptime(data, '%Y-%m-%dT%H:%M:%S').\ strftime("%m/%d/%Y") mensagem = _('NFS-e cancelada em ' + data) - raise ValidationError(_(mensagem)) + return mensagem else: numero = retorno.findall(".//tipo:InfNfse/tipo:Numero", @@ -235,10 +235,9 @@ def action_consultar_nfse_rps(self): mensagem = 'Os seguintes campos não condizem com' \ ' o provedor NFS-e: \n' mensagem += '\n'.join(varibles_error) - raise ValidationError(_(mensagem)) + return mensagem else: - # TODO: Mensagem de sucesso - pass + return "NFS-e enviada e corresponde com o provedor" elif nao_encontrado: # NFS-e não foi enviada @@ -254,8 +253,8 @@ def action_consultar_nfse_rps(self): ' - Correção: ' + correcao + '\n' ) - raise ValidationError(_(mensagem)) + return mensagem else: mensagem = _('Erro desconhecido.') - raise ValidationError(_(mensagem)) + return mensagem From 6bb5046355300f91dd9f1a1d12386ef58e7bbd84 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Wed, 5 Aug 2020 07:35:31 -0300 Subject: [PATCH 20/81] [ADD] NFS-e Wizard Document Status --- l10n_br_nfse_ginfes/models/document.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 66cbfebbbe84..547ce8039eac 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -232,12 +232,13 @@ def action_consultar_nfse_rps(self): varibles_error.append('Razão Social de pestrador') if varibles_error: - mensagem = 'Os seguintes campos não condizem com' \ - ' o provedor NFS-e: \n' + mensagem = _('Os seguintes campos não condizem com' + ' o provedor NFS-e: \n') mensagem += '\n'.join(varibles_error) return mensagem else: - return "NFS-e enviada e corresponde com o provedor" + return _( + "NFS-e enviada e corresponde com o provedor") elif nao_encontrado: # NFS-e não foi enviada @@ -248,7 +249,7 @@ def action_consultar_nfse_rps(self): ".//tipo:Correcao", namespaces=nsmap)[0].text codigo = retorno.findall( ".//tipo:Codigo", namespaces=nsmap)[0].text - mensagem = ( + mensagem = _( codigo + ' - ' + mensagem_erro + ' - Correção: ' + correcao + '\n' ) From 75997c85c332672c4afd83f61aa67d36fb914347 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Wed, 5 Aug 2020 08:18:53 -0300 Subject: [PATCH 21/81] [REM] Button Consultar NFS-e por RPS --- l10n_br_nfse_ginfes/__manifest__.py | 1 - l10n_br_nfse_ginfes/views/document_view.xml | 18 ------------------ 2 files changed, 19 deletions(-) delete mode 100644 l10n_br_nfse_ginfes/views/document_view.xml diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index e154b35e4eb0..c8c4e0dc3f81 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -22,7 +22,6 @@ 'l10n_br_nfse', ], 'data': [ - 'views/document_view.xml', ], 'demo': [ ], diff --git a/l10n_br_nfse_ginfes/views/document_view.xml b/l10n_br_nfse_ginfes/views/document_view.xml deleted file mode 100644 index df907594ced5..000000000000 --- a/l10n_br_nfse_ginfes/views/document_view.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - l10n_br_nfse_ginfes.document.form.inherit - l10n_br_fiscal.document - - - - - - - From 4e35bdfded2b0b5fdea411602d680864f98395e7 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Wed, 5 Aug 2020 08:19:07 -0300 Subject: [PATCH 22/81] [FIX] Flake8 --- l10n_br_nfse_ginfes/models/document.py | 1 - 1 file changed, 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 547ce8039eac..f7216b7218fe 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -23,7 +23,6 @@ EnviarLoteRpsEnvio from odoo import models, _ -from odoo.exceptions import ValidationError from odoo.addons.l10n_br_fiscal.constants.fiscal import ( MODELO_FISCAL_NFSE, ) From 224566f7b9070949b598d014f718f9e85a3f831a Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Wed, 12 Aug 2020 12:36:06 -0300 Subject: [PATCH 23/81] [REM] Manifest empty tags --- l10n_br_nfse_ginfes/__manifest__.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index c8c4e0dc3f81..33b8dba7bb1e 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -21,8 +21,4 @@ 'depends': [ 'l10n_br_nfse', ], - 'data': [ - ], - 'demo': [ - ], } From 84c8f5923e6cad1ac31c761cf60a22bf736f19c4 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Wed, 12 Aug 2020 12:40:49 -0300 Subject: [PATCH 24/81] [REF] NFSe Ginfes Test with NFSe Common Test --- .../tests/test_fiscal_document_nfse_ginfes.py | 92 +------------------ 1 file changed, 5 insertions(+), 87 deletions(-) diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py index 3faf20bae228..a6e1999fd245 100644 --- a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -14,100 +14,18 @@ from odoo.tools.misc import format_date from ... import l10n_br_nfse_ginfes +from odoo.addons.l10n_br_nfse.tests.test_fiscal_document_nfse_common import TestFiscalDocumentNFSeCommon + + _logger = logging.getLogger(__name__) -class TestFiscalDocumentNFSeGinfes(TransactionCase): +class TestFiscalDocumentNFSeGinfes(TestFiscalDocumentNFSeCommon): def setUp(self): super(TestFiscalDocumentNFSeGinfes, self).setUp() - self.nfse_same_state = self.env.ref( - 'l10n_br_nfse.demo_nfse_same_state' - ) - self.company_ginfes = self.env.ref( - 'l10n_br_fiscal.empresa_simples_nacional') - - self.company_ginfes.processador_edoc = 'erpbrasil_edoc' - self.company_ginfes.provedor_nfse = 'ginfes' - self.company_ginfes.partner_id.inscr_mun = '35172' - self.company_ginfes.partner_id.inscr_est = '' - self.company_ginfes.partner_id.state_id = self.env.ref( - 'base.state_br_mg') - self.company_ginfes.partner_id.city_id = self.env.ref( - 'l10n_br_base.city_3132404') - self.company_ginfes.icms_regulation_id = self.env.ref( - 'l10n_br_fiscal.tax_icms_regulation').id - self.company_ginfes.city_taxation_code_id = self.env.ref( - 'l10n_br_fiscal.city_taxation_code_itajuba').id - self.company_ginfes.document_type_id = self.env.ref( - 'l10n_br_fiscal.document_SE') - - self.cert_country = "BR" - self.cert_issuer_a = "EMISSOR A TESTE" - self.cert_issuer_b = "EMISSOR B TESTE" - self.cert_subject_valid = "CERTIFICADO VALIDO TESTE" - self.cert_date_exp = fields.Datetime.today() + timedelta(days=365) - self.cert_subject_invalid = "CERTIFICADO INVALIDO TESTE" - self.cert_passwd = "123456" - self.cert_name = "{} - {} - {} - Valid: {}".format( - "NF-E", - "A1", - self.cert_subject_valid, - format_date(self.env, self.cert_date_exp), - ) - self.certificate_model = self.env["l10n_br_fiscal.certificate"] - - self.certificate_valid = self._create_certificate( - valid=True, passwd=self.cert_passwd, issuer=self.cert_issuer_a, - country=self.cert_country, subject=self.cert_subject_valid) - - cert = self.certificate_model.create( - { - 'type': 'nf-e', - 'subtype': 'a1', - 'password': self.cert_passwd, - 'file': self.certificate_valid - } - ) - - self.company_ginfes.certificate_nfe_id = cert - self.nfse_same_state.company_id = self.company_ginfes.id - - def _create_certificate(self, valid=True, passwd=None, issuer=None, - country=None, subject=None): - """Creating a fake certificate""" - - key = crypto.PKey() - key.generate_key(crypto.TYPE_RSA, 2048) - - cert = crypto.X509() - - cert.get_issuer().C = country - cert.get_issuer().CN = issuer - - cert.get_subject().C = country - cert.get_subject().CN = subject - - cert.set_serial_number(2009) - - if valid: - time_before = 0 - time_after = 365 * 24 * 60 * 60 - else: - time_before = -1 * (365 * 24 * 60 * 60) - time_after = 0 - - cert.gmtime_adj_notBefore(time_before) - cert.gmtime_adj_notAfter(time_after) - cert.set_pubkey(key) - cert.sign(key, 'md5') - - p12 = crypto.PKCS12() - p12.set_privatekey(key) - p12.set_certificate(cert) - - return b64encode(p12.export(passwd)) + self.company.provedor_nfse = 'ginfes' def test_nfse_ginfes(self): """ Test NFS-e same state. """ From 26524bb8746cc6a0db7792169cf37e4ed46116fd Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Mon, 17 Aug 2020 11:58:52 -0300 Subject: [PATCH 25/81] [FIX] Flake8 --- .../tests/test_fiscal_document_nfse_ginfes.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py index a6e1999fd245..9f8f9f06feff 100644 --- a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -1,20 +1,17 @@ # Copyright 2020 KMEE INFORMATICA LTDA # Gabriel Cardoso de Faria # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from base64 import b64encode + from xmldiff import main import os import logging -from OpenSSL import crypto -from odoo.tests.common import TransactionCase -from datetime import datetime, timedelta +from datetime import datetime from odoo.tools import config -from odoo import fields -from odoo.tools.misc import format_date from ... import l10n_br_nfse_ginfes -from odoo.addons.l10n_br_nfse.tests.test_fiscal_document_nfse_common import TestFiscalDocumentNFSeCommon +from odoo.addons.l10n_br_nfse.tests.test_fiscal_document_nfse_common \ + import TestFiscalDocumentNFSeCommon _logger = logging.getLogger(__name__) From 3e3d59b45fc0bb53132f2264e7ae37a9d88b1a4a Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Thu, 27 Aug 2020 08:12:37 -0300 Subject: [PATCH 26/81] [REF] Move ginfes constants to l10n_br_nfse_ginfes --- l10n_br_nfse_ginfes/constants/ginfes.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 l10n_br_nfse_ginfes/constants/ginfes.py diff --git a/l10n_br_nfse_ginfes/constants/ginfes.py b/l10n_br_nfse_ginfes/constants/ginfes.py new file mode 100644 index 000000000000..b848d3763249 --- /dev/null +++ b/l10n_br_nfse_ginfes/constants/ginfes.py @@ -0,0 +1,10 @@ + +RECEPCIONAR_LOTE_RPS = [ + 'RecepcionarLoteRpsV3', + 'RecepcionarLoteRps' +] + +CONSULTAR_SITUACAO_LOTE_RPS = [ + 'ConsultarSituacaoLoteRpsV3', + 'ConsultarSituacaoLoteRps' +] From cc06da4275dac350f8018c042ccb1df92ce1213d Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Thu, 27 Aug 2020 08:13:22 -0300 Subject: [PATCH 27/81] [REF] Move ginfes _eletronic_document_send to l10n_br_nfse_ginfes --- l10n_br_nfse_ginfes/models/document.py | 104 ++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index f7216b7218fe..29067c5b61da 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -22,13 +22,20 @@ from nfselib.ginfes.v3_01.servico_enviar_lote_rps_envio_v03 import \ EnviarLoteRpsEnvio -from odoo import models, _ +from odoo import models, api, _ from odoo.addons.l10n_br_fiscal.constants.fiscal import ( MODELO_FISCAL_NFSE, + SITUACAO_EDOC_AUTORIZADA, ) from odoo.addons.l10n_br_nfse.models.res_company import PROCESSADOR +from ..constants.ginfes import ( + RECEPCIONAR_LOTE_RPS, + CONSULTAR_SITUACAO_LOTE_RPS, +) + + def fiter_processador_edoc_nfse_ginfes(record): if (record.processador_edoc == PROCESSADOR and @@ -258,3 +265,98 @@ def action_consultar_nfse_rps(self): else: mensagem = _('Erro desconhecido.') return mensagem + + @api.multi + def _eletronic_document_send(self): + super(Document, self)._eletronic_document_send() + for record in self.filtered(fiter_processador_edoc_nfse_ginfes): + for record in self.filtered(fiter_provedor_ginfes): + processador = record._processador_erpbrasil_nfse() + + protocolo = record.protocolo_autorizacao + vals = dict() + + if not protocolo: + for edoc in record.serialize(): + processo = None + for p in processador.processar_documento(edoc): + processo = p + + if processo.webservice in RECEPCIONAR_LOTE_RPS: + if processo.resposta.Protocolo is None: + mensagem_completa = '' + if processo.resposta.ListaMensagemRetorno: + lista_msgs = processo.resposta.\ + ListaMensagemRetorno + for mr in lista_msgs.MensagemRetorno: + + correcao = '' + if mr.Correcao: + correcao = mr.Correcao + + mensagem_completa += ( + mr.Codigo + ' - ' + + mr.Mensagem + + ' - Correção: ' + + correcao + '\n' + ) + vals['edoc_error_message'] = \ + mensagem_completa + record.write(vals) + return + protocolo = processo.resposta.Protocolo + + if processo.webservice in CONSULTAR_SITUACAO_LOTE_RPS: + vals['codigo_situacao'] = \ + processo.resposta.Situacao + else: + vals['codigo_situacao'] = 4 + + if vals.get('codigo_situacao') == 1: + vals['motivo_situacao'] = _('Não Recebido') + + elif vals.get('codigo_situacao') == 2: + vals['motivo_situacao'] = _('Lote ainda não processado') + + elif vals.get('codigo_situacao') == 3: + vals['motivo_situacao'] = _('Procesado com Erro') + + elif vals.get('codigo_situacao') == 4: + vals['motivo_situacao'] = _('Procesado com Sucesso') + vals['protocolo_autorizacao'] = protocolo + + if vals.get('codigo_situacao') in (3, 4): + processo = processador.consultar_lote_rps(protocolo) + + if processo.resposta: + mensagem_completa = '' + if processo.resposta.ListaMensagemRetorno: + lista_msgs = processo.resposta.ListaMensagemRetorno + for mr in lista_msgs.MensagemRetorno: + + correcao = '' + if mr.Correcao: + correcao = mr.Correcao + + mensagem_completa += ( + mr.Codigo + ' - ' + + mr.Mensagem + + ' - Correção: ' + + correcao + '\n' + ) + vals['edoc_error_message'] = mensagem_completa + + if processo.resposta.ListaNfse: + xml_file = processador._generateds_to_string_etree( + processo.resposta)[0] + record.autorizacao_event_id.set_done(xml_file) + for comp in processo.resposta.ListaNfse.CompNfse: + vals['number'] = comp.Nfse.InfNfse.Numero + vals['data_hora_autorizacao'] = \ + comp.Nfse.InfNfse.DataEmissao + vals['verify_code'] = \ + comp.Nfse.InfNfse.CodigoVerificacao + record._change_state(SITUACAO_EDOC_AUTORIZADA) + + record.write(vals) + return From d04f1124fe49579b4a880fa63b02f3d5929c8a12 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Thu, 27 Aug 2020 08:48:17 -0300 Subject: [PATCH 28/81] [REM] Test on_change_partner_id --- l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py index 9f8f9f06feff..2f778e4b17f7 100644 --- a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -28,7 +28,6 @@ def test_nfse_ginfes(self): """ Test NFS-e same state. """ self.nfse_same_state._onchange_document_serie_id() - self.nfse_same_state._onchange_partner_id() self.nfse_same_state._onchange_fiscal_operation_id() self.nfse_same_state._onchange_company_id() self.nfse_same_state.rps_number = 50 From bc41f23edc2ed6011c7d35f1114a2875d0649691 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Thu, 27 Aug 2020 09:30:46 -0300 Subject: [PATCH 29/81] [FIX] Flake8 --- l10n_br_nfse_ginfes/models/document.py | 1 - 1 file changed, 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 29067c5b61da..6e6fcb08d0d7 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -36,7 +36,6 @@ ) - def fiter_processador_edoc_nfse_ginfes(record): if (record.processador_edoc == PROCESSADOR and record.document_type_id.code in [ From 549f8ac0569a7e742f8a834a8a216cf6a026ccc7 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Thu, 27 Aug 2020 12:39:11 -0300 Subject: [PATCH 30/81] [ADD] Updated README --- l10n_br_nfse_ginfes/README.rst | 14 ++++++++++++++ l10n_br_nfse_ginfes/__manifest__.py | 1 + l10n_br_nfse_ginfes/static/description/index.html | 2 ++ 3 files changed, 17 insertions(+) diff --git a/l10n_br_nfse_ginfes/README.rst b/l10n_br_nfse_ginfes/README.rst index 2c78090fbce6..87a5cbf9ab21 100644 --- a/l10n_br_nfse_ginfes/README.rst +++ b/l10n_br_nfse_ginfes/README.rst @@ -89,6 +89,20 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. +.. |maintainer-gabrielcardoso21| image:: https://github.com/gabrielcardoso21.png?size=40px + :target: https://github.com/gabrielcardoso21 + :alt: gabrielcardoso21 +.. |maintainer-mileo| image:: https://github.com/mileo.png?size=40px + :target: https://github.com/mileo + :alt: mileo +.. |maintainer-luismalta| image:: https://github.com/luismalta.png?size=40px + :target: https://github.com/luismalta + :alt: luismalta + +Current `maintainers `__: + +|maintainer-gabrielcardoso21| |maintainer-mileo| |maintainer-luismalta| + This module is part of the `OCA/l10n-brazil `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index 33b8dba7bb1e..3e9d9b93d5ee 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -8,6 +8,7 @@ 'version': '12.0.1.0.0', 'license': 'AGPL-3', 'author': 'KMEE, Odoo Community Association (OCA)', + 'maintainers': ['gabrielcardoso21', 'mileo', 'luismalta'], 'website': 'https://github.com/OCA/l10n-brazil', 'external_dependencies': { 'python': [ diff --git a/l10n_br_nfse_ginfes/static/description/index.html b/l10n_br_nfse_ginfes/static/description/index.html index 4d78fd8c547d..3dbbe3b5d436 100644 --- a/l10n_br_nfse_ginfes/static/description/index.html +++ b/l10n_br_nfse_ginfes/static/description/index.html @@ -433,6 +433,8 @@

Maintainers

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

+

Current maintainers:

+

gabrielcardoso21 mileo luismalta

This module is part of the OCA/l10n-brazil project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

From abec50197283d6731e933c9a0967ecfd4372ef30 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Fri, 28 Aug 2020 09:50:36 -0300 Subject: [PATCH 31/81] [REF] Rename module l10n_br_nfse_ginfes --- l10n_br_nfse_ginfes/__manifest__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index 3e9d9b93d5ee..951b29f13128 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -2,9 +2,9 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { - 'name': 'Edoc Nfse Ginfes', + 'name': 'NFS-e (Ginfes)', 'summary': """ - NFS-E Ginfes""", + NFS-e (Ginfes)""", 'version': '12.0.1.0.0', 'license': 'AGPL-3', 'author': 'KMEE, Odoo Community Association (OCA)', From d9ee04b886fd779a272e85dafda34284f65f1ff5 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Fri, 28 Aug 2020 09:51:03 -0300 Subject: [PATCH 32/81] [ADD] Ginfes constants --- l10n_br_nfse_ginfes/constants/ginfes.py | 10 ++++++++++ l10n_br_nfse_ginfes/models/document.py | 6 ++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/l10n_br_nfse_ginfes/constants/ginfes.py b/l10n_br_nfse_ginfes/constants/ginfes.py index b848d3763249..4f320d4f0348 100644 --- a/l10n_br_nfse_ginfes/constants/ginfes.py +++ b/l10n_br_nfse_ginfes/constants/ginfes.py @@ -8,3 +8,13 @@ 'ConsultarSituacaoLoteRpsV3', 'ConsultarSituacaoLoteRps' ] + +CANCELAR_NFSE = [ + 'CancelarNfseV3', + 'CancelarNfse', +], + +CONSULTAR_NFSE_POR_RPS = [ + 'ConsultarNfsePorRpsV3', + 'ConsultarNfsePorRps', +], diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 6e6fcb08d0d7..7bf1bb01e6cf 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -33,6 +33,8 @@ from ..constants.ginfes import ( RECEPCIONAR_LOTE_RPS, CONSULTAR_SITUACAO_LOTE_RPS, + CANCELAR_NFSE, + CONSULTAR_NFSE_POR_RPS, ) @@ -163,7 +165,7 @@ def cancelar_documento(self): processador = record._processador_erpbrasil_nfse() processo = processador.cancela_documento(doc_numero=self.number) - if processo.webservice == 'CancelarNfseV3': + if processo.webservice in CANCELAR_NFSE: mensagem_completa = '' situacao = True retorno = ET.fromstring(processo.retorno) @@ -194,7 +196,7 @@ def action_consultar_nfse_rps(self): nsmap = {'consulta': 'http://www.ginfes.com.br/servico_consultar_' 'nfse_rps_resposta_v03.xsd', 'tipo': 'http://www.ginfes.com.br/tipos_v03.xsd'} - if processo.webservice == 'ConsultarNfsePorRpsV3': + if processo.webservice in CONSULTAR_NFSE_POR_RPS: enviado = retorno.findall( ".//consulta:CompNfse", namespaces=nsmap) nao_encontrado = retorno.findall( From 5cbcf11312bca895e8842867eebd8c3fc924c3ca Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Fri, 28 Aug 2020 11:11:17 -0300 Subject: [PATCH 33/81] [REF] Analisa retorno consulta --- l10n_br_nfse_ginfes/models/document.py | 81 +++----------------------- 1 file changed, 7 insertions(+), 74 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 7bf1bb01e6cf..59b24e6e7334 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -192,80 +192,13 @@ def action_consultar_nfse_rps(self): processo = processador.consulta_nfse_rps( self.rps_number, self.document_serie, self.rps_type) - retorno = ET.fromstring(processo.retorno) - nsmap = {'consulta': 'http://www.ginfes.com.br/servico_consultar_' - 'nfse_rps_resposta_v03.xsd', - 'tipo': 'http://www.ginfes.com.br/tipos_v03.xsd'} - if processo.webservice in CONSULTAR_NFSE_POR_RPS: - enviado = retorno.findall( - ".//consulta:CompNfse", namespaces=nsmap) - nao_encontrado = retorno.findall( - ".//tipo:MensagemRetorno", namespaces=nsmap) - - if enviado: - # NFS-e já foi enviada - - cancelada = retorno.findall( - ".//tipo:NfseCancelamento", namespaces=nsmap) - - if cancelada: - # NFS-e enviada foi cancelada - - data = retorno.findall( - ".//tipo:DataHora", namespaces=nsmap)[0].text - data = datetime.strptime(data, '%Y-%m-%dT%H:%M:%S').\ - strftime("%m/%d/%Y") - mensagem = _('NFS-e cancelada em ' + data) - return mensagem - - else: - numero = retorno.findall(".//tipo:InfNfse/tipo:Numero", - namespaces=nsmap)[0].text - cnpj_prestador = retorno.findall( - ".//tipo:IdentificacaoPrestador/tipo:Cnpj", - namespaces=nsmap)[0].text - razao_social_prestador = retorno.findall( - ".//tipo:PrestadorServico/tipo:RazaoSocial", - namespaces=nsmap)[0].text - - varibles_error = [] - - if numero != self.number: - varibles_error.append('Número') - if cnpj_prestador != misc.punctuation_rm( - self.company_cnpj_cpf): - varibles_error.append('CNPJ do prestador') - if razao_social_prestador != self.company_legal_name: - varibles_error.append('Razão Social de pestrador') - - if varibles_error: - mensagem = _('Os seguintes campos não condizem com' - ' o provedor NFS-e: \n') - mensagem += '\n'.join(varibles_error) - return mensagem - else: - return _( - "NFS-e enviada e corresponde com o provedor") - - elif nao_encontrado: - # NFS-e não foi enviada - - mensagem_erro = retorno.findall( - ".//tipo:Mensagem", namespaces=nsmap)[0].text - correcao = retorno.findall( - ".//tipo:Correcao", namespaces=nsmap)[0].text - codigo = retorno.findall( - ".//tipo:Codigo", namespaces=nsmap)[0].text - mensagem = _( - codigo + ' - ' + mensagem_erro + - ' - Correção: ' + correcao + '\n' - ) - - return mensagem - - else: - mensagem = _('Erro desconhecido.') - return mensagem + return _( + processador.analisa_retorno_consulta( + processo, + self.number, + self.company_cnpj_cpf, + self.company_legal_name) + ) @api.multi def _eletronic_document_send(self): From 7cc84969d73feed82b734b916d32ff2b51c5e6b8 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Mon, 14 Sep 2020 18:48:55 -0300 Subject: [PATCH 34/81] [FIX] Flake8 --- l10n_br_nfse_ginfes/models/document.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 59b24e6e7334..d00330025fd5 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -3,8 +3,6 @@ import xml.etree.ElementTree as ET -from datetime import datetime -from erpbrasil.base import misc from nfselib.ginfes.v3_01.tipos_v03 import ( ListaRpsType, tcCpfCnpj, @@ -34,7 +32,6 @@ RECEPCIONAR_LOTE_RPS, CONSULTAR_SITUACAO_LOTE_RPS, CANCELAR_NFSE, - CONSULTAR_NFSE_POR_RPS, ) From 5d181eddc736eea962f13519c7e95c77c0f34cac Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Tue, 15 Sep 2020 10:19:43 -0300 Subject: [PATCH 35/81] [FIX] Update test NFSe with Cnae Code --- l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml index 4182e31bfb5f..c960d0953012 100644 --- a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml +++ b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml @@ -35,6 +35,7 @@ 100.00 105 + 3101-2/00 6311900 [ODOO_DEV] Customized Odoo Development 3132404 From cbff6c7587edf7decab14c3152681b70eca7da01 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Wed, 16 Sep 2020 08:40:31 -0300 Subject: [PATCH 36/81] [REF] Move analisa_retorno_cancelamento to erpbrasil.edoc --- l10n_br_nfse_ginfes/models/document.py | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index d00330025fd5..0bf38ba904fd 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -2,7 +2,6 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import xml.etree.ElementTree as ET from nfselib.ginfes.v3_01.tipos_v03 import ( ListaRpsType, tcCpfCnpj, @@ -31,7 +30,6 @@ from ..constants.ginfes import ( RECEPCIONAR_LOTE_RPS, CONSULTAR_SITUACAO_LOTE_RPS, - CANCELAR_NFSE, ) @@ -162,26 +160,7 @@ def cancelar_documento(self): processador = record._processador_erpbrasil_nfse() processo = processador.cancela_documento(doc_numero=self.number) - if processo.webservice in CANCELAR_NFSE: - mensagem_completa = '' - situacao = True - retorno = ET.fromstring(processo.retorno) - nsmap = {'tipo': 'http://www.ginfes.com.br/tipos_v03.xsd'} - - sucesso = retorno.findall(".//tipo:Sucesso", namespaces=nsmap) - if not sucesso: - mensagem_erro = retorno.findall( - ".//tipo:Mensagem", namespaces=nsmap)[0].text - correcao = retorno.findall( - ".//tipo:Correcao", namespaces=nsmap)[0].text - codigo = retorno.findall( - ".//tipo:Codigo", namespaces=nsmap)[0].text - mensagem_completa += ( - codigo + ' - ' + mensagem_erro + - ' - Correção: ' + correcao + '\n') - situacao = False - - return situacao, mensagem_completa + return processador.analisa_retorno_cancelamento(processo) def action_consultar_nfse_rps(self): for record in self.filtered(fiter_processador_edoc_nfse_ginfes): From 89a728f26c8f56906a5c8ff7e6ef5ac47f5b6966 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Wed, 16 Sep 2020 09:32:54 -0300 Subject: [PATCH 37/81] [FIX] Update test nfse ginfes --- l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml index c960d0953012..023acb07b5db 100644 --- a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml +++ b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml @@ -35,7 +35,7 @@ 100.00 105 - 3101-2/00 + 3101200 6311900 [ODOO_DEV] Customized Odoo Development 3132404 From 55d588a1cae2c0d435c73a3961124024be18614f Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Mon, 28 Sep 2020 08:56:24 -0300 Subject: [PATCH 38/81] [FIX] Update nfse_ginfes XML --- l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml index 023acb07b5db..306c5b511673 100644 --- a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml +++ b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml @@ -27,11 +27,11 @@ 0.00 0.00 2 - 0.00 + 5.00 0.00 0.00 - 0.00 - 0.00 + 100.00 + 0.05 100.00 105 From f681c1aa92d3f660a14c50f4760a09c3e7e0cabd Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Thu, 15 Oct 2020 07:20:13 -0300 Subject: [PATCH 39/81] [REF] New nfselib structure --- l10n_br_nfse_ginfes/models/document.py | 183 ++++++++++++++++++------- 1 file changed, 130 insertions(+), 53 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 0bf38ba904fd..dc8d9a69584c 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -2,7 +2,8 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from nfselib.ginfes.v3_01.tipos_v03 import ( +from nfselib.ginfes.v3_01.servico_enviar_lote_rps_envio import ( + EnviarLoteRpsEnvio, ListaRpsType, tcCpfCnpj, tcDadosServico, @@ -16,8 +17,6 @@ tcRps, tcValores, ) -from nfselib.ginfes.v3_01.servico_enviar_lote_rps_envio_v03 import \ - EnviarLoteRpsEnvio from odoo import models, api, _ from odoo.addons.l10n_br_fiscal.constants.fiscal import ( @@ -52,6 +51,26 @@ class Document(models.Model): _inherit = 'l10n_br_fiscal.document' + def convert_type_nfselib(self, class_object, object_filed, value): + if value is None: + return value + + value_type = '' + for field in class_object().member_data_items_: + if field.name == object_filed: + value_type = field.child_attrs.get('type', '').\ + replace('xsd:', '') + break + + if value_type in ('int', 'byte', 'nonNegativeInteger'): + return int(value) + elif value_type == 'decimal': + return float(value) + elif value_type == 'string': + return str(value) + else: + return value + def _serialize(self, edocs): edocs = super(Document, self)._serialize(edocs) for record in self.filtered( @@ -65,26 +84,48 @@ def _serialize_dados_servico(self): dados = self._prepare_dados_servico() return tcDadosServico( Valores=tcValores( - ValorServicos=dados['valor_servicos'], - ValorDeducoes=dados['valor_deducoes'], - ValorPis=dados['valor_pis'], - ValorCofins=dados['valor_cofins'], - ValorInss=dados['valor_inss'], - ValorIr=dados['valor_ir'], - ValorCsll=dados['valor_csll'], - IssRetido=dados['iss_retido'], - ValorIss=dados['valor_iss'], - ValorIssRetido=dados['valor_iss_retido'], - OutrasRetencoes=dados['outras_retencoes'], - BaseCalculo=dados['base_calculo'], - Aliquota=dados['aliquota'], - ValorLiquidoNfse=dados['valor_liquido_nfse'], + ValorServicos=self.convert_type_nfselib( + tcValores, 'ValorServicos', dados['valor_servicos']), + ValorDeducoes=self.convert_type_nfselib( + tcValores, 'ValorDeducoes', dados['valor_deducoes']), + ValorPis=self.convert_type_nfselib( + tcValores, 'ValorPis', dados['valor_pis']), + ValorCofins=self.convert_type_nfselib( + tcValores, 'ValorCofins', dados['valor_cofins']), + ValorInss=self.convert_type_nfselib( + tcValores, 'ValorInss', dados['valor_inss']), + ValorIr=self.convert_type_nfselib( + tcValores, 'ValorIr', dados['valor_ir']), + ValorCsll=self.convert_type_nfselib( + tcValores, 'ValorIr', dados['valor_csll']), + IssRetido=self.convert_type_nfselib( + tcValores, 'IssRetido', dados['iss_retido']), + ValorIss=self.convert_type_nfselib( + tcValores, 'ValorIss', dados['valor_iss']), + ValorIssRetido=self.convert_type_nfselib( + tcValores, 'ValorIssRetido', dados['valor_iss_retido']), + OutrasRetencoes=self.convert_type_nfselib( + tcValores, 'OutrasRetencoes', dados['outras_retencoes']), + BaseCalculo=self.convert_type_nfselib( + tcValores, 'BaseCalculo', dados['base_calculo']), + Aliquota=self.convert_type_nfselib( + tcValores, 'Aliquota', dados['aliquota']), + ValorLiquidoNfse=self.convert_type_nfselib( + tcValores, 'ValorLiquidoNfse', + dados['valor_liquido_nfse']), ), - ItemListaServico=dados['item_lista_servico'], - CodigoCnae=dados['codigo_cnae'], - CodigoTributacaoMunicipio=dados['codigo_tributacao_municipio'], - Discriminacao=dados['discriminacao'], - CodigoMunicipio=dados['codigo_municipio'], + ItemListaServico=self.convert_type_nfselib( + tcDadosServico, 'ItemListaServico', + dados['item_lista_servico']), + CodigoCnae=self.convert_type_nfselib( + tcDadosServico, 'CodigoCnae', dados['codigo_cnae']), + CodigoTributacaoMunicipio=self.convert_type_nfselib( + tcDadosServico, 'CodigoTributacaoMunicipio', + dados['codigo_tributacao_municipio']), + Discriminacao=self.convert_type_nfselib( + tcDadosServico, 'Discriminacao', dados['discriminacao']), + CodigoMunicipio=self.convert_type_nfselib( + tcDadosServico, 'CodigoMunicipio', dados['codigo_municipio']), ) def _serialize_dados_tomador(self): @@ -92,20 +133,30 @@ def _serialize_dados_tomador(self): return tcDadosTomador( IdentificacaoTomador=tcIdentificacaoTomador( CpfCnpj=tcCpfCnpj( - Cnpj=dados['cnpj'], - Cpf=dados['cpf'], + Cnpj=self.convert_type_nfselib( + tcCpfCnpj, 'Cnpj', dados['cnpj']), + Cpf=self.convert_type_nfselib( + tcCpfCnpj, 'Cpf', dados['cpf']), ), - InscricaoMunicipal=dados['inscricao_municipal'] + InscricaoMunicipal=self.convert_type_nfselib( + tcIdentificacaoTomador, 'InscricaoMunicipal', + dados['inscricao_municipal']) ), - RazaoSocial=dados['razao_social'], + RazaoSocial=self.convert_type_nfselib( + tcDadosTomador, 'RazaoSocial', dados['razao_social']), Endereco=tcEndereco( - Endereco=dados['endereco'], - Numero=dados['numero'], - Complemento=dados['complemento'], - Bairro=dados['bairro'], - CodigoMunicipio=dados['codigo_municipio'], - Uf=dados['uf'], - Cep=dados['cep'], + Endereco=self.convert_type_nfselib( + tcEndereco, 'Endereco', dados['endereco']), + Numero=self.convert_type_nfselib( + tcEndereco, 'Numero', dados['numero']), + Complemento=self.convert_type_nfselib( + tcEndereco, 'Complemento', dados['complemento']), + Bairro=self.convert_type_nfselib( + tcEndereco, 'Bairro', dados['bairro']), + CodigoMunicipio=self.convert_type_nfselib( + tcEndereco, 'CodigoMunicipio', dados['codigo_municipio']), + Uf=self.convert_type_nfselib(tcEndereco, 'Uf', dados['uf']), + Cep=self.convert_type_nfselib(tcEndereco, 'Cep', dados['cep']), ) or None, ) @@ -115,34 +166,55 @@ def _serialize_rps(self, dados): InfRps=tcInfRps( Id=dados['id'], IdentificacaoRps=tcIdentificacaoRps( - Numero=dados['numero'], - Serie=dados['serie'], - Tipo=dados['tipo'], + Numero=self.convert_type_nfselib( + tcIdentificacaoRps, 'Numero', dados['numero']), + Serie=self.convert_type_nfselib( + tcIdentificacaoRps, 'Serie', dados['serie']), + Tipo=self.convert_type_nfselib( + tcIdentificacaoRps, 'Tipo', dados['tipo']), ), - DataEmissao=dados['data_emissao'], - NaturezaOperacao=dados['natureza_operacao'], - RegimeEspecialTributacao=dados['regime_especial_tributacao'], - OptanteSimplesNacional=dados['optante_simples_nacional'], - IncentivadorCultural=dados['incentivador_cultural'], - Status=dados['status'], - RpsSubstituido=dados['rps_substitiuido'], + DataEmissao=self.convert_type_nfselib( + tcInfRps, 'DataEmissao', dados['data_emissao']), + NaturezaOperacao=self.convert_type_nfselib( + tcInfRps, 'NaturezaOperacao', dados['natureza_operacao']), + RegimeEspecialTributacao=self.convert_type_nfselib( + tcInfRps, 'RegimeEspecialTributacao', + dados['regime_especial_tributacao']), + OptanteSimplesNacional=self.convert_type_nfselib( + tcInfRps, 'OptanteSimplesNacional', + dados['optante_simples_nacional']), + IncentivadorCultural=self.convert_type_nfselib( + tcInfRps, 'IncentivadorCultural', + dados['incentivador_cultural']), + Status=self.convert_type_nfselib( + tcInfRps, 'Status', dados['status']), + RpsSubstituido=self.convert_type_nfselib( + tcInfRps, 'RpsSubstituido', dados['rps_substitiuido']), Servico=self._serialize_dados_servico(), Prestador=tcIdentificacaoPrestador( - Cnpj=dados['cnpj'], - InscricaoMunicipal=dados['inscricao_municipal'], + Cnpj=self.convert_type_nfselib( + tcIdentificacaoPrestador, 'InscricaoMunicipal', + dados['cnpj']), + InscricaoMunicipal=self.convert_type_nfselib( + tcIdentificacaoPrestador, 'InscricaoMunicipal', + dados['inscricao_municipal']), ), Tomador=self._serialize_dados_tomador(), - IntermediarioServico=dados['intermediario_servico'], - ConstrucaoCivil=dados['construcao_civil'], + IntermediarioServico=self.convert_type_nfselib( + tcInfRps, 'IntermediarioServico', + dados['intermediario_servico']), + ConstrucaoCivil=self.convert_type_nfselib( + tcInfRps, 'ConstrucaoCivil', dados['construcao_civil']), ) ) def _serialize_lote_rps(self): dados = self._prepare_lote_rps() return tcLoteRps( - Cnpj=dados['cnpj'], - InscricaoMunicipal=dados['inscricao_municipal'], - QuantidadeRps='1', + Cnpj=self.convert_type_nfselib(tcLoteRps, 'Cnpj', dados['cnpj']), + InscricaoMunicipal=self.convert_type_nfselib( + tcLoteRps, 'InscricaoMunicipal', dados['inscricao_municipal']), + QuantidadeRps=1, ListaRps=ListaRpsType( Rps=[self._serialize_rps(dados)] ) @@ -155,10 +227,10 @@ def serialize_nfse_ginfes(self): ) return lote_rps - def cancelar_documento(self): + def cancel_document_ginfes(self): for record in self.filtered(fiter_processador_edoc_nfse_ginfes): processador = record._processador_erpbrasil_nfse() - processo = processador.cancela_documento(doc_numero=self.number) + processo = processador.cancela_documento(doc_numero=int(self.number)) return processador.analisa_retorno_cancelamento(processo) @@ -166,7 +238,7 @@ def action_consultar_nfse_rps(self): for record in self.filtered(fiter_processador_edoc_nfse_ginfes): processador = record._processador_erpbrasil_nfse() processo = processador.consulta_nfse_rps( - self.rps_number, self.document_serie, self.rps_type) + int(self.rps_number), self.document_serie, int(self.rps_type)) return _( processador.analisa_retorno_consulta( @@ -270,3 +342,8 @@ def _eletronic_document_send(self): record.write(vals) return + + def _exec_before_SITUACAO_EDOC_CANCELADA(self, old_state, new_state): + super(Document, self)._exec_before_SITUACAO_EDOC_CANCELADA( + old_state, new_state) + self.cancel_document_ginfes() From 8928a072a3f9d6a33f1260c672f3f5395bd68e13 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Thu, 15 Oct 2020 08:44:30 -0300 Subject: [PATCH 40/81] [IMP] Update ginfes nfse xml test --- .../tests/nfse/001_50_nfse.xml | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml index 306c5b511673..77db322e206d 100644 --- a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml +++ b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml @@ -19,20 +19,20 @@ 1 - 100.00 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 + 100 + 0 + 0 + 0 + 0 + 0 + 0 2 - 5.00 - 0.00 - 0.00 - 100.00 + 5 + 0 + 0 + 100 0.05 - 100.00 + 100 105 3101200 From 3fff762765e269e74b06c3bde49bfec484fdbbec Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Tue, 27 Oct 2020 07:58:28 -0300 Subject: [PATCH 41/81] [IMP] Return values from cancel workflow --- l10n_br_nfse_ginfes/models/document.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index dc8d9a69584c..ae901f83d73f 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -232,7 +232,10 @@ def cancel_document_ginfes(self): processador = record._processador_erpbrasil_nfse() processo = processador.cancela_documento(doc_numero=int(self.number)) - return processador.analisa_retorno_cancelamento(processo) + status, message = \ + processador.analisa_retorno_cancelamento(processo) + + return status def action_consultar_nfse_rps(self): for record in self.filtered(fiter_processador_edoc_nfse_ginfes): @@ -346,4 +349,4 @@ def _eletronic_document_send(self): def _exec_before_SITUACAO_EDOC_CANCELADA(self, old_state, new_state): super(Document, self)._exec_before_SITUACAO_EDOC_CANCELADA( old_state, new_state) - self.cancel_document_ginfes() + return self.cancel_document_ginfes() From 5f3265a24bb4c477f453ba89e8a9cf9137042886 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Wed, 11 Nov 2020 11:40:08 -0300 Subject: [PATCH 42/81] [FIX] xml resposta da consulta apos envio --- l10n_br_nfse_ginfes/models/document.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index ae901f83d73f..330a8f65a2a1 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -332,8 +332,7 @@ def _eletronic_document_send(self): vals['edoc_error_message'] = mensagem_completa if processo.resposta.ListaNfse: - xml_file = processador._generateds_to_string_etree( - processo.resposta)[0] + xml_file = processo.retorno record.autorizacao_event_id.set_done(xml_file) for comp in processo.resposta.ListaNfse.CompNfse: vals['number'] = comp.Nfse.InfNfse.Numero From 1a77b2c9d6c135814f8cac51a8d00467ead44527 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Thu, 12 Nov 2020 07:44:40 -0300 Subject: [PATCH 43/81] [REF] nfse consulta_nfse_rps method with kwargs --- l10n_br_nfse_ginfes/models/document.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 330a8f65a2a1..bca6cad39c68 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -241,7 +241,10 @@ def action_consultar_nfse_rps(self): for record in self.filtered(fiter_processador_edoc_nfse_ginfes): processador = record._processador_erpbrasil_nfse() processo = processador.consulta_nfse_rps( - int(self.rps_number), self.document_serie, int(self.rps_type)) + rps_number=int(self.rps_number), + rps_serie=self.document_serie, + rps_type=int(self.rps_type) + ) return _( processador.analisa_retorno_consulta( From 4cc1988d4a7d4f4a5ee41f39ba94ea280dcb3571 Mon Sep 17 00:00:00 2001 From: Luis Malta Date: Fri, 13 Nov 2020 10:00:48 -0300 Subject: [PATCH 44/81] [REF] Change dependency on nfselib.ginfes --- l10n_br_nfse_ginfes/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index 951b29f13128..2311cc0b36a1 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -16,7 +16,7 @@ 'erpbrasil.assinatura', 'erpbrasil.transmissao', 'erpbrasil.base', - 'nfselib', + 'nfselib.ginfes', ], }, 'depends': [ From 274f829e27bee83ba33bee5c973be82334c0bcf4 Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Tue, 24 Nov 2020 08:02:34 -0300 Subject: [PATCH 45/81] [ADD] Development status --- l10n_br_nfse_ginfes/__manifest__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index 2311cc0b36a1..20a82b209345 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -10,6 +10,7 @@ 'author': 'KMEE, Odoo Community Association (OCA)', 'maintainers': ['gabrielcardoso21', 'mileo', 'luismalta'], 'website': 'https://github.com/OCA/l10n-brazil', + "development_status": "Alpha", 'external_dependencies': { 'python': [ 'erpbrasil.edoc', From b6e03b1d9b34e35f790932f685d243c0db67d1b7 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Tue, 24 Nov 2020 12:19:46 +0000 Subject: [PATCH 46/81] [UPD] Update l10n_br_nfse_ginfes.pot --- .../i18n/l10n_br_nfse_ginfes.pot | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot diff --git a/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot b/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot new file mode 100644 index 000000000000..749de2e0a492 --- /dev/null +++ b/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot @@ -0,0 +1,59 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_br_nfse_ginfes +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: l10n_br_nfse_ginfes +#: model:ir.model,name:l10n_br_nfse_ginfes.model_res_company +msgid "Companies" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: model:ir.model,name:l10n_br_nfse_ginfes.model_l10n_br_fiscal_document +msgid "Fiscal Document" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: selection:res.company,provedor_nfse:0 +msgid "Ginfes" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: code:addons/l10n_br_nfse_ginfes/models/document.py:307 +#, python-format +msgid "Lote ainda não processado" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: model:ir.model.fields,field_description:l10n_br_nfse_ginfes.field_res_company__provedor_nfse +msgid "NFSe Provider" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: code:addons/l10n_br_nfse_ginfes/models/document.py:304 +#, python-format +msgid "Não Recebido" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: code:addons/l10n_br_nfse_ginfes/models/document.py:310 +#, python-format +msgid "Procesado com Erro" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: code:addons/l10n_br_nfse_ginfes/models/document.py:313 +#, python-format +msgid "Procesado com Sucesso" +msgstr "" + From 31baae0bd58ceb8a2ffa50169f34073d9d14815c Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 24 Nov 2020 12:34:20 +0000 Subject: [PATCH 47/81] [UPD] README.rst --- l10n_br_nfse_ginfes/README.rst | 15 ++++++++++----- l10n_br_nfse_ginfes/static/description/index.html | 14 ++++++++++---- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/l10n_br_nfse_ginfes/README.rst b/l10n_br_nfse_ginfes/README.rst index 87a5cbf9ab21..6763cb1c96fb 100644 --- a/l10n_br_nfse_ginfes/README.rst +++ b/l10n_br_nfse_ginfes/README.rst @@ -1,15 +1,15 @@ -================ -Edoc Nfse Ginfes -================ +============== +NFS-e (Ginfes) +============== .. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png :target: https://odoo-community.org/page/development-status - :alt: Beta + :alt: Alpha .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 @@ -27,6 +27,11 @@ Edoc Nfse Ginfes Esse módulo completa o documento criado pelo l10n_br_nfse para permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e) pelo sistema GINFES. +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ + **Table of contents** .. contents:: diff --git a/l10n_br_nfse_ginfes/static/description/index.html b/l10n_br_nfse_ginfes/static/description/index.html index 3dbbe3b5d436..21bf49bd13d9 100644 --- a/l10n_br_nfse_ginfes/static/description/index.html +++ b/l10n_br_nfse_ginfes/static/description/index.html @@ -4,7 +4,7 @@ -Edoc Nfse Ginfes +NFS-e (Ginfes) -
-

Edoc Nfse Ginfes

+
+

NFS-e (Ginfes)

-

Beta License: AGPL-3 OCA/l10n-brazil Translate me on Weblate Try me on Runbot

+

Alpha License: AGPL-3 OCA/l10n-brazil Translate me on Weblate Try me on Runbot

Esse módulo completa o documento criado pelo l10n_br_nfse para permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e) pelo sistema GINFES.

+
+

Important

+

This is an alpha version, the data model and design can change at any time without warning. +Only for development or testing purpose, do not use in production. +More details on development status

+

Table of contents

    From 3f1672795e48a8b239e2e0e189543ac6907b88f5 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 24 Nov 2020 12:34:20 +0000 Subject: [PATCH 48/81] l10n_br_nfse_ginfes 12.0.1.1.0 --- l10n_br_nfse_ginfes/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index 20a82b209345..b5e53561988e 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -5,7 +5,7 @@ 'name': 'NFS-e (Ginfes)', 'summary': """ NFS-e (Ginfes)""", - 'version': '12.0.1.0.0', + 'version': '12.0.1.1.0', 'license': 'AGPL-3', 'author': 'KMEE, Odoo Community Association (OCA)', 'maintainers': ['gabrielcardoso21', 'mileo', 'luismalta'], From f39cc5f2d6b1a6a9e76d4abe11e1316d44eb85d1 Mon Sep 17 00:00:00 2001 From: Marcel Savegnago Date: Thu, 17 Dec 2020 05:23:37 +0000 Subject: [PATCH 49/81] Added translation using Weblate (Portuguese (Brazil)) --- l10n_br_nfse_ginfes/i18n/pt_BR.po | 59 +++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 l10n_br_nfse_ginfes/i18n/pt_BR.po diff --git a/l10n_br_nfse_ginfes/i18n/pt_BR.po b/l10n_br_nfse_ginfes/i18n/pt_BR.po new file mode 100644 index 000000000000..48f783739e91 --- /dev/null +++ b/l10n_br_nfse_ginfes/i18n/pt_BR.po @@ -0,0 +1,59 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_br_nfse_ginfes +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" + +#. module: l10n_br_nfse_ginfes +#: model:ir.model,name:l10n_br_nfse_ginfes.model_res_company +msgid "Companies" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: model:ir.model,name:l10n_br_nfse_ginfes.model_l10n_br_fiscal_document +msgid "Fiscal Document" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: selection:res.company,provedor_nfse:0 +msgid "Ginfes" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: code:addons/l10n_br_nfse_ginfes/models/document.py:307 +#, python-format +msgid "Lote ainda não processado" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: model:ir.model.fields,field_description:l10n_br_nfse_ginfes.field_res_company__provedor_nfse +msgid "NFSe Provider" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: code:addons/l10n_br_nfse_ginfes/models/document.py:304 +#, python-format +msgid "Não Recebido" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: code:addons/l10n_br_nfse_ginfes/models/document.py:310 +#, python-format +msgid "Procesado com Erro" +msgstr "" + +#. module: l10n_br_nfse_ginfes +#: code:addons/l10n_br_nfse_ginfes/models/document.py:313 +#, python-format +msgid "Procesado com Sucesso" +msgstr "" From df5aa307bfa95b95d43b82c6d673b8880c306f6b Mon Sep 17 00:00:00 2001 From: Marcel Savegnago Date: Thu, 17 Dec 2020 05:24:14 +0000 Subject: [PATCH 50/81] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (8 of 8 strings) Translation: l10n-brazil-12.0/l10n-brazil-12.0-l10n_br_nfse_ginfes Translate-URL: https://translation.odoo-community.org/projects/l10n-brazil-12-0/l10n-brazil-12-0-l10n_br_nfse_ginfes/pt_BR/ --- l10n_br_nfse_ginfes/i18n/pt_BR.po | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/l10n_br_nfse_ginfes/i18n/pt_BR.po b/l10n_br_nfse_ginfes/i18n/pt_BR.po index 48f783739e91..93216b96446a 100644 --- a/l10n_br_nfse_ginfes/i18n/pt_BR.po +++ b/l10n_br_nfse_ginfes/i18n/pt_BR.po @@ -6,54 +6,56 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2020-12-17 05:24+0000\n" +"Last-Translator: Marcel Savegnago \n" "Language-Team: none\n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.3.2\n" #. module: l10n_br_nfse_ginfes #: model:ir.model,name:l10n_br_nfse_ginfes.model_res_company msgid "Companies" -msgstr "" +msgstr "Empresas" #. module: l10n_br_nfse_ginfes #: model:ir.model,name:l10n_br_nfse_ginfes.model_l10n_br_fiscal_document msgid "Fiscal Document" -msgstr "" +msgstr "Documento Fiscal" #. module: l10n_br_nfse_ginfes #: selection:res.company,provedor_nfse:0 msgid "Ginfes" -msgstr "" +msgstr "Ginfes" #. module: l10n_br_nfse_ginfes #: code:addons/l10n_br_nfse_ginfes/models/document.py:307 #, python-format msgid "Lote ainda não processado" -msgstr "" +msgstr "Lote ainda não processado" #. module: l10n_br_nfse_ginfes #: model:ir.model.fields,field_description:l10n_br_nfse_ginfes.field_res_company__provedor_nfse msgid "NFSe Provider" -msgstr "" +msgstr "Provedor NFSe" #. module: l10n_br_nfse_ginfes #: code:addons/l10n_br_nfse_ginfes/models/document.py:304 #, python-format msgid "Não Recebido" -msgstr "" +msgstr "Não Recebido" #. module: l10n_br_nfse_ginfes #: code:addons/l10n_br_nfse_ginfes/models/document.py:310 #, python-format msgid "Procesado com Erro" -msgstr "" +msgstr "Procesado com Erro" #. module: l10n_br_nfse_ginfes #: code:addons/l10n_br_nfse_ginfes/models/document.py:313 #, python-format msgid "Procesado com Sucesso" -msgstr "" +msgstr "Procesado com Sucesso" From 2a746b8949fc0ea9edab3420d1176da292a44772 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Mon, 11 Jan 2021 19:11:48 +0000 Subject: [PATCH 51/81] [UPD] Update l10n_br_nfse_ginfes.pot --- l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot b/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot index 749de2e0a492..9f19c65e3351 100644 --- a/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot +++ b/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot @@ -28,6 +28,11 @@ msgstr "" msgid "Ginfes" msgstr "" +#. module: l10n_br_nfse_ginfes +#: selection:res.company,provedor_nfse:0 +msgid "ISSNet / Nota Control" +msgstr "" + #. module: l10n_br_nfse_ginfes #: code:addons/l10n_br_nfse_ginfes/models/document.py:307 #, python-format From 9e9f490846a5db0fd13d910a1cd9a69f26893f19 Mon Sep 17 00:00:00 2001 From: Marcel Savegnago Date: Wed, 10 Feb 2021 15:25:57 -0300 Subject: [PATCH 52/81] [FIX] test --- .../tests/test_fiscal_document_nfse_ginfes.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py index 2f778e4b17f7..a9f6b5c8d030 100644 --- a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -27,12 +27,14 @@ def setUp(self): def test_nfse_ginfes(self): """ Test NFS-e same state. """ + xml_path = os.path.join( + l10n_br_nfse_ginfes.__path__[0], 'tests', 'nfse', + '001_50_nfse.xml') + self.nfse_same_state._onchange_document_serie_id() self.nfse_same_state._onchange_fiscal_operation_id() self.nfse_same_state._onchange_company_id() self.nfse_same_state.rps_number = 50 - self.nfse_same_state.date = datetime.strptime( - '2020-06-04T11:58:46', '%Y-%m-%dT%H:%M:%S') for line in self.nfse_same_state.line_ids: line._onchange_product_id_fiscal() @@ -44,13 +46,18 @@ def test_nfse_ginfes(self): self.nfse_same_state.action_document_confirm() - xml_path = os.path.join( - l10n_br_nfse_ginfes.__path__[0], 'tests', 'nfse', - '001_50_nfse.xml') + self.nfse_same_state.date = datetime.strptime( + '2020-06-04T11:58:46', '%Y-%m-%dT%H:%M:%S') + self.nfse_same_state.date_in_out = datetime.strptime( + '2020-06-04T11:58:46', '%Y-%m-%dT%H:%M:%S') + + self.nfse_same_state.with_context(lang='pt_BR')._document_export() + output = os.path.join(config['data_dir'], 'filestore', self.cr.dbname, self.nfse_same_state.file_xml_id.store_fname) _logger.info("XML file saved at %s" % (output,)) diff = main.diff_files(xml_path, output) _logger.info("Diff with expected XML (if any): %s" % (diff,)) + assert len(diff) == 0 From 9706ed9ef9cb42a489a735601f32448134555529 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 12 Feb 2021 20:23:29 +0000 Subject: [PATCH 53/81] l10n_br_nfse_ginfes 12.0.1.1.1 --- l10n_br_nfse_ginfes/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index b5e53561988e..3a85368ec253 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -5,7 +5,7 @@ 'name': 'NFS-e (Ginfes)', 'summary': """ NFS-e (Ginfes)""", - 'version': '12.0.1.1.0', + 'version': '12.0.1.1.1', 'license': 'AGPL-3', 'author': 'KMEE, Odoo Community Association (OCA)', 'maintainers': ['gabrielcardoso21', 'mileo', 'luismalta'], From 8e39cc0cecb5de919f2213e49f72486aea9c5236 Mon Sep 17 00:00:00 2001 From: Gabriel Cardoso de Faria Date: Tue, 16 Mar 2021 09:38:35 -0300 Subject: [PATCH 54/81] [FIX] Tests --- l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py index a9f6b5c8d030..d68707406447 100644 --- a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -34,7 +34,8 @@ def test_nfse_ginfes(self): self.nfse_same_state._onchange_document_serie_id() self.nfse_same_state._onchange_fiscal_operation_id() self.nfse_same_state._onchange_company_id() - self.nfse_same_state.rps_number = 50 + self.nfse_same_state.rps_number = '50' + self.nfse_same_state.number = '50' for line in self.nfse_same_state.line_ids: line._onchange_product_id_fiscal() From 0fc7de3163d2d2b6350a0ebab4579668e36c515a Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Wed, 24 Mar 2021 17:59:41 -0300 Subject: [PATCH 55/81] [FIX] Processador ginfes --- l10n_br_nfse_ginfes/models/document.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index bca6cad39c68..5c0a19f0ae13 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -22,10 +22,9 @@ from odoo.addons.l10n_br_fiscal.constants.fiscal import ( MODELO_FISCAL_NFSE, SITUACAO_EDOC_AUTORIZADA, + PROCESSADOR_OCA ) -from odoo.addons.l10n_br_nfse.models.res_company import PROCESSADOR - from ..constants.ginfes import ( RECEPCIONAR_LOTE_RPS, CONSULTAR_SITUACAO_LOTE_RPS, @@ -33,7 +32,7 @@ def fiter_processador_edoc_nfse_ginfes(record): - if (record.processador_edoc == PROCESSADOR and + if (record.processador_edoc == PROCESSADOR_OCA and record.document_type_id.code in [ MODELO_FISCAL_NFSE, ]): From 8a583a351a473184578851c11858b70499984298 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Fri, 26 Mar 2021 01:56:59 +0000 Subject: [PATCH 56/81] [UPD] Update l10n_br_nfse_ginfes.pot --- l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot b/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot index 9f19c65e3351..0d4ebd73a91e 100644 --- a/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot +++ b/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot @@ -34,7 +34,7 @@ msgid "ISSNet / Nota Control" msgstr "" #. module: l10n_br_nfse_ginfes -#: code:addons/l10n_br_nfse_ginfes/models/document.py:307 +#: code:addons/l10n_br_nfse_ginfes/models/document.py:306 #, python-format msgid "Lote ainda não processado" msgstr "" @@ -45,19 +45,19 @@ msgid "NFSe Provider" msgstr "" #. module: l10n_br_nfse_ginfes -#: code:addons/l10n_br_nfse_ginfes/models/document.py:304 +#: code:addons/l10n_br_nfse_ginfes/models/document.py:303 #, python-format msgid "Não Recebido" msgstr "" #. module: l10n_br_nfse_ginfes -#: code:addons/l10n_br_nfse_ginfes/models/document.py:310 +#: code:addons/l10n_br_nfse_ginfes/models/document.py:309 #, python-format msgid "Procesado com Erro" msgstr "" #. module: l10n_br_nfse_ginfes -#: code:addons/l10n_br_nfse_ginfes/models/document.py:313 +#: code:addons/l10n_br_nfse_ginfes/models/document.py:312 #, python-format msgid "Procesado com Sucesso" msgstr "" From f2fd678f88d8cc8a250afc7ec742badf37b1de24 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 26 Mar 2021 02:20:09 +0000 Subject: [PATCH 57/81] l10n_br_nfse_ginfes 12.0.2.0.0 --- l10n_br_nfse_ginfes/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index 3a85368ec253..e1cd08cb5695 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -5,7 +5,7 @@ 'name': 'NFS-e (Ginfes)', 'summary': """ NFS-e (Ginfes)""", - 'version': '12.0.1.1.1', + 'version': '12.0.2.0.0', 'license': 'AGPL-3', 'author': 'KMEE, Odoo Community Association (OCA)', 'maintainers': ['gabrielcardoso21', 'mileo', 'luismalta'], From c91030520a31045e5ddfc4e79ad4b9f031a4817f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Tue, 30 Mar 2021 03:23:56 -0300 Subject: [PATCH 58/81] typo fix, without backdoor (unlike PHP ;-) --- l10n_br_nfse_ginfes/models/document.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 5c0a19f0ae13..12bdde0b5555 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -31,7 +31,7 @@ ) -def fiter_processador_edoc_nfse_ginfes(record): +def filter_processador_edoc_nfse_ginfes(record): if (record.processador_edoc == PROCESSADOR_OCA and record.document_type_id.code in [ MODELO_FISCAL_NFSE, @@ -73,7 +73,7 @@ def convert_type_nfselib(self, class_object, object_filed, value): def _serialize(self, edocs): edocs = super(Document, self)._serialize(edocs) for record in self.filtered( - fiter_processador_edoc_nfse_ginfes).filtered( + filter_processador_edoc_nfse_ginfes).filtered( fiter_provedor_ginfes): edocs.append(record.serialize_nfse_ginfes()) return edocs @@ -227,7 +227,7 @@ def serialize_nfse_ginfes(self): return lote_rps def cancel_document_ginfes(self): - for record in self.filtered(fiter_processador_edoc_nfse_ginfes): + for record in self.filtered(filter_processador_edoc_nfse_ginfes): processador = record._processador_erpbrasil_nfse() processo = processador.cancela_documento(doc_numero=int(self.number)) @@ -237,7 +237,7 @@ def cancel_document_ginfes(self): return status def action_consultar_nfse_rps(self): - for record in self.filtered(fiter_processador_edoc_nfse_ginfes): + for record in self.filtered(filter_processador_edoc_nfse_ginfes): processador = record._processador_erpbrasil_nfse() processo = processador.consulta_nfse_rps( rps_number=int(self.rps_number), @@ -256,7 +256,7 @@ def action_consultar_nfse_rps(self): @api.multi def _eletronic_document_send(self): super(Document, self)._eletronic_document_send() - for record in self.filtered(fiter_processador_edoc_nfse_ginfes): + for record in self.filtered(filter_processador_edoc_nfse_ginfes): for record in self.filtered(fiter_provedor_ginfes): processador = record._processador_erpbrasil_nfse() From 05b0451cdeeeefec4d35ee611b82e27e8af239dc Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Mon, 19 Apr 2021 19:27:54 -0300 Subject: [PATCH 59/81] [REF] Renaming GINFES Wizard refactor --- l10n_br_nfse_ginfes/models/document.py | 2 +- l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 12bdde0b5555..c4e8b60f31c7 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -335,7 +335,7 @@ def _eletronic_document_send(self): if processo.resposta.ListaNfse: xml_file = processo.retorno - record.autorizacao_event_id.set_done(xml_file) + record.authorization_event_id.set_done(xml_file) for comp in processo.resposta.ListaNfse.CompNfse: vals['number'] = comp.Nfse.InfNfse.Numero vals['data_hora_autorizacao'] = \ diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py index d68707406447..50abee01c1f3 100644 --- a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -55,7 +55,7 @@ def test_nfse_ginfes(self): self.nfse_same_state.with_context(lang='pt_BR')._document_export() output = os.path.join(config['data_dir'], 'filestore', self.cr.dbname, - self.nfse_same_state.file_xml_id.store_fname) + self.nfse_same_state.send_file_id.store_fname) _logger.info("XML file saved at %s" % (output,)) diff = main.diff_files(xml_path, output) From a8b3cc673b61cc5aae3d693b831441cebc3ad668 Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Mon, 19 Apr 2021 21:07:49 -0300 Subject: [PATCH 60/81] [REF] Renaming GINFES fields --- l10n_br_nfse_ginfes/models/document.py | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index c4e8b60f31c7..5e1f31b9e5df 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -260,7 +260,7 @@ def _eletronic_document_send(self): for record in self.filtered(fiter_provedor_ginfes): processador = record._processador_erpbrasil_nfse() - protocolo = record.protocolo_autorizacao + protocolo = record.authorization_protocol vals = dict() if not protocolo: @@ -294,25 +294,25 @@ def _eletronic_document_send(self): protocolo = processo.resposta.Protocolo if processo.webservice in CONSULTAR_SITUACAO_LOTE_RPS: - vals['codigo_situacao'] = \ + vals['status_code'] = \ processo.resposta.Situacao else: - vals['codigo_situacao'] = 4 + vals['status_code'] = 4 - if vals.get('codigo_situacao') == 1: - vals['motivo_situacao'] = _('Não Recebido') + if vals.get('status_code') == 1: + vals['status_name'] = _('Não Recebido') - elif vals.get('codigo_situacao') == 2: - vals['motivo_situacao'] = _('Lote ainda não processado') + elif vals.get('status_code') == 2: + vals['status_name'] = _('Lote ainda não processado') - elif vals.get('codigo_situacao') == 3: - vals['motivo_situacao'] = _('Procesado com Erro') + elif vals.get('status_code') == 3: + vals['status_name'] = _('Procesado com Erro') - elif vals.get('codigo_situacao') == 4: - vals['motivo_situacao'] = _('Procesado com Sucesso') - vals['protocolo_autorizacao'] = protocolo + elif vals.get('status_code') == 4: + vals['status_name'] = _('Procesado com Sucesso') + vals['authorization_protocol'] = protocolo - if vals.get('codigo_situacao') in (3, 4): + if vals.get('status_code') in (3, 4): processo = processador.consultar_lote_rps(protocolo) if processo.resposta: @@ -338,7 +338,7 @@ def _eletronic_document_send(self): record.authorization_event_id.set_done(xml_file) for comp in processo.resposta.ListaNfse.CompNfse: vals['number'] = comp.Nfse.InfNfse.Numero - vals['data_hora_autorizacao'] = \ + vals['authorization_date'] = \ comp.Nfse.InfNfse.DataEmissao vals['verify_code'] = \ comp.Nfse.InfNfse.CodigoVerificacao From 54bc746a2cfa51a7bd6719238b05d366905a3e88 Mon Sep 17 00:00:00 2001 From: Marcel Savegnago Date: Sun, 25 Apr 2021 15:48:23 -0300 Subject: [PATCH 61/81] [FIX] l10n_br_nfse_ginfes: fix set_done() --- l10n_br_nfse_ginfes/models/document.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 5e1f31b9e5df..c1927acb43b5 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -335,13 +335,19 @@ def _eletronic_document_send(self): if processo.resposta.ListaNfse: xml_file = processo.retorno - record.authorization_event_id.set_done(xml_file) for comp in processo.resposta.ListaNfse.CompNfse: vals['number'] = comp.Nfse.InfNfse.Numero vals['authorization_date'] = \ comp.Nfse.InfNfse.DataEmissao vals['verify_code'] = \ comp.Nfse.InfNfse.CodigoVerificacao + self.authorization_event_id.set_done( + status_code=vals['status_code'], + response=vals['status_name'], + protocol_date=vals['authorization_date'], + protocol_number=protocolo, + file_response_xml=xml_file, + ) record._change_state(SITUACAO_EDOC_AUTORIZADA) record.write(vals) From 1cd3d44e6f7edb2b3c739f3c208fcb91877b3e22 Mon Sep 17 00:00:00 2001 From: Marcel Savegnago Date: Sun, 25 Apr 2021 15:57:39 -0300 Subject: [PATCH 62/81] [IMP] l10n_br_nfse_ginfes: rejected event --- l10n_br_nfse_ginfes/models/document.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index c1927acb43b5..9dad7e7262e0 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -22,7 +22,8 @@ from odoo.addons.l10n_br_fiscal.constants.fiscal import ( MODELO_FISCAL_NFSE, SITUACAO_EDOC_AUTORIZADA, - PROCESSADOR_OCA + SITUACAO_EDOC_REJEITADA, + PROCESSADOR_OCA, ) from ..constants.ginfes import ( @@ -289,6 +290,7 @@ def _eletronic_document_send(self): ) vals['edoc_error_message'] = \ mensagem_completa + record._change_state(SITUACAO_EDOC_REJEITADA) record.write(vals) return protocolo = processo.resposta.Protocolo @@ -332,6 +334,8 @@ def _eletronic_document_send(self): correcao + '\n' ) vals['edoc_error_message'] = mensagem_completa + if vals.get('status_code') == 3: + record._change_state(SITUACAO_EDOC_REJEITADA) if processo.resposta.ListaNfse: xml_file = processo.retorno From 7fa60f2ff99cafa53e13d7af65f151baa719ff04 Mon Sep 17 00:00:00 2001 From: Marcel Savegnago Date: Sun, 25 Apr 2021 15:58:22 -0300 Subject: [PATCH 63/81] [FIX] l10n_br_nfse_ginfes: remove comment and translate messages --- l10n_br_nfse_ginfes/models/document.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 9dad7e7262e0..bd31ff651ee8 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -221,7 +221,6 @@ def _serialize_lote_rps(self): ) def serialize_nfse_ginfes(self): - # numero_lote = 14 lote_rps = EnviarLoteRpsEnvio( LoteRps=self._serialize_lote_rps() ) @@ -302,16 +301,16 @@ def _eletronic_document_send(self): vals['status_code'] = 4 if vals.get('status_code') == 1: - vals['status_name'] = _('Não Recebido') + vals['status_name'] = _('Not received') elif vals.get('status_code') == 2: - vals['status_name'] = _('Lote ainda não processado') + vals['status_name'] = _('Batch not yet processed') elif vals.get('status_code') == 3: - vals['status_name'] = _('Procesado com Erro') + vals['status_name'] = _('Processed with Error') elif vals.get('status_code') == 4: - vals['status_name'] = _('Procesado com Sucesso') + vals['status_name'] = _('Successfully Processed') vals['authorization_protocol'] = protocolo if vals.get('status_code') in (3, 4): From 0a9cab03d366fca0176b01b6fa4be6c7cf1ad177 Mon Sep 17 00:00:00 2001 From: Marcel Savegnago Date: Sun, 25 Apr 2021 18:59:14 -0300 Subject: [PATCH 64/81] [IMP] l10n_br_nfse_ginfes: imp UserError when documento cancel fail. --- l10n_br_nfse_ginfes/models/document.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index bd31ff651ee8..eb1566e343c8 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -19,6 +19,7 @@ ) from odoo import models, api, _ +from odoo.exceptions import UserError from odoo.addons.l10n_br_fiscal.constants.fiscal import ( MODELO_FISCAL_NFSE, SITUACAO_EDOC_AUTORIZADA, @@ -234,6 +235,9 @@ def cancel_document_ginfes(self): status, message = \ processador.analisa_retorno_cancelamento(processo) + if not status: + raise UserError(_(message)) + return status def action_consultar_nfse_rps(self): From eda557dfc368360cfa9b05327510155db59cf7db Mon Sep 17 00:00:00 2001 From: Marcel Savegnago Date: Sun, 25 Apr 2021 19:29:23 -0300 Subject: [PATCH 65/81] [IMP] l10n_br_nfse_ginfes: change self > record --- l10n_br_nfse_ginfes/models/document.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index eb1566e343c8..bb5ab4e628be 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -230,7 +230,7 @@ def serialize_nfse_ginfes(self): def cancel_document_ginfes(self): for record in self.filtered(filter_processador_edoc_nfse_ginfes): processador = record._processador_erpbrasil_nfse() - processo = processador.cancela_documento(doc_numero=int(self.number)) + processo = processador.cancela_documento(doc_numero=int(record.number)) status, message = \ processador.analisa_retorno_cancelamento(processo) @@ -244,24 +244,24 @@ def action_consultar_nfse_rps(self): for record in self.filtered(filter_processador_edoc_nfse_ginfes): processador = record._processador_erpbrasil_nfse() processo = processador.consulta_nfse_rps( - rps_number=int(self.rps_number), - rps_serie=self.document_serie, - rps_type=int(self.rps_type) + rps_number=int(record.rps_number), + rps_serie=record.document_serie, + rps_type=int(record.rps_type) ) return _( processador.analisa_retorno_consulta( processo, - self.number, - self.company_cnpj_cpf, - self.company_legal_name) + record.number, + record.company_cnpj_cpf, + record.company_legal_name) ) @api.multi def _eletronic_document_send(self): super(Document, self)._eletronic_document_send() for record in self.filtered(filter_processador_edoc_nfse_ginfes): - for record in self.filtered(fiter_provedor_ginfes): + for record in record.filtered(fiter_provedor_ginfes): processador = record._processador_erpbrasil_nfse() protocolo = record.authorization_protocol @@ -348,7 +348,7 @@ def _eletronic_document_send(self): comp.Nfse.InfNfse.DataEmissao vals['verify_code'] = \ comp.Nfse.InfNfse.CodigoVerificacao - self.authorization_event_id.set_done( + record.authorization_event_id.set_done( status_code=vals['status_code'], response=vals['status_name'], protocol_date=vals['authorization_date'], From 03c78095e1d08d9418f572f3c3961e868e349ece Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Mon, 26 Apr 2021 06:27:59 -0300 Subject: [PATCH 66/81] [REF] Rename ginfes serialize methods to avoid collision --- l10n_br_nfse_ginfes/models/document.py | 231 ++++++++++++------------- 1 file changed, 115 insertions(+), 116 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index bb5ab4e628be..9cb3d170c832 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -33,7 +33,7 @@ ) -def filter_processador_edoc_nfse_ginfes(record): +def filter_processador_oca_nfse(record): if (record.processador_edoc == PROCESSADOR_OCA and record.document_type_id.code in [ MODELO_FISCAL_NFSE, @@ -42,7 +42,7 @@ def filter_processador_edoc_nfse_ginfes(record): return False -def fiter_provedor_ginfes(record): +def filter_ginfes(record): if record.company_id.provedor_nfse == 'ginfes': return True return False @@ -73,14 +73,14 @@ def convert_type_nfselib(self, class_object, object_filed, value): return value def _serialize(self, edocs): - edocs = super(Document, self)._serialize(edocs) + edocs = super()._serialize(edocs) for record in self.filtered( - filter_processador_edoc_nfse_ginfes).filtered( - fiter_provedor_ginfes): + filter_processador_oca_nfse).filtered( + filter_ginfes): edocs.append(record.serialize_nfse_ginfes()) return edocs - def _serialize_dados_servico(self): + def _serialize_ginfes_dados_servico(self): self.line_ids.ensure_one() dados = self._prepare_dados_servico() return tcDadosServico( @@ -129,7 +129,7 @@ def _serialize_dados_servico(self): tcDadosServico, 'CodigoMunicipio', dados['codigo_municipio']), ) - def _serialize_dados_tomador(self): + def _serialize_ginfes_dados_tomador(self): dados = self._prepare_dados_tomador() return tcDadosTomador( IdentificacaoTomador=tcIdentificacaoTomador( @@ -161,7 +161,7 @@ def _serialize_dados_tomador(self): ) or None, ) - def _serialize_rps(self, dados): + def _serialize_ginfes_rps(self, dados): return tcRps( InfRps=tcInfRps( @@ -191,7 +191,7 @@ def _serialize_rps(self, dados): tcInfRps, 'Status', dados['status']), RpsSubstituido=self.convert_type_nfselib( tcInfRps, 'RpsSubstituido', dados['rps_substitiuido']), - Servico=self._serialize_dados_servico(), + Servico=self._serialize_ginfes_dados_servico(), Prestador=tcIdentificacaoPrestador( Cnpj=self.convert_type_nfselib( tcIdentificacaoPrestador, 'InscricaoMunicipal', @@ -200,7 +200,7 @@ def _serialize_rps(self, dados): tcIdentificacaoPrestador, 'InscricaoMunicipal', dados['inscricao_municipal']), ), - Tomador=self._serialize_dados_tomador(), + Tomador=self._serialize_ginfes_dados_tomador(), IntermediarioServico=self.convert_type_nfselib( tcInfRps, 'IntermediarioServico', dados['intermediario_servico']), @@ -209,7 +209,7 @@ def _serialize_rps(self, dados): ) ) - def _serialize_lote_rps(self): + def _serialize_ginfes_lote_rps(self): dados = self._prepare_lote_rps() return tcLoteRps( Cnpj=self.convert_type_nfselib(tcLoteRps, 'Cnpj', dados['cnpj']), @@ -217,18 +217,18 @@ def _serialize_lote_rps(self): tcLoteRps, 'InscricaoMunicipal', dados['inscricao_municipal']), QuantidadeRps=1, ListaRps=ListaRpsType( - Rps=[self._serialize_rps(dados)] + Rps=[self._serialize_ginfes_rps(dados)] ) ) def serialize_nfse_ginfes(self): lote_rps = EnviarLoteRpsEnvio( - LoteRps=self._serialize_lote_rps() + LoteRps=self._serialize_ginfes_lote_rps() ) return lote_rps def cancel_document_ginfes(self): - for record in self.filtered(filter_processador_edoc_nfse_ginfes): + for record in self.filtered(filter_processador_oca_nfse): processador = record._processador_erpbrasil_nfse() processo = processador.cancela_documento(doc_numero=int(record.number)) @@ -241,7 +241,7 @@ def cancel_document_ginfes(self): return status def action_consultar_nfse_rps(self): - for record in self.filtered(filter_processador_edoc_nfse_ginfes): + for record in self.filtered(filter_processador_oca_nfse): processador = record._processador_erpbrasil_nfse() processo = processador.consulta_nfse_rps( rps_number=int(record.rps_number), @@ -259,108 +259,107 @@ def action_consultar_nfse_rps(self): @api.multi def _eletronic_document_send(self): - super(Document, self)._eletronic_document_send() - for record in self.filtered(filter_processador_edoc_nfse_ginfes): - for record in record.filtered(fiter_provedor_ginfes): - processador = record._processador_erpbrasil_nfse() - - protocolo = record.authorization_protocol - vals = dict() - - if not protocolo: - for edoc in record.serialize(): - processo = None - for p in processador.processar_documento(edoc): - processo = p - - if processo.webservice in RECEPCIONAR_LOTE_RPS: - if processo.resposta.Protocolo is None: - mensagem_completa = '' - if processo.resposta.ListaMensagemRetorno: - lista_msgs = processo.resposta.\ - ListaMensagemRetorno - for mr in lista_msgs.MensagemRetorno: - - correcao = '' - if mr.Correcao: - correcao = mr.Correcao - - mensagem_completa += ( - mr.Codigo + ' - ' + - mr.Mensagem + - ' - Correção: ' + - correcao + '\n' - ) - vals['edoc_error_message'] = \ - mensagem_completa - record._change_state(SITUACAO_EDOC_REJEITADA) - record.write(vals) - return - protocolo = processo.resposta.Protocolo - - if processo.webservice in CONSULTAR_SITUACAO_LOTE_RPS: - vals['status_code'] = \ - processo.resposta.Situacao - else: - vals['status_code'] = 4 - - if vals.get('status_code') == 1: - vals['status_name'] = _('Not received') - - elif vals.get('status_code') == 2: - vals['status_name'] = _('Batch not yet processed') - - elif vals.get('status_code') == 3: - vals['status_name'] = _('Processed with Error') - - elif vals.get('status_code') == 4: - vals['status_name'] = _('Successfully Processed') - vals['authorization_protocol'] = protocolo - - if vals.get('status_code') in (3, 4): - processo = processador.consultar_lote_rps(protocolo) - - if processo.resposta: - mensagem_completa = '' - if processo.resposta.ListaMensagemRetorno: - lista_msgs = processo.resposta.ListaMensagemRetorno - for mr in lista_msgs.MensagemRetorno: - - correcao = '' - if mr.Correcao: - correcao = mr.Correcao - - mensagem_completa += ( - mr.Codigo + ' - ' + - mr.Mensagem + - ' - Correção: ' + - correcao + '\n' - ) - vals['edoc_error_message'] = mensagem_completa - if vals.get('status_code') == 3: - record._change_state(SITUACAO_EDOC_REJEITADA) - - if processo.resposta.ListaNfse: - xml_file = processo.retorno - for comp in processo.resposta.ListaNfse.CompNfse: - vals['number'] = comp.Nfse.InfNfse.Numero - vals['authorization_date'] = \ - comp.Nfse.InfNfse.DataEmissao - vals['verify_code'] = \ - comp.Nfse.InfNfse.CodigoVerificacao - record.authorization_event_id.set_done( - status_code=vals['status_code'], - response=vals['status_name'], - protocol_date=vals['authorization_date'], - protocol_number=protocolo, - file_response_xml=xml_file, - ) - record._change_state(SITUACAO_EDOC_AUTORIZADA) - - record.write(vals) + super()._eletronic_document_send() + for record in self.filtered( + filter_processador_oca_nfse).filtered(filter_ginfes): + processador = record._processador_erpbrasil_nfse() + + protocolo = record.authorization_protocol + vals = dict() + + if not protocolo: + for edoc in record.serialize(): + processo = None + for p in processador.processar_documento(edoc): + processo = p + + if processo.webservice in RECEPCIONAR_LOTE_RPS: + if processo.resposta.Protocolo is None: + mensagem_completa = '' + if processo.resposta.ListaMensagemRetorno: + lista_msgs = processo.resposta.\ + ListaMensagemRetorno + for mr in lista_msgs.MensagemRetorno: + + correcao = '' + if mr.Correcao: + correcao = mr.Correcao + + mensagem_completa += ( + mr.Codigo + ' - ' + + mr.Mensagem + + ' - Correção: ' + + correcao + '\n' + ) + vals['edoc_error_message'] = \ + mensagem_completa + record._change_state(SITUACAO_EDOC_REJEITADA) + record.write(vals) + return + protocolo = processo.resposta.Protocolo + + if processo.webservice in CONSULTAR_SITUACAO_LOTE_RPS: + vals['status_code'] = \ + processo.resposta.Situacao + else: + vals['status_code'] = 4 + + if vals.get('status_code') == 1: + vals['status_name'] = _('Not received') + + elif vals.get('status_code') == 2: + vals['status_name'] = _('Batch not yet processed') + + elif vals.get('status_code') == 3: + vals['status_name'] = _('Processed with Error') + + elif vals.get('status_code') == 4: + vals['status_name'] = _('Successfully Processed') + vals['authorization_protocol'] = protocolo + + if vals.get('status_code') in (3, 4): + processo = processador.consultar_lote_rps(protocolo) + + if processo.resposta: + mensagem_completa = '' + if processo.resposta.ListaMensagemRetorno: + lista_msgs = processo.resposta.ListaMensagemRetorno + for mr in lista_msgs.MensagemRetorno: + + correcao = '' + if mr.Correcao: + correcao = mr.Correcao + + mensagem_completa += ( + mr.Codigo + ' - ' + + mr.Mensagem + + ' - Correção: ' + + correcao + '\n' + ) + vals['edoc_error_message'] = mensagem_completa + if vals.get('status_code') == 3: + record._change_state(SITUACAO_EDOC_REJEITADA) + + if processo.resposta.ListaNfse: + xml_file = processo.retorno + for comp in processo.resposta.ListaNfse.CompNfse: + vals['number'] = comp.Nfse.InfNfse.Numero + vals['authorization_date'] = \ + comp.Nfse.InfNfse.DataEmissao + vals['verify_code'] = \ + comp.Nfse.InfNfse.CodigoVerificacao + record.authorization_event_id.set_done( + status_code=vals['status_code'], + response=vals['status_name'], + protocol_date=vals['authorization_date'], + protocol_number=protocolo, + file_response_xml=xml_file, + ) + record._change_state(SITUACAO_EDOC_AUTORIZADA) + + record.write(vals) return def _exec_before_SITUACAO_EDOC_CANCELADA(self, old_state, new_state): - super(Document, self)._exec_before_SITUACAO_EDOC_CANCELADA( - old_state, new_state) + super()._exec_before_SITUACAO_EDOC_CANCELADA(old_state, new_state) return self.cancel_document_ginfes() From 7ef026ff6b1b8d515d3dc62fcfa9551f0ff13dfa Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Mon, 26 Apr 2021 06:33:59 -0300 Subject: [PATCH 67/81] [REM] Duplicate code --- l10n_br_nfse_ginfes/models/document.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 9cb3d170c832..43d5014789d8 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -52,26 +52,6 @@ class Document(models.Model): _inherit = 'l10n_br_fiscal.document' - def convert_type_nfselib(self, class_object, object_filed, value): - if value is None: - return value - - value_type = '' - for field in class_object().member_data_items_: - if field.name == object_filed: - value_type = field.child_attrs.get('type', '').\ - replace('xsd:', '') - break - - if value_type in ('int', 'byte', 'nonNegativeInteger'): - return int(value) - elif value_type == 'decimal': - return float(value) - elif value_type == 'string': - return str(value) - else: - return value - def _serialize(self, edocs): edocs = super()._serialize(edocs) for record in self.filtered( From 5c2f80eb1138b9087002b6d7d4b68a21371f5230 Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Tue, 27 Apr 2021 00:32:25 -0300 Subject: [PATCH 68/81] [FIX] l10n_br_nfse_ginfes date / protocolo cancelamento --- l10n_br_nfse_ginfes/__manifest__.py | 2 +- l10n_br_nfse_ginfes/models/document.py | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index e1cd08cb5695..be2ff9343bec 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -10,7 +10,7 @@ 'author': 'KMEE, Odoo Community Association (OCA)', 'maintainers': ['gabrielcardoso21', 'mileo', 'luismalta'], 'website': 'https://github.com/OCA/l10n-brazil', - "development_status": "Alpha", + "development_status": "Beta", 'external_dependencies': { 'python': [ 'erpbrasil.edoc', diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 43d5014789d8..2d0c607de9f9 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -33,7 +33,7 @@ ) -def filter_processador_oca_nfse(record): +def filter_oca_nfse(record): if (record.processador_edoc == PROCESSADOR_OCA and record.document_type_id.code in [ MODELO_FISCAL_NFSE, @@ -54,9 +54,7 @@ class Document(models.Model): def _serialize(self, edocs): edocs = super()._serialize(edocs) - for record in self.filtered( - filter_processador_oca_nfse).filtered( - filter_ginfes): + for record in self.filtered(filter_oca_nfse).filtered(filter_ginfes): edocs.append(record.serialize_nfse_ginfes()) return edocs @@ -155,7 +153,7 @@ def _serialize_ginfes_rps(self, dados): tcIdentificacaoRps, 'Tipo', dados['tipo']), ), DataEmissao=self.convert_type_nfselib( - tcInfRps, 'DataEmissao', dados['data_emissao']), + tcInfRps, 'DataEmissao', dados['date_in_out']), NaturezaOperacao=self.convert_type_nfselib( tcInfRps, 'NaturezaOperacao', dados['natureza_operacao']), RegimeEspecialTributacao=self.convert_type_nfselib( @@ -208,7 +206,7 @@ def serialize_nfse_ginfes(self): return lote_rps def cancel_document_ginfes(self): - for record in self.filtered(filter_processador_oca_nfse): + for record in self.filtered(filter_oca_nfse).filtered(filter_ginfes): processador = record._processador_erpbrasil_nfse() processo = processador.cancela_documento(doc_numero=int(record.number)) @@ -218,10 +216,18 @@ def cancel_document_ginfes(self): if not status: raise UserError(_(message)) + record.cancel_event_id = record.event_ids.create_event_save_xml( + company_id=record.company_id, + environment='prod' if record.nfse_environment == '1' else 'hml', + event_type='2', + xml_file=processo.envio_xml.decode('utf-8'), + document_id=record, + ) + return status def action_consultar_nfse_rps(self): - for record in self.filtered(filter_processador_oca_nfse): + for record in self.filtered(filter_oca_nfse): processador = record._processador_erpbrasil_nfse() processo = processador.consulta_nfse_rps( rps_number=int(record.rps_number), @@ -240,8 +246,7 @@ def action_consultar_nfse_rps(self): @api.multi def _eletronic_document_send(self): super()._eletronic_document_send() - for record in self.filtered( - filter_processador_oca_nfse).filtered(filter_ginfes): + for record in self.filtered(filter_oca_nfse).filtered(filter_ginfes): processador = record._processador_erpbrasil_nfse() protocolo = record.authorization_protocol From 80d6858879b6a38e9b826169a9aec6b4f8893f6f Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Tue, 27 Apr 2021 11:40:33 -0300 Subject: [PATCH 69/81] [REF] Event PROD/HML l10n_br_nfse_ginfes --- l10n_br_nfse_ginfes/models/document.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 2d0c607de9f9..03e6088ece9e 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -21,10 +21,12 @@ from odoo import models, api, _ from odoo.exceptions import UserError from odoo.addons.l10n_br_fiscal.constants.fiscal import ( + EVENT_ENV_HML, + EVENT_ENV_PROD, MODELO_FISCAL_NFSE, + PROCESSADOR_OCA, SITUACAO_EDOC_AUTORIZADA, SITUACAO_EDOC_REJEITADA, - PROCESSADOR_OCA, ) from ..constants.ginfes import ( @@ -218,7 +220,8 @@ def cancel_document_ginfes(self): record.cancel_event_id = record.event_ids.create_event_save_xml( company_id=record.company_id, - environment='prod' if record.nfse_environment == '1' else 'hml', + environment=( + EVENT_ENV_PROD if self.nfe_environment == '1' else EVENT_ENV_HML), event_type='2', xml_file=processo.envio_xml.decode('utf-8'), document_id=record, From 64898ccd8739cb2c69413e677ed2c31cd21e6532 Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Tue, 27 Apr 2021 14:12:34 -0300 Subject: [PATCH 70/81] [REF] number -> document_number on l10n_br_nfe_ginfes --- l10n_br_nfse_ginfes/models/document.py | 7 ++++--- .../tests/test_fiscal_document_nfse_ginfes.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 03e6088ece9e..1badcc0f309f 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -210,7 +210,8 @@ def serialize_nfse_ginfes(self): def cancel_document_ginfes(self): for record in self.filtered(filter_oca_nfse).filtered(filter_ginfes): processador = record._processador_erpbrasil_nfse() - processo = processador.cancela_documento(doc_numero=int(record.number)) + processo = processador.cancela_documento(doc_numero=int( + record.document_number)) status, message = \ processador.analisa_retorno_cancelamento(processo) @@ -241,7 +242,7 @@ def action_consultar_nfse_rps(self): return _( processador.analisa_retorno_consulta( processo, - record.number, + record.document_number, record.company_cnpj_cpf, record.company_legal_name) ) @@ -331,7 +332,7 @@ def _eletronic_document_send(self): if processo.resposta.ListaNfse: xml_file = processo.retorno for comp in processo.resposta.ListaNfse.CompNfse: - vals['number'] = comp.Nfse.InfNfse.Numero + vals['document_number'] = comp.Nfse.InfNfse.Numero vals['authorization_date'] = \ comp.Nfse.InfNfse.DataEmissao vals['verify_code'] = \ diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py index 50abee01c1f3..508cbf76d3ba 100644 --- a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -35,7 +35,7 @@ def test_nfse_ginfes(self): self.nfse_same_state._onchange_fiscal_operation_id() self.nfse_same_state._onchange_company_id() self.nfse_same_state.rps_number = '50' - self.nfse_same_state.number = '50' + self.nfse_same_state.document_number = '50' for line in self.nfse_same_state.line_ids: line._onchange_product_id_fiscal() From 96b5b887381f326463dad16defb7edd2aeacc45e Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Wed, 28 Apr 2021 20:50:17 -0300 Subject: [PATCH 71/81] [REF] l10n_br_nfse_ginfes _document_status --- l10n_br_nfse_ginfes/models/document.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index 1badcc0f309f..bf7499a6f831 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -230,7 +230,7 @@ def cancel_document_ginfes(self): return status - def action_consultar_nfse_rps(self): + def _document_status(self): for record in self.filtered(filter_oca_nfse): processador = record._processador_erpbrasil_nfse() processo = processador.consulta_nfse_rps( From d32a20b2452a6978a4dc0df2a47171493a574893 Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Wed, 5 May 2021 01:10:14 -0300 Subject: [PATCH 72/81] [REF] Document Date to avoid error when install l10n_br_account on ginfes --- l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py index 508cbf76d3ba..b1d5136054fb 100644 --- a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -47,7 +47,7 @@ def test_nfse_ginfes(self): self.nfse_same_state.action_document_confirm() - self.nfse_same_state.date = datetime.strptime( + self.nfse_same_state.document_date = datetime.strptime( '2020-06-04T11:58:46', '%Y-%m-%dT%H:%M:%S') self.nfse_same_state.date_in_out = datetime.strptime( '2020-06-04T11:58:46', '%Y-%m-%dT%H:%M:%S') From f2070c960adcfa135b0bc33874fec261152bb44f Mon Sep 17 00:00:00 2001 From: oca-travis Date: Wed, 12 May 2021 17:40:06 +0000 Subject: [PATCH 73/81] [UPD] Update l10n_br_nfse_ginfes.pot --- .../i18n/l10n_br_nfse_ginfes.pot | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot b/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot index 0d4ebd73a91e..9c993b8307d8 100644 --- a/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot +++ b/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot @@ -13,6 +13,12 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: l10n_br_nfse_ginfes +#: code:addons/l10n_br_nfse_ginfes/models/document.py:300 +#, python-format +msgid "Batch not yet processed" +msgstr "" + #. module: l10n_br_nfse_ginfes #: model:ir.model,name:l10n_br_nfse_ginfes.model_res_company msgid "Companies" @@ -33,32 +39,26 @@ msgstr "" msgid "ISSNet / Nota Control" msgstr "" -#. module: l10n_br_nfse_ginfes -#: code:addons/l10n_br_nfse_ginfes/models/document.py:306 -#, python-format -msgid "Lote ainda não processado" -msgstr "" - #. module: l10n_br_nfse_ginfes #: model:ir.model.fields,field_description:l10n_br_nfse_ginfes.field_res_company__provedor_nfse msgid "NFSe Provider" msgstr "" #. module: l10n_br_nfse_ginfes -#: code:addons/l10n_br_nfse_ginfes/models/document.py:303 +#: code:addons/l10n_br_nfse_ginfes/models/document.py:297 #, python-format -msgid "Não Recebido" +msgid "Not received" msgstr "" #. module: l10n_br_nfse_ginfes -#: code:addons/l10n_br_nfse_ginfes/models/document.py:309 +#: code:addons/l10n_br_nfse_ginfes/models/document.py:303 #, python-format -msgid "Procesado com Erro" +msgid "Processed with Error" msgstr "" #. module: l10n_br_nfse_ginfes -#: code:addons/l10n_br_nfse_ginfes/models/document.py:312 +#: code:addons/l10n_br_nfse_ginfes/models/document.py:306 #, python-format -msgid "Procesado com Sucesso" +msgid "Successfully Processed" msgstr "" From c1866d0b91b4f090af877bd162c2fa1fb1968bae Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 12 May 2021 18:54:52 +0000 Subject: [PATCH 74/81] [UPD] README.rst --- l10n_br_nfse_ginfes/README.rst | 9 ++------- l10n_br_nfse_ginfes/static/description/index.html | 8 +------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/l10n_br_nfse_ginfes/README.rst b/l10n_br_nfse_ginfes/README.rst index 6763cb1c96fb..1b1c7f9ad5ce 100644 --- a/l10n_br_nfse_ginfes/README.rst +++ b/l10n_br_nfse_ginfes/README.rst @@ -7,9 +7,9 @@ NFS-e (Ginfes) !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status - :alt: Alpha + :alt: Beta .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 @@ -27,11 +27,6 @@ NFS-e (Ginfes) Esse módulo completa o documento criado pelo l10n_br_nfse para permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e) pelo sistema GINFES. -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - **Table of contents** .. contents:: diff --git a/l10n_br_nfse_ginfes/static/description/index.html b/l10n_br_nfse_ginfes/static/description/index.html index 21bf49bd13d9..0dff68800e59 100644 --- a/l10n_br_nfse_ginfes/static/description/index.html +++ b/l10n_br_nfse_ginfes/static/description/index.html @@ -367,14 +367,8 @@

    NFS-e (Ginfes)

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

    Alpha License: AGPL-3 OCA/l10n-brazil Translate me on Weblate Try me on Runbot

    +

    Beta License: AGPL-3 OCA/l10n-brazil Translate me on Weblate Try me on Runbot

    Esse módulo completa o documento criado pelo l10n_br_nfse para permite a criação e transmissão de Notas Fiscais de Serviço Eletrônicas (NFS-e) pelo sistema GINFES.

    -
    -

    Important

    -

    This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

    -

    Table of contents

      From 205e4705c795a680ea0b09066b5e507014c8da4d Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 12 May 2021 18:54:55 +0000 Subject: [PATCH 75/81] l10n_br_nfse_ginfes 12.0.3.0.0 --- l10n_br_nfse_ginfes/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index be2ff9343bec..7488ecb2159c 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -5,7 +5,7 @@ 'name': 'NFS-e (Ginfes)', 'summary': """ NFS-e (Ginfes)""", - 'version': '12.0.2.0.0', + 'version': '12.0.3.0.0', 'license': 'AGPL-3', 'author': 'KMEE, Odoo Community Association (OCA)', 'maintainers': ['gabrielcardoso21', 'mileo', 'luismalta'], From a41b6fc2264383bdcda97c30d20925848a4a2927 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Thu, 27 May 2021 05:13:45 +0000 Subject: [PATCH 76/81] [UPD] Update l10n_br_nfse_ginfes.pot --- l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot b/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot index 9c993b8307d8..0fd8321915ed 100644 --- a/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot +++ b/l10n_br_nfse_ginfes/i18n/l10n_br_nfse_ginfes.pot @@ -50,6 +50,11 @@ msgstr "" msgid "Not received" msgstr "" +#. module: l10n_br_nfse_ginfes +#: selection:res.company,provedor_nfse:0 +msgid "Paulistana" +msgstr "" + #. module: l10n_br_nfse_ginfes #: code:addons/l10n_br_nfse_ginfes/models/document.py:303 #, python-format From be04668912284748122f3a2b1a43304f5c4c22fa Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Sat, 3 Sep 2022 09:16:59 -0300 Subject: [PATCH 77/81] [IMP] : black, isort, prettier --- l10n_br_nfse_ginfes/__manifest__.py | 32 +- l10n_br_nfse_ginfes/constants/ginfes.py | 31 +- l10n_br_nfse_ginfes/models/document.py | 284 ++++++++++-------- l10n_br_nfse_ginfes/models/res_company.py | 4 +- .../tests/nfse/001_50_nfse.xml | 8 +- .../tests/test_fiscal_document_nfse_ginfes.py | 43 +-- requirements.txt | 2 + .../odoo/addons/l10n_br_nfse_ginfes | 1 + setup/l10n_br_nfse_ginfes/setup.py | 6 + 9 files changed, 228 insertions(+), 183 deletions(-) create mode 120000 setup/l10n_br_nfse_ginfes/odoo/addons/l10n_br_nfse_ginfes create mode 100644 setup/l10n_br_nfse_ginfes/setup.py diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index 7488ecb2159c..7f402a278e08 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -2,25 +2,25 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { - 'name': 'NFS-e (Ginfes)', - 'summary': """ + "name": "NFS-e (Ginfes)", + "summary": """ NFS-e (Ginfes)""", - 'version': '12.0.3.0.0', - 'license': 'AGPL-3', - 'author': 'KMEE, Odoo Community Association (OCA)', - 'maintainers': ['gabrielcardoso21', 'mileo', 'luismalta'], - 'website': 'https://github.com/OCA/l10n-brazil', + "version": "12.0.3.0.0", + "license": "AGPL-3", + "author": "KMEE, Odoo Community Association (OCA)", + "maintainers": ["gabrielcardoso21", "mileo", "luismalta"], + "website": "https://github.com/OCA/l10n-brazil", "development_status": "Beta", - 'external_dependencies': { - 'python': [ - 'erpbrasil.edoc', - 'erpbrasil.assinatura', - 'erpbrasil.transmissao', - 'erpbrasil.base', - 'nfselib.ginfes', + "external_dependencies": { + "python": [ + "erpbrasil.edoc", + "erpbrasil.assinatura", + "erpbrasil.transmissao", + "erpbrasil.base", + "nfselib.ginfes", ], }, - 'depends': [ - 'l10n_br_nfse', + "depends": [ + "l10n_br_nfse", ], } diff --git a/l10n_br_nfse_ginfes/constants/ginfes.py b/l10n_br_nfse_ginfes/constants/ginfes.py index 4f320d4f0348..d152a2216747 100644 --- a/l10n_br_nfse_ginfes/constants/ginfes.py +++ b/l10n_br_nfse_ginfes/constants/ginfes.py @@ -1,20 +1,17 @@ +RECEPCIONAR_LOTE_RPS = ["RecepcionarLoteRpsV3", "RecepcionarLoteRps"] -RECEPCIONAR_LOTE_RPS = [ - 'RecepcionarLoteRpsV3', - 'RecepcionarLoteRps' -] +CONSULTAR_SITUACAO_LOTE_RPS = ["ConsultarSituacaoLoteRpsV3", "ConsultarSituacaoLoteRps"] -CONSULTAR_SITUACAO_LOTE_RPS = [ - 'ConsultarSituacaoLoteRpsV3', - 'ConsultarSituacaoLoteRps' -] +CANCELAR_NFSE = ( + [ + "CancelarNfseV3", + "CancelarNfse", + ], +) -CANCELAR_NFSE = [ - 'CancelarNfseV3', - 'CancelarNfse', -], - -CONSULTAR_NFSE_POR_RPS = [ - 'ConsultarNfsePorRpsV3', - 'ConsultarNfsePorRps', -], +CONSULTAR_NFSE_POR_RPS = ( + [ + "ConsultarNfsePorRpsV3", + "ConsultarNfsePorRps", + ], +) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index bf7499a6f831..f23554bc1d72 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -18,8 +18,9 @@ tcValores, ) -from odoo import models, api, _ +from odoo import _, api, models from odoo.exceptions import UserError + from odoo.addons.l10n_br_fiscal.constants.fiscal import ( EVENT_ENV_HML, EVENT_ENV_PROD, @@ -29,30 +30,26 @@ SITUACAO_EDOC_REJEITADA, ) -from ..constants.ginfes import ( - RECEPCIONAR_LOTE_RPS, - CONSULTAR_SITUACAO_LOTE_RPS, -) +from ..constants.ginfes import CONSULTAR_SITUACAO_LOTE_RPS, RECEPCIONAR_LOTE_RPS def filter_oca_nfse(record): - if (record.processador_edoc == PROCESSADOR_OCA and - record.document_type_id.code in [ - MODELO_FISCAL_NFSE, - ]): + if record.processador_edoc == PROCESSADOR_OCA and record.document_type_id.code in [ + MODELO_FISCAL_NFSE, + ]: return True return False def filter_ginfes(record): - if record.company_id.provedor_nfse == 'ginfes': + if record.company_id.provedor_nfse == "ginfes": return True return False class Document(models.Model): - _inherit = 'l10n_br_fiscal.document' + _inherit = "l10n_br_fiscal.document" def _serialize(self, edocs): edocs = super()._serialize(edocs) @@ -66,47 +63,65 @@ def _serialize_ginfes_dados_servico(self): return tcDadosServico( Valores=tcValores( ValorServicos=self.convert_type_nfselib( - tcValores, 'ValorServicos', dados['valor_servicos']), + tcValores, "ValorServicos", dados["valor_servicos"] + ), ValorDeducoes=self.convert_type_nfselib( - tcValores, 'ValorDeducoes', dados['valor_deducoes']), + tcValores, "ValorDeducoes", dados["valor_deducoes"] + ), ValorPis=self.convert_type_nfselib( - tcValores, 'ValorPis', dados['valor_pis']), + tcValores, "ValorPis", dados["valor_pis"] + ), ValorCofins=self.convert_type_nfselib( - tcValores, 'ValorCofins', dados['valor_cofins']), + tcValores, "ValorCofins", dados["valor_cofins"] + ), ValorInss=self.convert_type_nfselib( - tcValores, 'ValorInss', dados['valor_inss']), + tcValores, "ValorInss", dados["valor_inss"] + ), ValorIr=self.convert_type_nfselib( - tcValores, 'ValorIr', dados['valor_ir']), + tcValores, "ValorIr", dados["valor_ir"] + ), ValorCsll=self.convert_type_nfselib( - tcValores, 'ValorIr', dados['valor_csll']), + tcValores, "ValorIr", dados["valor_csll"] + ), IssRetido=self.convert_type_nfselib( - tcValores, 'IssRetido', dados['iss_retido']), + tcValores, "IssRetido", dados["iss_retido"] + ), ValorIss=self.convert_type_nfselib( - tcValores, 'ValorIss', dados['valor_iss']), + tcValores, "ValorIss", dados["valor_iss"] + ), ValorIssRetido=self.convert_type_nfselib( - tcValores, 'ValorIssRetido', dados['valor_iss_retido']), + tcValores, "ValorIssRetido", dados["valor_iss_retido"] + ), OutrasRetencoes=self.convert_type_nfselib( - tcValores, 'OutrasRetencoes', dados['outras_retencoes']), + tcValores, "OutrasRetencoes", dados["outras_retencoes"] + ), BaseCalculo=self.convert_type_nfselib( - tcValores, 'BaseCalculo', dados['base_calculo']), + tcValores, "BaseCalculo", dados["base_calculo"] + ), Aliquota=self.convert_type_nfselib( - tcValores, 'Aliquota', dados['aliquota']), + tcValores, "Aliquota", dados["aliquota"] + ), ValorLiquidoNfse=self.convert_type_nfselib( - tcValores, 'ValorLiquidoNfse', - dados['valor_liquido_nfse']), + tcValores, "ValorLiquidoNfse", dados["valor_liquido_nfse"] + ), ), ItemListaServico=self.convert_type_nfselib( - tcDadosServico, 'ItemListaServico', - dados['item_lista_servico']), + tcDadosServico, "ItemListaServico", dados["item_lista_servico"] + ), CodigoCnae=self.convert_type_nfselib( - tcDadosServico, 'CodigoCnae', dados['codigo_cnae']), + tcDadosServico, "CodigoCnae", dados["codigo_cnae"] + ), CodigoTributacaoMunicipio=self.convert_type_nfselib( - tcDadosServico, 'CodigoTributacaoMunicipio', - dados['codigo_tributacao_municipio']), + tcDadosServico, + "CodigoTributacaoMunicipio", + dados["codigo_tributacao_municipio"], + ), Discriminacao=self.convert_type_nfselib( - tcDadosServico, 'Discriminacao', dados['discriminacao']), + tcDadosServico, "Discriminacao", dados["discriminacao"] + ), CodigoMunicipio=self.convert_type_nfselib( - tcDadosServico, 'CodigoMunicipio', dados['codigo_municipio']), + tcDadosServico, "CodigoMunicipio", dados["codigo_municipio"] + ), ) def _serialize_ginfes_dados_tomador(self): @@ -114,107 +129,119 @@ def _serialize_ginfes_dados_tomador(self): return tcDadosTomador( IdentificacaoTomador=tcIdentificacaoTomador( CpfCnpj=tcCpfCnpj( - Cnpj=self.convert_type_nfselib( - tcCpfCnpj, 'Cnpj', dados['cnpj']), - Cpf=self.convert_type_nfselib( - tcCpfCnpj, 'Cpf', dados['cpf']), + Cnpj=self.convert_type_nfselib(tcCpfCnpj, "Cnpj", dados["cnpj"]), + Cpf=self.convert_type_nfselib(tcCpfCnpj, "Cpf", dados["cpf"]), ), InscricaoMunicipal=self.convert_type_nfselib( - tcIdentificacaoTomador, 'InscricaoMunicipal', - dados['inscricao_municipal']) + tcIdentificacaoTomador, + "InscricaoMunicipal", + dados["inscricao_municipal"], + ), ), RazaoSocial=self.convert_type_nfselib( - tcDadosTomador, 'RazaoSocial', dados['razao_social']), + tcDadosTomador, "RazaoSocial", dados["razao_social"] + ), Endereco=tcEndereco( Endereco=self.convert_type_nfselib( - tcEndereco, 'Endereco', dados['endereco']), - Numero=self.convert_type_nfselib( - tcEndereco, 'Numero', dados['numero']), + tcEndereco, "Endereco", dados["endereco"] + ), + Numero=self.convert_type_nfselib(tcEndereco, "Numero", dados["numero"]), Complemento=self.convert_type_nfselib( - tcEndereco, 'Complemento', dados['complemento']), - Bairro=self.convert_type_nfselib( - tcEndereco, 'Bairro', dados['bairro']), + tcEndereco, "Complemento", dados["complemento"] + ), + Bairro=self.convert_type_nfselib(tcEndereco, "Bairro", dados["bairro"]), CodigoMunicipio=self.convert_type_nfselib( - tcEndereco, 'CodigoMunicipio', dados['codigo_municipio']), - Uf=self.convert_type_nfselib(tcEndereco, 'Uf', dados['uf']), - Cep=self.convert_type_nfselib(tcEndereco, 'Cep', dados['cep']), - ) or None, + tcEndereco, "CodigoMunicipio", dados["codigo_municipio"] + ), + Uf=self.convert_type_nfselib(tcEndereco, "Uf", dados["uf"]), + Cep=self.convert_type_nfselib(tcEndereco, "Cep", dados["cep"]), + ) + or None, ) def _serialize_ginfes_rps(self, dados): return tcRps( InfRps=tcInfRps( - Id=dados['id'], + Id=dados["id"], IdentificacaoRps=tcIdentificacaoRps( Numero=self.convert_type_nfselib( - tcIdentificacaoRps, 'Numero', dados['numero']), + tcIdentificacaoRps, "Numero", dados["numero"] + ), Serie=self.convert_type_nfselib( - tcIdentificacaoRps, 'Serie', dados['serie']), + tcIdentificacaoRps, "Serie", dados["serie"] + ), Tipo=self.convert_type_nfselib( - tcIdentificacaoRps, 'Tipo', dados['tipo']), + tcIdentificacaoRps, "Tipo", dados["tipo"] + ), ), DataEmissao=self.convert_type_nfselib( - tcInfRps, 'DataEmissao', dados['date_in_out']), + tcInfRps, "DataEmissao", dados["date_in_out"] + ), NaturezaOperacao=self.convert_type_nfselib( - tcInfRps, 'NaturezaOperacao', dados['natureza_operacao']), + tcInfRps, "NaturezaOperacao", dados["natureza_operacao"] + ), RegimeEspecialTributacao=self.convert_type_nfselib( - tcInfRps, 'RegimeEspecialTributacao', - dados['regime_especial_tributacao']), + tcInfRps, + "RegimeEspecialTributacao", + dados["regime_especial_tributacao"], + ), OptanteSimplesNacional=self.convert_type_nfselib( - tcInfRps, 'OptanteSimplesNacional', - dados['optante_simples_nacional']), + tcInfRps, + "OptanteSimplesNacional", + dados["optante_simples_nacional"], + ), IncentivadorCultural=self.convert_type_nfselib( - tcInfRps, 'IncentivadorCultural', - dados['incentivador_cultural']), - Status=self.convert_type_nfselib( - tcInfRps, 'Status', dados['status']), + tcInfRps, "IncentivadorCultural", dados["incentivador_cultural"] + ), + Status=self.convert_type_nfselib(tcInfRps, "Status", dados["status"]), RpsSubstituido=self.convert_type_nfselib( - tcInfRps, 'RpsSubstituido', dados['rps_substitiuido']), + tcInfRps, "RpsSubstituido", dados["rps_substitiuido"] + ), Servico=self._serialize_ginfes_dados_servico(), Prestador=tcIdentificacaoPrestador( Cnpj=self.convert_type_nfselib( - tcIdentificacaoPrestador, 'InscricaoMunicipal', - dados['cnpj']), + tcIdentificacaoPrestador, "InscricaoMunicipal", dados["cnpj"] + ), InscricaoMunicipal=self.convert_type_nfselib( - tcIdentificacaoPrestador, 'InscricaoMunicipal', - dados['inscricao_municipal']), + tcIdentificacaoPrestador, + "InscricaoMunicipal", + dados["inscricao_municipal"], + ), ), Tomador=self._serialize_ginfes_dados_tomador(), IntermediarioServico=self.convert_type_nfselib( - tcInfRps, 'IntermediarioServico', - dados['intermediario_servico']), + tcInfRps, "IntermediarioServico", dados["intermediario_servico"] + ), ConstrucaoCivil=self.convert_type_nfselib( - tcInfRps, 'ConstrucaoCivil', dados['construcao_civil']), + tcInfRps, "ConstrucaoCivil", dados["construcao_civil"] + ), ) ) def _serialize_ginfes_lote_rps(self): dados = self._prepare_lote_rps() return tcLoteRps( - Cnpj=self.convert_type_nfselib(tcLoteRps, 'Cnpj', dados['cnpj']), + Cnpj=self.convert_type_nfselib(tcLoteRps, "Cnpj", dados["cnpj"]), InscricaoMunicipal=self.convert_type_nfselib( - tcLoteRps, 'InscricaoMunicipal', dados['inscricao_municipal']), + tcLoteRps, "InscricaoMunicipal", dados["inscricao_municipal"] + ), QuantidadeRps=1, - ListaRps=ListaRpsType( - Rps=[self._serialize_ginfes_rps(dados)] - ) + ListaRps=ListaRpsType(Rps=[self._serialize_ginfes_rps(dados)]), ) def serialize_nfse_ginfes(self): - lote_rps = EnviarLoteRpsEnvio( - LoteRps=self._serialize_ginfes_lote_rps() - ) + lote_rps = EnviarLoteRpsEnvio(LoteRps=self._serialize_ginfes_lote_rps()) return lote_rps def cancel_document_ginfes(self): for record in self.filtered(filter_oca_nfse).filtered(filter_ginfes): processador = record._processador_erpbrasil_nfse() - processo = processador.cancela_documento(doc_numero=int( - record.document_number)) + processo = processador.cancela_documento( + doc_numero=int(record.document_number) + ) - status, message = \ - processador.analisa_retorno_cancelamento(processo) + status, message = processador.analisa_retorno_cancelamento(processo) if not status: raise UserError(_(message)) @@ -222,9 +249,10 @@ def cancel_document_ginfes(self): record.cancel_event_id = record.event_ids.create_event_save_xml( company_id=record.company_id, environment=( - EVENT_ENV_PROD if self.nfe_environment == '1' else EVENT_ENV_HML), - event_type='2', - xml_file=processo.envio_xml.decode('utf-8'), + EVENT_ENV_PROD if self.nfe_environment == "1" else EVENT_ENV_HML + ), + event_type="2", + xml_file=processo.envio_xml.decode("utf-8"), document_id=record, ) @@ -236,7 +264,7 @@ def _document_status(self): processo = processador.consulta_nfse_rps( rps_number=int(record.rps_number), rps_serie=record.document_serie, - rps_type=int(record.rps_type) + rps_type=int(record.rps_type), ) return _( @@ -244,7 +272,8 @@ def _document_status(self): processo, record.document_number, record.company_cnpj_cpf, - record.company_legal_name) + record.company_legal_name, + ) ) @api.multi @@ -264,83 +293,82 @@ def _eletronic_document_send(self): if processo.webservice in RECEPCIONAR_LOTE_RPS: if processo.resposta.Protocolo is None: - mensagem_completa = '' + mensagem_completa = "" if processo.resposta.ListaMensagemRetorno: - lista_msgs = processo.resposta.\ - ListaMensagemRetorno + lista_msgs = processo.resposta.ListaMensagemRetorno for mr in lista_msgs.MensagemRetorno: - correcao = '' + correcao = "" if mr.Correcao: correcao = mr.Correcao mensagem_completa += ( - mr.Codigo + ' - ' + - mr.Mensagem + - ' - Correção: ' + - correcao + '\n' + mr.Codigo + + " - " + + mr.Mensagem + + " - Correção: " + + correcao + + "\n" ) - vals['edoc_error_message'] = \ - mensagem_completa + vals["edoc_error_message"] = mensagem_completa record._change_state(SITUACAO_EDOC_REJEITADA) record.write(vals) return protocolo = processo.resposta.Protocolo if processo.webservice in CONSULTAR_SITUACAO_LOTE_RPS: - vals['status_code'] = \ - processo.resposta.Situacao + vals["status_code"] = processo.resposta.Situacao else: - vals['status_code'] = 4 + vals["status_code"] = 4 - if vals.get('status_code') == 1: - vals['status_name'] = _('Not received') + if vals.get("status_code") == 1: + vals["status_name"] = _("Not received") - elif vals.get('status_code') == 2: - vals['status_name'] = _('Batch not yet processed') + elif vals.get("status_code") == 2: + vals["status_name"] = _("Batch not yet processed") - elif vals.get('status_code') == 3: - vals['status_name'] = _('Processed with Error') + elif vals.get("status_code") == 3: + vals["status_name"] = _("Processed with Error") - elif vals.get('status_code') == 4: - vals['status_name'] = _('Successfully Processed') - vals['authorization_protocol'] = protocolo + elif vals.get("status_code") == 4: + vals["status_name"] = _("Successfully Processed") + vals["authorization_protocol"] = protocolo - if vals.get('status_code') in (3, 4): + if vals.get("status_code") in (3, 4): processo = processador.consultar_lote_rps(protocolo) if processo.resposta: - mensagem_completa = '' + mensagem_completa = "" if processo.resposta.ListaMensagemRetorno: lista_msgs = processo.resposta.ListaMensagemRetorno for mr in lista_msgs.MensagemRetorno: - correcao = '' + correcao = "" if mr.Correcao: correcao = mr.Correcao mensagem_completa += ( - mr.Codigo + ' - ' + - mr.Mensagem + - ' - Correção: ' + - correcao + '\n' + mr.Codigo + + " - " + + mr.Mensagem + + " - Correção: " + + correcao + + "\n" ) - vals['edoc_error_message'] = mensagem_completa - if vals.get('status_code') == 3: + vals["edoc_error_message"] = mensagem_completa + if vals.get("status_code") == 3: record._change_state(SITUACAO_EDOC_REJEITADA) if processo.resposta.ListaNfse: xml_file = processo.retorno for comp in processo.resposta.ListaNfse.CompNfse: - vals['document_number'] = comp.Nfse.InfNfse.Numero - vals['authorization_date'] = \ - comp.Nfse.InfNfse.DataEmissao - vals['verify_code'] = \ - comp.Nfse.InfNfse.CodigoVerificacao + vals["document_number"] = comp.Nfse.InfNfse.Numero + vals["authorization_date"] = comp.Nfse.InfNfse.DataEmissao + vals["verify_code"] = comp.Nfse.InfNfse.CodigoVerificacao record.authorization_event_id.set_done( - status_code=vals['status_code'], - response=vals['status_name'], - protocol_date=vals['authorization_date'], + status_code=vals["status_code"], + response=vals["status_name"], + protocol_date=vals["authorization_date"], protocol_number=protocolo, file_response_xml=xml_file, ) diff --git a/l10n_br_nfse_ginfes/models/res_company.py b/l10n_br_nfse_ginfes/models/res_company.py index 51785e6dfe3f..3c6445fa1429 100644 --- a/l10n_br_nfse_ginfes/models/res_company.py +++ b/l10n_br_nfse_ginfes/models/res_company.py @@ -6,10 +6,10 @@ class ResCompany(models.Model): - _inherit = 'res.company' + _inherit = "res.company" provedor_nfse = fields.Selection( selection_add=[ - ('ginfes', 'Ginfes'), + ("ginfes", "Ginfes"), ] ) diff --git a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml index 77db322e206d..5330b5ed8e55 100644 --- a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml +++ b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml @@ -1,4 +1,7 @@ - + 59594315000157 35172 @@ -37,7 +40,8 @@ 105 3101200 6311900 - [ODOO_DEV] Customized Odoo Development + [ODOO_DEV] Customized Odoo Development 3132404 diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py index b1d5136054fb..b8df4d597978 100644 --- a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -2,40 +2,41 @@ # Gabriel Cardoso de Faria # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from xmldiff import main -import os import logging - +import os from datetime import datetime + +from xmldiff import main + from odoo.tools import config -from ... import l10n_br_nfse_ginfes -from odoo.addons.l10n_br_nfse.tests.test_fiscal_document_nfse_common \ - import TestFiscalDocumentNFSeCommon +from odoo.addons.l10n_br_nfse.tests.test_fiscal_document_nfse_common import ( + TestFiscalDocumentNFSeCommon, +) +from ... import l10n_br_nfse_ginfes _logger = logging.getLogger(__name__) class TestFiscalDocumentNFSeGinfes(TestFiscalDocumentNFSeCommon): - def setUp(self): super(TestFiscalDocumentNFSeGinfes, self).setUp() - self.company.provedor_nfse = 'ginfes' + self.company.provedor_nfse = "ginfes" def test_nfse_ginfes(self): - """ Test NFS-e same state. """ + """Test NFS-e same state.""" xml_path = os.path.join( - l10n_br_nfse_ginfes.__path__[0], 'tests', 'nfse', - '001_50_nfse.xml') + l10n_br_nfse_ginfes.__path__[0], "tests", "nfse", "001_50_nfse.xml" + ) self.nfse_same_state._onchange_document_serie_id() self.nfse_same_state._onchange_fiscal_operation_id() self.nfse_same_state._onchange_company_id() - self.nfse_same_state.rps_number = '50' - self.nfse_same_state.document_number = '50' + self.nfse_same_state.rps_number = "50" + self.nfse_same_state.document_number = "50" for line in self.nfse_same_state.line_ids: line._onchange_product_id_fiscal() @@ -48,14 +49,20 @@ def test_nfse_ginfes(self): self.nfse_same_state.action_document_confirm() self.nfse_same_state.document_date = datetime.strptime( - '2020-06-04T11:58:46', '%Y-%m-%dT%H:%M:%S') + "2020-06-04T11:58:46", "%Y-%m-%dT%H:%M:%S" + ) self.nfse_same_state.date_in_out = datetime.strptime( - '2020-06-04T11:58:46', '%Y-%m-%dT%H:%M:%S') + "2020-06-04T11:58:46", "%Y-%m-%dT%H:%M:%S" + ) - self.nfse_same_state.with_context(lang='pt_BR')._document_export() + self.nfse_same_state.with_context(lang="pt_BR")._document_export() - output = os.path.join(config['data_dir'], 'filestore', self.cr.dbname, - self.nfse_same_state.send_file_id.store_fname) + output = os.path.join( + config["data_dir"], + "filestore", + self.cr.dbname, + self.nfse_same_state.send_file_id.store_fname, + ) _logger.info("XML file saved at %s" % (output,)) diff = main.diff_files(xml_path, output) diff --git a/requirements.txt b/requirements.txt index 9bd791a09b91..454ed4807c70 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,7 @@ erpbrasil.edoc erpbrasil.edoc.pdf erpbrasil.transmissao nfelib>=2.0.0 +nfselib.ginfes nfselib.paulistana num2words phonenumbers @@ -14,3 +15,4 @@ pyyaml satcomum unidecode workalendar +xmldiff diff --git a/setup/l10n_br_nfse_ginfes/odoo/addons/l10n_br_nfse_ginfes b/setup/l10n_br_nfse_ginfes/odoo/addons/l10n_br_nfse_ginfes new file mode 120000 index 000000000000..f44df05d62df --- /dev/null +++ b/setup/l10n_br_nfse_ginfes/odoo/addons/l10n_br_nfse_ginfes @@ -0,0 +1 @@ +../../../../l10n_br_nfse_ginfes \ No newline at end of file diff --git a/setup/l10n_br_nfse_ginfes/setup.py b/setup/l10n_br_nfse_ginfes/setup.py new file mode 100644 index 000000000000..28c57bb64031 --- /dev/null +++ b/setup/l10n_br_nfse_ginfes/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 391a9f58f240445b4e633940bb7d68966e83f064 Mon Sep 17 00:00:00 2001 From: Diego Paradeda Date: Thu, 27 Oct 2022 11:31:15 -0300 Subject: [PATCH 78/81] [FIX] fiscal_document_line field name and complex method split --- l10n_br_nfse_ginfes/models/document.py | 158 ++++++++++-------- .../tests/test_fiscal_document_nfse_ginfes.py | 2 +- 2 files changed, 86 insertions(+), 74 deletions(-) diff --git a/l10n_br_nfse_ginfes/models/document.py b/l10n_br_nfse_ginfes/models/document.py index f23554bc1d72..3752523db11c 100644 --- a/l10n_br_nfse_ginfes/models/document.py +++ b/l10n_br_nfse_ginfes/models/document.py @@ -18,7 +18,7 @@ tcValores, ) -from odoo import _, api, models +from odoo import _, models from odoo.exceptions import UserError from odoo.addons.l10n_br_fiscal.constants.fiscal import ( @@ -58,7 +58,7 @@ def _serialize(self, edocs): return edocs def _serialize_ginfes_dados_servico(self): - self.line_ids.ensure_one() + self.fiscal_line_ids.ensure_one() dados = self._prepare_dados_servico() return tcDadosServico( Valores=tcValores( @@ -276,7 +276,86 @@ def _document_status(self): ) ) - @api.multi + @staticmethod + def _get_protocolo(record, processador, vals): + for edoc in record.serialize(): + processo = None + for p in processador.processar_documento(edoc): + processo = p + + if processo.webservice in RECEPCIONAR_LOTE_RPS: + if processo.resposta.Protocolo is None: + mensagem_completa = "" + if processo.resposta.ListaMensagemRetorno: + lista_msgs = processo.resposta.ListaMensagemRetorno + for mr in lista_msgs.MensagemRetorno: + + correcao = "" + if mr.Correcao: + correcao = mr.Correcao + + mensagem_completa += ( + mr.Codigo + + " - " + + mr.Mensagem + + " - Correção: " + + correcao + + "\n" + ) + vals["edoc_error_message"] = mensagem_completa + record._change_state(SITUACAO_EDOC_REJEITADA) + record.write(vals) + return + protocolo = processo.resposta.Protocolo + + if processo.webservice in CONSULTAR_SITUACAO_LOTE_RPS: + vals["status_code"] = processo.resposta.Situacao + + return vals, protocolo + + @staticmethod + def _set_response(record, processador, protocolo, vals): + processo = processador.consultar_lote_rps(protocolo) + + if processo.resposta: + mensagem_completa = "" + if processo.resposta.ListaMensagemRetorno: + lista_msgs = processo.resposta.ListaMensagemRetorno + for mr in lista_msgs.MensagemRetorno: + + correcao = "" + if mr.Correcao: + correcao = mr.Correcao + + mensagem_completa += ( + mr.Codigo + + " - " + + mr.Mensagem + + " - Correção: " + + correcao + + "\n" + ) + vals["edoc_error_message"] = mensagem_completa + if vals.get("status_code") == 3: + record._change_state(SITUACAO_EDOC_REJEITADA) + + if processo.resposta.ListaNfse: + xml_file = processo.retorno + for comp in processo.resposta.ListaNfse.CompNfse: + vals["document_number"] = comp.Nfse.InfNfse.Numero + vals["authorization_date"] = comp.Nfse.InfNfse.DataEmissao + vals["verify_code"] = comp.Nfse.InfNfse.CodigoVerificacao + record.authorization_event_id.set_done( + status_code=vals["status_code"], + response=vals["status_name"], + protocol_date=vals["authorization_date"], + protocol_number=protocolo, + file_response_xml=xml_file, + ) + record._change_state(SITUACAO_EDOC_AUTORIZADA) + + return vals + def _eletronic_document_send(self): super()._eletronic_document_send() for record in self.filtered(filter_oca_nfse).filtered(filter_ginfes): @@ -286,38 +365,8 @@ def _eletronic_document_send(self): vals = dict() if not protocolo: - for edoc in record.serialize(): - processo = None - for p in processador.processar_documento(edoc): - processo = p - - if processo.webservice in RECEPCIONAR_LOTE_RPS: - if processo.resposta.Protocolo is None: - mensagem_completa = "" - if processo.resposta.ListaMensagemRetorno: - lista_msgs = processo.resposta.ListaMensagemRetorno - for mr in lista_msgs.MensagemRetorno: - - correcao = "" - if mr.Correcao: - correcao = mr.Correcao - - mensagem_completa += ( - mr.Codigo - + " - " - + mr.Mensagem - + " - Correção: " - + correcao - + "\n" - ) - vals["edoc_error_message"] = mensagem_completa - record._change_state(SITUACAO_EDOC_REJEITADA) - record.write(vals) - return - protocolo = processo.resposta.Protocolo - - if processo.webservice in CONSULTAR_SITUACAO_LOTE_RPS: - vals["status_code"] = processo.resposta.Situacao + vals, protocolo = self._get_protocolo(record, processador, vals) + else: vals["status_code"] = 4 @@ -335,44 +384,7 @@ def _eletronic_document_send(self): vals["authorization_protocol"] = protocolo if vals.get("status_code") in (3, 4): - processo = processador.consultar_lote_rps(protocolo) - - if processo.resposta: - mensagem_completa = "" - if processo.resposta.ListaMensagemRetorno: - lista_msgs = processo.resposta.ListaMensagemRetorno - for mr in lista_msgs.MensagemRetorno: - - correcao = "" - if mr.Correcao: - correcao = mr.Correcao - - mensagem_completa += ( - mr.Codigo - + " - " - + mr.Mensagem - + " - Correção: " - + correcao - + "\n" - ) - vals["edoc_error_message"] = mensagem_completa - if vals.get("status_code") == 3: - record._change_state(SITUACAO_EDOC_REJEITADA) - - if processo.resposta.ListaNfse: - xml_file = processo.retorno - for comp in processo.resposta.ListaNfse.CompNfse: - vals["document_number"] = comp.Nfse.InfNfse.Numero - vals["authorization_date"] = comp.Nfse.InfNfse.DataEmissao - vals["verify_code"] = comp.Nfse.InfNfse.CodigoVerificacao - record.authorization_event_id.set_done( - status_code=vals["status_code"], - response=vals["status_name"], - protocol_date=vals["authorization_date"], - protocol_number=protocolo, - file_response_xml=xml_file, - ) - record._change_state(SITUACAO_EDOC_AUTORIZADA) + vals = self._set_response(record, processador, protocolo, vals) record.write(vals) return diff --git a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py index b8df4d597978..0443a5b6b122 100644 --- a/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py +++ b/l10n_br_nfse_ginfes/tests/test_fiscal_document_nfse_ginfes.py @@ -38,7 +38,7 @@ def test_nfse_ginfes(self): self.nfse_same_state.rps_number = "50" self.nfse_same_state.document_number = "50" - for line in self.nfse_same_state.line_ids: + for line in self.nfse_same_state.fiscal_line_ids: line._onchange_product_id_fiscal() line._onchange_commercial_quantity() line._onchange_ncm_id() From 2ec9d001464897e3cec78d2ef1d11b08d5993246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Felipe=20Mil=C3=A9o?= Date: Thu, 27 Oct 2022 14:15:46 -0300 Subject: [PATCH 79/81] [MIG][l10n_br_nfse_ginfes] bump module version --- l10n_br_nfse_ginfes/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index 7f402a278e08..48bae1cc236c 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -5,7 +5,7 @@ "name": "NFS-e (Ginfes)", "summary": """ NFS-e (Ginfes)""", - "version": "12.0.3.0.0", + "version": "14.0.1.0.0", "license": "AGPL-3", "author": "KMEE, Odoo Community Association (OCA)", "maintainers": ["gabrielcardoso21", "mileo", "luismalta"], From ef420dcaa45140b82c02a4ed112bef1c870a01d2 Mon Sep 17 00:00:00 2001 From: Daniel Venancio Date: Thu, 30 Mar 2023 19:46:33 -0300 Subject: [PATCH 80/81] [FIX] 001_50_nfse.xml --- l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml index 5330b5ed8e55..fa03e595763c 100644 --- a/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml +++ b/l10n_br_nfse_ginfes/tests/nfse/001_50_nfse.xml @@ -33,7 +33,7 @@ 5 0 0 - 100 + 0 0.05 100 From cba07b9b87b23ff9675f2266bea1d429c76b3e90 Mon Sep 17 00:00:00 2001 From: Marcel Savegnago Date: Sat, 10 Jun 2023 09:41:17 -0300 Subject: [PATCH 81/81] [FIX] l10n_br_nfse_ginfes: fix external_dependencies --- l10n_br_nfse_ginfes/__manifest__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/l10n_br_nfse_ginfes/__manifest__.py b/l10n_br_nfse_ginfes/__manifest__.py index 48bae1cc236c..a4e4ea10fb6d 100644 --- a/l10n_br_nfse_ginfes/__manifest__.py +++ b/l10n_br_nfse_ginfes/__manifest__.py @@ -16,8 +16,9 @@ "erpbrasil.edoc", "erpbrasil.assinatura", "erpbrasil.transmissao", - "erpbrasil.base", + "erpbrasil.base>=2.3.0", "nfselib.ginfes", + "xmldiff", ], }, "depends": [