diff --git a/setup/stock_helper/odoo/addons/stock_helper b/setup/stock_helper/odoo/addons/stock_helper new file mode 120000 index 000000000..0284ed59e --- /dev/null +++ b/setup/stock_helper/odoo/addons/stock_helper @@ -0,0 +1 @@ +../../../../stock_helper \ No newline at end of file diff --git a/setup/stock_helper/setup.py b/setup/stock_helper/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/stock_helper/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_helper/__init__.py b/stock_helper/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/stock_helper/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/stock_helper/__manifest__.py b/stock_helper/__manifest__.py new file mode 100644 index 000000000..c422457cb --- /dev/null +++ b/stock_helper/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2020-2021 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). + +{ + "name": "Stock Helpers", + "summary": "Add methods shared between various stock modules", + "version": "13.0.1.0.0", + "author": "Camptocamp, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/stock-logistics-warehouse", + "category": "Hidden", + "depends": ["stock"], + "data": [], + "installable": True, + "license": "LGPL-3", +} diff --git a/stock_helper/models/__init__.py b/stock_helper/models/__init__.py new file mode 100644 index 000000000..88493e35d --- /dev/null +++ b/stock_helper/models/__init__.py @@ -0,0 +1 @@ +from . import stock_location diff --git a/stock_helper/models/stock_location.py b/stock_helper/models/stock_location.py new file mode 100644 index 000000000..cad6d288c --- /dev/null +++ b/stock_helper/models/stock_location.py @@ -0,0 +1,20 @@ +# Copyright 2020-2021 Camptocamp SA (http://www.camptocamp.com) +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). + +from odoo import models + + +class StockLocation(models.Model): + _inherit = "stock.location" + + def is_sublocation_of(self, others, func=any): + """Return True if self is a sublocation of others (or equal) + + By default, it return True if any other is a parent or equal. + ``all`` can be passed to ``func`` to require all the other locations + to be parent or equal to be True. + """ + self.ensure_one() + # Efficient way to verify that the current location is + # below one of the other location without using SQL. + return func(self.parent_path.startswith(other.parent_path) for other in others) diff --git a/stock_helper/readme/CONTRIBUTORS.rst b/stock_helper/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..48286263c --- /dev/null +++ b/stock_helper/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Guewen Baconnier diff --git a/stock_helper/readme/DESCRIPTION.rst b/stock_helper/readme/DESCRIPTION.rst new file mode 100644 index 000000000..198d259e3 --- /dev/null +++ b/stock_helper/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Add methods to be used by other modules. This is not a functional module. diff --git a/stock_helper/tests/__init__.py b/stock_helper/tests/__init__.py new file mode 100644 index 000000000..e67580e62 --- /dev/null +++ b/stock_helper/tests/__init__.py @@ -0,0 +1 @@ +from . import test_location_is_sublocation_of diff --git a/stock_helper/tests/common.py b/stock_helper/tests/common.py new file mode 100644 index 000000000..871a216ad --- /dev/null +++ b/stock_helper/tests/common.py @@ -0,0 +1,19 @@ +# Copyright 2020-2021 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). + +from odoo.tests import SavepointCase + + +class StockHelperCommonCase(SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + + cls.wh = cls.env.ref("stock.warehouse0") + + cls.customer_loc = cls.env.ref("stock.stock_location_customers") + cls.supplier_loc = cls.env.ref("stock.stock_location_suppliers") + cls.stock_loc = cls.wh.lot_stock_id + cls.shelf1_loc = cls.env.ref("stock.stock_location_components") + cls.shelf2_loc = cls.env.ref("stock.stock_location_14") diff --git a/stock_helper/tests/test_location_is_sublocation_of.py b/stock_helper/tests/test_location_is_sublocation_of.py new file mode 100644 index 000000000..f88047727 --- /dev/null +++ b/stock_helper/tests/test_location_is_sublocation_of.py @@ -0,0 +1,48 @@ +# Copyright 2020-2021 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). + + +from .common import StockHelperCommonCase + + +class TestStockLocationIsSublocationOf(StockHelperCommonCase): + def test_is_sublocation_of_equal(self): + self.assertTrue(self.shelf1_loc.is_sublocation_of(self.shelf1_loc)) + + def test_is_sublocation_of_equal_child_ko(self): + bin_loc = self.env["stock.location"].create( + {"name": "bin", "location_id": self.shelf1_loc.id} + ) + self.assertFalse(self.shelf1_loc.is_sublocation_of(bin_loc)) + + def test_is_sublocation_of_equal_child_sibling(self): + self.assertFalse(self.shelf1_loc.is_sublocation_of(self.shelf2_loc)) + + def test_is_sublocation_of_any_ok(self): + self.assertTrue( + self.shelf1_loc.is_sublocation_of(self.stock_loc | self.customer_loc) + ) + + def test_is_sublocation_of_any_ko(self): + self.assertFalse( + self.shelf1_loc.is_sublocation_of(self.supplier_loc | self.customer_loc) + ) + + def test_is_sublocation_of_all_ok(self): + self.assertTrue( + self.shelf1_loc.is_sublocation_of( + self.stock_loc | self.stock_loc.location_id, func=all + ) + ) + + def test_is_sublocation_of_all_ko(self): + self.assertFalse( + self.shelf1_loc.is_sublocation_of( + self.stock_loc | self.customer_loc, func=all + ) + ) + self.assertFalse( + self.shelf1_loc.is_sublocation_of( + self.supplier_loc | self.customer_loc, func=all + ) + ) diff --git a/stock_reserve_rule/__manifest__.py b/stock_reserve_rule/__manifest__.py index 7260fc480..f848698c8 100644 --- a/stock_reserve_rule/__manifest__.py +++ b/stock_reserve_rule/__manifest__.py @@ -7,7 +7,11 @@ "author": "Camptocamp, Odoo Community Association (OCA)", "website": "https://github.com/OCA/stock-logistics-warehouse", "category": "Stock Management", - "depends": ["stock", "product_packaging_type"], # OCA/product-attribute + "depends": [ + "stock", + "stock_helper", + "product_packaging_type", # OCA/product-attribute + ], "demo": [ "demo/product_demo.xml", "demo/stock_location_demo.xml", diff --git a/stock_reserve_rule/models/__init__.py b/stock_reserve_rule/models/__init__.py index 47796b0c2..2dc701116 100644 --- a/stock_reserve_rule/models/__init__.py +++ b/stock_reserve_rule/models/__init__.py @@ -1,5 +1,4 @@ from . import stock_move -from . import stock_location from . import stock_quant from . import stock_picking_type from . import stock_reserve_rule diff --git a/stock_reserve_rule/models/stock_location.py b/stock_reserve_rule/models/stock_location.py deleted file mode 100644 index 60caf1b3f..000000000 --- a/stock_reserve_rule/models/stock_location.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright 2019 Camptocamp SA -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import models - - -class StockLocation(models.Model): - _inherit = "stock.location" - - def is_sublocation_of(self, others): - """Return True if self is a sublocation of at least one other""" - self.ensure_one() - # Efficient way to verify that the current location is - # below one of the other location without using SQL. - return any(self.parent_path.startswith(other.parent_path) for other in others)