mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[MIG] stock_location_lockdown : Migration to 12.0
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2018 Akretion
|
# Copyright 2018 Akretion
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2018 Akretion
|
# Copyright 2018 Akretion
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "Stock Location Lockdown",
|
"name": "Stock Location Lockdown",
|
||||||
"summary": "Prevent to add stock on flagged locations",
|
"summary": "Prevent to add stock on locked locations",
|
||||||
"author": "Akretion, Odoo Community Association (OCA)",
|
"author": "Akretion, Odoo Community Association (OCA)",
|
||||||
"website": "https://github.com/OCA/stock-logistics-warehouse",
|
"website": "https://github.com/OCA/stock-logistics-warehouse",
|
||||||
"category": "Warehouse",
|
"category": "Warehouse",
|
||||||
"version": "10.0.1.1.0",
|
"version": "12.0.1.0.0",
|
||||||
"license": "AGPL-3",
|
"license": "AGPL-3",
|
||||||
"application": False,
|
"application": False,
|
||||||
"installable": True,
|
"installable": True,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# Copyright 2019 Akretion
|
||||||
# Copyright 2018 Akretion
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from . import stock_location
|
from . import stock_location
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# Copyright 2019 Akretion
|
||||||
# Copyright 2018 Akretion
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import fields, models
|
from odoo import fields, models, _
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
|
||||||
class StockLocation(models.Model):
|
class StockLocation(models.Model):
|
||||||
@@ -12,3 +12,20 @@ class StockLocation(models.Model):
|
|||||||
help="if this box is checked, putting stock on this location won't be "
|
help="if this box is checked, putting stock on this location won't be "
|
||||||
"allowed. Usually used for a virtual location that has "
|
"allowed. Usually used for a virtual location that has "
|
||||||
"childrens.")
|
"childrens.")
|
||||||
|
|
||||||
|
# Raise error if the location that you're trying to block
|
||||||
|
# has already got quants
|
||||||
|
def write(self, values):
|
||||||
|
res = super().write(values)
|
||||||
|
|
||||||
|
if ('block_stock_entrance' in values
|
||||||
|
and values['block_stock_entrance']):
|
||||||
|
# Unlink zero quants before checking
|
||||||
|
# if there are quants on the location
|
||||||
|
self.env['stock.quant']._unlink_zero_quants()
|
||||||
|
if self.mapped('quant_ids'):
|
||||||
|
raise UserError(
|
||||||
|
_("It is impossible to prohibit this location from\
|
||||||
|
receiving products as it already contains some.")
|
||||||
|
)
|
||||||
|
return res
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# Copyright 2019 Akretion
|
||||||
# Copyright 2018 Akretion
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import api, models, _
|
from odoo import api, models, _
|
||||||
@@ -9,8 +8,10 @@ from odoo.exceptions import ValidationError
|
|||||||
class StockQuant(models.Model):
|
class StockQuant(models.Model):
|
||||||
_inherit = 'stock.quant'
|
_inherit = 'stock.quant'
|
||||||
|
|
||||||
|
# Raise an error when trying to change a quant
|
||||||
|
# which corresponding stock location is blocked
|
||||||
@api.constrains('location_id')
|
@api.constrains('location_id')
|
||||||
def _check_location_blocked(self):
|
def check_location_blocked(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
if record.location_id.block_stock_entrance:
|
if record.location_id.block_stock_entrance:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# Copyright 2019 Akretion
|
||||||
# Copyright 2018 Akretion
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from . import test_block_stock_location_entrance
|
from . import test_block_stock_location_entrance
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# Copyright 2019 Akretion France
|
||||||
# Copyright 2018 Akretion France
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo.exceptions import ValidationError
|
from odoo.exceptions import ValidationError, UserError
|
||||||
from odoo.tests.common import TransactionCase
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
@@ -10,42 +9,78 @@ class TestStockLocationLockdown(TransactionCase):
|
|||||||
|
|
||||||
def setUp(self, *args, **kwargs):
|
def setUp(self, *args, **kwargs):
|
||||||
super(TestStockLocationLockdown, self).setUp(*args, **kwargs)
|
super(TestStockLocationLockdown, self).setUp(*args, **kwargs)
|
||||||
self.main_stock_location = self.env.ref('stock.stock_location_stock')
|
|
||||||
self.main_stock_location.block_stock_entrance = True
|
# Create a new stock location with no quants and blocked stock entrance
|
||||||
|
new_loc = {'name': 'location_test', 'usage': 'internal'}
|
||||||
|
self.new_stock_location = self.env['stock.location'].create(new_loc)
|
||||||
|
self.new_stock_location.block_stock_entrance = True
|
||||||
|
|
||||||
self.supplier_location = self.env.ref('stock.stock_location_suppliers')
|
self.supplier_location = self.env.ref('stock.stock_location_suppliers')
|
||||||
self.customer_location = self.env.ref('stock.stock_location_customers')
|
self.customer_location = self.env.ref('stock.stock_location_customers')
|
||||||
|
|
||||||
|
# Call an existing product and force no Lot/Serial Number tracking
|
||||||
self.product = self.env.ref('product.product_product_27')
|
self.product = self.env.ref('product.product_product_27')
|
||||||
|
self.product.tracking = 'none'
|
||||||
|
|
||||||
|
# Catch the first quant's stock location
|
||||||
|
self.stock_location = self.env['stock.quant'].search([])[0].location_id
|
||||||
|
|
||||||
def test_transfer_stock_in_locked_location(self):
|
def test_transfer_stock_in_locked_location(self):
|
||||||
"""
|
"""
|
||||||
Test to move stock within a location that should not accept
|
Test to move stock within a location that should not accept
|
||||||
Stock entrance.
|
stock entrance.
|
||||||
"""
|
"""
|
||||||
move_vals = {
|
move_vals = {
|
||||||
'location_id': self.supplier_location.id,
|
'location_id': self.supplier_location.id,
|
||||||
'location_dest_id': self.main_stock_location.id,
|
'location_dest_id': self.new_stock_location.id,
|
||||||
'product_id': self.product.id,
|
'product_id': self.product.id,
|
||||||
'product_uom_qty': self.product.qty_available + 1,
|
'product_uom_qty': self.product.qty_available + 1,
|
||||||
'product_uom': 1,
|
'product_uom': 1,
|
||||||
'name': 'test',
|
'name': 'test',
|
||||||
|
'move_line_ids': [(0, 0, {
|
||||||
|
'product_id': self.product.id,
|
||||||
|
'product_uom_qty': 0,
|
||||||
|
'product_uom_id': 1,
|
||||||
|
'qty_done': self.product.qty_available + 1,
|
||||||
|
'location_id': self.supplier_location.id,
|
||||||
|
'location_dest_id': self.new_stock_location.id,
|
||||||
|
})]
|
||||||
}
|
}
|
||||||
stock_move = self.env['stock.move'].create(move_vals)
|
stock_move = self.env['stock.move'].create(move_vals)
|
||||||
|
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
stock_move.action_done()
|
stock_move._action_done()
|
||||||
|
|
||||||
def test_transfer_stock_out_locked_location(self):
|
def test_transfer_stock_out_locked_location(self):
|
||||||
"""
|
"""
|
||||||
Test to move stock within a location that should not accept
|
Test to move stock out from a location that should not accept
|
||||||
Stock entrance.
|
stock removal.
|
||||||
"""
|
"""
|
||||||
move_vals = {
|
move_vals = {
|
||||||
'location_id': self.main_stock_location.id,
|
'location_id': self.new_stock_location.id,
|
||||||
'location_dest_id': self.customer_location.id,
|
'location_dest_id': self.customer_location.id,
|
||||||
'product_id': self.product.id,
|
'product_id': self.product.id,
|
||||||
'product_uom_qty': self.product.qty_available + 1,
|
'product_uom_qty': self.product.qty_available + 1,
|
||||||
'product_uom': 1,
|
'product_uom': 1,
|
||||||
'name': 'test',
|
'name': 'test',
|
||||||
|
'move_line_ids': [(0, 0, {
|
||||||
|
'product_id': self.product.id,
|
||||||
|
'product_uom_qty': 0,
|
||||||
|
'product_uom_id': 1,
|
||||||
|
'qty_done': self.product.qty_available + 1,
|
||||||
|
'location_id': self.supplier_location.id,
|
||||||
|
'location_dest_id': self.new_stock_location.id,
|
||||||
|
})]
|
||||||
}
|
}
|
||||||
stock_move = self.env['stock.move'].create(move_vals)
|
stock_move = self.env['stock.move'].create(move_vals)
|
||||||
|
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
stock_move.action_done()
|
stock_move._action_done()
|
||||||
|
|
||||||
|
def test_block_location_with_quants(self):
|
||||||
|
"""
|
||||||
|
Test to click on block_stock_entrance checkbox in a location
|
||||||
|
that should not be blocked because it has already got quants
|
||||||
|
"""
|
||||||
|
with self.assertRaises(UserError):
|
||||||
|
self.stock_location.write({'block_stock_entrance': True})
|
||||||
|
|||||||
Reference in New Issue
Block a user