From 227c5d13dc0d522e6d08156cca802dc7ce3f46cd Mon Sep 17 00:00:00 2001 From: "David (dafr)" Date: Thu, 3 Mar 2022 11:44:14 +0000 Subject: [PATCH] [FIX] stock_account: Return product with revaluation layer How to reproduce: 1- Create Product Category "PC" AVCO|FIFO Automated. 2- Create Storable Product "P" with product category PC and unit cost to 1. 3- Create SO with 10 units of P. 4- Create PO with 10 units of P and unit cost of 2. Delivery of the SO should now have 2 IV layers, with one being "Revaluation of XXX (negative inventory)" Global IV of P should be 0 qty, 0 value. 5- Return the delivery order of SO. 6- Open valuation of the return Error: The value is 0, should be 20 In `_get_price_unit`, `price_unit` is taken on the last svl of the origin_returned_move_id, in our case it's the revaluation layer. `_get_price_unit` now take all svls of origin_returned_move_id into account. OPW-2784033 closes odoo/odoo#88177 X-original-commit: bfd1a06b054dcc115f7fb0937db98812f4a6d5dc Signed-off-by: Arnold Moyaux Signed-off-by: DavidFesquet --- addons/stock_account/models/stock_move.py | 4 +++- .../tests/test_stockvaluationlayer.py | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/addons/stock_account/models/stock_move.py b/addons/stock_account/models/stock_move.py index 829d15ac0d5..d313ad0a481 100644 --- a/addons/stock_account/models/stock_move.py +++ b/addons/stock_account/models/stock_move.py @@ -45,7 +45,9 @@ class StockMove(models.Model): precision = self.env['decimal.precision'].precision_get('Product Price') # If the move is a return, use the original move's price unit. if self.origin_returned_move_id and self.origin_returned_move_id.sudo().stock_valuation_layer_ids: - return self.origin_returned_move_id.sudo().stock_valuation_layer_ids[-1].unit_cost + layers = self.origin_returned_move_id.sudo().stock_valuation_layer_ids + quantity = sum(layers.mapped("quantity")) + return layers.currency_id.round(sum(layers.mapped("value")) / quantity) if not float_is_zero(quantity, layers.uom_id.rounding) else 0 return price_unit if not float_is_zero(price_unit, precision) or self._should_force_price_unit() else self.product_id.standard_price @api.model diff --git a/addons/stock_account/tests/test_stockvaluationlayer.py b/addons/stock_account/tests/test_stockvaluationlayer.py index 871c75a7bf6..b92f197f131 100644 --- a/addons/stock_account/tests/test_stockvaluationlayer.py +++ b/addons/stock_account/tests/test_stockvaluationlayer.py @@ -518,6 +518,16 @@ class TestStockValuationAVCO(TestStockValuationCommon): self.assertEqual(self.product1.quantity_svl, 0) self.assertEqual(self.product1.standard_price, 1.01) + def test_return_delivery_2(self): + self.product1.write({"standard_price": 1}) + move1 = self._make_out_move(self.product1, 10, create_picking=True, force_assign=True) + self._make_in_move(self.product1, 10, unit_cost=2) + self._make_return(move1, 10) + + self.assertEqual(self.product1.value_svl, 20) + self.assertEqual(self.product1.quantity_svl, 10) + self.assertEqual(self.product1.standard_price, 2) + class TestStockValuationFIFO(TestStockValuationCommon): @classmethod @@ -689,6 +699,15 @@ class TestStockValuationFIFO(TestStockValuationCommon): returned = self._make_return(out_move02, 1) self.assertEqual(returned.stock_valuation_layer_ids.value, 0) + def test_return_delivery_3(self): + self.product1.write({"standard_price": 1}) + move1 = self._make_out_move(self.product1, 10, create_picking=True, force_assign=True) + self._make_in_move(self.product1, 10, unit_cost=2) + self._make_return(move1, 10) + + self.assertEqual(self.product1.value_svl, 20) + self.assertEqual(self.product1.quantity_svl, 10) + class TestStockValuationChangeCostMethod(TestStockValuationCommon): def test_standard_to_fifo_1(self):