From 88bdaf8cd0fcd41ee7ec5b34bfb11ec503afeaff Mon Sep 17 00:00:00 2001 From: Karl Southern Date: Wed, 11 Jan 2023 14:10:19 +0000 Subject: [PATCH] feat: experiment move commingle_ok into mrp.bom. This is how we did it under 12.0. We discarded this for many reasons, however its causing issues. This commit is incomplete R&D [ci skip] --- product_commingle_mrp/__manifest__.py | 5 +- product_commingle_mrp/models/__init__.py | 1 + product_commingle_mrp/models/mrp_bom.py | 139 ++++++++++++++++++++ product_commingle_mrp/views/mrp_bom.xml | 18 +++ product_commingle_sale_stock/models/sale.py | 14 ++ 5 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 product_commingle_mrp/models/mrp_bom.py create mode 100644 product_commingle_mrp/views/mrp_bom.xml diff --git a/product_commingle_mrp/__manifest__.py b/product_commingle_mrp/__manifest__.py index f7d0379..c6ca6fd 100644 --- a/product_commingle_mrp/__manifest__.py +++ b/product_commingle_mrp/__manifest__.py @@ -6,6 +6,9 @@ "category": "Uncategorized", "version": "15.0.1.0.0", "depends": ["product_commingle", "mrp"], - "data": [], + "data": [ + "views/mrp_bom.xml", + ], "license": "AGPL-3", + "auto_install": True, } diff --git a/product_commingle_mrp/models/__init__.py b/product_commingle_mrp/models/__init__.py index 6bda2d2..a17020a 100644 --- a/product_commingle_mrp/models/__init__.py +++ b/product_commingle_mrp/models/__init__.py @@ -1 +1,2 @@ from . import stock_move +from . import mrp_bom diff --git a/product_commingle_mrp/models/mrp_bom.py b/product_commingle_mrp/models/mrp_bom.py new file mode 100644 index 0000000..f1b2fd4 --- /dev/null +++ b/product_commingle_mrp/models/mrp_bom.py @@ -0,0 +1,139 @@ +from odoo import fields, models +from odoo.tools import float_round + + +class MrpBomLine(models.Model): + _inherit = "mrp.bom.line" + + def _commingled_bom_line(self): + self.ensure_one() + commingled_boms_dict = self.env["mrp.bom"]._bom_find( + self.product_id, + bom_type="commingled", + ) + + # we always skip the commingled lines as we'll do these ourselves within + # our super()'d explode + if commingled_boms_dict.get(self.product_id): + return True + + def _skip_bom_line(self, product): + if self._commingled_bom_line(): + return True + + return super()._skip_bom_line(product) + + +class MrpBom(models.Model): + _inherit = "mrp.bom" + + type = fields.Selection( + selection_add=[("commingled", "Commingled")], + ondelete={ + "commingled": "cascade", + }, + ) + + def _commingled_select_line(self, location_id=False): + self.ensure_one() + + # TODO: FIX ME + return self.bom_line_ids[0] + + def action_test_explode(self): + self.ensure_one() + self.explode(self.product_id, 1) + + def explode(self, product, quantity, picking_type=False): + boms_done, lines_done = super().explode(product, quantity, picking_type) + + bom_lines_product_ids = self.env["product.product"] + + for bom_id, _bom_dict in boms_done: + bom_lines_product_ids |= bom_id.mapped("bom_line_ids.product_id") + + boms_dict = self._bom_find( + bom_lines_product_ids, + ) + + if not boms_dict: + return boms_done, lines_done + + todo = [] + + for bom_id, bom_dict in boms_done: + for bom_line in bom_id.bom_line_ids: + commingled_bom_id = boms_dict.get(bom_line.product_id) + if not commingled_bom_id or commingled_bom_id.type != "commingled": + continue + + line_quantity = bom_dict.get("qty") * bom_line.product_qty + + converted_line_quantity = bom_line.product_uom_id._compute_quantity( + line_quantity / bom_id.product_qty, bom_id.product_uom_id + ) + + todo.append((converted_line_quantity, bom_line)) + + while todo: + quantity, current_line = todo[0] + todo = todo[1:] + + if current_line.product_id not in boms_dict: + boms_dict.update(self._bom_find(current_line.product_id)) + + rounding = current_line.product_uom_id.rounding + line_quantity = float_round( + quantity, precision_rounding=rounding, rounding_method="UP" + ) + + bom_id = boms_dict.get(current_line.product_id, self.env["mrp.bom"]) + + if bom_id.type == "commingled": + selected_line = bom_id._commingled_select_line() + todo.append((quantity, selected_line)) + continue + + elif bom_id.type == "phantom": + phantom_done, phantom_lines_done = bom_id.explode( + current_line.product_id, + line_quantity, + ) + # FIXME: the lines_done and probably boms_done may the values + # updated? Verify how this works where depth > 1 + boms_done += phantom_done + lines_done += phantom_lines_done + continue + + elif not bom_id: + # We round up here because the user expects that if he has to consume a little more, the whole UOM unit + # should be consumed. + lines_done.append( + ( + current_line, + { + "qty": line_quantity, + "product": current_line.product_id, + "original_qty": quantity, + "parent_line": current_line, + }, + ) + ) + + boms_done.append( + ( + bom_id, + { + "qty": line_quantity, + "product": current_line.bom_id.product_id, # FIXME + "original_qty": quantity, + "parent_line": current_line, + }, + ) + ) + + continue + + __import__("wdb").set_trace() + + return boms_done, lines_done diff --git a/product_commingle_mrp/views/mrp_bom.xml b/product_commingle_mrp/views/mrp_bom.xml new file mode 100644 index 0000000..41aa341 --- /dev/null +++ b/product_commingle_mrp/views/mrp_bom.xml @@ -0,0 +1,18 @@ + + + mrp_bom_form_view + mrp.bom + + + +
+
+
+
+
+
diff --git a/product_commingle_sale_stock/models/sale.py b/product_commingle_sale_stock/models/sale.py index eba4466..594dd64 100644 --- a/product_commingle_sale_stock/models/sale.py +++ b/product_commingle_sale_stock/models/sale.py @@ -47,3 +47,17 @@ def _onchange_product_id_commingle(self): "message": _("This product will split into %s lines") % len(lines), } } + + def _get_qty_procurement(self, previous_product_uom_qty=False): + self.ensure_one() + qty = 0.0 + outgoing_moves, incoming_moves = self._get_outgoing_incoming_moves() + for move in outgoing_moves: + qty += move.product_uom._compute_quantity( + move.product_uom_qty, self.product_uom, rounding_method="HALF-UP" + ) + for move in incoming_moves: + qty -= move.product_uom._compute_quantity( + move.product_uom_qty, self.product_uom, rounding_method="HALF-UP" + ) + return qty