From 1791df4fd209288286fbe075333099e1c7b3d23f Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Fri, 3 Apr 2026 20:19:28 +0700 Subject: [PATCH] refactor: update location filtering to use child_of operator for improved sub-location support --- models/stock_location.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/models/stock_location.py b/models/stock_location.py index 6ec0297..bf25642 100644 --- a/models/stock_location.py +++ b/models/stock_location.py @@ -14,11 +14,10 @@ class StockLocation(models.Model): Used by UI-level overrides in StockQuant and StockLot. Returns: list: IDs of allowed locations. - False: If no restriction should be applied (e.g. no picking type found). + False: If no restriction should be applied. """ ctx = self.env.context # 1. Identify the Picking Type (Operation Type) - # Check multiple common context keys used by stock/mrp models picking_type_id = (ctx.get('default_picking_type_id') or ctx.get('picking_type_id') or ctx.get('active_picking_type_id')) @@ -36,7 +35,6 @@ class StockLocation(models.Model): picking_type_id = mo.picking_type_id.id if not picking_type_id: - # NO identification of operation type = NO restriction (safe fallback) return False # 3. Retrieve allowed locations from the picking type @@ -59,13 +57,14 @@ class StockQuant(models.Model): def web_search_read(self, domain, specification, offset=0, limit=None, order=None, count_limit=None): """ UI-SURFACE OVERRIDE: Applies location filtering ONLY for the web interface. + Uses 'child_of' to support stock stored in shelves/aisles of allowed locations. """ ctx = self.env.context if not ctx.get('skip_location_restriction') and ctx.get('uid'): allowed_location_ids = self.env['stock.location']._get_allowed_locations() if allowed_location_ids: - # Add location filter to the domain ONLY if we have an explicit list - domain = expression.AND([domain, [('location_id', 'in', allowed_location_ids)]]) + # FIX (Attempt 9): Switch to 'child_of' to support sub-locations + domain = expression.AND([domain, [('location_id', 'child_of', allowed_location_ids)]]) return super().web_search_read(domain, specification, offset=offset, limit=limit, order=order, count_limit=count_limit) @@ -81,14 +80,13 @@ class StockLot(models.Model): if not ctx.get('skip_location_restriction') and ctx.get('uid'): allowed_location_ids = self.env['stock.location']._get_allowed_locations() - # If our custom helper failed to find a picking-type restriction, - # we check if a simple default_location_id filter was passed directly. if not allowed_location_ids and ctx.get('default_location_id'): allowed_location_ids = [ctx.get('default_location_id')] if allowed_location_ids: quant_domain = [ - ('location_id', 'in', allowed_location_ids), + # FIX (Attempt 9): Switch to 'child_of' to support sub-locations + ('location_id', 'child_of', allowed_location_ids), ('quantity', '>', 0), ('lot_id', '!=', False) ] @@ -117,7 +115,8 @@ class StockLot(models.Model): if allowed_location_ids: quant_domain = [ - ('location_id', 'in', allowed_location_ids), + # FIX (Attempt 9): Switch to 'child_of' to support sub-locations + ('location_id', 'child_of', allowed_location_ids), ('quantity', '>', 0), ('lot_id', '!=', False) ]