From 67c7ad017f8c976e3aaed328b6ca61ba86f187fa Mon Sep 17 00:00:00 2001 From: thcl-odoo Date: Wed, 13 Oct 2021 07:10:14 +0000 Subject: [PATCH] [FIX] purchase: fix qty received computation Expected behavior : The log note sent when received quantity is updated should take into account the quantity already received. Current behavior : The log note sent doesn't take into account the quantity already received for a 'stock_moves'. So it always displays `Received Quantity: 0.0 -> quantity in stock` instead of `Received Quantity: quantity already received -> quantity in stock` Steps to reproduce the error : - Create a RFQ with few units of a Storable Product (e.g. 5 units) - Partially validate the receipt and create a backorder (e.g. 3 units) - Validate the backorder (e.g. 2 units) Log notes should be : `Received Quantity: 0.0 -> 3.0` `Received Quantity: 3.0 -> 5.0` But are : `Received Quantity: 0.0 -> 3.0` `Received Quantity: 0.0 -> 5.0` The value is always equal to 0.0 because `qty_received_method == 'stock_moves'` so `line.qty_received` is overridden by 0.0 in parent `_compute_qty_received` even though its value is already set to 0.0 (default) or to the quantity already received opw-2600221 opw-2613116 closes odoo/odoo#78858 X-original-commit: 0c8ea86fb8d706af139cd2d412d01487e5899df6 Signed-off-by: William Henrotin (whe) --- addons/purchase_stock/models/purchase.py | 3 +- .../tests/test_purchase_order.py | 44 ++++++++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/addons/purchase_stock/models/purchase.py b/addons/purchase_stock/models/purchase.py index 913a3932853..6352e27edb1 100644 --- a/addons/purchase_stock/models/purchase.py +++ b/addons/purchase_stock/models/purchase.py @@ -292,7 +292,8 @@ class PurchaseOrderLine(models.Model): @api.depends('move_ids.state', 'move_ids.product_uom_qty', 'move_ids.product_uom') def _compute_qty_received(self): - super(PurchaseOrderLine, self)._compute_qty_received() + from_stock_lines = self.filtered(lambda order_line: order_line.qty_received_method == 'stock_moves') + super(PurchaseOrderLine, self - from_stock_lines)._compute_qty_received() for line in self: if line.qty_received_method == 'stock_moves': total = 0.0 diff --git a/addons/purchase_stock/tests/test_purchase_order.py b/addons/purchase_stock/tests/test_purchase_order.py index 56e621575c0..59ff58abf5c 100644 --- a/addons/purchase_stock/tests/test_purchase_order.py +++ b/addons/purchase_stock/tests/test_purchase_order.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. - +import re from datetime import datetime, timedelta from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT @@ -366,3 +366,45 @@ class TestPurchaseOrder(ValuationReconciliationTestCommon): picking.move_line_ids.write({'qty_done': 3.66}) picking.button_validate() self.assertEqual(po.order_line.mapped('qty_received'), [4.0], 'Purchase: no conversion error on receipt in different uom"') + + def test_message_qty_already_received(self): + _product = self.env['product.product'].create({ + 'name': 'TempProduct', + 'type': 'consu', + 'company_id': self.env.user.company_id.id, + }) + + _purchase_order = self.env['purchase.order'].create({ + 'company_id': self.env.user.company_id.id, + 'partner_id': self.partner_a.id, + 'order_line': [ + (0, 0, { + 'name': _product.name, + 'product_id': _product.id, + 'product_qty': 25.0, + 'price_unit': 250.0, + })], + }) + + _purchase_order.button_confirm() + + first_picking = _purchase_order.picking_ids[0] + first_picking.move_lines.quantity_done = 5 + backorder_wizard_dict = first_picking.button_validate() + backorder_wizard = Form(self.env[backorder_wizard_dict['res_model']].with_context(backorder_wizard_dict['context'])).save() + backorder_wizard.process() + + second_picking = _purchase_order.picking_ids[1] + second_picking.move_lines.quantity_done = 5 + backorder_wizard_dict = second_picking.button_validate() + backorder_wizard = Form(self.env[backorder_wizard_dict['res_model']].with_context(backorder_wizard_dict['context'])).save() + backorder_wizard.process() + + third_picking = _purchase_order.picking_ids[2] + third_picking.move_lines.quantity_done = 5 + backorder_wizard_dict = third_picking.button_validate() + backorder_wizard = Form(self.env[backorder_wizard_dict['res_model']].with_context(backorder_wizard_dict['context'])).save() + backorder_wizard.process() + + _message_content = _purchase_order.message_ids.mapped("body")[0] + self.assertIsNotNone(re.search(r"Received Quantity: 5.0 -> 10.0", _message_content), "Already received quantity isn't correctly taken into consideration")