From e52135014ea06eb3c066d672ce28e15c17555341 Mon Sep 17 00:00:00 2001 From: Joan Sisquella Date: Thu, 25 Jan 2024 20:37:42 +0100 Subject: [PATCH] [IMP] stock_request: add route_id to stock.request.order --- stock_request/models/stock_request_order.py | 78 ++++++++ stock_request/tests/test_stock_request.py | 185 ++++++++++++++++++ .../views/stock_request_order_views.xml | 8 + 3 files changed, 271 insertions(+) diff --git a/stock_request/models/stock_request_order.py b/stock_request/models/stock_request_order.py index 74da83ea..93c0c7e7 100644 --- a/stock_request/models/stock_request_order.py +++ b/stock_request/models/stock_request_order.py @@ -126,10 +126,88 @@ def _get_default_requested_by(self): string="Stock requests", compute="_compute_stock_request_count", readonly=True ) + route_ids = fields.Many2many( + "stock.route", + string="Routes", + compute="_compute_route_ids", + readonly=True, + store=True, + ) + + route_id = fields.Many2one( + "stock.route", + compute="_compute_route_id", + inverse="_inverse_route_id", + readonly=True, + store=True, + help="The route related to a stock request order", + ) + _sql_constraints = [ ("name_uniq", "unique(name, company_id)", "Stock Request name must be unique") ] + @api.depends("warehouse_id", "location_id", "stock_request_ids") + def _compute_route_ids(self): + route_obj = self.env["stock.route"] + routes = route_obj.search( + [("warehouse_ids", "in", self.mapped("warehouse_id").ids)] + ) + routes_by_warehouse = {} + for route in routes: + for warehouse in route.warehouse_ids: + routes_by_warehouse.setdefault(warehouse.id, self.env["stock.route"]) + routes_by_warehouse[warehouse.id] |= route + for record in self: + routes = route_obj + if record.warehouse_id and routes_by_warehouse.get(record.warehouse_id.id): + routes |= routes_by_warehouse[record.warehouse_id.id] + parents = record.get_parents().ids + valid_routes = [] + for route in routes: + if any(p.location_dest_id.id in parents for p in route.rule_ids): + valid_routes.append(route) + filtered_routes = self.env["stock.route"].browse( + [route.id for route in valid_routes] + ) + if record.stock_request_ids: + all_routes = record.stock_request_ids.mapped("route_ids") + common_routes = all_routes + for line in record.stock_request_ids: + common_routes &= line.route_ids + final_routes = filtered_routes | common_routes + record.route_ids = [(6, 0, final_routes.ids)] + else: + record.route_ids = [(6, 0, filtered_routes.ids)] + + def get_parents(self): + location = self.location_id + result = location + while location.location_id: + location = location.location_id + result |= location + return result + + @api.depends("stock_request_ids") + def _compute_route_id(self): + for order in self: + if order.stock_request_ids: + first_route = order.stock_request_ids[0].route_id or False + if any(r.route_id != first_route for r in order.stock_request_ids): + first_route = False + order.route_id = first_route + + def _inverse_route_id(self): + for order in self: + if order.route_id: + order.stock_request_ids.write({"route_id": order.route_id.id}) + + @api.onchange("route_id") + def _onchange_route_id(self): + if self.route_id: + for request in self.stock_request_ids: + request.route_id = self.route_id + @api.depends("stock_request_ids.state") def _compute_state(self): for item in self: diff --git a/stock_request/tests/test_stock_request.py b/stock_request/tests/test_stock_request.py index 0249d38a..1e9521ce 100644 --- a/stock_request/tests/test_stock_request.py +++ b/stock_request/tests/test_stock_request.py @@ -77,6 +77,9 @@ def setUp(self): self.route_2 = self._create_location_route( name="Transfer", company_id=self.company_2.id ) + self.route_3 = self._create_location_route( + name="Transfer", company_id=self.main_company.id + ) self.uom_dozen = self.env["uom.uom"].create( { "name": "Test-DozenA", @@ -1383,3 +1386,185 @@ def test_rounding_half_up_in_progress_02(self): 1, "Quantity in progress should be the rounded down after confirmation", ) + + def test_route_id_propagation_on_creation(self): + order_vals = { + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": fields.Datetime.now(), + "route_id": self.route.id, + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + }, + ), + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 10.0, + }, + ), + ], + } + order = self.request_order.create(order_vals) + self.assertEqual(len(order.stock_request_ids), 2) + order.write({"route_id": self.route_3}) + for request in order.stock_request_ids: + self.assertEqual( + request.route_id.id, + order.route_id.id, + "The route_id from stock.request.order has not " + "been set in the associated stock.requests.", + ) + + def test_compute_route_id_consistency_1(self): + order_vals = { + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": fields.Datetime.now(), + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "route_id": self.route.id, + }, + ), + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 10.0, + "route_id": self.route_3.id, + }, + ), + ], + } + order = self.request_order.create(order_vals) + order._compute_route_id() + self.assertFalse( + order.route_id, + "Route ID should be False due to inconsistent routes in stock requests.", + ) + + def test_compute_route_id_consistency_2(self): + order_vals = { + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": fields.Datetime.now(), + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "route_id": self.route.id, + }, + ), + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 10.0, + "route_id": self.route.id, + }, + ), + ], + } + order = self.request_order.create(order_vals) + order._compute_route_id() + self.assertEqual(order.route_id, self.route) + + def test_inverse_route_id_propagation(self): + order_vals = { + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": fields.Datetime.now(), + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + }, + ), + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 10.0, + }, + ), + ], + } + order = self.request_order.create(order_vals) + order.route_id = self.route.id + order._inverse_route_id() + for request in order.stock_request_ids: + self.assertEqual( + request.route_id.id, + self.route.id, + "Route ID should propagate to all stock requests.", + ) + + def test_onchange_route_id_propagation(self): + order_vals = { + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": fields.Datetime.now(), + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + }, + ), + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 10.0, + }, + ), + ], + } + order = self.request_order.create(order_vals) + order.route_id = self.route.id + order._onchange_route_id() + for request in order.stock_request_ids: + self.assertEqual( + request.route_id.id, + self.route.id, + "Route ID should update on all stock requests on onchange.", + ) diff --git a/stock_request/views/stock_request_order_views.xml b/stock_request/views/stock_request_order_views.xml index 0f8badd1..b7467c1e 100644 --- a/stock_request/views/stock_request_order_views.xml +++ b/stock_request/views/stock_request_order_views.xml @@ -95,6 +95,14 @@ groups="stock.group_stock_multi_locations" /> + +