From d251496bbfa902ea7b675c7fec401aa0fdbd5f38 Mon Sep 17 00:00:00 2001 From: "Tiffany Chang (tic)" Date: Mon, 20 Feb 2023 16:21:17 +0000 Subject: [PATCH] [FIX] stock: do not allow direct deletion of quants Some users were updating their access rights to allow for direct deletion of quants. This could lead to the infamous: "It is not possible to unreserve more products of %s than you have in stock." error since directly deleting a quant bypasses the flows of correctly unreserving the amounts you are deleting. Therefore we now restrict the unlinking to: - when in sudo mode, since the automatic unlinking of zero quants always occurs in sudo mode. - stock manager when unlink access right = True. Normally we would allow any user with the unlink access to do it, but since we are using the existing `_apply_inventory` to ensure that reserved qtys of the quant are correctly unreserved before the unlinking, only stock managers will correctly do this unreservation. It is expected that some custom code may break due to this restriction, but if custom code is directly unlinking quants without a sudo or with a non-stock manager, then the code in these cases probably need to be fixed anyways since this will cause inconsistent db data and lead to the error above. X-original-commit: d1602e7ddefd59cafa1ce0a5522a53c987135858 Part-of: odoo/odoo#115613 --- addons/stock/models/stock_quant.py | 9 +++++++++ addons/stock/tests/test_quant.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/addons/stock/models/stock_quant.py b/addons/stock/models/stock_quant.py index 67a51966e2f..f1c696426f8 100644 --- a/addons/stock/models/stock_quant.py +++ b/addons/stock/models/stock_quant.py @@ -335,6 +335,15 @@ class StockQuant(models.Model): self = self.sudo() return super(StockQuant, self).write(vals) + @api.ondelete(at_uninstall=False) + def _unlink_except_wrong_permission(self): + if not self.env.is_superuser(): + if not self.user_has_groups('stock.group_stock_manager'): + raise UserError(_("Quants are auto-deleted when appropriate. If you must manually delete them, please ask a stock manager to do it.")) + self = self.with_context(inventory_mode=True) + self.inventory_quantity = 0 + self._apply_inventory() + def action_view_stock_moves(self): self.ensure_one() action = self.env["ir.actions.actions"]._for_xml_id("stock.stock_move_line_action") diff --git a/addons/stock/tests/test_quant.py b/addons/stock/tests/test_quant.py index c70f746a1c6..71cebe479b9 100644 --- a/addons/stock/tests/test_quant.py +++ b/addons/stock/tests/test_quant.py @@ -509,7 +509,7 @@ class StockQuant(TransactionCase): }) with self.assertRaises(AccessError): quant.with_user(self.demo_user).write({'quantity': 2.0}) - with self.assertRaises(AccessError): + with self.assertRaises(UserError): quant.with_user(self.demo_user).unlink() self.env = self.env(user=self.stock_user)