From c8fa51330dbaff6e26b77b0cb6eeee775c5e8565 Mon Sep 17 00:00:00 2001 From: William Henrotin Date: Mon, 14 Sep 2020 08:49:20 +0000 Subject: [PATCH] [FIX] stock_account: empty move valuation The validation of a stock move without quantity done create an empty stock valuation layer. This is not a wanted behavior as : 1. it create record without useful information (0 value, 0 remaining qty, 0 remaining value) 2. The landed cost value is set on a wrong layer in case of complete backorder. This commit bypass the valuation process on a move if it is validated without any quantity. opw : 2328258 closes odoo/odoo#58776 X-original-commit: 01e21735dbf3ac2fe975323cee2f4bb93e4ca747 Signed-off-by: William Henrotin Signed-off-by: Nicolas Martinelli (nim) --- addons/stock_account/models/stock_move.py | 2 + .../tests/test_stockvaluationlayer.py | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/addons/stock_account/models/stock_move.py b/addons/stock_account/models/stock_move.py index 56109a86583..6f9c34c49b5 100644 --- a/addons/stock_account/models/stock_move.py +++ b/addons/stock_account/models/stock_move.py @@ -237,6 +237,8 @@ class StockMove(models.Model): # Init a dict that will group the moves by valuation type, according to `move._is_valued_type`. valued_moves = {valued_type: self.env['stock.move'] for valued_type in self._get_valued_types()} for move in self: + if float_is_zero(move.quantity_done, precision_rounding=move.product_uom.rounding): + continue for valued_type in self._get_valued_types(): if getattr(move, '_is_%s' % valued_type)(): valued_moves[valued_type] |= move diff --git a/addons/stock_account/tests/test_stockvaluationlayer.py b/addons/stock_account/tests/test_stockvaluationlayer.py index 451bd2528e4..c05f9042923 100644 --- a/addons/stock_account/tests/test_stockvaluationlayer.py +++ b/addons/stock_account/tests/test_stockvaluationlayer.py @@ -261,6 +261,44 @@ class TestStockValuationStandard(TestStockValuationCommon): self.assertEqual(self.product1.value_svl, 0) self.assertEqual(self.product1.quantity_svl, 0) + def test_empty_stock_move_valorisation(self): + product1 = self.env['product.product'].create({ + 'name': 'p1', + 'type': 'product', + }) + product2 = self.env['product.product'].create({ + 'name': 'p2', + 'type': 'product', + }) + picking = self.env['stock.picking'].create({ + 'picking_type_id': self.picking_type_in.id, + 'location_id': self.supplier_location.id, + 'location_dest_id': self.stock_location.id, + }) + for product in (product1, product2): + product.standard_price = 10 + in_move = self.env['stock.move'].create({ + 'name': 'in %s units @ %s per unit' % (2, str(10)), + 'product_id': product.id, + 'location_id': self.supplier_location.id, + 'location_dest_id': self.stock_location.id, + 'product_uom': self.uom_unit.id, + 'product_uom_qty': 2, + 'price_unit': 10, + 'picking_type_id': self.picking_type_in.id, + 'picking_id': picking.id + }) + + picking.action_confirm() + # set quantity done only on one move + in_move.move_line_ids.qty_done = 2 + res_dict = picking.button_validate() + wizard = self.env[(res_dict.get('res_model'))].with_context(res_dict.get('context')).browse(res_dict.get('res_id')) + res_dict_for_back_order = wizard.process() + + self.assertTrue(product2.stock_valuation_layer_ids) + self.assertFalse(product1.stock_valuation_layer_ids) + class TestStockValuationAVCO(TestStockValuationCommon): def setUp(self):