Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[15.0][spec_driven_model][l10n_br_nfe][l10n_br_nfe_spec][l10n_br_account_nfe] Oca port spec driven model 14.0 to 15.0 51e0f3 (fwp 3431) #3510

Draft
wants to merge 12 commits into
base: 15.0
Choose a base branch
from
Draft
6 changes: 6 additions & 0 deletions .oca/oca-port/blacklist/spec_driven_model.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"pull_requests": {
"OCA/l10n-brazil#3335": "done in #3442",
"OCA/l10n-brazil#3345": "dotfiles not ported to 15.0 yet"
}
}
46 changes: 21 additions & 25 deletions l10n_br_account_nfe/tests/test_nfce_contingency.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,65 +5,61 @@


class TestAccountNFCeContingency(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
# this hook is required to test l10n_br_account_nfe alone:
cls.env["spec.mixin.nfe"]._register_hook()
cls.document_id = cls.env.ref("l10n_br_nfe.demo_nfce_same_state")
cls.prepare_account_move_nfce()
def setUp(self):
super().setUp()
self.document_id = self.env.ref("l10n_br_nfe.demo_nfce_same_state")
self.prepare_account_move_nfce()

@classmethod
def prepare_account_move_nfce(cls):
receivable_account_id = cls.env["account.account"].create(
def prepare_account_move_nfce(self):
receivable_account_id = self.env["account.account"].create(
{
"name": "TEST ACCOUNT",
"code": "01.1.1.2.2",
"code": "1.1.1.2.2",
"reconcile": 1,
"company_id": cls.env.ref("base.main_company").id,
"user_type_id": cls.env.ref("account.data_account_type_receivable").id,
"company_id": self.env.ref("base.main_company").id,
"user_type_id": self.env.ref("account.data_account_type_receivable").id,
}
)
payable_account_id = cls.env["account.account"].create(
payable_account_id = self.env["account.account"].create(
{
"name": "TEST ACCOUNT 2",
"code": "01.1.1.2.3",
"code": "1.1.1.2.3",
"reconcile": 1,
"company_id": cls.env.ref("base.main_company").id,
"user_type_id": cls.env.ref("account.data_account_type_payable").id,
"company_id": self.env.ref("base.main_company").id,
"user_type_id": self.env.ref("account.data_account_type_payable").id,
}
)
payment_method = cls.env.ref("account.account_payment_method_manual_in").id
journal_id = cls.env["account.journal"].create(
payment_method = self.env.ref("account.account_payment_method_manual_in").id
journal_id = self.env["account.journal"].create(
{
"name": "JOURNAL TEST",
"code": "TEST",
"type": "bank",
"company_id": cls.env.ref("base.main_company").id,
"company_id": self.env.ref("base.main_company").id,
}
)
payment_mode = cls.env["account.payment.mode"].create(
payment_mode = self.env["account.payment.mode"].create(
{
"name": "PAYMENT MODE TEST",
"company_id": cls.env.ref("base.main_company").id,
"company_id": self.env.ref("base.main_company").id,
"payment_method_id": payment_method,
"fiscal_payment_mode": "15",
"bank_account_link": "fixed",
"fixed_journal_id": journal_id.id,
}
)
cls.document_move_id = cls.env["account.move"].create(
self.document_move_id = self.env["account.move"].create(
{
"name": "MOVE TEST",
"payment_mode_id": payment_mode.id,
"company_id": cls.env.ref("base.main_company").id,
"company_id": self.env.ref("base.main_company").id,
"line_ids": [
(0, 0, {"account_id": receivable_account_id.id, "credit": 10}),
(0, 0, {"account_id": payable_account_id.id, "debit": 10}),
],
}
)
cls.document_move_id.fiscal_document_id = cls.document_id.id
self.document_move_id.fiscal_document_id = self.document_id.id

def test_nfce_contingencia(self):
self.document_id._update_nfce_for_offline_contingency()
Expand Down
3 changes: 1 addition & 2 deletions l10n_br_nfe/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

def post_init_hook(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})
env["nfe.40.infnfe"]._register_hook()
cr.execute("select demo from ir_module_module where name='l10n_br_nfe';")
is_demo = cr.fetchone()[0]
if is_demo:
Expand All @@ -37,7 +36,7 @@ def post_init_hook(cr, registry):
nfe = (
env["nfe.40.infnfe"]
.with_context(tracking_disable=True, edoc_type="in")
.build_from_binding(binding.NFe.infNFe)
.build_from_binding("nfe", "40", binding.NFe.infNFe)
)
_logger.info(nfe.nfe40_emit.nfe40_CNPJ)
except ValidationError:
Expand Down
3 changes: 3 additions & 0 deletions l10n_br_nfe/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@
from . import invalidate_number
from . import dfe
from . import mde

spec_schema = "nfe"
spec_version = "40"
52 changes: 28 additions & 24 deletions l10n_br_nfe/models/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,24 +77,19 @@ def filter_processador_edoc_nfe(record):

class NFe(spec_models.StackedModel):
_name = "l10n_br_fiscal.document"
_inherit = ["l10n_br_fiscal.document", "nfe.40.infnfe", "nfe.40.fat"]
_stacked = "nfe.40.infnfe"
_field_prefix = "nfe40_"
_schema_name = "nfe"
_schema_version = "4.0.0"
_odoo_module = "l10n_br_nfe"
_spec_module = "odoo.addons.l10n_br_nfe_spec.models.v4_0.leiaute_nfe_v4_00"
_spec_tab_name = "NFe"
_nfe_search_keys = ["nfe40_Id"]
_inherit = ["l10n_br_fiscal.document", "nfe.40.infnfe"]

_nfe40_odoo_module = "odoo.addons.l10n_br_nfe_spec.models.v4_0.leiaute_nfe_v4_00"
_nfe40_stacking_mixin = "nfe.40.infnfe"
# all m2o at this level will be stacked even if not required:
_force_stack_paths = (
_nfe40_stacking_force_paths = (
"infnfe.total",
"infnfe.infAdic",
"infnfe.exporta",
"infnfe.cobr",
"infnfe.cobr.fat",
)
_nfe_search_keys = ["nfe40_Id"]

# When dynamic stacking is applied the NFe structure is:
INFNFE_TREE = """
Expand Down Expand Up @@ -675,29 +670,31 @@ def _export_many2one(self, field_name, xsd_required, class_obj=None):
denormalized inner attribute has been set.
"""
self.ensure_one()
if field_name in self._stacking_points.keys():
if field_name in self._get_stacking_points().keys():
if field_name == "nfe40_ISSQNtot" and not any(
t == "issqn"
for t in self.nfe40_det.mapped("product_id.tax_icms_or_issqn")
):
return False

elif (not xsd_required) and field_name not in ["nfe40_enderDest"]:
comodel = self.env[self._stacking_points.get(field_name).comodel_name]
comodel = self.env[
self._get_stacking_points().get(field_name).comodel_name
]
fields = [
f
for f in comodel._fields
if f.startswith(self._field_prefix)
if f.startswith(self._spec_prefix())
and f in self._fields.keys()
and f
# don't try to nfe40_fat id when reading nfe40_cobr for instance
not in self._stacking_points.keys()
not in self._get_stacking_points().keys()
]
sub_tag_read = self.read(fields)[0]
if not any(
v
for k, v in sub_tag_read.items()
if k.startswith(self._field_prefix)
if k.startswith(self._spec_prefix())
):
return False

Expand Down Expand Up @@ -733,7 +730,7 @@ def _prepare_import_dict(
}

def _build_attr(self, node, fields, vals, path, attr):
key = "nfe40_%s" % (attr[0],) # TODO schema wise
key = f"nfe40_{attr[0]}" # TODO schema wise
value = getattr(node, attr[0])

if key == "nfe40_mod":
Expand Down Expand Up @@ -866,7 +863,8 @@ def _check_document_date_key(self):
):
raise ValidationError(
_(
"The document date does not match the date in the document key."
"The document date does not match the date in the document "
"key."
)
)

Expand Down Expand Up @@ -897,11 +895,11 @@ def _serialize(self, edocs):
):
record.flush()
record.invalidate_cache()
inf_nfe = record.export_ds()[0]
inf_nfe = record._build_binding("nfe", "40")

inf_nfe_supl = None
if record.nfe40_infNFeSupl:
inf_nfe_supl = record.nfe40_infNFeSupl.export_ds()[0]
inf_nfe_supl = record.nfe40_infNFeSupl._build_binding("nfe", "40")

nfe = Nfe(infNFe=inf_nfe, infNFeSupl=inf_nfe_supl, signature=None)
edocs.append(nfe)
Expand Down Expand Up @@ -1066,13 +1064,17 @@ def _exec_after_SITUACAO_EDOC_AUTORIZADA(self, old_state, new_state):
# autorizado, podendo perder dados.
# Se der problema que apareça quando
# o usuário clicar no gerar PDF novamente.
_logger.error("DANFE Error \n {}".format(e))
_logger.error(f"DANFE Error \n {e}")
return super()._exec_after_SITUACAO_EDOC_AUTORIZADA(old_state, new_state)

def _generate_key(self):
for record in self.filtered(filter_processador_edoc_nfe):
date = fields.Datetime.context_timestamp(record, record.document_date)
if self.document_type_id.code not in [
MODELO_FISCAL_NFE,
MODELO_FISCAL_NFCE,
]:
return super()._generate_key()

for record in self.filtered(filter_processador_edoc_nfe):
required_fields_gen_edoc = []
if not record.company_cnpj_cpf:
required_fields_gen_edoc.append("CNPJ/CPF")
Expand All @@ -1090,6 +1092,7 @@ def _generate_key(self):
_("To Generate EDoc Key, you need to fill the %s field.") % field
)

date = fields.Datetime.context_timestamp(record, record.document_date)
chave_edoc = ChaveEdoc(
ano_mes=date.strftime("%y%m").zfill(4),
cnpj_cpf_emitente=record.company_cnpj_cpf,
Expand Down Expand Up @@ -1346,7 +1349,7 @@ def import_binding_nfe(self, binding, edoc_type="out"):
document = (
self.env["nfe.40.infnfe"]
.with_context(tracking_disable=True, edoc_type=edoc_type, dry_run=False)
.build_from_binding(binding.NFe.infNFe)
.build_from_binding("nfe", "40", binding.NFe.infNFe)
)

if edoc_type == "in" and document.company_id.cnpj_cpf != cnpj_cpf.formata(
Expand All @@ -1362,7 +1365,8 @@ def _document_cancel(self, justificative):
if not justificative or len(justificative) < 15:
raise ValidationError(
_(
"Please enter a justification that is at least 15 characters long."
"Please enter a justification that is at least 15 characters "
"long."
)
)
result = super()._document_cancel(justificative)
Expand Down
Loading
Loading