From 1518dc966a053e96fc9a2b9fd495199fd9de2044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Mon, 7 Oct 2024 19:09:48 +0000 Subject: [PATCH] [REF] l10n_br_nfe: multi-schemas compat --- l10n_br_nfe/hooks.py | 2 +- l10n_br_nfe/models/__init__.py | 3 ++ l10n_br_nfe/models/document.py | 38 +++++++++++++---------- l10n_br_nfe/models/document_line.py | 14 +++++---- l10n_br_nfe/models/document_related.py | 10 +++--- l10n_br_nfe/models/document_supplement.py | 8 +++-- l10n_br_nfe/tests/test_nfe_import.py | 4 +-- l10n_br_nfe/tests/test_nfe_structure.py | 21 ++++++++++--- 8 files changed, 63 insertions(+), 37 deletions(-) diff --git a/l10n_br_nfe/hooks.py b/l10n_br_nfe/hooks.py index b6e8745b0167..18d2bbcdf4bd 100644 --- a/l10n_br_nfe/hooks.py +++ b/l10n_br_nfe/hooks.py @@ -37,7 +37,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: diff --git a/l10n_br_nfe/models/__init__.py b/l10n_br_nfe/models/__init__.py index e8a09f1a5adc..7222c6a3032b 100644 --- a/l10n_br_nfe/models/__init__.py +++ b/l10n_br_nfe/models/__init__.py @@ -21,3 +21,6 @@ from . import invalidate_number from . import dfe from . import mde + +spec_schema = "nfe" +spec_version = "40" diff --git a/l10n_br_nfe/models/document.py b/l10n_br_nfe/models/document.py index 67a1cfa80f03..fbeb3c9345e5 100644 --- a/l10n_br_nfe/models/document.py +++ b/l10n_br_nfe/models/document.py @@ -79,19 +79,21 @@ 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" - _spec_module = "odoo.addons.l10n_br_nfe_spec.models.v4_0.leiaute_nfe_v4_00" + _nfe40_spec_settings = { + "module": "odoo.addons.l10n_br_nfe_spec.models.v4_0.leiaute_nfe_v4_00", + "stacking_mixin": "nfe.40.infnfe", + "stacking_points": {}, + # all m2o at this level will be stacked even if not required: + "stacking_force_paths": ( + "infnfe.total", + "infnfe.infAdic", + "infnfe.exporta", + "infnfe.cobr", + "infnfe.cobr.fat", + ), + } _nfe_search_keys = ["nfe40_Id"] - # all m2o at this level will be stacked even if not required: - _force_stack_paths = ( - "infnfe.total", - "infnfe.infAdic", - "infnfe.exporta", - "infnfe.cobr", - "infnfe.cobr.fat", - ) - # When dynamic stacking is applied the NFe structure is: INFNFE_TREE = """ > @@ -671,7 +673,7 @@ 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") @@ -679,7 +681,9 @@ def _export_many2one(self, field_name, xsd_required, class_obj=None): 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 @@ -687,7 +691,7 @@ def _export_many2one(self, field_name, xsd_required, class_obj=None): 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( @@ -894,11 +898,11 @@ def _serialize(self, edocs): ): record.flush() record.invalidate_cache() - inf_nfe = record.export_ds()[0] + inf_nfe = record.export_ds("nfe", "40")[0] inf_nfe_supl = None if record.nfe40_infNFeSupl: - inf_nfe_supl = record.nfe40_infNFeSupl.export_ds()[0] + inf_nfe_supl = record.nfe40_infNFeSupl.export_ds("nfe", "40")[0] nfe = Nfe(infNFe=inf_nfe, infNFeSupl=inf_nfe_supl, signature=None) edocs.append(nfe) @@ -1343,7 +1347,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( diff --git a/l10n_br_nfe/models/document_line.py b/l10n_br_nfe/models/document_line.py index ca9d19a9c7bc..938f9cfbd1e4 100644 --- a/l10n_br_nfe/models/document_line.py +++ b/l10n_br_nfe/models/document_line.py @@ -70,12 +70,14 @@ class NFeLine(spec_models.StackedModel): _name = "l10n_br_fiscal.document.line" _inherit = ["l10n_br_fiscal.document.line", "nfe.40.det"] - _stacked = "nfe.40.det" - _spec_module = "odoo.addons.l10n_br_nfe_spec.models.v4_0.leiaute_nfe_v4_00" - _stacking_points = {} - # all m2o below this level will be stacked even if not required: - _force_stack_paths = ("det.imposto.",) - _stack_skip = ("nfe40_det_infNFe_id",) + _nfe40_spec_settings = { + "module": "odoo.addons.l10n_br_nfe_spec.models.v4_0.leiaute_nfe_v4_00", + "stacking_mixin": "nfe.40.det", + "stacking_points": {}, + # all m2o below this level will be stacked even if not required: + "stacking_force_paths": ("det.imposto.",), + "stacking_skip_paths": ("nfe40_det_infNFe_id",), + } # When dynamic stacking is applied, the NFe line has the following structure: DET_TREE = """ diff --git a/l10n_br_nfe/models/document_related.py b/l10n_br_nfe/models/document_related.py index 6dda2590a328..a265287731d4 100644 --- a/l10n_br_nfe/models/document_related.py +++ b/l10n_br_nfe/models/document_related.py @@ -20,10 +20,12 @@ class NFeRelated(spec_models.StackedModel): _name = "l10n_br_fiscal.document.related" _inherit = ["l10n_br_fiscal.document.related", "nfe.40.nfref"] - _stacked = "nfe.40.nfref" - _stacking_points = {} - _spec_module = "odoo.addons.l10n_br_nfe_spec.models.v4_0.leiaute_nfe_v4_00" - _stack_skip = ("nfe40_NFref_ide_id",) + _nfe40_spec_settings = { + "module": "odoo.addons.l10n_br_nfe_spec.models.v4_0.leiaute_nfe_v4_00", + "stacking_mixin": "nfe.40.nfref", + "stacking_points": {}, + "stacking_skip_paths": ("nfe40_NFref_ide_id",), + } # all m2o below this level will be stacked even if not required: _rec_name = "nfe40_refNFe" diff --git a/l10n_br_nfe/models/document_supplement.py b/l10n_br_nfe/models/document_supplement.py index a4e55aab4632..6d114ed23d5f 100644 --- a/l10n_br_nfe/models/document_supplement.py +++ b/l10n_br_nfe/models/document_supplement.py @@ -9,6 +9,8 @@ class NFeSupplement(spec_models.StackedModel): _name = "l10n_br_fiscal.document.supplement" _description = "NFe Supplement Document" _inherit = "nfe.40.infnfesupl" - _stacked = "nfe.40.infnfesupl" - _stacking_points = {} - _spec_module = "odoo.addons.l10n_br_nfe_spec.models.v4_0.leiaute_nfe_v4_00" + _nfe40_spec_settings = { + "module": "odoo.addons.l10n_br_nfe_spec.models.v4_0.leiaute_nfe_v4_00", + "stacking_mixin": "nfe.40.infnfesupl", + "stacking_points": {}, + } diff --git a/l10n_br_nfe/tests/test_nfe_import.py b/l10n_br_nfe/tests/test_nfe_import.py index 758ce30b0a20..8927b0a2a5c0 100644 --- a/l10n_br_nfe/tests/test_nfe_import.py +++ b/l10n_br_nfe/tests/test_nfe_import.py @@ -32,7 +32,7 @@ def test_import_in_nfe_dry_run(self): nfe = ( self.env["nfe.40.infnfe"] .with_context(tracking_disable=True, edoc_type="in") - .build_from_binding(binding.NFe.infNFe, dry_run=True) + .build_from_binding("nfe", "40", binding.NFe.infNFe, dry_run=True) ) assert isinstance(nfe.id, NewId) self._check_nfe(nfe) @@ -51,7 +51,7 @@ def test_import_in_nfe(self): nfe = ( self.env["nfe.40.infnfe"] .with_context(tracking_disable=True, edoc_type="in") - .build_from_binding(binding.NFe.infNFe, dry_run=False) + .build_from_binding("nfe", "40", binding.NFe.infNFe, dry_run=False) ) assert isinstance(nfe.id, int) diff --git a/l10n_br_nfe/tests/test_nfe_structure.py b/l10n_br_nfe/tests/test_nfe_structure.py index eadcf4b0f6f1..b34f59cd4dd7 100644 --- a/l10n_br_nfe/tests/test_nfe_structure.py +++ b/l10n_br_nfe/tests/test_nfe_structure.py @@ -26,11 +26,14 @@ def get_stacked_tree(cls, klass): # ≡ means o2m. Eventually followd by the mapped Odoo model """ spec_module = "odoo.addons.l10n_br_nfe_spec.models.v4_0.leiaute_nfe_v4_00" - node = SpecModel._odoo_name_to_class(klass._stacked, spec_module) + stacking_settings = klass._nfe40_spec_settings + node = SpecModel._odoo_name_to_class( + stacking_settings["stacking_mixin"], spec_module + ) tree = StringIO() visited = set() for kind, n, path, field_path, child_concrete in klass._visit_stack( - cls.env, node + cls.env, node, stacking_settings ): visited.add(n) path_items = path.split(".") @@ -118,7 +121,13 @@ def test_doc_stacking_points(self): "nfe40_cobr", "nfe40_fat", ] - keys = [k for k in self.env["l10n_br_fiscal.document"]._stacking_points.keys()] + keys = [ + k + for k in self.env["l10n_br_fiscal.document"] + .with_context(spec_schema="nfe", spec_version="40") + ._get_stacking_points() + .keys() + ] self.assertEqual(sorted(keys), sorted(doc_keys)) def test_doc_tree(self): @@ -154,7 +163,11 @@ def test_doc_line_stacking_points(self): "nfe40_prod", ] keys = [ - k for k in self.env["l10n_br_fiscal.document.line"]._stacking_points.keys() + k + for k in self.env["l10n_br_fiscal.document.line"] + .with_context(spec_schema="nfe", spec_version="40") + ._get_stacking_points() + .keys() ] self.assertEqual(sorted(keys), line_keys)