Add stock_helper: share common code used by stock modules

The first method is: StockLocation.is_sublocation_of()

This method is currently used in:

* wms/stock_dynamic_routing
* wms/shopfloor
* wms/stock_move_source_relocate
* stock-logistics-warehouse/stock_reserve_rule
* ddmrp/ddmrp

The goal will be to use this module as dependency instead of
reimplementing the method in each.

Other methods should follow in "stock_helper".

Note: I opened https://github.com/odoo/odoo/pull/53866 to propose a
generic version of this method, expecting odoo's opinion, but got no
answer.
This commit is contained in:
Guewen Baconnier
2021-02-09 12:06:44 +01:00
committed by davidborromeo
parent 5d3776cc4d
commit f04c497a9e
9 changed files with 107 additions and 0 deletions

1
stock_helper/__init__.py Normal file
View File

@@ -0,0 +1 @@
from . import models

View File

@@ -0,0 +1,15 @@
# Copyright 2020-2021 Camptocamp SA
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{
"name": "Stock Move Helpers",
"summary": "Add methods shared between various stock modules",
"version": "13.0.1.1.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",
}

View File

@@ -0,0 +1 @@
from . import stock_location

View File

@@ -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)

View File

@@ -0,0 +1 @@
* Guewen Baconnier <guewen.baconnier@camptocamp.com>

View File

@@ -0,0 +1 @@
Add methods to be used by other modules. This is not a functional module.

View File

@@ -0,0 +1 @@
from . import test_location_is_sublocation_of

View File

@@ -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")

View File

@@ -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
)
)