From 43dedb5f3c0e2024e7f4c99a7583ea0dabb22bdc Mon Sep 17 00:00:00 2001 From: guva-odoo Date: Mon, 23 Oct 2023 15:09:15 +0000 Subject: [PATCH] [FIX] purchase: payment_reference purchase autocomplete When selecting a purchase order on a vendor bill, the payment_reference is replaced even it was manually filled. Steps: - Create and confirm a PO - Create a vendor bill, set the bill ref and the payment reference (different than bill ref) - Select PO as purchase_vendor_bill_id -> payment_reference is replaced by bill ref value With this commit, we keep the payment_reference as it is if not empty. opw-3549673 closes odoo/odoo#141853 X-original-commit: 77a0449938dafdd234ecd5bf469ef3800336ba27 Signed-off-by: Laurent Smet (las) Signed-off-by: Guillaume Vanleynseele (guva) --- addons/purchase/models/account_invoice.py | 11 ++-- .../purchase/tests/test_purchase_invoice.py | 57 +++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/addons/purchase/models/account_invoice.py b/addons/purchase/models/account_invoice.py index b9f1c12bd32..41e2b3d316d 100644 --- a/addons/purchase/models/account_invoice.py +++ b/addons/purchase/models/account_invoice.py @@ -25,7 +25,7 @@ class AccountMove(models.Model): def _get_invoice_reference(self): self.ensure_one() - vendor_refs = [ref for ref in set(self.line_ids.mapped('purchase_line_id.order_id.partner_ref')) if ref] + vendor_refs = [ref for ref in set(self.invoice_line_ids.mapped('purchase_line_id.order_id.partner_ref')) if ref] if self.ref: return [ref for ref in self.ref.split(', ') if ref and ref not in vendor_refs] + vendor_refs return vendor_refs @@ -53,7 +53,7 @@ class AccountMove(models.Model): # Copy data from PO invoice_vals = self.purchase_id.with_company(self.purchase_id.company_id)._prepare_invoice() new_currency_id = self.invoice_line_ids and self.currency_id or invoice_vals.get('currency_id') - del invoice_vals['ref'] + del invoice_vals['ref'], invoice_vals['payment_reference'] del invoice_vals['company_id'] # avoid recomputing the currency if self.move_type == invoice_vals['move_type']: del invoice_vals['move_type'] # no need to be updated if it's same value, to avoid recomputes @@ -76,8 +76,11 @@ class AccountMove(models.Model): self.ref = ', '.join(refs) # Compute payment_reference. - if len(refs) == 1: - self.payment_reference = refs[0] + if not self.payment_reference: + if len(refs) == 1: + self.payment_reference = refs[0] + elif len(refs) > 1: + self.payment_reference = refs[-1] self.purchase_id = False diff --git a/addons/purchase/tests/test_purchase_invoice.py b/addons/purchase/tests/test_purchase_invoice.py index 75b39fdb0bf..23e3af30454 100644 --- a/addons/purchase/tests/test_purchase_invoice.py +++ b/addons/purchase/tests/test_purchase_invoice.py @@ -931,3 +931,60 @@ class TestInvoicePurchaseMatch(TestPurchaseToInvoiceCommon): self.assertEqual(bill.currency_id, self.currency_data['currency'], "The currency of the Bill should be the one of the context") self.assertEqual(bill.invoice_line_ids.currency_id, self.currency_data['currency'], "The currency of the Bill lines should be the same as the currency of the Bill") + + def test_payment_reference_autocomplete_invoice(self): + """ + Test that the payment_reference field is not replaced when selected a purchase order + We test the flow for 8 use cases: + - Purchase order with partner ref: + - Bill with ref: + - Bill with payment_reference -> should not be replaced + - Bill without payment_reference -> should be the po.partner_ref + - Bill without ref: + - Bill with payment_reference -> should not be replaced + - Bill without payment_reference -> should be the po.partner_ref + - Purchase order without partner ref: + - Bill with ref + - Bill with payment_reference -> should not be replaced + - Bill without payment_reference -> should be the bill ref + - Bill with ref + - Bill with payment_reference -> should not be replaced + - Bill without payment_reference -> should be empty + """ + purchase_order_w_ref, purchase_order_wo_ref = self.env['purchase.order'].with_context(tracking_disable=True).create([ + { + 'partner_id': self.partner_a.id, + 'partner_ref': partner_ref, + 'order_line': [ + Command.create({ + 'product_id': self.product_order.id, + 'product_qty': 1.0, + 'price_unit': self.product_order.list_price, + 'taxes_id': False, + }), + ] + } for partner_ref in ('PO-001', False) + ]) + (purchase_order_w_ref + purchase_order_wo_ref).button_confirm() + + expected_values_dict = { + purchase_order_w_ref: { + 'w_bill_ref': {'w_payment_reference': '222', 'wo_payment_reference': purchase_order_w_ref.partner_ref}, + 'wo_bill_ref': {'w_payment_reference': '222', 'wo_payment_reference': purchase_order_w_ref.partner_ref}, + }, + purchase_order_wo_ref: { + 'w_bill_ref': {'w_payment_reference': '222', 'wo_payment_reference': '111'}, + 'wo_bill_ref': {'w_payment_reference': '222', 'wo_payment_reference': ''}, + } + } + + for purchase_order, purchase_expected_values in expected_values_dict.items(): + for w_bill_ref, expected_values in purchase_expected_values.items(): + for w_payment_reference, expected_value in expected_values.items(): + with self.subTest(po_partner_ref=purchase_order.partner_ref, w_bill_ref=w_bill_ref, w_payment_reference=w_payment_reference, expected_value=expected_value): + move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice')) + move_form.ref = '111' if w_bill_ref == 'w_bill_ref' else '' + move_form.payment_reference = '222' if w_payment_reference == 'w_payment_reference' else '' + move_form.purchase_vendor_bill_id = self.env['purchase.bill.union'].browse(-purchase_order.id).exists() + payment_reference = move_form._values['payment_reference'] + self.assertEqual(payment_reference, expected_value, "The payment reference should be %s" % expected_value)