mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
Add area location relation
So we can use it in group-by and filters. Note that we can have several levels of areas... only the top-level will be used. This commit fixes the computed field dependencies: _compute_location_kind should have a dependency on both it's parent's location_kind and on its child_ids to know if we are in a bin. This can't work without triggering an infinite loop. The trick used here is to split the computation of 'zone_location_id + area_location_id' in one computed method, and move the computation of the kind in a different method with triggers an the current record's zone_location + area_location_id, but not on the parent. Plus the zone_location_id and area_location_id do not depend anymore on the parent's kind, which is the reason for the infinite loop.
This commit is contained in:
committed by
Denis Roussel
parent
817c0032f2
commit
463c3c7fff
@@ -16,11 +16,17 @@ class StockLocation(models.Model):
|
||||
|
||||
zone_location_id = fields.Many2one(
|
||||
'stock.location',
|
||||
string='Location zone',
|
||||
compute='_compute_location_zone',
|
||||
string='Location Zone',
|
||||
compute='_compute_zone_location_id',
|
||||
store=True,
|
||||
index=True,
|
||||
)
|
||||
area_location_id = fields.Many2one(
|
||||
'stock.location',
|
||||
string='Location Area',
|
||||
compute='_compute_zone_location_id',
|
||||
store=True,
|
||||
)
|
||||
|
||||
location_kind = fields.Selection(
|
||||
[
|
||||
@@ -31,61 +37,71 @@ class StockLocation(models.Model):
|
||||
('other', 'Other'),
|
||||
],
|
||||
string='Location Kind',
|
||||
compute='_compute_location_zone',
|
||||
help='Group location according to their kinds:'
|
||||
'* Zone: locations that are flagged as being zones'
|
||||
'* Area: locations with children that are part of a zone'
|
||||
'* Bin: locations without children that are part of a zone'
|
||||
'* Stock: internal locations whose parent is a view'
|
||||
compute='_compute_location_kind',
|
||||
store=True,
|
||||
help='Group location according to their kinds: '
|
||||
'* Zone: locations that are flagged as being zones '
|
||||
'* Area: locations with children that are part of a zone '
|
||||
'* Bin: locations without children that are part of a zone '
|
||||
'* Stock: internal locations whose parent is a view '
|
||||
'* Other: any other location',
|
||||
)
|
||||
|
||||
@api.depends('is_zone', 'usage', 'location_id.usage', 'child_ids',
|
||||
'location_id.is_zone')
|
||||
def _compute_location_zone(self):
|
||||
@api.depends('is_zone', 'location_id.zone_location_id',
|
||||
'location_id.area_location_id')
|
||||
def _compute_zone_location_id(self):
|
||||
for location in self:
|
||||
location.zone_location_id = self.browse()
|
||||
location.area_location_id = self.browse()
|
||||
if location.is_zone:
|
||||
location.location_kind = 'zone'
|
||||
location.zone_location_id = location
|
||||
continue
|
||||
|
||||
# Get the zone from the parents
|
||||
parent = location.location_id
|
||||
while parent:
|
||||
if parent.is_zone:
|
||||
zone_location = parent
|
||||
break
|
||||
parent = parent.location_id
|
||||
else:
|
||||
zone_location = self.browse()
|
||||
if parent.zone_location_id:
|
||||
location.zone_location_id = parent.zone_location_id
|
||||
# If we have more than one level of area in a zone,
|
||||
# the grouping is done by the first level
|
||||
if parent.area_location_id:
|
||||
location.area_location_id = parent.area_location_id
|
||||
else:
|
||||
location.area_location_id = location
|
||||
|
||||
location.zone_location_id = zone_location
|
||||
|
||||
# Internal locations whose parent is view are main stocks
|
||||
if (
|
||||
location.usage == 'internal'
|
||||
and location.location_id.usage == 'view'
|
||||
):
|
||||
location.location_kind = 'stock'
|
||||
@api.depends('usage', 'location_id.usage',
|
||||
'child_ids',
|
||||
'area_location_id',
|
||||
'zone_location_id')
|
||||
def _compute_location_kind(self):
|
||||
for location in self:
|
||||
if location.zone_location_id and not location.area_location_id:
|
||||
location.location_kind = 'zone'
|
||||
continue
|
||||
# Internal locations having a zone and no children are bins
|
||||
|
||||
parent = location.location_id
|
||||
if (
|
||||
location.usage == 'internal'
|
||||
and zone_location
|
||||
and parent.usage == 'view'
|
||||
):
|
||||
# Internal locations whose parent is view are main stocks
|
||||
location.location_kind = 'stock'
|
||||
elif (
|
||||
# Internal locations having a zone and no children are bins
|
||||
location.usage == 'internal'
|
||||
and location.zone_location_id
|
||||
and location.area_location_id
|
||||
and not location.child_ids
|
||||
):
|
||||
location.location_kind = 'bin'
|
||||
continue
|
||||
# Internal locations having a zone and children are areas
|
||||
if (
|
||||
elif (
|
||||
location.usage == 'internal'
|
||||
and zone_location
|
||||
and location.zone_location_id
|
||||
and location.area_location_id
|
||||
and location.child_ids
|
||||
):
|
||||
# Internal locations having a zone and children are areas
|
||||
location.location_kind = 'area'
|
||||
continue
|
||||
# All the rest are other locations
|
||||
location.location_kind = 'other'
|
||||
else:
|
||||
# All the rest are other locations
|
||||
location.location_kind = 'other'
|
||||
|
||||
@api.multi
|
||||
@api.returns('self', lambda value: value.id)
|
||||
|
||||
@@ -3,8 +3,8 @@ classification of stock locations in a warehouse.
|
||||
|
||||
Locations are then classified by location kinds that could be:
|
||||
|
||||
* Zone: locations that are flagged as being zones
|
||||
* Area: locations with children that are part of a zone
|
||||
* Zone: locations that are flagged as being zones. Zones are subdivisions of the warehouse for splitting picking operations. A picking operator work in a zone and can pick from any location of the zone.
|
||||
* Area: locations with children that are part of a zone. Areas are subdivisions of the warehouse for put-away operations. Each area has storage characteristics and strategy, e.g. area for pallets, shelf for boxes...
|
||||
* Bin: locations without children that are part of a zone
|
||||
* Stock: internal locations whose parent is a view
|
||||
* Other: any other location
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<field name="usage" position="after">
|
||||
<field name="location_kind" />
|
||||
<field name="zone_location_id" />
|
||||
<field name="area_location_id" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
@@ -25,9 +26,11 @@
|
||||
<field name="location_kind"/>
|
||||
<field name="is_zone" />
|
||||
<field name="zone_location_id" />
|
||||
<field name="area_location_id" />
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Location Kind" name="location_kind" domain="[]" context="{'group_by':'location_kind'}"/>
|
||||
<filter string="Zone location" name="zone_location" domain="[]" context="{'group_by':'zone_location_id'}"/>
|
||||
<filter string="Area location" name="area_location" domain="[]" context="{'group_by':'area_location_id'}"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
|
||||
Reference in New Issue
Block a user