prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  [12.0][BUG] account_payment_sale
  Hi
  I have found a bug in module account_payment_sale, but I am not sure how to fix it nicely.
  The payment_mode_id does not propagate from the sale order to the invoice. 
  I guess the tests are a bit to naive, that is why they pass anyway.
  Here we try to propagate the payment mode : https://github.com/OCA/bank-payment/blob/12.0/account_payment_sale/models/sale_order.py#L35
  Here, the invoice is created with the right value (coming from the SO) : https://github.com/OCA/OCB/blob/12.0/addons/sale/models/sale.py#L521
  And it is overriden here https://github.com/OCA/OCB/blob/12.0/addons/sale/models/sale.py#L570
  
  I really don't get why they have refactored it this way, they create the invoice and then they override a lot of values...
  And I do not really see a clean solution to solve this.
  Any idea?
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `account_payment_sale/models/sale_order.py`
  Content:
  ```
  1 # Copyright 2014-2016 Akretion - Alexis de Lattre
  2 # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3 
  4 from odoo import models, fields, api
  5 
  6 
  7 class SaleOrder(models.Model):
  8     _inherit = "sale.order"
  9 
  10     payment_mode_id = fields.Many2one(
  11         'account.payment.mode', string='Payment Mode',
  12         domain=[('payment_type', '=', 'inbound')])
  13 
  14     def _get_payment_mode_vals(self, vals):
  15         if self.payment_mode_id:
  16             vals['payment_mode_id'] = self.payment_mode_id.id
  17             if self.payment_mode_id.bank_account_link == 'fixed':
  18                 vals['partner_bank_id'] =\
  19                     self.payment_mode_id.fixed_journal_id.bank_account_id.id
  20         return vals
  21 
  22     @api.onchange('partner_id')
  23     def onchange_partner_id(self):
  24         res = super().onchange_partner_id()
  25         if self.partner_id:
  26             self.payment_mode_id = self.partner_id.customer_payment_mode_id
  27         else:
  28             self.payment_mode_id = False
  29         return res
  30 
  31     @api.multi
  32     def _prepare_invoice(self):
  33         """Copy bank partner from sale order to invoice"""
  34         vals = super()._prepare_invoice()
  35         return self._get_payment_mode_vals(vals)
  36
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/account_payment_sale/models/sale_order.py b/account_payment_sale/models/sale_order.py
  --- a/account_payment_sale/models/sale_order.py
  +++ b/account_payment_sale/models/sale_order.py
  @@ -33,3 +33,31 @@
           """Copy bank partner from sale order to invoice"""
           vals = super()._prepare_invoice()
           return self._get_payment_mode_vals(vals)
  +
  +    def _finalize_invoices(self, invoices, references):
  +        """
  +        Invoked after creating invoices at the end of action_invoice_create.
  +
  +        We must override this method since the onchange on partner is called by
  +        the base method and therefore will change the specific payment_mode set
  +        on the SO if one is defined on the partner..
  +
  +        :param invoices: {group_key: invoice}
  +        :param references: {invoice: order}
  +        """
  +        payment_vals_by_invoice = {}
  +        for invoice in invoices.values():
  +            payment_vals_by_invoice[invoice] = {
  +                'payment_mode_id': invoice.payment_mode_id.id,
  +                'partner_bank_id': invoice.partner_bank_id.id
  +            }
  +        res = super()._finalize_invoices(invoices, references)
  +        for invoice in invoices.values():
  +            payment_vals = payment_vals_by_invoice[invoice]
  +            if invoice.payment_mode_id.id == payment_vals['payment_mode_id']:
  +                payment_vals.pop("payment_mode_id")
  +            if invoice.partner_bank_id.id == payment_vals["partner_bank_id"]:
  +                payment_vals.pop("partner_bank_id")
  +            if payment_vals:
  +                invoice.write(payment_vals)
  +        return res
  
verification_info: {"golden_diff": "diff --git a/account_payment_sale/models/sale_order.py b/account_payment_sale/models/sale_order.py\n--- a/account_payment_sale/models/sale_order.py\n+++ b/account_payment_sale/models/sale_order.py\n@@ -33,3 +33,31 @@\n         \"\"\"Copy bank partner from sale order to invoice\"\"\"\n         vals = super()._prepare_invoice()\n         return self._get_payment_mode_vals(vals)\n+\n+    def _finalize_invoices(self, invoices, references):\n+        \"\"\"\n+        Invoked after creating invoices at the end of action_invoice_create.\n+\n+        We must override this method since the onchange on partner is called by\n+        the base method and therefore will change the specific payment_mode set\n+        on the SO if one is defined on the partner..\n+\n+        :param invoices: {group_key: invoice}\n+        :param references: {invoice: order}\n+        \"\"\"\n+        payment_vals_by_invoice = {}\n+        for invoice in invoices.values():\n+            payment_vals_by_invoice[invoice] = {\n+                'payment_mode_id': invoice.payment_mode_id.id,\n+                'partner_bank_id': invoice.partner_bank_id.id\n+            }\n+        res = super()._finalize_invoices(invoices, references)\n+        for invoice in invoices.values():\n+            payment_vals = payment_vals_by_invoice[invoice]\n+            if invoice.payment_mode_id.id == payment_vals['payment_mode_id']:\n+                payment_vals.pop(\"payment_mode_id\")\n+            if invoice.partner_bank_id.id == payment_vals[\"partner_bank_id\"]:\n+                payment_vals.pop(\"partner_bank_id\")\n+            if payment_vals:\n+                invoice.write(payment_vals)\n+        return res\n", "issue": "[12.0][BUG] account_payment_sale\nHi\r\nI have found a bug in module account_payment_sale, but I am not sure how to fix it nicely.\r\nThe payment_mode_id does not propagate from the sale order to the invoice. \r\nI guess the tests are a bit to naive, that is why they pass anyway.\r\nHere we try to propagate the payment mode : https://github.com/OCA/bank-payment/blob/12.0/account_payment_sale/models/sale_order.py#L35\r\nHere, the invoice is created with the right value (coming from the SO) : https://github.com/OCA/OCB/blob/12.0/addons/sale/models/sale.py#L521\r\nAnd it is overriden here https://github.com/OCA/OCB/blob/12.0/addons/sale/models/sale.py#L570\r\n\r\nI really don't get why they have refactored it this way, they create the invoice and then they override a lot of values...\r\nAnd I do not really see a clean solution to solve this.\r\nAny idea?\n", "before_files": [{"content": "# Copyright 2014-2016 Akretion - Alexis de Lattre\n# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).\n\nfrom odoo import models, fields, api\n\n\nclass SaleOrder(models.Model):\n    _inherit = \"sale.order\"\n\n    payment_mode_id = fields.Many2one(\n        'account.payment.mode', string='Payment Mode',\n        domain=[('payment_type', '=', 'inbound')])\n\n    def _get_payment_mode_vals(self, vals):\n        if self.payment_mode_id:\n            vals['payment_mode_id'] = self.payment_mode_id.id\n            if self.payment_mode_id.bank_account_link == 'fixed':\n                vals['partner_bank_id'] =\\\n                    self.payment_mode_id.fixed_journal_id.bank_account_id.id\n        return vals\n\n    @api.onchange('partner_id')\n    def onchange_partner_id(self):\n        res = super().onchange_partner_id()\n        if self.partner_id:\n            self.payment_mode_id = self.partner_id.customer_payment_mode_id\n        else:\n            self.payment_mode_id = False\n        return res\n\n    @api.multi\n    def _prepare_invoice(self):\n        \"\"\"Copy bank partner from sale order to invoice\"\"\"\n        vals = super()._prepare_invoice()\n        return self._get_payment_mode_vals(vals)\n", "path": "account_payment_sale/models/sale_order.py"}], "after_files": [{"content": "# Copyright 2014-2016 Akretion - Alexis de Lattre\n# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).\n\nfrom odoo import models, fields, api\n\n\nclass SaleOrder(models.Model):\n    _inherit = \"sale.order\"\n\n    payment_mode_id = fields.Many2one(\n        'account.payment.mode', string='Payment Mode',\n        domain=[('payment_type', '=', 'inbound')])\n\n    def _get_payment_mode_vals(self, vals):\n        if self.payment_mode_id:\n            vals['payment_mode_id'] = self.payment_mode_id.id\n            if self.payment_mode_id.bank_account_link == 'fixed':\n                vals['partner_bank_id'] =\\\n                    self.payment_mode_id.fixed_journal_id.bank_account_id.id\n        return vals\n\n    @api.onchange('partner_id')\n    def onchange_partner_id(self):\n        res = super().onchange_partner_id()\n        if self.partner_id:\n            self.payment_mode_id = self.partner_id.customer_payment_mode_id\n        else:\n            self.payment_mode_id = False\n        return res\n\n    @api.multi\n    def _prepare_invoice(self):\n        \"\"\"Copy bank partner from sale order to invoice\"\"\"\n        vals = super()._prepare_invoice()\n        return self._get_payment_mode_vals(vals)\n\n    def _finalize_invoices(self, invoices, references):\n        \"\"\"\n        Invoked after creating invoices at the end of action_invoice_create.\n\n        We must override this method since the onchange on partner is called by\n        the base method and therefore will change the specific payment_mode set\n        on the SO if one is defined on the partner..\n\n        :param invoices: {group_key: invoice}\n        :param references: {invoice: order}\n        \"\"\"\n        payment_vals_by_invoice = {}\n        for invoice in invoices.values():\n            payment_vals_by_invoice[invoice] = {\n                'payment_mode_id': invoice.payment_mode_id.id,\n                'partner_bank_id': invoice.partner_bank_id.id\n            }\n        res = super()._finalize_invoices(invoices, references)\n        for invoice in invoices.values():\n            payment_vals = payment_vals_by_invoice[invoice]\n            if invoice.payment_mode_id.id == payment_vals['payment_mode_id']:\n                payment_vals.pop(\"payment_mode_id\")\n            if invoice.partner_bank_id.id == payment_vals[\"partner_bank_id\"]:\n                payment_vals.pop(\"partner_bank_id\")\n            if payment_vals:\n                invoice.write(payment_vals)\n        return res\n", "path": "account_payment_sale/models/sale_order.py"}]}