From 1b2c045f03397583b03edbb12e638a8a11712ea8 Mon Sep 17 00:00:00 2001
From: PNO <pno@odoo.com>
Date: Thu, 29 Sep 2022 08:43:47 +0000
Subject: [PATCH] [FIX] stock: block product type change if sales count

Steps to reproduce:
- Create a product and complete a sales order.
- Then try to change the product type.
- The following message is shown:
"You cannot change the products type because it is already used in sales orders."
However, we can close the message and save.

Problem:
If some sales were already made, it should not be possible to change the product type.
There is a warning message on the onchange but it's not blocking.
This causes inconsistencies between the quantities and value shown in the quants and in the valuation layers.

Solution:
Raise an user error when trying to save the changes.

opw-3000886

closes odoo/odoo#101547

Signed-off-by: William Henrotin (whe) <whe@odoo.com>
---
 addons/stock/models/product.py | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/addons/stock/models/product.py b/addons/stock/models/product.py
index ef651708ba5d..a0b3849c7966 100644
--- a/addons/stock/models/product.py
+++ b/addons/stock/models/product.py
@@ -739,11 +739,17 @@ class ProductTemplate(models.Model):
         if 'type' in vals and vals['type'] != 'product' and sum(self.mapped('nbr_reordering_rules')) != 0:
             raise UserError(_('You still have some active reordering rules on this product. Please archive or delete them first.'))
         if any('type' in vals and vals['type'] != prod_tmpl.type for prod_tmpl in self):
-            existing_move_lines = self.env['stock.move.line'].search([
+            existing_done_move_lines = self.env['stock.move.line'].search([
+                ('product_id', 'in', self.mapped('product_variant_ids').ids),
+                ('state', '=', 'done'),
+            ], limit=1)
+            if existing_done_move_lines:
+                raise UserError(_("You can not change the type of a product that was already used."))
+            existing_reserved_move_lines = self.env['stock.move.line'].search([
                 ('product_id', 'in', self.mapped('product_variant_ids').ids),
                 ('state', 'in', ['partially_available', 'assigned']),
             ])
-            if existing_move_lines:
+            if existing_reserved_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"))
-- 
GitLab