From 99c8368bddbad74efad6969953a38e6c2a504e04 Mon Sep 17 00:00:00 2001 From: "Adrien Widart (awt)" Date: Wed, 9 Nov 2022 11:37:06 +0000 Subject: [PATCH] [FIX] sale{,_stock}: decrease qty of SOL When decreasing the qty of a SOL, if there is already a packaging defined, a return will be created for the difference To reproduce the issue: 1. Create a product P - Storable - With one packaging PK for 10 x P 2. Create and confirm a SO - Order Lines: - 10 x P with PK 3. On the SO, decrease the quantity of P to 8 Error: a return is created for the difference. Instead, the existing picking should be updated At some point, we try to merge the stock moves (`10 x P` and `-2 x P`) and, to do so, they must have the same `product_packaging_id`: https://github.com/odoo/odoo/blob/08f53ffa30479cfb452ebaed61b42655eb0e6a95/addons/stock/models/stock_move.py#L808-L813 However, on the SO, when decreasing the quantity, an onchange tries to find the best packaging. Because the new quantity is not a multiple of PK, this one is not returned. As a result, the SO has no more packaging and so does the new stock move (`-2 x P`). Therefore, the stock moves can not be merged and a new picking (the return) is created. This commit updates the onchange method so it behaves the same way as purchase side: https://github.com/odoo/odoo/blob/20fa7c6f0f5c9cdfae2519ea8d0ff849d7fa3b9e/addons/purchase/models/purchase.py#L1224-L1231 In this onchange, the same diff has recently be added for another reason (see [1]) [1] 20fa7c6f0f5c9cdfae2519ea8d0ff849d7fa3b9e OPW-3027110 X-original-commit: e92e960a36babf4daf8f79d210c7f53fb376aa74 Part-of: odoo/odoo#107045 --- addons/sale/models/sale_order_line.py | 2 +- addons/sale_stock/tests/test_sale_stock.py | 23 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/addons/sale/models/sale_order_line.py b/addons/sale/models/sale_order_line.py index 0fde107d632..fc15a5abe73 100644 --- a/addons/sale/models/sale_order_line.py +++ b/addons/sale/models/sale_order_line.py @@ -617,7 +617,7 @@ class SaleOrderLine(models.Model): # Find biggest suitable packaging if line.product_id and line.product_uom_qty and line.product_uom: line.product_packaging_id = line.product_id.packaging_ids.filtered( - 'sales')._find_suitable_product_packaging(line.product_uom_qty, line.product_uom) + 'sales')._find_suitable_product_packaging(line.product_uom_qty, line.product_uom) or line.product_packaging_id @api.depends('product_packaging_id', 'product_uom', 'product_uom_qty') def _compute_product_packaging_qty(self): diff --git a/addons/sale_stock/tests/test_sale_stock.py b/addons/sale_stock/tests/test_sale_stock.py index 4b7da8a0e3c..7b60abbd877 100644 --- a/addons/sale_stock/tests/test_sale_stock.py +++ b/addons/sale_stock/tests/test_sale_stock.py @@ -1292,3 +1292,26 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon): so.order_line.product_uom_qty = 8 self.assertRecordValues(so.picking_ids, [{'location_id': warehouse.lot_stock_id.id, 'location_dest_id': customer_location.id}]) self.assertEqual(so.picking_ids.move_ids.product_uom_qty, 8) + + def test_packaging_and_qty_decrease(self): + packaging = self.env['product.packaging'].create({ + 'name': "Super Packaging", + 'product_id': self.product_a.id, + 'qty': 10.0, + }) + + so_form = Form(self.env['sale.order']) + so_form.partner_id = self.partner_a + with so_form.order_line.new() as line: + line.product_id = self.product_a + line.product_uom_qty = 10 + so = so_form.save() + so.action_confirm() + + self.assertEqual(so.order_line.product_packaging_id, packaging) + + with Form(so) as so_form: + with so_form.order_line.edit(0) as line: + line.product_uom_qty = 8 + + self.assertEqual(so.picking_ids.move_ids.product_uom_qty, 8)