Skip to content

Commit

Permalink
Add area location relation
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
guewen committed Sep 20, 2019
1 parent fc0c26f commit 5853edb
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 35 deletions.
86 changes: 51 additions & 35 deletions stock_location_zone/models/stock_location.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
[
Expand All @@ -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
@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 whose parent is view are main stocks
parent = location.location_id
if (
location.usage == 'internal'
and location.location_id.usage == 'view'
and parent.usage == 'view'
):
# Internal locations whose parent is view are main stocks
location.location_kind = 'stock'
continue
# Internal locations having a zone and no children are bins
if (
elif (
# Internal locations having a zone and no children are bins
location.usage == 'internal'
and zone_location
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)
Expand Down
3 changes: 3 additions & 0 deletions stock_location_zone/views/stock_location.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Expand Down

0 comments on commit 5853edb

Please sign in to comment.