From a9ff983d8f685fd0e251fe4d879e7649210b6848 Mon Sep 17 00:00:00 2001 From: Walid Date: Tue, 26 Dec 2023 16:09:34 +0100 Subject: [PATCH] [FIX] purchase_stock: bill before reciept Steps to reproduce: - Create a product with AVCO that you invoice on Ordered quantities in the Vendor tab. - Create a PO with a value of 200 - Create an invoice and change the price to 100. Then cancel the Invoice. - Create a new invoice and confirm it without changing anything (so price is 200) - Receive the product - The valuation will be 150, the average of the 2 invoices. Bug: all linked invoices are taken into account Fix: only consider posted ones opw-3633051 closes odoo/odoo#147485 X-original-commit: b899edd5b9c2f5e813fc0a83ea5506672785f47b Signed-off-by: Arnold Moyaux (arm) Signed-off-by: Walid Hanniche (waha) --- addons/purchase_stock/models/stock_move.py | 2 + .../tests/test_average_price.py | 40 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/addons/purchase_stock/models/stock_move.py b/addons/purchase_stock/models/stock_move.py index 6c4ce66f292..68827b92501 100644 --- a/addons/purchase_stock/models/stock_move.py +++ b/addons/purchase_stock/models/stock_move.py @@ -61,6 +61,8 @@ class StockMove(models.Model): invoiced_value = 0 invoiced_qty = 0 for invoice_line in line.sudo().invoice_lines: + if invoice_line.move_id.state != 'posted': + continue if invoice_line.tax_ids: invoiced_value += invoice_line.tax_ids.with_context(round=False).compute_all( invoice_line.price_unit, currency=invoice_line.currency_id, quantity=invoice_line.quantity)['total_void'] diff --git a/addons/purchase_stock/tests/test_average_price.py b/addons/purchase_stock/tests/test_average_price.py index 35a02ae374c..20f5c39e0d8 100644 --- a/addons/purchase_stock/tests/test_average_price.py +++ b/addons/purchase_stock/tests/test_average_price.py @@ -164,3 +164,43 @@ class TestAveragePrice(ValuationReconciliationTestCommon): picking.with_user(self.res_users_stock_user).button_validate() self.assertEqual(picking.state, 'done', 'Transfer should be in the DONE state') + + def test_bill_before_reciept(self): + """ Check unit price of recieved product that has been invoiced already """ + + avco_product = self.env['product.product'].create({ + 'name': 'Average Ice Cream', + 'type': 'product', + 'categ_id': self.stock_account_product_categ.id, + 'purchase_method': 'purchase', + }) + avco_product.categ_id.property_cost_method = 'average' + + purchase_order = self.env['purchase.order'].create({ + 'partner_id': self.partner_a.id, + 'order_line': [(0, 0, { + 'product_id': avco_product.id, + 'product_qty': 1.0, + })] + }) + + purchase_order.button_confirm() + purchase_order.action_create_invoice() + bill = purchase_order.invoice_ids[0] + + bill.invoice_date = time.strftime('%Y-%m-%d') + bill.invoice_line_ids[0].price_unit = 100.0 + bill.button_cancel() + + purchase_order.action_create_invoice() + bill = purchase_order.invoice_ids[1] + + bill.invoice_date = time.strftime('%Y-%m-%d') + bill.invoice_line_ids[0].price_unit = 300.0 + bill.invoice_line_ids[0].quantity = 1.0 + bill.action_post() + + picking = purchase_order.picking_ids[0] + picking.button_validate() + + self.assertEqual(avco_product.avg_cost, 300)