diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 64ba66f6e6a62831927915174f73c3766dc77f87..27839d923f2d2ee21b89946b802b099040c5d39a 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -2018,6 +2018,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(): @@ -2061,17 +2074,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 08fc96cb80fd82f638df72432d6395263d289e53..64efc90521170e3a92264d7a53d422fd98dafb30 100644 --- a/addons/account/tests/test_account_move_out_invoice.py +++ b/addons/account/tests/test_account_move_out_invoice.py @@ -3563,3 +3563,22 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon): # Date of the reversal of the exchange move should be the last day of the month/year of the payment depending on the sequence format self.assertEqual(exchange_move_reversal.date, fields.Date.to_date(expected_date)) + + 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)