feat: prioritize context-based location filtering and sync allowed locations to modals
This commit is contained in:
parent
1791df4fd2
commit
20fb9a40d0
@ -10,19 +10,41 @@ class StockLocation(models.Model):
|
|||||||
|
|
||||||
def _get_allowed_locations(self):
|
def _get_allowed_locations(self):
|
||||||
"""
|
"""
|
||||||
Helper to retrieve allowed locations based on the current context (picking type).
|
Helper to retrieve allowed locations based on the current context.
|
||||||
Used by UI-level overrides in StockQuant and StockLot.
|
PRIORITY 1: Use explicit IDs passed in context (from views).
|
||||||
|
PRIORITY 2: Manual lookup from picking type or MO.
|
||||||
Returns:
|
Returns:
|
||||||
list: IDs of allowed locations.
|
list: IDs of allowed locations.
|
||||||
False: If no restriction should be applied.
|
False: If no restriction should be applied.
|
||||||
"""
|
"""
|
||||||
ctx = self.env.context
|
ctx = self.env.context
|
||||||
# 1. Identify the Picking Type (Operation Type)
|
|
||||||
|
# 1. PRIORITY: Check the context for allowed locations (Passed by views)
|
||||||
|
# This is the most reliable source in the MO "Add line" catalog/details view.
|
||||||
|
# It handles both 'allowed_source_location_ids' and 'default_allowed_source_location_ids'
|
||||||
|
context_ids = (ctx.get('allowed_source_location_ids') or
|
||||||
|
ctx.get('default_allowed_source_location_ids'))
|
||||||
|
|
||||||
|
if context_ids:
|
||||||
|
# Handle list of IDs, or Command tuples (e.g. [Command.set([ID1, ID2])])
|
||||||
|
if isinstance(context_ids, list):
|
||||||
|
# Simple list of IDs
|
||||||
|
if all(isinstance(x, int) for x in context_ids):
|
||||||
|
return context_ids
|
||||||
|
# Command format: [(6, 0, [ID1, ID2])]
|
||||||
|
for cmd in context_ids:
|
||||||
|
if isinstance(cmd, (list, tuple)) and cmd[0] == 6:
|
||||||
|
return cmd[2]
|
||||||
|
# Single ID
|
||||||
|
if isinstance(context_ids, int):
|
||||||
|
return [context_ids]
|
||||||
|
|
||||||
|
# 2. FALLBACK: Identify the Picking Type (Operation Type)
|
||||||
picking_type_id = (ctx.get('default_picking_type_id') or
|
picking_type_id = (ctx.get('default_picking_type_id') or
|
||||||
ctx.get('picking_type_id') or
|
ctx.get('picking_type_id') or
|
||||||
ctx.get('active_picking_type_id'))
|
ctx.get('active_picking_type_id'))
|
||||||
|
|
||||||
# 2. Advanced MO Support: find picking type from MO ID if needed
|
# MO IDs
|
||||||
mo_id = (ctx.get('active_mo_id') or
|
mo_id = (ctx.get('active_mo_id') or
|
||||||
ctx.get('default_mo_id') or
|
ctx.get('default_mo_id') or
|
||||||
ctx.get('default_production_id') or
|
ctx.get('default_production_id') or
|
||||||
@ -37,14 +59,14 @@ class StockLocation(models.Model):
|
|||||||
if not picking_type_id:
|
if not picking_type_id:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# 3. Retrieve allowed locations from the picking type
|
# 3. Retrieve allowed locations from the identified picking type
|
||||||
picking_type = self.env['stock.picking.type'].browse(picking_type_id)
|
picking_type = self.env['stock.picking.type'].browse(picking_type_id)
|
||||||
if picking_type.exists():
|
if picking_type.exists():
|
||||||
# Priority 1: Use the M2M "Allowed Source Locations" if set
|
# Many-to-Many "Allowed Source Locations"
|
||||||
if picking_type.default_location_src_ids:
|
if picking_type.default_location_src_ids:
|
||||||
return picking_type.default_location_src_ids.ids
|
return picking_type.default_location_src_ids.ids
|
||||||
|
|
||||||
# Priority 2: Fallback to the primary "Default Source Location" (M2O)
|
# Many-to-One "Default Source Location"
|
||||||
if picking_type.default_location_src_id:
|
if picking_type.default_location_src_id:
|
||||||
return [picking_type.default_location_src_id.id]
|
return [picking_type.default_location_src_id.id]
|
||||||
|
|
||||||
@ -63,7 +85,7 @@ class StockQuant(models.Model):
|
|||||||
if not ctx.get('skip_location_restriction') and ctx.get('uid'):
|
if not ctx.get('skip_location_restriction') and ctx.get('uid'):
|
||||||
allowed_location_ids = self.env['stock.location']._get_allowed_locations()
|
allowed_location_ids = self.env['stock.location']._get_allowed_locations()
|
||||||
if allowed_location_ids:
|
if allowed_location_ids:
|
||||||
# FIX (Attempt 9): Switch to 'child_of' to support sub-locations
|
# Add location filter to the domain ONLY if we have an explicit list
|
||||||
domain = expression.AND([domain, [('location_id', 'child_of', allowed_location_ids)]])
|
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)
|
return super().web_search_read(domain, specification, offset=offset, limit=limit, order=order, count_limit=count_limit)
|
||||||
@ -80,12 +102,12 @@ class StockLot(models.Model):
|
|||||||
if not ctx.get('skip_location_restriction') and ctx.get('uid'):
|
if not ctx.get('skip_location_restriction') and ctx.get('uid'):
|
||||||
allowed_location_ids = self.env['stock.location']._get_allowed_locations()
|
allowed_location_ids = self.env['stock.location']._get_allowed_locations()
|
||||||
|
|
||||||
|
# Safe Fallback for lots
|
||||||
if not allowed_location_ids and ctx.get('default_location_id'):
|
if not allowed_location_ids and ctx.get('default_location_id'):
|
||||||
allowed_location_ids = [ctx.get('default_location_id')]
|
allowed_location_ids = [ctx.get('default_location_id')]
|
||||||
|
|
||||||
if allowed_location_ids:
|
if allowed_location_ids:
|
||||||
quant_domain = [
|
quant_domain = [
|
||||||
# FIX (Attempt 9): Switch to 'child_of' to support sub-locations
|
|
||||||
('location_id', 'child_of', allowed_location_ids),
|
('location_id', 'child_of', allowed_location_ids),
|
||||||
('quantity', '>', 0),
|
('quantity', '>', 0),
|
||||||
('lot_id', '!=', False)
|
('lot_id', '!=', False)
|
||||||
@ -115,7 +137,6 @@ class StockLot(models.Model):
|
|||||||
|
|
||||||
if allowed_location_ids:
|
if allowed_location_ids:
|
||||||
quant_domain = [
|
quant_domain = [
|
||||||
# FIX (Attempt 9): Switch to 'child_of' to support sub-locations
|
|
||||||
('location_id', 'child_of', allowed_location_ids),
|
('location_id', 'child_of', allowed_location_ids),
|
||||||
('quantity', '>', 0),
|
('quantity', '>', 0),
|
||||||
('lot_id', '!=', False)
|
('lot_id', '!=', False)
|
||||||
|
|||||||
@ -30,6 +30,14 @@ patch(SMLX2ManyField.prototype, {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Final Sync: ensure allowed locations from the parent view are passed to the modal
|
||||||
|
if (this.props.context.default_allowed_source_location_ids) {
|
||||||
|
context = {
|
||||||
|
...context,
|
||||||
|
default_allowed_source_location_ids: this.props.context.default_allowed_source_location_ids,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return super.onAdd({ context, editable });
|
return super.onAdd({ context, editable });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user