feat: add skip_location_restriction context flag to bypass custom domain filtering in stock location and lot searches
This commit is contained in:
parent
dd0b07a23b
commit
255aaef265
@ -73,13 +73,18 @@ class StockQuant(models.Model):
|
|||||||
"""Override to apply location restrictions during reservation (gather)"""
|
"""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)
|
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.
|
ctx = self.env.context
|
||||||
|
# 0. Bypass if skip flag is set
|
||||||
|
if ctx.get('skip_location_restriction'):
|
||||||
|
return result_domain
|
||||||
|
|
||||||
|
# 1. FIX: If reserving from a non-internal location, DO NOT apply internal restrictions.
|
||||||
if location_id and location_id.usage != 'internal':
|
if location_id and location_id.usage != 'internal':
|
||||||
return result_domain
|
return result_domain
|
||||||
|
|
||||||
allowed_location_ids = self._get_allowed_locations()
|
allowed_location_ids = self._get_allowed_locations()
|
||||||
if allowed_location_ids:
|
if allowed_location_ids:
|
||||||
# 1. Smart Domain Swap: find if there's already a location_id restriction (like child_of)
|
# 2. Smart Domain Swap: find if there's already a location_id restriction (like child_of)
|
||||||
found_collision = False
|
found_collision = False
|
||||||
new_domain = []
|
new_domain = []
|
||||||
for leaf in result_domain:
|
for leaf in result_domain:
|
||||||
@ -101,11 +106,10 @@ class StockQuant(models.Model):
|
|||||||
|
|
||||||
def _search(self, domain, offset=0, limit=None, order=None, *args, **kwargs):
|
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)"""
|
"""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),
|
ctx = self.env.context
|
||||||
# we must NOT restrict the search results or we trigger 'Missing Product' validation errors
|
# 0. CRITICAL FIX: If searching for specific IDs or skip flag set, bypass custom filtering
|
||||||
# on backend fallback create logic.
|
|
||||||
search_by_id = any(isinstance(leaf, (list, tuple)) and leaf[0] == 'id' for leaf in domain)
|
search_by_id = any(isinstance(leaf, (list, tuple)) and leaf[0] == 'id' for leaf in domain)
|
||||||
if search_by_id:
|
if search_by_id or ctx.get('skip_location_restriction'):
|
||||||
return super()._search(domain, offset=offset, limit=limit, order=order, *args, **kwargs)
|
return super()._search(domain, offset=offset, limit=limit, order=order, *args, **kwargs)
|
||||||
|
|
||||||
allowed_location_ids = self._get_allowed_locations()
|
allowed_location_ids = self._get_allowed_locations()
|
||||||
@ -131,7 +135,6 @@ class StockQuant(models.Model):
|
|||||||
|
|
||||||
return super()._search(domain, offset=offset, limit=limit, order=order, *args, **kwargs)
|
return super()._search(domain, offset=offset, limit=limit, order=order, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class StockLocation(models.Model):
|
class StockLocation(models.Model):
|
||||||
_inherit = 'stock.location'
|
_inherit = 'stock.location'
|
||||||
|
|
||||||
@ -157,28 +160,33 @@ class StockLot(models.Model):
|
|||||||
|
|
||||||
# FIX: If we are searching for specific IDs, bypass custom filtering to avoid backend failures
|
# FIX: If we are searching for specific IDs, bypass custom filtering to avoid backend failures
|
||||||
search_by_id = any(isinstance(leaf, (list, tuple)) and leaf[0] == 'id' for leaf in domain)
|
search_by_id = any(isinstance(leaf, (list, tuple)) and leaf[0] == 'id' for leaf in domain)
|
||||||
if search_by_id:
|
if search_by_id or ctx.get('skip_location_restriction'):
|
||||||
return super()._search(domain, offset=offset, limit=limit, order=order, *args, **kwargs)
|
return super()._search(domain, offset=offset, limit=limit, order=order, *args, **kwargs)
|
||||||
|
|
||||||
active_picking_id = ctx.get('active_picking_id')
|
# 1. Identify which locations we should look into for quants
|
||||||
loc_id = ctx.get('default_location_id')
|
allowed_location_ids = self.env['stock.quant']._get_allowed_locations()
|
||||||
|
|
||||||
if active_picking_id and loc_id:
|
# 2. If no explicit allowed locations, fallback to the default source location in context
|
||||||
loc = self.env['stock.location'].sudo().browse(loc_id)
|
if not allowed_location_ids:
|
||||||
if loc.exists() and loc.usage != 'supplier':
|
loc_id = ctx.get('default_location_id')
|
||||||
quant_domain = [
|
if loc_id:
|
||||||
('location_id', 'child_of', loc.id),
|
allowed_location_ids = [loc_id]
|
||||||
('quantity', '>', 0),
|
|
||||||
('lot_id', '!=', False)
|
if allowed_location_ids:
|
||||||
]
|
quant_domain = [
|
||||||
product_id = ctx.get('default_product_id')
|
('location_id', 'in', allowed_location_ids),
|
||||||
if product_id:
|
('quantity', '>', 0),
|
||||||
quant_domain.append(('product_id', '=', product_id))
|
('lot_id', '!=', False)
|
||||||
|
]
|
||||||
quants = self.env['stock.quant'].sudo().search(quant_domain)
|
product_id = ctx.get('default_product_id')
|
||||||
lot_ids = list(set(quants.mapped('lot_id').ids))
|
if product_id:
|
||||||
|
quant_domain.append(('product_id', '=', product_id))
|
||||||
domain = Domain.AND([domain, [('id', 'in', lot_ids)]])
|
|
||||||
|
# Use internal bypass when searching quants to filter lots
|
||||||
|
quants = self.env['stock.quant'].with_context(skip_location_restriction=True).sudo().search(quant_domain)
|
||||||
|
lot_ids = list(set(quants.mapped('lot_id').ids))
|
||||||
|
|
||||||
|
domain = Domain.AND([domain, [('id', 'in', lot_ids)]])
|
||||||
|
|
||||||
return super()._search(domain, offset=offset, limit=limit, order=order, *args, **kwargs)
|
return super()._search(domain, offset=offset, limit=limit, order=order, *args, **kwargs)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user