diff --git a/addons/stock/i18n/stock.pot b/addons/stock/i18n/stock.pot index 636606f7ccd..47c4572197a 100644 --- a/addons/stock/i18n/stock.pot +++ b/addons/stock/i18n/stock.pot @@ -784,6 +784,12 @@ msgstr "" msgid "Available Quantity" msgstr "" +#. module: stock +#: code:addons/stock/models/product.py:581 +#, python-format +msgid "Available quantity should be set to zero before changing type" +msgstr "" + #. module: stock #: model:ir.model.fields,field_description:stock.field_stock_move__backorder_id #: model:ir.model.fields,field_description:stock.field_stock_picking__backorder_id diff --git a/addons/stock/models/product.py b/addons/stock/models/product.py index f62cfc3742c..239fa673a66 100644 --- a/addons/stock/models/product.py +++ b/addons/stock/models/product.py @@ -8,6 +8,7 @@ from collections import defaultdict from odoo import _, api, fields, models, SUPERUSER_ID from odoo.exceptions import UserError from odoo.osv import expression +from odoo.tools import pycompat,float_is_zero from odoo.tools.float_utils import float_round OPERATORS = { @@ -733,6 +734,8 @@ class ProductTemplate(models.Model): ]) if existing_move_lines: raise UserError(_("You can not change the type of a product that is currently reserved on a stock move. If you need to change the type, you should first unreserve the stock move.")) + if 'type' in vals and vals['type'] != 'product' and any(p.type == 'product' and not float_is_zero(p.qty_available, precision_rounding=p.uom_id.rounding) for p in self): + raise UserError(_("Available quantity should be set to zero before changing type")) return super(ProductTemplate, self).write(vals) # Be aware that the exact same function exists in product.product diff --git a/addons/stock/tests/test_move.py b/addons/stock/tests/test_move.py index 389ca4428b5..65dd48a1c75 100644 --- a/addons/stock/tests/test_move.py +++ b/addons/stock/tests/test_move.py @@ -4270,8 +4270,9 @@ class StockMove(SavepointCase): self.assertEqual(move1.state, 'assigned') def test_change_product_type(self): - """ Changing type of an existing product will raise a user error if some move - are reserved. + """ Changing type of an existing product will raise a user error if + - some move are reserved + - switching from a stockable product when qty_available is not zero """ self.env['stock.quant']._update_available_quantity(self.product, self.stock_location, 10) move1 = self.env['stock.move'].create({ @@ -4289,6 +4290,11 @@ class StockMove(SavepointCase): with self.assertRaises(UserError): self.product.type = 'consu' move1._action_cancel() + + with self.assertRaises(UserError): + self.product.type = 'consu' + + self.env['stock.quant']._update_available_quantity(self.product, self.stock_location, -self.product.qty_available) self.product.type = 'consu' move2 = self.env['stock.move'].create({