From 387f199ee7234e25c52c9d6c5900eeb6286751f4 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Tue, 7 Jan 2020 10:23:18 +0000 Subject: [PATCH] [FIX] stock_landed_costs: remaining_value and multiple lc Steps to reproduce: Create one product with FIFO and automatic inventory valuation. Purchase product with 10 quantity and cost price 100 and mark shipment as done. Add landed cost for done incoming shipment with 2 cost lines E.g. 1. Freight Charges - 100 2. Duty and Charges - 50 So ideally after first outgoing shipment total cost should get updated in product is (1000 + 100 + 50) / 10 which is 115 The issue is that we increment `remaining_value` on the wrong layer. Fixes #41923 task-2167659 closes odoo/odoo#42871 X-original-commit: 8b89a5e4a85071055bc152b11cf150e62a5c5211 Signed-off-by: Simon Lejeune (sle) --- .../models/stock_landed_cost.py | 2 +- .../tests/test_stock_landed_costs.py | 17 +++++++++++++++++ .../tests/test_stockvaluationlayer.py | 12 ++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/addons/stock_landed_costs/models/stock_landed_cost.py b/addons/stock_landed_costs/models/stock_landed_cost.py index dbbcac1071e..f65bed8b803 100644 --- a/addons/stock_landed_costs/models/stock_landed_cost.py +++ b/addons/stock_landed_costs/models/stock_landed_cost.py @@ -122,7 +122,7 @@ class LandedCost(models.Model): } for line in cost.valuation_adjustment_lines.filtered(lambda line: line.move_id): remaining_qty = sum(line.move_id.stock_valuation_layer_ids.mapped('remaining_qty')) - linked_layer = line.move_id.stock_valuation_layer_ids[-1] # Maybe the LC layer should be linked to multiple IN layer? + linked_layer = line.move_id.stock_valuation_layer_ids[0] # Prorate the value at what's still in stock cost_to_add = (remaining_qty / line.move_id.product_qty) * line.additional_landed_cost diff --git a/addons/stock_landed_costs/tests/test_stock_landed_costs.py b/addons/stock_landed_costs/tests/test_stock_landed_costs.py index 708f0aaedbc..1021b652c6f 100644 --- a/addons/stock_landed_costs/tests/test_stock_landed_costs.py +++ b/addons/stock_landed_costs/tests/test_stock_landed_costs.py @@ -34,6 +34,11 @@ class TestStockLandedCosts(TestStockLandedCostsCommon, StockAccountTestCommon): product_landed_cost_2.product_tmpl_id.categ_id.property_stock_account_input_categ_id = self.o_expense product_landed_cost_2.product_tmpl_id.categ_id.property_stock_account_output_categ_id = self.o_income + self.assertEqual(product_landed_cost_1.value_svl, 0) + self.assertEqual(product_landed_cost_1.quantity_svl, 0) + self.assertEqual(product_landed_cost_2.value_svl, 0) + self.assertEqual(product_landed_cost_2.quantity_svl, 0) + picking_default_vals = self.env['stock.picking'].default_get(list(self.env['stock.picking'].fields_get())) # I create 2 picking moving those products @@ -86,6 +91,11 @@ class TestStockLandedCosts(TestStockLandedCostsCommon, StockAccountTestCommon): picking_landed_cost_2.move_lines.quantity_done = 10 picking_landed_cost_2.button_validate() + self.assertEqual(product_landed_cost_1.value_svl, 0) + self.assertEqual(product_landed_cost_1.quantity_svl, -5) + self.assertEqual(product_landed_cost_2.value_svl, 0) + self.assertEqual(product_landed_cost_2.quantity_svl, -10) + # I create a landed cost for those 2 pickings default_vals = self.env['stock.landed.cost'].default_get(list(self.env['stock.landed.cost'].fields_get())) virtual_home_staging = self.env['product.product'].create({'name': 'Virtual Home Staging'}) @@ -142,3 +152,10 @@ class TestStockLandedCosts(TestStockLandedCostsCommon, StockAccountTestCommon): self.assertEqual(stock_landed_cost_1.state, "done") self.assertTrue(stock_landed_cost_1.account_move_id) self.assertEqual(len(stock_landed_cost_1.account_move_id.line_ids), 48) + + lc_value = sum(stock_landed_cost_1.account_move_id.line_ids.filtered(lambda aml: aml.account_id.name.startswith('Expenses')).mapped('debit')) + product_value = abs(product_landed_cost_1.value_svl) + abs(product_landed_cost_2.value_svl) + self.assertEqual(lc_value, product_value) + + self.assertEqual(len(picking_landed_cost_1.move_lines.stock_valuation_layer_ids), 5) + self.assertEqual(len(picking_landed_cost_2.move_lines.stock_valuation_layer_ids), 5) diff --git a/addons/stock_landed_costs/tests/test_stockvaluationlayer.py b/addons/stock_landed_costs/tests/test_stockvaluationlayer.py index 9bf87094d84..372006a5c0b 100644 --- a/addons/stock_landed_costs/tests/test_stockvaluationlayer.py +++ b/addons/stock_landed_costs/tests/test_stockvaluationlayer.py @@ -179,6 +179,18 @@ class TestStockValuationLCFIFO(TestStockValuationLCCommon): self.assertEqual(self.product1.value_svl, 0) self.assertEqual(self.product1.quantity_svl, 0) + def test_in_and_out_1(self): + move1 = self._make_in_move(self.product1, 10, unit_cost=100, create_picking=True) + self.assertEqual(move1.stock_valuation_layer_ids[0].remaining_value, 1000) + lc1 = self._make_lc(move1, 100) + self.assertEqual(move1.stock_valuation_layer_ids[0].remaining_value, 1100) + lc2 = self._make_lc(move1, 50) + self.assertEqual(move1.stock_valuation_layer_ids[0].remaining_value, 1150) + self.assertEqual(self.product1.value_svl, 1150) + self.assertEqual(self.product1.quantity_svl, 10) + move2 = self._make_out_move(self.product1, 1) + self.assertEqual(move2.stock_valuation_layer_ids.value, -115) + class TestStockValuationLCAVCO(TestStockValuationLCCommon): def setUp(self):