Skip to content

Commit c7767c7

Browse files
[REF] l10n_br_nfe: DFe implementation
1 parent be49e28 commit c7767c7

17 files changed

+417
-576
lines changed

l10n_br_nfe/__manifest__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"views/res_company_view.xml",
3030
"views/nfe_document_view.xml",
3131
"views/res_config_settings_view.xml",
32-
"views/mde/mde_views.xml",
32+
"views/nfe_recipient_manifestation_event/nfe_recipient_manifestation_event_view.xml",
3333
"views/dfe/dfe_views.xml",
3434
"views/supplier_info_view.xml",
3535
# Report
@@ -38,6 +38,7 @@
3838
"report/danfe_report.xml",
3939
# Wizards
4040
"wizards/import_document.xml",
41+
"wizards/nfe_recipient_manifestation_event_wizard.xml",
4142
# Actions,
4243
"views/nfe_action.xml",
4344
# Menus

l10n_br_nfe/constants/mde.py

-18
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,10 @@
77
SIT_MANIF_DESCONHECIDO = ("desconhecido", "Desconhecimento")
88
SIT_MANIF_NAO_REALIZADO = ("nao_realizado", "Não realizado")
99

10-
SCHEMA_RESNFE = ("resNFe", "NFe Resumida")
11-
SCHEMA_RESEVENTO = ("resEvento", "Evento de NFe Resumido")
12-
SCHEMA_PROCNFE = ("procNFe", "NFe Completa")
13-
SCHEMA_PROCEVENTONFE = ("procEventoNFe", "Evento de NFe Completo")
14-
15-
SCHEMAS = [SCHEMA_RESNFE, SCHEMA_RESEVENTO, SCHEMA_PROCNFE, SCHEMA_PROCEVENTONFE]
16-
1710
SITUACAO_MANIFESTACAO = [
1811
SIT_MANIF_PENDENTE,
1912
SIT_MANIF_CIENTE,
2013
SIT_MANIF_CONFIRMADO,
2114
SIT_MANIF_DESCONHECIDO,
2215
SIT_MANIF_NAO_REALIZADO,
2316
]
24-
25-
SIT_NFE_AUTORIZADA = ("1", "Autorizada")
26-
SIT_NFE_CANCELADA = ("2", "Cancelada")
27-
SIT_NFE_DENEGADA = ("3", "Denegada")
28-
29-
SITUACAO_NFE = [SIT_NFE_AUTORIZADA, SIT_NFE_CANCELADA, SIT_NFE_DENEGADA]
30-
31-
OP_TYPE_ENTRADA = ("0", "Entrada")
32-
OP_TYPE_SAIDA = ("1", "Saída")
33-
34-
OPERATION_TYPE = [OP_TYPE_ENTRADA, OP_TYPE_SAIDA]

l10n_br_nfe/models/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
from . import res_config_settings
1919
from . import cfop
2020
from . import invalidate_number
21+
from . import nfe_recipient_manifestation_event
2122
from . import dfe
22-
from . import mde
2323

2424
spec_schema = "nfe"
2525
spec_version = "40"

l10n_br_nfe/models/dfe.py

+29-118
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,42 @@
1-
# Copyright (C) 2023 KMEE Informatica LTDA
1+
# Copyright (C) 2023 KMEE Informatica LTDA from odoo import _, fields, models
22
# License AGPL-3 or later (http://www.gnu.org/licenses/agpl)
3-
4-
from datetime import datetime
5-
6-
from lxml import objectify
7-
from nfelib.nfe.bindings.v4_0.leiaute_nfe_v4_00 import TnfeProc
8-
9-
from odoo import api, fields, models
10-
11-
from odoo.addons.l10n_br_fiscal_dfe.tools import utils
3+
from odoo import _, fields, models
124

135

146
class DFe(models.Model):
157
_inherit = "l10n_br_fiscal.dfe"
168

17-
mde_ids = fields.One2many(
18-
comodel_name="l10n_br_nfe.mde",
9+
nfe_recipient_manifestation_event_ids = fields.One2many(
10+
comodel_name="l10n_br_nfe.recipient_manifestation_event",
1911
inverse_name="dfe_id",
2012
string="Manifestações do Destinatário Importadas",
2113
)
2214

23-
def _process_distribution(self, result):
24-
for doc in result.resposta.loteDistDFeInt.docZip:
25-
xml = utils.parse_gzip_xml(doc.valueOf_).read()
26-
root = objectify.fromstring(xml)
27-
28-
mde_id = self.env["l10n_br_nfe.mde"].search(
29-
[
30-
("nsu", "=", utils.format_nsu(doc.NSU)),
31-
("company_id", "=", self.company_id.id),
32-
],
33-
limit=1,
15+
def create_mde_action(self):
16+
return {
17+
"name": _("Manifestação do Destinatário"),
18+
"type": "ir.actions.act_window",
19+
"res_model": "nfe_recipient_manifestation_event.wizard",
20+
"view_mode": "form",
21+
"target": "new",
22+
"context": {
23+
"default_dfe_id": self.id,
24+
},
25+
}
26+
27+
def import_document(self):
28+
self.ensure_one()
29+
try:
30+
document = self.dfe_monitor_id._download_document(self.key)
31+
document_id = self.dfe_monitor_id._parse_xml_document(document)
32+
except Exception as e:
33+
self.message_post(
34+
body=_("Error importing document: \n\n %(error)s", error=e)
3435
)
35-
if not mde_id:
36-
mde_id = self._create_mde_from_schema(doc.schema, root)
37-
if mde_id:
38-
mde_id.nsu = doc.NSU
39-
mde_id.create_xml_attachment(xml)
40-
41-
@api.model
42-
def _create_mde_from_schema(self, schema, root):
43-
schema_type = schema.split("_")[0]
44-
method = "_create_mde_from_%s" % schema_type
45-
if not hasattr(self, method):
4636
return
37+
if document_id:
38+
self.document_id = document_id
4739

48-
return getattr(self, method)(root)
49-
50-
@api.model
51-
def _create_mde_from_procNFe(self, root):
52-
nfe_key = root.protNFe.infProt.chNFe
53-
mde_id = self.find_mde_by_key(nfe_key)
54-
if mde_id:
55-
return mde_id
56-
57-
supplier_cnpj = utils.mask_cnpj("%014d" % root.NFe.infNFe.emit.CNPJ)
58-
partner = self.env["res.partner"].search([("cnpj_cpf", "=", supplier_cnpj)])
59-
60-
return self.env["l10n_br_nfe.mde"].create(
61-
{
62-
"number": root.NFe.infNFe.ide.nNF,
63-
"key": nfe_key,
64-
"operation_type": str(root.NFe.infNFe.ide.tpNF),
65-
"document_value": root.NFe.infNFe.total.ICMSTot.vNF,
66-
"state": "pendente",
67-
"inclusion_datetime": datetime.now(),
68-
"cnpj_cpf": supplier_cnpj,
69-
"ie": root.NFe.infNFe.emit.IE,
70-
"partner_id": partner.id,
71-
"emission_datetime": datetime.strptime(
72-
str(root.NFe.infNFe.ide.dhEmi)[:19],
73-
"%Y-%m-%dT%H:%M:%S",
74-
),
75-
"company_id": self.company_id.id,
76-
"dfe_id": self.id,
77-
"inclusion_mode": "Verificação agendada",
78-
"schema": "procNFe",
79-
}
80-
)
81-
82-
@api.model
83-
def _create_mde_from_resNFe(self, root):
84-
nfe_key = root.chNFe
85-
mde_id = self.find_mde_by_key(nfe_key)
86-
if mde_id:
87-
return mde_id
88-
89-
supplier_cnpj = utils.mask_cnpj("%014d" % root.CNPJ)
90-
partner_id = self.env["res.partner"].search([("cnpj_cpf", "=", supplier_cnpj)])
91-
92-
return self.env["l10n_br_nfe.mde"].create(
93-
{
94-
"key": nfe_key,
95-
"emitter": root.xNome,
96-
"operation_type": str(root.tpNF),
97-
"document_value": root.vNF,
98-
"document_state": str(root.cSitNFe),
99-
"state": "pendente",
100-
"inclusion_datetime": datetime.now(),
101-
"cnpj_cpf": supplier_cnpj,
102-
"ie": root.IE,
103-
"partner_id": partner_id.id,
104-
"emission_datetime": datetime.strptime(
105-
str(root.dhEmi)[:19], "%Y-%m-%dT%H:%M:%S"
106-
),
107-
"company_id": self.company_id.id,
108-
"dfe_id": self.id,
109-
"inclusion_mode": "Verificação agendada - manifestada por outro app",
110-
"schema": "resNFe",
111-
}
112-
)
113-
114-
@api.model
115-
def find_mde_by_key(self, key):
116-
mde_id = self.env["l10n_br_nfe.mde"].search([("key", "=", key)])
117-
if not mde_id:
118-
return False
119-
120-
if mde_id not in self.mde_ids:
121-
mde_id.dfe_id = self.id
122-
return mde_id
123-
124-
def import_documents(self):
125-
for record in self:
126-
record.mde_ids.import_document_multi()
127-
128-
@api.model
129-
def parse_procNFe(self, xml):
130-
binding = TnfeProc.from_xml(xml.read().decode())
131-
return self.env["l10n_br_fiscal.document"].import_binding_nfe(binding)
40+
def import_document_multi(self):
41+
for rec in self:
42+
rec.import_document()

0 commit comments

Comments
 (0)