[IMP] account: don't calculate cash rounding if state is posted

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) <wan@odoo.com>
This commit is contained in:
Nishant Jain
2024-01-11 21:50:36 +00:00
parent e616795b08
commit 83f63df06b
2 changed files with 37 additions and 1 deletions
+2 -1
View File
@@ -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):
@@ -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",