From 838b856b88caeb8101a3f21f4786bd3212affc76 Mon Sep 17 00:00:00 2001 From: momegahed Date: Mon, 23 May 2022 12:44:28 +0000 Subject: [PATCH] [FIX] sale: SO amendments after invoicing change the unit price Steps to reproduce: 1- install sale, invoicing 2- create a product p with price pr 3- create a new Sales Order SO with p and edit the price to any other price than pr 4- create an invoice 5- go to SO, reduce quantity to 0 ( customer returns the item ) 6- the unit price is set back to pr and there is no way to edit it Bug: in 836f463c9778195a00bcf2f5290ddef18d8e75d5 the `_compute_price_unit` method was changed from onchange to depends which caused the edits now to be commited to memory. While it can be beneficial for other flows, for this specific use case, it is not Fix: make an exception for lines with already invoiced quantities OPW-2830824 closes odoo/odoo#94482 X-original-commit: b77346926f634f2f06fe1b06b68835a360ae91c5 Signed-off-by: Mohamed Megahed Abbas Megahed SALLAM (mome) --- addons/sale/models/sale_order_line.py | 4 ++++ addons/sale/tests/test_sale_to_invoice.py | 26 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/addons/sale/models/sale_order_line.py b/addons/sale/models/sale_order_line.py index 9332592a06d..46fda7b1133 100644 --- a/addons/sale/models/sale_order_line.py +++ b/addons/sale/models/sale_order_line.py @@ -388,6 +388,10 @@ class SaleOrderLine(models.Model): @api.depends('product_id', 'product_uom', 'product_uom_qty') def _compute_price_unit(self): for line in self: + # check if there is already invoiced amount. if so, the price shouldn't change as it might have been + # manually edited + if line.qty_invoiced > 0: + continue if not line.product_uom or not line.product_id or not line.order_id.pricelist_id: line.price_unit = 0.0 else: diff --git a/addons/sale/tests/test_sale_to_invoice.py b/addons/sale/tests/test_sale_to_invoice.py index bf2173769ff..1954f4d9c7c 100644 --- a/addons/sale/tests/test_sale_to_invoice.py +++ b/addons/sale/tests/test_sale_to_invoice.py @@ -475,3 +475,29 @@ class TestSaleToInvoice(TestSaleCommon): aml = self.env['account.move.line'].search([('move_id', 'in', so.invoice_ids.ids)])[0] self.assertRecordValues(aml, [{'analytic_account_id': analytic_account_so.id}]) + + def test_invoice_after_product_return_price_not_default(self): + so = self.env['sale.order'].create({ + 'name': 'Sale order', + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'order_line': [ + (0, 0, {'name': self.product_a.name, 'product_id': self.product_a.id, 'product_uom_qty': 1, 'price_unit': 123}), + ] + }) + self._check_order_search(so, [('invoice_ids', '=', False)], so) + so.action_confirm() + so_context = { + 'active_model': 'sale.order', + 'active_ids': [so.id], + 'active_id': so.id, + 'default_journal_id': self.company_data['default_journal_sale'].id, + } + invoicing_wizard = self.env['sale.advance.payment.inv'].with_context(so_context).create({}) + invoicing_wizard.create_invoices() + self.assertTrue(so.invoice_ids, "The invoice was not created") + # simulating return by changing product_uom_qty to 0 + so.order_line.product_uom_qty = 0 + # checking if the price_unit is the same + self.assertEqual(so.order_line.price_unit, 123, + "The unit price should be the same as the one used to create the sales order line")