[FIX] stock_account: convert qty to product UOM before creating an SVL

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) <arm@odoo.com>
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
This commit is contained in:
Touati Djamel (otd)
2022-10-28 09:17:45 +02:00
parent 54130986ac
commit 70f089fe25
2 changed files with 35 additions and 2 deletions
@@ -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)
@@ -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)