From 8985426bf38affedb82990bd2158049b4d6b0bce Mon Sep 17 00:00:00 2001
From: Yolann Sabaux <yosa@odoo.com>
Date: Tue, 28 Mar 2023 13:26:10 +0000
Subject: [PATCH] [FIX] purchase: enable correct currency on onchange
 partner_id

Steps to reproduce:
- company currency = USD
- set a partner P with a `property_purchase_currency_id` in EUR
- create a bill with Azure partner and set an bill line
- change to partner P
issue -> the currency of the line has not been change
- change to Azure
issue -> no change about the currency

Cause:
- We update the move.currency_id but not the line_ids.currency_id
- after setting Partner P, we try to set a partner that no `property_purchase_currency_id`, we do not enter in the condition

opw-3233527

closes odoo/odoo#116852

Signed-off-by: Cedric Snauwaert <csn@odoo.com>
---
 addons/purchase/models/account_invoice.py     | 22 +++++-----
 .../purchase/tests/test_purchase_invoice.py   | 40 +++++++++++++++++++
 2 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/addons/purchase/models/account_invoice.py b/addons/purchase/models/account_invoice.py
index 992705e424fb..856a84e6fc7d 100644
--- a/addons/purchase/models/account_invoice.py
+++ b/addons/purchase/models/account_invoice.py
@@ -81,23 +81,27 @@ class AccountMove(models.Model):
     @api.onchange('partner_id', 'company_id')
     def _onchange_partner_id(self):
         res = super(AccountMove, self)._onchange_partner_id()
-        if self.partner_id and\
-                self.move_type in ['in_invoice', 'in_refund'] and\
-                self.currency_id != self.partner_id.property_purchase_currency_id and\
-                self.partner_id.property_purchase_currency_id.id:
+
+        currency_id = (
+                self.partner_id.property_purchase_currency_id
+                or self.env.context.get("default_currency_id")
+                or self.env.company.currency_id
+        )
+
+        if self.partner_id and self.move_type in ['in_invoice', 'in_refund'] and self.currency_id != currency_id:
             if not self.env.context.get('default_journal_id'):
                 journal_domain = [
                     ('type', '=', 'purchase'),
                     ('company_id', '=', self.company_id.id),
-                    ('currency_id', '=', self.partner_id.property_purchase_currency_id.id),
+                    ('currency_id', '=', currency_id.id),
                 ]
                 default_journal_id = self.env['account.journal'].search(journal_domain, limit=1)
                 if default_journal_id:
                     self.journal_id = default_journal_id
-            if self.env.context.get('default_currency_id'):
-                self.currency_id = self.env.context['default_currency_id']
-            if self.partner_id.property_purchase_currency_id:
-                self.currency_id = self.partner_id.property_purchase_currency_id
+
+            self.currency_id = currency_id
+            self._onchange_currency()
+
         return res
 
     @api.model_create_multi
diff --git a/addons/purchase/tests/test_purchase_invoice.py b/addons/purchase/tests/test_purchase_invoice.py
index cad8b0b032f4..ecde9b1f08ef 100644
--- a/addons/purchase/tests/test_purchase_invoice.py
+++ b/addons/purchase/tests/test_purchase_invoice.py
@@ -576,3 +576,43 @@ class TestPurchaseToInvoice(AccountTestInvoicingCommon):
         po_line.write({'product_qty': 4})
         po_line._onchange_quantity()
         self.assertEqual(40.0, po_line.price_unit, "Unit price should be set to 40.0 for 4 quantity")
+
+    def test_onchange_partner_currency(self):
+        """
+        Test that the currency of the Bill is correctly set when the partner is changed
+        as well as the currency of the Bill lines
+        """
+
+        vendor_eur = self.env['res.partner'].create({
+            'name': 'Vendor EUR',
+            'property_purchase_currency_id': self.env.ref('base.EUR').id,
+        })
+        vendor_us = self.env['res.partner'].create({
+            'name': 'Vendor USD',
+            'property_purchase_currency_id': self.env.ref('base.USD').id,
+        })
+        vendor_no_currency = self.env['res.partner'].create({
+            'name': 'Vendor No Currency',
+        })
+
+        move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+        move_form.partner_id = vendor_eur
+        with move_form.invoice_line_ids.new() as line_form:
+            line_form.product_id = self.product_order
+            line_form.quantity = 1
+        bill = move_form.save()
+
+        self.assertEqual(bill.currency_id, self.env.ref('base.EUR'), "The currency of the Bill should be the same as the currency of the partner")
+        self.assertEqual(bill.invoice_line_ids.currency_id, self.env.ref('base.EUR'), "The currency of the Bill lines should be the same as the currency of the partner")
+
+        move_form.partner_id = vendor_us
+        bill = move_form.save()
+
+        self.assertEqual(bill.currency_id, self.env.ref('base.USD'), "The currency of the Bill should be the same as the currency of the partner")
+        self.assertEqual(bill.invoice_line_ids.currency_id, self.env.ref('base.USD'), "The currency of the Bill lines should be the same as the currency of the partner")
+
+        move_form.partner_id = vendor_no_currency
+        bill = move_form.save()
+
+        self.assertEqual(bill.currency_id, self.env.company.currency_id, "The currency of the Bill should be the same as the currency of the company")
+        self.assertEqual(bill.invoice_line_ids.currency_id, self.env.company.currency_id, "The currency of the Bill lines should be the same as the currency of the company")
-- 
GitLab