Add corrections to stock_location_zone

* Allow copy of stock locations (was blocked by constraint on unique name)
* Correct loop in _compute_name returning too early if a record had no
parent with a 'location_name_format'
* Rename field pick_type_id to picking_type_id for coherency
* Add missing _description on stock.picking.zone
* Correct location_name_format format when the record is a NewId
This commit is contained in:
Guewen Baconnier
2019-08-27 11:22:50 +02:00
parent fa7961a7ad
commit 35400e528e
4 changed files with 85 additions and 18 deletions

View File

@@ -5,7 +5,7 @@
{
'name': 'Stock Location Zone',
'version': '12.0.1.0.0',
'author': "BCIM, Okia, Odoo Community Association (OCA)",
'author': "BCIM, Okia, Camptocamp, Odoo Community Association (OCA)",
'website': "https://github.com/OCA/stock-logistics-warehouse",
'summary': "Add coordinate attributes on stock location. "
"Define picking zone with links to picking type.",

View File

@@ -2,7 +2,32 @@
# Copyright 2018-2019 Jacques-Etienne Baudoux (BCIM sprl) <je@bcim.be>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import _, api, fields, models
from psycopg2 import sql
from odoo import _, api, exceptions, fields, models, SUPERUSER_ID
from odoo.tools.sql import index_exists, _schema
def create_unique_index_where(cr, indexname, tablename, expressions, where):
"""Create the given unique index unless it exists."""
if index_exists(cr, indexname):
return
args = ', '.join(expressions)
# pylint: disable=sql-injection
cr.execute(
sql.SQL(
'CREATE UNIQUE INDEX {} ON {} ({}) WHERE {}').format(
sql.Identifier(indexname),
sql.Identifier(tablename),
sql.SQL(args),
sql.SQL(where),
)
)
_schema.debug(
"Table %r: created unique index %r (%s) WHERE {}",
tablename, indexname, args, where
)
class StockLocation(models.Model):
@@ -18,10 +43,12 @@ class StockLocation(models.Model):
picking_zone_id = fields.Many2one(
'stock.picking.zone',
string='Picking zone')
string='Picking zone',
index=True,
)
picking_type_id = fields.Many2one(
related='picking_zone_id.pick_type_id',
related='picking_zone_id.picking_type_id',
help="Picking type for operations from this location",
oldname='barcode_picking_type_id')
@@ -61,18 +88,57 @@ class StockLocation(models.Model):
if not location.kind == 'bin':
continue
area = location
while not area.location_name_format:
if not area.location_id:
return
while area and not area.location_name_format:
area = area.location_id
location.name = area.location_name_format\
.format(**location.read())
if not area:
continue
template = area.location_name_format
# We don't want to use the full browse record as it would
# give too much access to internals for the users.
# We cannot use location.read() as we may have a NewId.
# We should have the record's values in the cache at this
# point. We must be cautious not to leak an environment through
# relational fields.
location.name = template.format(**location._cache)
_sql_constraints = [
(
'unique_location_name',
'UNIQUE(name, location_id)',
_('The location name must be unique'),
@api.multi
@api.returns('self', lambda value: value.id)
def copy(self, default=None):
self.ensure_one()
default = dict(default or {})
if 'name' not in default:
default['name'] = _("%s (copy)") % (self.name)
return super().copy(default=default)
@api.model_cr
def init(self):
env = api.Environment(self._cr, SUPERUSER_ID, {})
self._init_zone_index(env)
def _init_zone_index(self, env):
"""Add unique index on name per zone
We cannot use _sql_constraints because it doesn't support
WHERE conditions. We need to apply the unique constraint
only within the same zone, otherwise the constraint fails
even on demo data (locations created automatically for
warehouses).
"""
index_name = 'stock_location_unique_name_zone_index'
create_unique_index_where(
env.cr, index_name, self._table,
['name', 'picking_zone_id'],
'picking_zone_id IS NOT NULL'
)
]
@classmethod
def _init_constraints_onchanges(cls):
# As the unique index created in this model acts as a unique
# constraints but cannot be registered in '_sql_constraints'
# (it doesn't support WHERE clause), associate an error
# message manually (reproduce what _sql_constraints does).
key = 'unique_name_zone'
message = ('Another location with the same name exists in the same'
' zone. Please rename the location.')
cls.pool._sql_error[cls._table + '_' + key] = message
super()._init_constraints_onchanges()

View File

@@ -7,14 +7,15 @@ from odoo import fields, models
class PickingZone(models.Model):
_name = 'stock.picking.zone'
_description = "Stock Picking Zone"
name = fields.Char('Name', required=True, translate=True)
code = fields.Char('Code', required=True)
pick_type_id = fields.Many2one(
picking_type_id = fields.Many2one(
'stock.picking.type',
string='Pick Type',
help="Picking type for operations from this location",
)
)
_sql_constraints = [
(

View File

@@ -17,7 +17,7 @@
<tree string="Picking Zones" editable="bottom">
<field name="name"/>
<field name="code"/>
<field name="pick_type_id"/>
<field name="picking_type_id"/>
</tree>
</field>
</record>