diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 9c9fc1fbb85..b405c724aba 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -2078,6 +2078,19 @@ class AccountMove(models.Model): ignore = False if ignore: del res[key] + + # Convert float values to their "ORM cache" one to prevent different rounding calculations + for dict_key in res: + move_id = dict_key.get('move_id') + if not move_id: + continue + record = self.env['account.move'].browse(move_id) + for fname, current_value in res[dict_key].items(): + field = self.env['account.move.line']._fields[fname] + if isinstance(current_value, float): + new_value = field.convert_to_cache(current_value, record) + res[dict_key][fname] = new_value + return res def dirty(): @@ -2111,17 +2124,18 @@ class AccountMove(models.Model): if needed_after == needed_before: return - to_delete = sorted({ + to_delete = [ line.id for key, line in existing_before.items() if key not in needed_after and key in existing_after and before2after[key] not in needed_after - } | { - line.id + ] + to_delete_set = set(to_delete) + to_delete.extend(line.id for key, line in existing_after.items() - if key not in needed_after - }) + if key not in needed_after and line.id not in to_delete_set + ) to_create = { key: values for key, values in needed_after.items() diff --git a/addons/account/tests/test_account_move_out_invoice.py b/addons/account/tests/test_account_move_out_invoice.py index e6f25fd6d4f..b4568c82d30 100644 --- a/addons/account/tests/test_account_move_out_invoice.py +++ b/addons/account/tests/test_account_move_out_invoice.py @@ -3558,3 +3558,22 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): }) invoice.action_post() self.assertEqual(invoice.name, 'INV1/2023/00010') + + def test_invoice_mass_posting(self): + """ + With some particular setup (in this case, rounding issue), partner get mixed up in the + invoice lines after mass posting. + """ + currency = self.company_data['currency'] + currency.rounding = 0.0001 + invoice1 = self.init_invoice(move_type='out_invoice', partner=self.partner_a, invoice_date='2016-01-20', products=self.product_a) + invoice1.invoice_line_ids.price_unit = 12.36 + invoice2 = self.init_invoice(move_type='out_invoice', partner=self.partner_b, invoice_date='2016-01-20', products=self.product_a) + + vam = self.env["validate.account.move"].create({"force_post": True}) + vam.with_context(active_model='account.move', active_ids=[invoice2.id, invoice1.id]).validate_move() + + for aml in invoice1.line_ids: + self.assertEqual(aml.partner_id, self.partner_a) + for aml in invoice2.line_ids: + self.assertEqual(aml.partner_id, self.partner_b)