From 5457412e3e747b9adfc55bfdf2de7963781d70af Mon Sep 17 00:00:00 2001 From: Souheil Bejaoui Date: Wed, 25 Mar 2026 11:02:07 +0100 Subject: [PATCH] [IMP] product_packaging_unece: cache UNECE code mapping add an ormcache based helper to map UNECE codes to packaging level --- .../models/product_packaging_level.py | 35 +++++++++- product_packaging_unece/tests/__init__.py | 1 + .../tests/test_product_packaging_unece.py | 66 +++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 product_packaging_unece/tests/__init__.py create mode 100644 product_packaging_unece/tests/test_product_packaging_unece.py diff --git a/product_packaging_unece/models/product_packaging_level.py b/product_packaging_unece/models/product_packaging_level.py index da79af60..5078ddd2 100644 --- a/product_packaging_unece/models/product_packaging_level.py +++ b/product_packaging_unece/models/product_packaging_level.py @@ -1,7 +1,9 @@ # Copyright 2026 ACSONE SA/NV # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from collections import defaultdict -from odoo import fields, models +from odoo import api, fields, models +from odoo.tools import ormcache class ProductPackagingLevel(models.Model): @@ -16,3 +18,34 @@ class ProductPackagingLevel(models.Model): "nomenclature of the United Nations Economic " "Commission for Europe (UNECE), DataElement Rec 21)", ) + + @api.model + @ormcache() + def _get_packaging_level_ids_by_unece_code(self): + res = defaultdict(list) + for level in self.search([("unece_type_ids", "!=", False)]): + for unece_type in level.unece_type_ids: + res[unece_type.code].append(level.id) + return res + + def get_packaging_level_ids_by_unece_code(self, *unece_codes): + mapping = self._get_packaging_level_ids_by_unece_code() + if len(unece_codes) == 1 and isinstance(unece_codes[0], (list, tuple, set)): + unece_codes = unece_codes[0] + return [lid for code in unece_codes for lid in mapping.get(code, [])] + + @api.model_create_multi + def create(self, vals_list): + records = super().create(vals_list) + self._get_packaging_level_ids_by_unece_code.clear_cache(self) + return records + + def write(self, vals): + res = super().write(vals) + self._get_packaging_level_ids_by_unece_code.clear_cache(self) + return res + + def unlink(self): + res = super().unlink() + self._get_packaging_level_ids_by_unece_code.clear_cache(self) + return res diff --git a/product_packaging_unece/tests/__init__.py b/product_packaging_unece/tests/__init__.py new file mode 100644 index 00000000..5efb8209 --- /dev/null +++ b/product_packaging_unece/tests/__init__.py @@ -0,0 +1 @@ +from . import test_product_packaging_unece diff --git a/product_packaging_unece/tests/test_product_packaging_unece.py b/product_packaging_unece/tests/test_product_packaging_unece.py new file mode 100644 index 00000000..b90c7e7e --- /dev/null +++ b/product_packaging_unece/tests/test_product_packaging_unece.py @@ -0,0 +1,66 @@ +# Copyright 2026 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import Command +from odoo.tests.common import TransactionCase + + +class TestProductPackagingUnece(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.level_model = cls.env["product.packaging.level"] + cls.unece_bx = cls.env.ref("product_packaging_unece.unece_packaging_bx") + cls.unece_ct = cls.env.ref("product_packaging_unece.unece_packaging_ct") + cls.unece_pl = cls.env.ref("product_packaging_unece.unece_packaging_pl") + + cls.level_box = cls.level_model.create( + { + "name": "Box level", + "code": "BX", + "sequence": 1, + "unece_type_ids": [Command.set([cls.unece_bx.id])], + } + ) + cls.level_carton_pallet = cls.level_model.create( + { + "name": "Carton/Pallet level", + "code": "CA", + "sequence": 2, + "unece_type_ids": [Command.set([cls.unece_ct.id, cls.unece_pl.id])], + } + ) + cls.level_pallet = cls.level_model.create( + { + "name": "Pallet level", + "code": "PL", + "sequence": 3, + "unece_type_ids": [Command.set([cls.unece_pl.id])], + } + ) + + def test_get_packaging_level_ids_by_one_code(self): + level_ids = self.level_model.get_packaging_level_ids_by_unece_code("BX") + self.assertEqual(set(level_ids), {self.level_box.id}) + + def test_get_packaging_level_ids_by_multiple_codes(self): + level_ids = self.level_model.get_packaging_level_ids_by_unece_code("BX", "PL") + self.assertEqual( + set(level_ids), + {self.level_box.id, self.level_carton_pallet.id, self.level_pallet.id}, + ) + + def test_get_packaging_level_ids_by_list_of_codes(self): + level_ids = self.level_model.get_packaging_level_ids_by_unece_code(["CT", "PL"]) + self.assertEqual( + set(level_ids), + {self.level_carton_pallet.id, self.level_pallet.id}, + ) + + def test_get_packaging_level_ids_by_unknown_code(self): + level_ids = self.level_model.get_packaging_level_ids_by_unece_code("XXX") + self.assertEqual(level_ids, []) + + def test_get_packaging_level_ids_by_false_code(self): + level_ids = self.level_model.get_packaging_level_ids_by_unece_code(False) + self.assertEqual(level_ids, [])