From 83f63df06bee6f4617a6be221b3a7c968b9cefc3 Mon Sep 17 00:00:00 2001 From: Nishant Jain Date: Thu, 28 Dec 2023 11:26:45 +0530 Subject: [PATCH] [IMP] account: don't calculate cash rounding if state is posted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steps: 1. Install the Accounting module. 2. Enable cash rounding for Customer Invoices in the settings. 3. Activate Developer mode. 4. Navigate to Accounting > Configuration > Management > Cash Rounding. 5. Create a Cash Rounding rule with the following settings: a. Rounding Precision = 1 b. Rounding Method = UP c. Rounding Strategy = Add a rounding line. 6. Create a bill and apply the rounding rule. Add invoice lines with products priced at $99.5 and a tax rate of 15%. 7. Confirm the invoice. 8. Access the cash rounding settings and change the Rounding Method to Down. 9. Open the bill, navigate to the "Other Info" page, and select the "To Check" option. This will result in a UserError: "You cannot modify the taxes related to a posted journal item, you should reset the journal entry to draft to do so." Reason: If there is any change in the rounding method after the journal entry is confirmed, the compute method of tax_totals is triggered when some field of that record is modified. This may lead to the creation of another journal item or changes to existing ones based on the new rounding configuration. However, performing this on a confirmed entry is restricted so it will raise UserError. Solution: Don't compute rounding according to the amount_total after its conformation. Instead, count it using journal items for type-rounding Task - 3468308 closes odoo/odoo#149118 X-original-commit: 612d044b19072d549ba8b12eb3a9a7583adad174 Signed-off-by: William André (wan) --- addons/account/models/account_move.py | 3 +- .../account/tests/test_invoice_tax_totals.py | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 92685ed167a..51cd48f9f45 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -2151,7 +2151,8 @@ class AccountMove(models.Model): def _sync_rounding_lines(self, container): yield for invoice in container['records']: - invoice._recompute_cash_rounding_lines() + if invoice.state != 'posted': + invoice._recompute_cash_rounding_lines() @contextmanager def _sync_dynamic_line(self, existing_key_fname, needed_vals_fname, needed_dirty_fname, line_type, container): diff --git a/addons/account/tests/test_invoice_tax_totals.py b/addons/account/tests/test_invoice_tax_totals.py index db099c539be..004e96bd6c0 100644 --- a/addons/account/tests/test_invoice_tax_totals.py +++ b/addons/account/tests/test_invoice_tax_totals.py @@ -870,6 +870,41 @@ class TestTaxTotals(AccountTestInvoicingCommon): self.assertEqual(move.tax_totals['rounding_amount'], 0.3) self.assertEqual(move.tax_totals['amount_total'], 545) + def test_recompute_cash_rounding_lines(self): + # if rounding_method is changed then rounding shouldn't be recomputed in posted invoices + cash_rounding_add_invoice_line = self.env['account.cash.rounding'].create({ + 'name': 'Add invoice line Rounding UP', + 'rounding': 1, + 'strategy': 'add_invoice_line', + 'profit_account_id': self.company_data['default_account_revenue'].id, + 'loss_account_id': self.company_data['default_account_expense'].id, + 'rounding_method': 'UP', + }) + moves_rounding = {} + moves = self.env['account.move'] + for move_type in ['out_invoice', 'in_invoice']: + move = self.env['account.move'].create({ + 'move_type': move_type, + 'partner_id': self.partner_a.id, + 'invoice_date': '2019-01-01', + 'invoice_cash_rounding_id': cash_rounding_add_invoice_line.id, + 'invoice_line_ids': [ + Command.create({ + 'name': 'line', + 'display_type': 'product', + 'price_unit': 99.5, + }) + ], + }) + moves_rounding[move] = sum(move.line_ids.filtered(lambda line: line.display_type == 'rounding').mapped('balance')) + moves += move + moves.action_post() + cash_rounding_add_invoice_line.rounding_method = 'DOWN' + # check if rounding is recomputed + moves.to_check = True + for move in moves_rounding: + self.assertEqual(sum(move.line_ids.filtered(lambda line: line.display_type == 'rounding').mapped('balance')), moves_rounding[move]) + def test_cash_rounding_amount_total_rounded_foreign_currency(self): tax_15 = self.env['account.tax'].create({ 'name': "tax_15",