Skip to content

Commit bcc5e08

Browse files
committed
Merge PR #14 into 13.0
Signed-off-by guewen
2 parents 53dd4ad + b2e8d4c commit bcc5e08

File tree

13 files changed

+239
-0
lines changed

13 files changed

+239
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../stock_storage_type_putaway_abc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import setuptools
2+
3+
setuptools.setup(
4+
setup_requires=['setuptools-odoo'],
5+
odoo_addon=True,
6+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2019 Camptocamp SA
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
3+
{
4+
"name": "Stock Storage Type ABC Strategy",
5+
"summary": "Advanced storage strategy ABC for WMS",
6+
"version": "13.0.1.0.0",
7+
"development_status": "Alpha",
8+
"category": "Warehouse Management",
9+
"website": "https://github.com/OCA/wms",
10+
"author": "Camptocamp, Odoo Community Association (OCA)",
11+
"license": "AGPL-3",
12+
"application": False,
13+
"installable": True,
14+
"depends": ["stock_storage_type"],
15+
"data": ["views/product.xml", "views/stock_location.xml"],
16+
"demo": [],
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from . import product_template
2+
from . import stock_location
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright 2019 Camptocamp SA
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
3+
from odoo import fields, models
4+
5+
from .stock_location import ABC_SELECTION
6+
7+
8+
class ProductTemplate(models.Model):
9+
10+
_inherit = "product.template"
11+
12+
abc_storage = fields.Selection(ABC_SELECTION, default="b")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Copyright 2019 Camptocamp SA
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
3+
from random import shuffle
4+
5+
from odoo import api, fields, models
6+
from odoo.fields import first
7+
8+
ABC_SELECTION = [("a", "A"), ("b", "B"), ("c", "C")]
9+
10+
11+
class StockLocation(models.Model):
12+
13+
_inherit = "stock.location"
14+
15+
pack_putaway_strategy = fields.Selection(selection_add=[("abc", "Chaotic ABC")])
16+
display_abc_storage = fields.Boolean(compute="_compute_display_abc_storage")
17+
abc_storage = fields.Selection(ABC_SELECTION, required=True, default="b")
18+
19+
@api.depends(
20+
"location_id",
21+
"location_id.pack_putaway_strategy",
22+
"location_id.display_abc_storage",
23+
)
24+
def _compute_display_abc_storage(self):
25+
for location in self:
26+
current_location = location.location_id
27+
display_abc_storage = current_location.display_abc_storage
28+
while current_location and not display_abc_storage:
29+
if current_location.pack_putaway_strategy == "abc":
30+
display_abc_storage = True
31+
break
32+
else:
33+
current_location = current_location.location_id
34+
location.display_abc_storage = display_abc_storage
35+
36+
def get_storage_locations(self, products=None):
37+
if products is None:
38+
products = self.env["product.product"]
39+
if self.pack_putaway_strategy == "abc":
40+
return self._get_abc_locations(products)
41+
return super().get_storage_locations(products)
42+
43+
def _get_abc_locations(self, products):
44+
return self.leaf_location_ids._sort_abc_locations(first(products).abc_storage)
45+
46+
def _sort_abc_locations(self, product_abc):
47+
product_abc = product_abc or "a"
48+
a_location_ids = []
49+
b_location_ids = []
50+
c_location_ids = []
51+
for loc in self:
52+
if loc.abc_storage == "a":
53+
a_location_ids.append(loc.id)
54+
elif loc.abc_storage == "b":
55+
b_location_ids.append(loc.id)
56+
elif loc.abc_storage == "c":
57+
c_location_ids.append(loc.id)
58+
shuffle(a_location_ids)
59+
shuffle(b_location_ids)
60+
shuffle(c_location_ids)
61+
if product_abc == "a":
62+
location_ids = a_location_ids + b_location_ids + c_location_ids
63+
elif product_abc == "b":
64+
location_ids = b_location_ids + c_location_ids + a_location_ids
65+
elif product_abc == "c":
66+
location_ids = c_location_ids + a_location_ids + b_location_ids
67+
else:
68+
raise ValueError("product_abc = %s" % product_abc)
69+
return self.env["stock.location"].browse(location_ids)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* Akim Juillerat <[email protected]>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
This module implements chaotic storage 'ABC' according to Package Storage Type
2+
and Location Storage Type.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import test_abc_location
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Copyright 2019 Camptocamp SA
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
3+
from odoo.tests import SavepointCase
4+
5+
6+
class TestAbcLocation(SavepointCase):
7+
@classmethod
8+
def setUpClass(cls):
9+
super().setUpClass()
10+
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
11+
ref = cls.env.ref
12+
cls.stock_location = ref("stock.stock_location_stock")
13+
cls.cardboxes_location = ref("stock_storage_type.stock_location_cardboxes")
14+
cls.pallets_location = ref("stock_storage_type.stock_location_pallets")
15+
cls.cardboxes_bin_1_location = ref(
16+
"stock_storage_type.stock_location_cardboxes_bin_1"
17+
)
18+
cls.cardboxes_bin_2_location = ref(
19+
"stock_storage_type.stock_location_cardboxes_bin_2"
20+
)
21+
cls.cardboxes_bin_3_location = ref(
22+
"stock_storage_type.stock_location_cardboxes_bin_3"
23+
)
24+
cls.pallets_bin_1_location = ref(
25+
"stock_storage_type.stock_location_pallets_bin_1"
26+
)
27+
cls.pallets_bin_2_location = ref(
28+
"stock_storage_type.stock_location_pallets_bin_2"
29+
)
30+
cls.pallets_bin_3_location = ref(
31+
"stock_storage_type.stock_location_pallets_bin_3"
32+
)
33+
cls.product = ref("product.product_product_9")
34+
35+
def test_display_abc_storage_one_level(self):
36+
self.cardboxes_location.write({"pack_putaway_strategy": "abc"})
37+
self.assertTrue(self.cardboxes_bin_1_location.display_abc_storage)
38+
self.assertTrue(self.cardboxes_bin_2_location.display_abc_storage)
39+
self.assertTrue(self.cardboxes_bin_3_location.display_abc_storage)
40+
self.assertFalse(self.pallets_bin_1_location.display_abc_storage)
41+
self.assertFalse(self.pallets_bin_2_location.display_abc_storage)
42+
self.assertFalse(self.pallets_bin_3_location.display_abc_storage)
43+
self.cardboxes_location.write({"pack_putaway_strategy": "ordered_locations"})
44+
self.assertFalse(self.cardboxes_bin_1_location.display_abc_storage)
45+
self.assertFalse(self.cardboxes_bin_2_location.display_abc_storage)
46+
self.assertFalse(self.cardboxes_bin_3_location.display_abc_storage)
47+
self.assertFalse(self.pallets_bin_1_location.display_abc_storage)
48+
self.assertFalse(self.pallets_bin_2_location.display_abc_storage)
49+
self.assertFalse(self.pallets_bin_3_location.display_abc_storage)
50+
51+
def test_display_abc_storage_two_levels(self):
52+
self.stock_location.write({"pack_putaway_strategy": "abc"})
53+
self.assertTrue(self.cardboxes_bin_1_location.display_abc_storage)
54+
self.assertTrue(self.cardboxes_bin_2_location.display_abc_storage)
55+
self.assertTrue(self.cardboxes_bin_3_location.display_abc_storage)
56+
self.assertTrue(self.pallets_bin_1_location.display_abc_storage)
57+
self.assertTrue(self.pallets_bin_2_location.display_abc_storage)
58+
self.assertTrue(self.pallets_bin_3_location.display_abc_storage)
59+
self.stock_location.write({"pack_putaway_strategy": "none"})
60+
self.assertFalse(self.cardboxes_bin_1_location.display_abc_storage)
61+
self.assertFalse(self.cardboxes_bin_2_location.display_abc_storage)
62+
self.assertFalse(self.cardboxes_bin_3_location.display_abc_storage)
63+
self.assertFalse(self.pallets_bin_1_location.display_abc_storage)
64+
self.assertFalse(self.pallets_bin_2_location.display_abc_storage)
65+
self.assertFalse(self.pallets_bin_3_location.display_abc_storage)
66+
67+
def test_abc_ordered(self):
68+
self.cardboxes_location.write({"pack_putaway_strategy": "abc"})
69+
self.cardboxes_bin_1_location.write({"abc_storage": "b"})
70+
self.cardboxes_bin_2_location.write({"abc_storage": "a"})
71+
self.cardboxes_bin_3_location.write({"abc_storage": "c"})
72+
self.product.write({"abc_storage": "a"})
73+
ordered_locations = self.cardboxes_location.get_storage_locations(self.product)
74+
self.assertEqual(
75+
ordered_locations,
76+
self.cardboxes_bin_2_location
77+
| self.cardboxes_bin_1_location
78+
| self.cardboxes_bin_3_location,
79+
)
80+
self.product.write({"abc_storage": "b"})
81+
ordered_locations = self.cardboxes_location.get_storage_locations(self.product)
82+
self.assertEqual(
83+
ordered_locations,
84+
self.cardboxes_bin_1_location
85+
| self.cardboxes_bin_3_location
86+
| self.cardboxes_bin_2_location,
87+
)
88+
self.product.write({"abc_storage": "c"})
89+
ordered_locations = self.cardboxes_location.get_storage_locations(self.product)
90+
self.assertEqual(
91+
ordered_locations,
92+
self.cardboxes_bin_3_location
93+
| self.cardboxes_bin_2_location
94+
| self.cardboxes_bin_1_location,
95+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<odoo>
3+
<record id="product_template_form_view_inherit" model="ir.ui.view">
4+
<field name="name">product.template.common.form.inherit</field>
5+
<field name="model">product.template</field>
6+
<field name="inherit_id" ref="product.product_template_form_view" />
7+
<field name="arch" type="xml">
8+
<group name="packaging" position="after">
9+
<group name="abc" string="ABC Storage preference">
10+
<field name="abc_storage" />
11+
</group>
12+
</group>
13+
</field>
14+
</record>
15+
</odoo>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<odoo>
3+
<record id="view_location_form_inherit" model="ir.ui.view">
4+
<field name="name">stock.location.form.inherit</field>
5+
<field name="model">stock.location</field>
6+
<field name="inherit_id" ref="stock_storage_type.view_location_form_inherit" />
7+
<field name="arch" type="xml">
8+
<field name="pack_putaway_strategy" position="after">
9+
<field name="display_abc_storage" invisible="1" />
10+
<field
11+
name="abc_storage"
12+
attrs="{'invisible': [('display_abc_storage', '=', False)]}"
13+
/>
14+
</field>
15+
</field>
16+
</record>
17+
</odoo>

0 commit comments

Comments
 (0)