fix: improve MO ID resolution and refine domain stripping logic to prevent RPC errors in location restriction

This commit is contained in:
Suherdy Yacob 2026-04-03 21:59:37 +07:00
parent e72d491660
commit a70ad3f2ac

View File

@ -16,10 +16,9 @@ class StockLocation(models.Model):
# 1. HIGHEST PRIORITY: Direct Manufacturing Order Database Lookup
# This bypasses incomplete UI data by querying the MO directly via context IDs.
mo_id = (ctx.get('active_mo_id') or
ctx.get('default_mo_id') or
ctx.get('default_production_id') or
ctx.get('mo_id') or
ctx.get('production_id'))
ctx.get('production_id') or
ctx.get('active_id') if ctx.get('active_model') == 'mrp.production' else None)
if mo_id:
# sudo() ensures we can read the MO and its allowed locations regardless of field access
@ -83,23 +82,26 @@ class StockQuant(models.Model):
@api.model
def web_search_read(self, domain, specification, offset=0, limit=None, order=None, count_limit=None):
"""
UI Override with DOMAIN STRIPPING to prevent Odoo's native JS from blocking us.
UI Override with ROBUST DOMAIN STRIPPING to fix RPC_ERROR/ValueError.
"""
ctx = self.env.context
if not ctx.get('skip_location_restriction') and ctx.get('uid'):
allowed_ids = self.env['stock.location']._get_allowed_locations()
if allowed_ids:
# STRIP any existing native location_id filters from the domain.
# Odoo's JS often adds its own ["location_id", "child_of", single_id].
# By stripping them, we ensure our multi-location list takes precedence.
stripped_domain = []
# STRIP both native location_id filters AND their orphaned operators.
# The safest way is to extract only the non-location tuples (leaves).
# expression.AND(list_of_tuples) reconstruction a perfectly valid
# Polish notation with implicit 'AND' between our leaves.
clean_leaves = []
for leaf in domain:
if isinstance(leaf, (list, tuple)) and len(leaf) == 3 and leaf[0] == 'location_id':
continue
stripped_domain.append(leaf)
if isinstance(leaf, (list, tuple)):
if len(leaf) == 3 and leaf[0] == 'location_id':
continue
clean_leaves.append(leaf)
# Re-apply our multi-location filter
domain = expression.AND([stripped_domain, [('location_id', 'child_of', allowed_ids)]])
# Re-apply our multi-location filter using expression.AND.
# This treats clean_leaves + [location_id filter] as a fresh, valid domain.
domain = expression.AND([clean_leaves, [('location_id', 'child_of', allowed_ids)]])
_logger.error(f"DEBUG_RESTRICT: SEARCH QUANT - Allowed: {allowed_ids} - Final Domain: {domain}")
return super().web_search_read(domain, specification, offset=offset, limit=limit, order=order, count_limit=count_limit)