From 28fbc3c5d23616ab1281edec323a04d90eeea1ae Mon Sep 17 00:00:00 2001 From: Jordi Ballester Date: Tue, 27 Jun 2017 12:24:38 +0200 Subject: [PATCH] refactor the module to perform lockdown validations using constraint in stock move instead of checks in quants. This will allow for a more robust lockdown, and still make it possible to perform inventory adjustments in the locked location. Also resolves an outstanding issue related to the previous design not allowing inventory adjustments where negative quants existed. --- stock_inventory_lockdown/README.rst | 4 ++ stock_inventory_lockdown/__openerp__.py | 2 +- stock_inventory_lockdown/models/__init__.py | 2 +- .../models/stock_inventory.py | 6 --- stock_inventory_lockdown/models/stock_move.py | 26 ++++++++++ .../models/stock_quant.py | 51 ------------------- 6 files changed, 32 insertions(+), 59 deletions(-) create mode 100644 stock_inventory_lockdown/models/stock_move.py delete mode 100644 stock_inventory_lockdown/models/stock_quant.py diff --git a/stock_inventory_lockdown/README.rst b/stock_inventory_lockdown/README.rst index eb9dc5bfe..4d61c6d69 100644 --- a/stock_inventory_lockdown/README.rst +++ b/stock_inventory_lockdown/README.rst @@ -39,6 +39,10 @@ Contributors * Loïc Bellier (Numérigraphe) * Lionel Sausin (Numérigraphe) * Laetitia Gangloff (Acsone) +* Laurent Mignon (Acsone) +* Lois Rilo (Eficent) +* Jordi Ballester (Eficent) + Maintainer ---------- diff --git a/stock_inventory_lockdown/__openerp__.py b/stock_inventory_lockdown/__openerp__.py index abccecde3..6e5205497 100644 --- a/stock_inventory_lockdown/__openerp__.py +++ b/stock_inventory_lockdown/__openerp__.py @@ -5,7 +5,7 @@ { "name": "Inventory Lock Down", "summary": "Lock down stock locations during inventories.", - "version": "9.0.1.0.0", + "version": "9.0.1.0.1", "depends": ["stock"], "author": "Numérigraphe,Odoo Community Association (OCA)", "category": "Warehouse Management", diff --git a/stock_inventory_lockdown/models/__init__.py b/stock_inventory_lockdown/models/__init__.py index 6062634c0..dfae546a6 100644 --- a/stock_inventory_lockdown/models/__init__.py +++ b/stock_inventory_lockdown/models/__init__.py @@ -2,6 +2,6 @@ # © 2013-2016 Numérigraphe SARL # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from . import stock_quant +from . import stock_move from . import stock_inventory from . import stock_location diff --git a/stock_inventory_lockdown/models/stock_inventory.py b/stock_inventory_lockdown/models/stock_inventory.py index 71c001f6c..8839115be 100644 --- a/stock_inventory_lockdown/models/stock_inventory.py +++ b/stock_inventory_lockdown/models/stock_inventory.py @@ -27,9 +27,3 @@ class StockInventory(models.Model): if locations_ids: location_domain.append(('location_id', 'child_of', locations_ids)) return self.env['stock.location'].search(location_domain) - - @api.multi - def action_done(self): - """Add value in the context to ignore the lockdown""" - return super(StockInventory, - self.with_context(bypass_lockdown=True)).action_done() diff --git a/stock_inventory_lockdown/models/stock_move.py b/stock_inventory_lockdown/models/stock_move.py new file mode 100644 index 000000000..d5ffdfb7f --- /dev/null +++ b/stock_inventory_lockdown/models/stock_move.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# © 2016 Numérigraphe SARL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp import models, api, _ +from openerp.exceptions import ValidationError + + +class StockMove(models.Model): + _inherit = 'stock.move' + + @api.constrains('location_dest_id', 'location_id', 'state') + def _check_locked_location(self): + for move in self: + if move.state == 'draft': + continue + locked_location_ids = self.env[ + 'stock.inventory']._get_locations_open_inventories( + [move.location_dest_id.id, move.location_id.id]) + if (locked_location_ids and + move.product_id.property_stock_inventory not in [ + move.location_dest_id, move.location_id]): + location_names = locked_location_ids.mapped('complete_name') + raise ValidationError( + _('An inventory is being conducted at the following ' + 'location(s):\n%s') % "\n - ".join(location_names)) diff --git a/stock_inventory_lockdown/models/stock_quant.py b/stock_inventory_lockdown/models/stock_quant.py deleted file mode 100644 index 5cec98a4b..000000000 --- a/stock_inventory_lockdown/models/stock_quant.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# © 2016 Numérigraphe SARL -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from openerp import models, api, _ -from openerp.exceptions import ValidationError - - -class StockQuant(models.Model): - _inherit = 'stock.quant' - - @api.multi - def write(self, vals): - """Check that the location is not locked by an open inventory. - Check both the location as it was (source) and the location as - it will be (destination). - We verify the locations even if they are unchanged, because changing - ie. the quantity is not acceptable either. - @raise ValidationError if they are. - """ - if not self.env.context.get('bypass_lockdown', False): - # Find the locked locations - locked_location_ids = [] - if 'location_id' in vals.keys(): - locked_location_ids = self.env[ - 'stock.inventory']._get_locations_open_inventories( - self.env['stock.location'].browse( - vals['location_id']).ids + self.mapped( - 'location_id').ids - ) - if locked_location_ids: - location_names = locked_location_ids.mapped('name') - raise ValidationError( - _('An inventory is being conducted at the following ' - 'location(s):\n%s') % "\n - ".join(location_names)) - return super(StockQuant, self).write(vals) - - @api.model - def create(self, vals): - """Check that the locations are not locked by an open inventory. - @raise ValidationError if they are. - """ - quant = super(StockQuant, self).create(vals) - if not self.env.context.get('bypass_lockdown', False): - locked_location_ids = self.env['stock.inventory'].\ - _get_locations_open_inventories(quant.location_id.ids) - if locked_location_ids: - raise ValidationError( - _('An inventory is being conducted at the following ' - 'location(s):\n%s') % " - " + quant.location_id.name) - return quant