mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
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:
@@ -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.",
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 = [
|
||||
(
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user