diff --git a/stock_putaway_product_template/__manifest__.py b/stock_putaway_product_template/__manifest__.py index 9cacc4285..9ee31bc46 100644 --- a/stock_putaway_product_template/__manifest__.py +++ b/stock_putaway_product_template/__manifest__.py @@ -8,11 +8,7 @@ "author": "Akretion, Odoo Community Association (OCA)", "license": "AGPL-3", "depends": ["stock"], - "external_dependencies": { - "python": [ - "openupgradelib", - ], - }, + "external_dependencies": {"python": ["openupgradelib"]}, "data": ["views/product.xml"], "demo": ["demo/putaway_strategies.xml"], "maintainers": ["kevinkhao", "sebastienbeau"], diff --git a/stock_putaway_product_template/demo/putaway_strategies.xml b/stock_putaway_product_template/demo/putaway_strategies.xml index 40ea4ce98..c1ffcc5f3 100644 --- a/stock_putaway_product_template/demo/putaway_strategies.xml +++ b/stock_putaway_product_template/demo/putaway_strategies.xml @@ -1,36 +1,31 @@ - + - Putaway Strategy 1 - - - + + + - - - - + + + - Putaway Strategy 2 - - - + + + - - - - + + + - diff --git a/stock_putaway_product_template/hooks.py b/stock_putaway_product_template/hooks.py index 3da582463..3287c519a 100644 --- a/stock_putaway_product_template/hooks.py +++ b/stock_putaway_product_template/hooks.py @@ -2,6 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). import logging + from openupgradelib import openupgrade _logger = logging.getLogger(__name__) @@ -9,11 +10,12 @@ _logger = logging.getLogger(__name__) def post_init_hook(cr, registry): openupgrade.logged_query( - cr, """ + cr, + """ UPDATE stock_fixed_putaway_strat sfps SET product_tmpl_id=pp.product_tmpl_id FROM product_product pp WHERE pp.id=sfps.product_id AND sfps.product_tmpl_id <> pp.product_tmpl_id - """ + """, ) diff --git a/stock_putaway_product_template/models/product_template.py b/stock_putaway_product_template/models/product_template.py index 5098eca07..39d4b6893 100644 --- a/stock_putaway_product_template/models/product_template.py +++ b/stock_putaway_product_template/models/product_template.py @@ -20,15 +20,11 @@ class ProductTemplate(models.Model): def _find_closest_categ_match(self, categ, putaway_lines): """Returns the putaway line with the nearest product category""" - lines_match_categ = putaway_lines.filtered( - lambda r: r.category_id == categ - ) + lines_match_categ = putaway_lines.filtered(lambda r: r.category_id == categ) if lines_match_categ: return lines_match_categ[0] elif categ.parent_id: - return self._find_closest_categ_match( - categ.parent_id, putaway_lines - ) + return self._find_closest_categ_match(categ.parent_id, putaway_lines) else: return self.env["stock.fixed.putaway.strat"] @@ -50,9 +46,9 @@ class ProductTemplate(models.Model): categ = rec.categ_id categs = self._get_categ_and_parents(categ) # get matching lines from our category or its parents - product_putaway_categ_lines = self.env[ - "stock.fixed.putaway.strat" - ].search([("category_id", "in", categs.ids)]) + product_putaway_categ_lines = self.env["stock.fixed.putaway.strat"].search( + [("category_id", "in", categs.ids)] + ) # from these, get the matching putaway.strats and find # the lowest-level category match product_putaways = product_putaway_categ_lines.mapped("putaway_id") diff --git a/stock_putaway_product_template/models/putaway_strategy.py b/stock_putaway_product_template/models/putaway_strategy.py index 99da525cc..1a0411559 100644 --- a/stock_putaway_product_template/models/putaway_strategy.py +++ b/stock_putaway_product_template/models/putaway_strategy.py @@ -5,14 +5,15 @@ from odoo import api, fields, models class PutAwayStrategy(models.Model): - _inherit = 'product.putaway' + _inherit = "product.putaway" # Remove product domain to allow to select product templates product_location_ids = fields.One2many(domain=[]) def _get_putaway_rule(self, product): - return super(PutAwayStrategy, self.with_context( - filter_putaway_rule=True))._get_putaway_rule(product) + return super( + PutAwayStrategy, self.with_context(filter_putaway_rule=True) + )._get_putaway_rule(product) class FixedPutAwayStrategy(models.Model): @@ -26,23 +27,25 @@ class FixedPutAwayStrategy(models.Model): ondelete="cascade", ) - @api.depends('product_id') + @api.depends("product_id") def _compute_product_tmpl_id(self): for rec in self: if rec.product_id: rec.product_tmpl_id = rec.product_id.product_tmpl_id else: - params = self.env.context.get('params', {}) - if params.get('model', '') == 'product.template': - rec.product_tmpl_id = params.get('id', False) + params = self.env.context.get("params", {}) + if params.get("model", "") == "product.template": + rec.product_tmpl_id = params.get("id", False) def filtered(self, func): res = super(FixedPutAwayStrategy, self).filtered(func) - if res or not self.env.context.get('filter_putaway_rule'): + if res or not self.env.context.get("filter_putaway_rule"): return res product = func.__closure__[0].cell_contents - if product._name != 'product.product': + if product._name != "product.product": return res return self.with_context(filter_putaway_rule=False).filtered( - lambda x: (x.product_tmpl_id == product.product_tmpl_id and - not x.product_id)) + lambda x: ( + x.product_tmpl_id == product.product_tmpl_id and not x.product_id + ) + ) diff --git a/stock_putaway_product_template/tests/test_product_putaway.py b/stock_putaway_product_template/tests/test_product_putaway.py index 3790488a2..f4de9f10f 100644 --- a/stock_putaway_product_template/tests/test_product_putaway.py +++ b/stock_putaway_product_template/tests/test_product_putaway.py @@ -13,114 +13,90 @@ class TestProductPutaway(TransactionCase): ProductAttributeValue = self.env["product.attribute.value"] TemplateAttributeLine = self.env["product.template.attribute.line"] ref = self.env.ref - self.product_tmpl_chair = ref( - "product.product_product_11_product_template" - ) + self.product_tmpl_chair = ref("product.product_product_11_product_template") self.product_product_chair = ref("product.product_product_11") self.category_services = ref("product.product_category_3") - self.putaway_line_1 = ref( - "stock_putaway_product_form.putaway_strat_1_line_1" - ) - self.putaway_line_2 = ref( - "stock_putaway_product_form.putaway_strat_1_line_2" - ) - self.putaway_line_3 = ref( - "stock_putaway_product_form.putaway_strat_2_line_1" - ) - self.putaway_line_4 = ref( - "stock_putaway_product_form.putaway_strat_2_line_2" - ) + self.putaway_line_1 = ref("stock_putaway_product_form.putaway_strat_1_line_1") + self.putaway_line_2 = ref("stock_putaway_product_form.putaway_strat_1_line_2") + self.putaway_line_3 = ref("stock_putaway_product_form.putaway_strat_2_line_1") + self.putaway_line_4 = ref("stock_putaway_product_form.putaway_strat_2_line_2") # Add a product with variants - self.template = ProductTemplate.create({ - 'name': 'Product test', - 'type': 'consu', - }) - self.size_attribute = ProductAttribute.create({ - 'name': 'Test size', - 'sequence': 1, - }) - self.size_m = ProductAttributeValue.create({ - 'name': 'Size M', - 'attribute_id': self.size_attribute.id, - 'sequence': 1, - }) - self.size_l = ProductAttributeValue.create({ - 'name': 'Size L', - 'attribute_id': self.size_attribute.id, - 'sequence': 2, - }) - self.template_attribute_lines = TemplateAttributeLine.create({ - 'product_tmpl_id': self.template.id, - 'attribute_id': self.size_attribute.id, - 'value_ids': [(6, 0, [self.size_m.id, self.size_l.id])], - }) + self.template = ProductTemplate.create( + {"name": "Product test", "type": "consu"} + ) + self.size_attribute = ProductAttribute.create( + {"name": "Test size", "sequence": 1} + ) + self.size_m = ProductAttributeValue.create( + {"name": "Size M", "attribute_id": self.size_attribute.id, "sequence": 1} + ) + self.size_l = ProductAttributeValue.create( + {"name": "Size L", "attribute_id": self.size_attribute.id, "sequence": 2} + ) + self.template_attribute_lines = TemplateAttributeLine.create( + { + "product_tmpl_id": self.template.id, + "attribute_id": self.size_attribute.id, + "value_ids": [(6, 0, [self.size_m.id, self.size_l.id])], + } + ) self.template.create_variant_ids() def test_tmpl_has_putaways_from_products(self): self.assertIn( - self.putaway_line_1, - self.product_tmpl_chair.product_tmpl_putaway_ids, + self.putaway_line_1, self.product_tmpl_chair.product_tmpl_putaway_ids, ) self.putaway_line_1.product_id = self.env["product.product"] self.assertNotIn( - self.putaway_line_1, - self.product_tmpl_chair.product_tmpl_putaway_ids, + self.putaway_line_1, self.product_tmpl_chair.product_tmpl_putaway_ids, ) def test_tmpl_has_putaways_from_category_simple(self): self.assertIn( - self.putaway_line_2, - self.product_tmpl_chair.product_putaway_categ_ids, + self.putaway_line_2, self.product_tmpl_chair.product_putaway_categ_ids, ) self.product_tmpl_chair.categ_id = self.category_services self.assertNotIn( - self.putaway_line_2, - self.product_tmpl_chair.product_putaway_categ_ids, + self.putaway_line_2, self.product_tmpl_chair.product_putaway_categ_ids, ) def test_tmpl_has_putaways_from_category_parent(self): # chair is under category: all/saleable/office self.assertIn( - self.putaway_line_3, - self.product_tmpl_chair.product_putaway_categ_ids, + self.putaway_line_3, self.product_tmpl_chair.product_putaway_categ_ids, ) self.assertNotIn( - self.putaway_line_4, - self.product_tmpl_chair.product_putaway_categ_ids, + self.putaway_line_4, self.product_tmpl_chair.product_putaway_categ_ids, ) def test_apply_putaway(self): # Create one strategy line for product template and other with a # specific variant - location = self.env.ref('stock.stock_location_shop0') - location1 = location.copy({ - 'name': 'Location test 1', - 'location_id': location.id - }) - location2 = location.copy({ - 'name': 'Location test 2', - 'location_id': location.id - }) + location = self.env.ref("stock.stock_location_shop0") + location1 = location.copy( + {"name": "Location test 1", "location_id": location.id} + ) + location2 = location.copy( + {"name": "Location test 2", "location_id": location.id} + ) variant1 = self.template.product_variant_ids[0] variant2 = self.template.product_variant_ids[1] - putaway = self.putawayObj.create({'name': 'Putaway for test'}) + putaway = self.putawayObj.create({"name": "Putaway for test"}) val_list = [ { - 'putaway_id': putaway.id, - 'product_tmpl_id': self.template.id, - 'fixed_location_id': location1.id, + "putaway_id": putaway.id, + "product_tmpl_id": self.template.id, + "fixed_location_id": location1.id, }, { - 'putaway_id': putaway.id, - 'product_id': variant2.id, - 'fixed_location_id': location2.id, + "putaway_id": putaway.id, + "product_id": variant2.id, + "fixed_location_id": location2.id, }, ] self.putawayLineObj.create(val_list) - location_applied = putaway._get_putaway_rule( - variant1).fixed_location_id + location_applied = putaway._get_putaway_rule(variant1).fixed_location_id self.assertEqual(location_applied, location1) - location_applied = putaway._get_putaway_rule( - variant2).fixed_location_id + location_applied = putaway._get_putaway_rule(variant2).fixed_location_id self.assertEqual(location_applied, location2) diff --git a/stock_putaway_product_template/views/product.xml b/stock_putaway_product_template/views/product.xml index 6b75712ed..1102606d2 100644 --- a/stock_putaway_product_template/views/product.xml +++ b/stock_putaway_product_template/views/product.xml @@ -1,39 +1,52 @@ - + product.template.product.form product.template - - + + - - - + + + The rules defined per product will be applied before the rules defined per product category. - Keep empty product field to apply strategy to all variants. + Keep empty product field to apply strategy to all variants. - - - + + + - - + + - - - + + + @@ -41,20 +54,26 @@ - product.product.form.putaway product.product - - + + - - + + - - + +
The rules defined per product will be applied before the rules defined per product category. -