diff --git a/stock_whole_kit_constraint/__manifest__.py b/stock_whole_kit_constraint/__manifest__.py index 5570650cd..9c6e31ba7 100644 --- a/stock_whole_kit_constraint/__manifest__.py +++ b/stock_whole_kit_constraint/__manifest__.py @@ -9,8 +9,6 @@ "author": "Tecnativa, Odoo Community Association (OCA)", "license": "AGPL-3", "installable": True, - "depends": [ - "mrp", - ], - "data": ["views/product_template_views.xml"] + "depends": ["mrp"], + "data": ["views/product_template_views.xml"], } diff --git a/stock_whole_kit_constraint/models/product_template.py b/stock_whole_kit_constraint/models/product_template.py index 725130ee6..5540989f5 100644 --- a/stock_whole_kit_constraint/models/product_template.py +++ b/stock_whole_kit_constraint/models/product_template.py @@ -9,5 +9,5 @@ class ProductTemplate(models.Model): allow_partial_kit_delivery = fields.Boolean( default=True, help="If not set, and this product is delivered with a BoM of type " - "kit, partial deliveries of the components won't be allowed.", + "kit, partial deliveries of the components won't be allowed.", ) diff --git a/stock_whole_kit_constraint/models/stock_move.py b/stock_whole_kit_constraint/models/stock_move.py index 359bcfb04..335498e63 100644 --- a/stock_whole_kit_constraint/models/stock_move.py +++ b/stock_whole_kit_constraint/models/stock_move.py @@ -7,13 +7,10 @@ class StockMove(models.Model): _inherit = "stock.move" allow_partial_kit_delivery = fields.Boolean( - compute="_compute_allow_partial_kit_delivery", - compute_sudo=True, + compute="_compute_allow_partial_kit_delivery", compute_sudo=True, ) - @api.depends( - "product_id.product_tmpl_id.allow_partial_kit_delivery", "state" - ) + @api.depends("product_id.product_tmpl_id.allow_partial_kit_delivery", "state") def _compute_allow_partial_kit_delivery(self): """Take it from the product only if it's a kit""" self.write({"allow_partial_kit_delivery": True}) @@ -21,9 +18,7 @@ class StockMove(models.Model): lambda x: x.product_id and x.state not in ["done", "cancel"] ): # If it isn't a kit it will always be True - if ( - not move.bom_line_id or move.bom_line_id.bom_id.type != "phantom" - ): + if not move.bom_line_id or move.bom_line_id.bom_id.type != "phantom": move.allow_partial_kit_delivery = True continue move.allow_partial_kit_delivery = ( @@ -48,7 +43,7 @@ class StockMove(models.Model): quantity_todo[move.product_id.id] += move.product_uom_qty quantity_done[move.product_id.id] += move.quantity_done for ops in self.mapped("move_line_ids").filtered( - lambda x: x.package_id and not x.product_id and not x.move_id + lambda x: x.package_id and not x.product_id and not x.move_id ): for quant in ops.package_id.quant_ids: quantity_done.setdefault(quant.product_id.id, 0) @@ -57,12 +52,7 @@ class StockMove(models.Model): lambda x: x.product_id and not x.move_id ): quantity_done.setdefault(pack.product_id.id, 0) - quantity_done[pack.product_id.id] += ( - pack.product_uom_id._compute_quantity( - pack.qty_done, pack.product_id.uom_id - ) + quantity_done[pack.product_id.id] += pack.product_uom_id._compute_quantity( + pack.qty_done, pack.product_id.uom_id ) - return any( - quantity_done[x] < quantity_todo.get(x, 0) - for x in quantity_done - ) + return any(quantity_done[x] < quantity_todo.get(x, 0) for x in quantity_done) diff --git a/stock_whole_kit_constraint/models/stock_picking.py b/stock_whole_kit_constraint/models/stock_picking.py index a437484ef..a756094ce 100644 --- a/stock_whole_kit_constraint/models/stock_picking.py +++ b/stock_whole_kit_constraint/models/stock_picking.py @@ -20,8 +20,10 @@ class StockPicking(models.Model): if not sum(bom_moves.mapped("quantity_done")): continue if bom_moves._check_backorder_moves(): - raise ValidationError(_( - "You can't make a partial delivery of components of the " - "%s kit" % bom.product_tmpl_id.display_name - )) + raise ValidationError( + _( + "You can't make a partial delivery of components of the " + "%s kit" % bom.product_tmpl_id.display_name + ) + ) return super()._check_backorder() diff --git a/stock_whole_kit_constraint/tests/test_stock_whole_kit_constraint.py b/stock_whole_kit_constraint/tests/test_stock_whole_kit_constraint.py index ec993b36e..71a892fe8 100644 --- a/stock_whole_kit_constraint/tests/test_stock_whole_kit_constraint.py +++ b/stock_whole_kit_constraint/tests/test_stock_whole_kit_constraint.py @@ -1,29 +1,24 @@ # Copyright 2021 Tecnativa - David Vidal # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo.tests import Form, common from odoo.exceptions import ValidationError +from odoo.tests import Form, common class TestStockWholeKitConstraint(common.SavepointCase): @classmethod def setUpClass(cls): super().setUpClass() - cls.customer = cls.env["res.partner"].create({ - "name": "Mr. Odoo", - }) + cls.customer = cls.env["res.partner"].create({"name": "Mr. Odoo"}) # Kit 1 that can be partially delivered - cls.product_kit_1 = cls.env["product.product"].create({ - "name": "Product Kit 1", - "type": "consu", - }) - cls.component_1_kit_1 = cls.env["product.product"].create({ - "name": "Component 1 Kit 1", - "type": "product", - }) - cls.component_2_kit_1 = cls.env["product.product"].create({ - "name": "Component 2 Kit 1", - "type": "product", - }) + cls.product_kit_1 = cls.env["product.product"].create( + {"name": "Product Kit 1", "type": "consu"} + ) + cls.component_1_kit_1 = cls.env["product.product"].create( + {"name": "Component 1 Kit 1", "type": "product"} + ) + cls.component_2_kit_1 = cls.env["product.product"].create( + {"name": "Component 2 Kit 1", "type": "product"} + ) bom_form = Form(cls.env["mrp.bom"]) bom_form.product_tmpl_id = cls.product_kit_1.product_tmpl_id bom_form.product_id = cls.product_kit_1 @@ -34,19 +29,19 @@ class TestStockWholeKitConstraint(common.SavepointCase): line.product_id = cls.component_2_kit_1 cls.bom_kit_1 = bom_form.save() # Kit 2 - disallow partial deliveries - cls.product_kit_2 = cls.env["product.product"].create({ - "name": "Product Kit 2", - "type": "consu", - "allow_partial_kit_delivery": False, - }) - cls.component_1_kit_2 = cls.env["product.product"].create({ - "name": "Component 1 Kit 2", - "type": "product", - }) - cls.component_2_kit_2 = cls.env["product.product"].create({ - "name": "Component 2 Kit 2", - "type": "product", - }) + cls.product_kit_2 = cls.env["product.product"].create( + { + "name": "Product Kit 2", + "type": "consu", + "allow_partial_kit_delivery": False, + } + ) + cls.component_1_kit_2 = cls.env["product.product"].create( + {"name": "Component 1 Kit 2", "type": "product"} + ) + cls.component_2_kit_2 = cls.env["product.product"].create( + {"name": "Component 2 Kit 2", "type": "product"} + ) bom_form = Form(cls.env["mrp.bom"]) bom_form.product_tmpl_id = cls.product_kit_2.product_tmpl_id bom_form.product_id = cls.product_kit_2 @@ -57,13 +52,15 @@ class TestStockWholeKitConstraint(common.SavepointCase): line.product_id = cls.component_2_kit_2 cls.bom_kit_2 = bom_form.save() # Manufactured product as control - cls.product_mrp = cls.env["product.product"].create({ - "name": "Product Kit 2", - "type": "consu", - # Force the setting in a manufactured product. - # It should not affect it - "allow_partial_kit_delivery": False, - }) + cls.product_mrp = cls.env["product.product"].create( + { + "name": "Product Kit 2", + "type": "consu", + # Force the setting in a manufactured product. + # It should not affect it + "allow_partial_kit_delivery": False, + } + ) bom_form = Form(cls.env["mrp.bom"]) bom_form.product_tmpl_id = cls.product_mrp.product_tmpl_id bom_form.product_id = cls.product_mrp @@ -72,12 +69,14 @@ class TestStockWholeKitConstraint(common.SavepointCase): line.product_id = cls.component_1_kit_2 cls.bom_mrp = bom_form.save() # Not a kit product as control - cls.regular_product = cls.env["product.product"].create({ - "name": "Regular test product", - "type": "product", - # Force the setting in a regular product. It should not affect it - "allow_partial_kit_delivery": False, - }) + cls.regular_product = cls.env["product.product"].create( + { + "name": "Regular test product", + "type": "product", + # Force the setting in a regular product. It should not affect it + "allow_partial_kit_delivery": False, + } + ) # Delivery picking picking_form = Form(cls.env["stock.picking"]) picking_form.picking_type_id = cls.env.ref("stock.picking_type_out") @@ -105,9 +104,7 @@ class TestStockWholeKitConstraint(common.SavepointCase): ) moves_allowed.write({"quantity_done": 1}) response = self.customer_picking.button_validate() - self.assertEqual( - "stock.backorder.confirmation", response.get("res_model") - ) + self.assertEqual("stock.backorder.confirmation", response.get("res_model")) def test_02_all_done_but_partial_disallow_partial_kit(self): """We try to deliver partially the disallowed kit""" @@ -121,9 +118,7 @@ class TestStockWholeKitConstraint(common.SavepointCase): moves_disallowed.write({"quantity_done": 3}) # We've got a backorder on the rest of the lines response = self.customer_picking.button_validate() - self.assertEqual( - "stock.backorder.confirmation", response.get("res_model") - ) + self.assertEqual("stock.backorder.confirmation", response.get("res_model")) def test_03_all_done(self): """Deliver the whole picking normally""" diff --git a/stock_whole_kit_constraint/views/product_template_views.xml b/stock_whole_kit_constraint/views/product_template_views.xml index 3b5f2b171..c3d24cc3f 100644 --- a/stock_whole_kit_constraint/views/product_template_views.xml +++ b/stock_whole_kit_constraint/views/product_template_views.xml @@ -1,23 +1,29 @@ - + product.template - + - + product.product - + - +