From 70f089fe2546b9041114b5bb06c4540d3ecdda6e Mon Sep 17 00:00:00 2001 From: "Touati Djamel (otd)" Date: Tue, 25 Oct 2022 13:52:47 +0000 Subject: [PATCH] [FIX] stock_account: convert qty to product UOM before creating an SVL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steps to reproduce the bug: - Create a Storable product “P1”: - UOM: unit - Update the qty to 100 - Create an out transfert: - Product: P1 - Qty: 2 - UOM: dozens - Validate the transfert - Click on the valuation button - an SVL is created with Qty: 24 → 2 pack of 12 - Go back to the picking: - Unlock it - change the done qty from 2 to 3 - Lock the picking Problem: The quantity on the new SVL is not converted to the default UoM set on the product. In the write function of `stock.move.line` we calculate the difference between the old and the new qty (3 - 2), then, the `_create_correction_svl` is called: https://github.com/odoo/odoo/blob/15.0/addons/stock_account/models/stock_move_line.py#L45-L48 without converting the diff qty into the product uom, The `_create_out_svl` function is called with the `forced_quantity` parameter: https://github.com/odoo/odoo/blob/15.0/addons/stock_account/models/stock_move_line.py#L66 As it is a forced quantity, it will not convert it: https://github.com/odoo/odoo/blob/14.0/addons/stock_account/models/stock_move.py#L188 Solution: Convert diff qty in the `_create_correction_svl`, to avoid converting it in every function it may call opw-3041279 closes odoo/odoo#104371 X-original-commit: 30aaa668c46f899ed05dee2b6d2f810aa1e6e2e4 Signed-off-by: Arnold Moyaux (arm) Signed-off-by: Djamel Touati (otd) --- .../stock_account/models/stock_move_line.py | 4 +-- .../tests/test_stockvaluation.py | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/addons/stock_account/models/stock_move_line.py b/addons/stock_account/models/stock_move_line.py index 56e58b11e83..8582e3cf938 100644 --- a/addons/stock_account/models/stock_move_line.py +++ b/addons/stock_account/models/stock_move_line.py @@ -21,7 +21,7 @@ class StockMoveLine(models.Model): if move_line.state != 'done': continue rounding = move.product_id.uom_id.rounding - diff = move_line.qty_done + diff = move.product_uom._compute_quantity(move_line.qty_done, move.product_id.uom_id) if float_is_zero(diff, precision_rounding=rounding): continue self._create_correction_svl(move, diff) @@ -42,7 +42,7 @@ class StockMoveLine(models.Model): continue move = move_line.move_id rounding = move.product_id.uom_id.rounding - diff = vals['qty_done'] - move_line.qty_done + diff = move.product_uom._compute_quantity(vals['qty_done'] - move_line.qty_done, move.product_id.uom_id) if float_is_zero(diff, precision_rounding=rounding): continue self._create_correction_svl(move, diff) diff --git a/addons/stock_account/tests/test_stockvaluation.py b/addons/stock_account/tests/test_stockvaluation.py index acd3f69c2d3..17f70124d52 100644 --- a/addons/stock_account/tests/test_stockvaluation.py +++ b/addons/stock_account/tests/test_stockvaluation.py @@ -3935,3 +3935,36 @@ class TestStockValuation(TransactionCase): self.assertEqual(move.stock_valuation_layer_ids.value, 10) self.assertEqual(move.stock_valuation_layer_ids.account_move_id.amount_total, 10) + + def test_create_svl_different_uom(self): + """ + Create a transfer and use in the move a different unit of measure than + the one set on the product form and ensure that when the qty done is changed + and the picking is already validated, an svl is created in the uom set in the product. + """ + uom_dozen = self.env.ref('uom.product_uom_dozen') + receipt = self.env['stock.picking'].create({ + 'location_id': self.supplier_location.id, + 'location_dest_id': self.stock_location.id, + 'picking_type_id': self.env.ref('stock.picking_type_in').id, + 'owner_id': self.env.company.partner_id.id, + }) + + move = self.env['stock.move'].create({ + 'picking_id': receipt.id, + 'name': 'test', + 'location_id': self.supplier_location.id, + 'location_dest_id': self.stock_location.id, + 'product_id': self.product1.id, + 'product_uom': uom_dozen.id, + 'product_uom_qty': 1.0, + 'price_unit': 10, + }) + receipt.action_confirm() + move.quantity_done = 1 + receipt.button_validate() + + self.assertEqual(self.product1.uom_name, 'Units') + self.assertEqual(self.product1.quantity_svl, 12) + move.quantity_done = 2 + self.assertEqual(self.product1.quantity_svl, 24)