diff --git a/models/stock_location.py b/models/stock_location.py index c8ab6a1..e80a907 100644 --- a/models/stock_location.py +++ b/models/stock_location.py @@ -68,6 +68,69 @@ class StockQuant(models.Model): return allowed_location_ids + @api.model + def _get_gather_domain(self, product_id, location_id, lot_id=None, package_id=None, owner_id=None, strict=False): + """Override to apply location restrictions during reservation (gather)""" + result_domain = super()._get_gather_domain(product_id, location_id, lot_id, package_id, owner_id, strict) + + # FIX: If reserving from a non-internal location, DO NOT apply internal restrictions. + if location_id and location_id.usage != 'internal': + return result_domain + + allowed_location_ids = self._get_allowed_locations() + if allowed_location_ids: + # 1. Smart Domain Swap: find if there's already a location_id restriction (like child_of) + found_collision = False + new_domain = [] + for leaf in result_domain: + if (isinstance(leaf, (list, tuple)) and + len(leaf) == 3 and + leaf[0] == 'location_id' and + leaf[1] in ('child_of', '=', 'in')): + + new_domain.append(('location_id', 'in', allowed_location_ids)) + found_collision = True + else: + new_domain.append(leaf) + if found_collision: + result_domain = new_domain + else: + result_domain = Domain.AND([result_domain, [('location_id', 'in', allowed_location_ids)]]) + + return result_domain + + def _search(self, domain, offset=0, limit=None, order=None, *args, **kwargs): + """Override to apply location restrictions during search (e.g. catalog or list selection)""" + # CRITICAL FIX: If we are searching for specific IDs (e.g., Odoo is fetching selected records for save), + # we must NOT restrict the search results or we trigger 'Missing Product' validation errors + # on backend fallback create logic. + search_by_id = any(isinstance(leaf, (list, tuple)) and leaf[0] == 'id' for leaf in domain) + if search_by_id: + return super()._search(domain, offset=offset, limit=limit, order=order, *args, **kwargs) + + allowed_location_ids = self._get_allowed_locations() + if allowed_location_ids: + # 1. Smart Domain Swap: find if there's already a location_id restriction (like child_of) + found_collision = False + new_domain = [] + for leaf in domain: + if (isinstance(leaf, (list, tuple)) and + len(leaf) == 3 and + leaf[0] == 'location_id' and + leaf[1] == 'child_of'): + + new_domain.append(('location_id', 'in', allowed_location_ids)) + found_collision = True + else: + new_domain.append(leaf) + + if found_collision: + domain = new_domain + else: + domain = Domain.AND([domain, [('location_id', 'in', allowed_location_ids)]]) + + return super()._search(domain, offset=offset, limit=limit, order=order, *args, **kwargs) + class StockLocation(models.Model): _inherit = 'stock.location'