Skip to content

Commit

Permalink
Merge PR #1985 into 12.0
Browse files Browse the repository at this point in the history
Signed-off-by rvalyi
  • Loading branch information
OCA-git-bot committed Jul 15, 2022
2 parents 98bd54b + 874ad3e commit 14135be
Show file tree
Hide file tree
Showing 13 changed files with 634 additions and 22 deletions.
1 change: 1 addition & 0 deletions l10n_br_nfe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

from .hooks import post_init_hook
from . import models
from . import wizards
7 changes: 7 additions & 0 deletions l10n_br_nfe/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright (C) 2019 Renato Lima - Akretion
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html


{
"name": "NF-e",
"summary": "Brazilian Eletronic Invoice NF-e .",
Expand All @@ -24,6 +25,12 @@
"views/res_company_view.xml",
"views/nfe_document_view.xml",
"views/res_config_settings_view.xml",
# Wizards
"wizards/import_document.xml",
# Actions,
"views/nfe_action.xml",
# Menus
"views/nfe_menu.xml",
],
"demo": [
"demo/res_users_demo.xml",
Expand Down
47 changes: 44 additions & 3 deletions l10n_br_nfe/models/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import base64
import io
import logging
import re
import string
Expand All @@ -11,7 +12,7 @@
from unicodedata import normalize

from erpbrasil.assinatura import certificado as cert
from erpbrasil.base.fiscal.edoc import ChaveEdoc
from erpbrasil.base.fiscal.edoc import ChaveEdoc, cnpj_cpf
from erpbrasil.edoc.nfe import NFe as edoc_nfe
from erpbrasil.edoc.pdf import base
from erpbrasil.transmissao import TransmissaoSOAP
Expand Down Expand Up @@ -65,6 +66,14 @@ def filter_processador_edoc_nfe(record):
return False


def parse_xml_nfe(xml):
arq = io.BytesIO()
arq.write(xml)
arq.seek(0)
nfe_binding = nfe_sub.parse(arq, silence=True)
return nfe_binding


class NFe(spec_models.StackedModel):
_name = "l10n_br_fiscal.document"
_inherit = ["l10n_br_fiscal.document", "nfe.40.infnfe"]
Expand Down Expand Up @@ -504,10 +513,18 @@ def _compute_nfe40_additional_data(self):
##########################

nfe40_infRespTec = fields.Many2one(
comodel_name="res.partner",
related="company_id.technical_support_id",
comodel_name="res.partner", compute="_compute_resp_tec_data"
)

def _compute_resp_tec_data(self):
for record in self:
if record.company_id.technical_support_id:
record.nfe40_infRespTec = record.company_id.technical_support_id

##########################

imported_document = fields.Boolean(string="Imported", default=False)

################################
# Framework Spec model's methods
################################
Expand Down Expand Up @@ -695,6 +712,30 @@ def _document_export(self, pretty_print=True):
xml_assinado = processador.assina_raiz(edoc, edoc.infNFe.Id)
self._valida_xml(xml_assinado)

def _invert_fiscal_operation_type(self, document, nfe_binding, edoc_type):
if edoc_type == "in" and document.company_id.cnpj_cpf != cnpj_cpf.formata(
nfe_binding.infNFe.emit.CNPJ
):
document.fiscal_operation_type = "in"
document.issuer = "partner"

def _import_xml(self, nfe_binding, dry_run, edoc_type="out"):
document = (
self.env["nfe.40.infnfe"]
.with_context(
tracking_disable=True,
edoc_type=edoc_type,
lang="pt_BR",
)
.build(nfe_binding.infNFe, dry_run=dry_run)
)
document.imported_document = True
self._invert_fiscal_operation_type(document, nfe_binding, edoc_type)
return document

def import_xml(self, nfe_binding, dry_run, edoc_type="out"):
return self._import_xml(nfe_binding, dry_run, edoc_type)

def atualiza_status_nfe(self, infProt, xml_file):
self.ensure_one()
# TODO: Verificar a consulta de notas
Expand Down
7 changes: 5 additions & 2 deletions l10n_br_nfe/models/product_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ def create(self, values):
values["list_price"] = parent_dict.get("nfe40_vUnCom")

# Barcode
if parent_dict.get("nfe40_cEAN") and parent_dict["nfe40_cEAN"] != "SEM GTIN":
values["barcode"] = parent_dict["nfe40_cEAN"]
if (
parent_dict.get("nfe40_cEANTrib")
and parent_dict["nfe40_cEANTrib"] != "SEM GTIN"
):
values["barcode"] = parent_dict["nfe40_cEANTrib"]

# NCM
if parent_dict.get("nfe40_NCM"):
Expand Down
1 change: 1 addition & 0 deletions l10n_br_nfe/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# from . import test_nfe_export
from . import test_nfe_structure
from . import test_nfe_import
from . import test_nfe_import_wizard
from . import test_nfe_serialize
from . import test_nfe_serialize_lc
from . import test_nfe_serialize_sn
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<NFe xmlns="http://www.portalfiscal.inf.br/nfe">
<infNFe versao="4.00" Id="NFe35200181583054000129550010000000052062777166">
<ide>
<cUF>35</cUF>
<cNF>06277716</cNF>
<natOp>Venda</natOp>
<mod>55</mod>
<serie>1</serie>
<nNF>5</nNF>
<dhEmi>2020-01-01T12:00:00+01:00</dhEmi>
<dhSaiEnt>2020-01-01T12:00:00+01:00</dhSaiEnt>
<tpNF>1</tpNF>
<idDest>1</idDest>
<cMunFG>3501152</cMunFG>
<tpImp>1</tpImp>
<tpEmis>1</tpEmis>
<cDV>1</cDV>
<tpAmb>2</tpAmb>
<finNFe>1</finNFe>
<indFinal>1</indFinal>
<indPres>0</indPres>
<procEmi>0</procEmi>
<verProc>Odoo Brasil OCA 12.0</verProc>
</ide>
<emit>
<CNPJ>81583054000129</CNPJ>
<xNome>Empresa Lucro Presumido Ltda</xNome>
<xFant>Empresa Lucro Presumido</xFant>
<enderEmit>
<xLgr>Avenida Paulista</xLgr>
<nro>1</nro>
<xBairro>Bela Vista</xBairro>
<cMun>3550308</cMun>
<xMun>São Paulo</xMun>
<UF>SP</UF>
<CEP>01311000</CEP>
<cPais>1058</cPais>
<xPais>Brasil</xPais>
<fone>551199999999</fone>
</enderEmit>
<IE>078016350838</IE>
<CRT>3</CRT>
</emit>
<dest>
<CNPJ>81493979000189</CNPJ>
<xNome>NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL</xNome>
<enderDest>
<xLgr>Rua Samuel Morse</xLgr>
<nro>135</nro>
<xCpl>20º andar - Conjunto 151</xCpl>
<xBairro>Brooklin</xBairro>
<cMun>3550308</cMun>
<xMun>São Paulo</xMun>
<UF>SP</UF>
<CEP>04576060</CEP>
<cPais>1058</cPais>
<xPais>Brasil</xPais>
<fone>551134782150</fone>
</enderDest>
<indIEDest>1</indIEDest>
<IE>460429771334</IE>
<email>[email protected]</email>
</dest>
<entrega>
<CNPJ>81583054000129</CNPJ>
<xLgr>XXXXXXXXXXXX</xLgr>
<nro>586</nro>
<xCpl>XXXXXXXXX</xCpl>
<xBairro>XXXXXXX</xBairro>
<cMun>9999999</cMun>
<xMun>XXXXXX</xMun>
<UF>XX</UF>
<CEP>18125000</CEP>
<cPais>0000</cPais>
<xPais>XXXXXX</xPais>
<IE>114472132119</IE>
</entrega>
<det nItem="1">
<prod>
<cProd>E-COM11</cProd>
<cEAN>SEM GTIN</cEAN>
<xProd>[E-COM11] Cabinet with Doors</xProd>
<NCM>94033000</NCM>
<CFOP>5102</CFOP>
<uCom>UNID</uCom>
<qCom>1.0000</qCom>
<vUnCom>14.0000000000</vUnCom>
<vProd>14.00</vProd>
<cEANTrib>SEM GTIN</cEANTrib>
<uTrib>UNID</uTrib>
<qTrib>1.0000</qTrib>
<vUnTrib>14.0000000000</vUnTrib>
<indTot>1</indTot>
</prod>
<imposto>
<vTotTrib>0.00</vTotTrib>
<ICMS>
<ICMSSN101>
<orig>0</orig>
<CSOSN>101</CSOSN>
<pCredSN>2.7000</pCredSN>
<vCredICMSSN>0.38</vCredICMSSN>
</ICMSSN101>
</ICMS>
<IPI>
<cEnq>999</cEnq>
<IPINT>
<CST>53</CST>
</IPINT>
</IPI>
<PIS>
<PISOutr>
<CST>49</CST>
<vBC>0.00</vBC>
<pPIS>0.0000</pPIS>
<vPIS>0.00</vPIS>
</PISOutr>
</PIS>
<COFINS>
<COFINSOutr>
<CST>49</CST>
<vBC>0.00</vBC>
<pCOFINS>0.0000</pCOFINS>
<vCOFINS>0.00</vCOFINS>
</COFINSOutr>
</COFINS>
</imposto>
</det>
<total>
<ICMSTot>
<vBC>0.00</vBC>
<vICMS>0.00</vICMS>
<vICMSDeson>0.00</vICMSDeson>
<vFCPUFDest>0.00</vFCPUFDest>
<vICMSUFDest>0.00</vICMSUFDest>
<vICMSUFRemet>0.00</vICMSUFRemet>
<vFCP>0.00</vFCP>
<vBCST>0.00</vBCST>
<vST>0.00</vST>
<vFCPST>0.00</vFCPST>
<vFCPSTRet>0.00</vFCPSTRet>
<vProd>14.00</vProd>
<vFrete>0.00</vFrete>
<vSeg>0.00</vSeg>
<vDesc>0.00</vDesc>
<vII>0.00</vII>
<vIPI>0.00</vIPI>
<vIPIDevol>0.00</vIPIDevol>
<vPIS>0.00</vPIS>
<vCOFINS>0.00</vCOFINS>
<vOutro>0.00</vOutro>
<vNF>14.00</vNF>
<vTotTrib>0.00</vTotTrib>
</ICMSTot>
</total>
<transp>
<modFrete>9</modFrete>
</transp>
<pag>
<detPag>
<indPag>0</indPag>
<tPag>01</tPag>
<vPag>14.00</vPag>
</detPag>
<vTroco>0.00</vTroco>
</pag>
<infAdic>
<infAdFisco>Documento emitido por: Marc Demo</infAdFisco>
</infAdic>
</infNFe>
</NFe>
72 changes: 72 additions & 0 deletions l10n_br_nfe/tests/test_nfe_import_wizard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import base64
import logging
import os

from odoo.tests import SavepointCase

_logger = logging.getLogger(__name__)


class NFeImportWizardTest(SavepointCase):
def setUp(self):
super(NFeImportWizardTest, self).setUp()
self.wizard = self.env["l10n_br_nfe.import_xml"].create(
{
"company_id": self.env.ref("base.main_company").id,
"importing_type": "xml_file",
}
)
path = os.path.dirname(os.path.abspath(__file__))
path_1 = path + (
"/nfe/v4_00/leiauteNFe/NFe35200159594315000157550010000000012062777161.xml"
)
with open(path_1, "rb") as f:
self.xml_1 = f.read()
path_2 = path + (
"/nfe/v4_00/leiauteNFe/NFe35200181583054000129550010000000052062777166.xml"
)
with open(path_2, "rb") as f:
self.xml_2 = f.read()

def test_onchange_nfe_xml(self):
xml = self.xml_1
wizard = self.wizard
wizard.nfe_xml = base64.b64encode(xml)
wizard._onchange_partner_id()
# Check wizard header info
self.assertEqual(
wizard.document_key, "35200159594315000157550010000000012062777161"
)
self.assertEqual(wizard.document_number, "1")
self.assertEqual(wizard.document_serie, "1")
self.assertEqual(wizard.partner_cpf_cnpj, "59.594.315/0001-57")
self.assertEqual(wizard.partner_name, "TESTE - Simples Nacional")
self.assertEqual(
wizard.partner_id, self.env.ref("l10n_br_base.simples_nacional_partner")
)
# Check wizard product info
self.assertEqual(
wizard.imported_products_ids[0].product_name, "[E-COM11] Cabinet with Doors"
)
self.assertEqual(wizard.imported_products_ids[0].uom_com, "UNID")
self.assertEqual(wizard.imported_products_ids[0].quantity_com, 1)
self.assertEqual(wizard.imported_products_ids[0].price_unit_com, 14)
self.assertEqual(wizard.imported_products_ids[0].uom_trib, "UNID")
self.assertEqual(wizard.imported_products_ids[0].quantity_trib, 1)
self.assertEqual(wizard.imported_products_ids[0].price_unit_trib, 14)
self.assertEqual(wizard.imported_products_ids[0].total, 14)

def test_match_country_state_city(self):
xml = self.xml_2
wizard = self.wizard
product_10 = self.env.ref("product.product_product_10")
wizard.nfe_xml = base64.b64encode(xml)
wizard._onchange_partner_id()
wizard.imported_products_ids[0].product_id = product_10
wizard.imported_products_ids[0].uom_internal = product_10.uom_id
action = wizard.import_nfe_xml()
edoc = self.env["l10n_br_fiscal.document"].browse(action["res_id"])
delivery_adress = edoc.partner_id.child_ids[0]
self.assertFalse(delivery_adress.country_id)
self.assertFalse(delivery_adress.crc_state_id)
self.assertFalse(delivery_adress.city_id)
Loading

0 comments on commit 14135be

Please sign in to comment.