From b01bfb0ab9f2370e0905edbe356e21d4b5e460e4 Mon Sep 17 00:00:00 2001 From: hupo-odoo Date: Mon, 24 Apr 2023 14:05:42 +0000 Subject: [PATCH] [FIX] account: cash rounding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the cash rounding displayed on accounting documents such as customer invoices, credit notes, vendor bills and vendor refunds. The amount that was computed was incorrect in most case. The only case that was working was the customer invoice when using the company currency. The PR address the issue of cash rounding for all account move type and when using foreign currencies as well. Steps to Reproduce - Activate Cash Roundings. - Create a half-up cash rounding with a precision of 1. - Create a new bill with a pre-tax amount of 378 and a tax rate of 15% - Apply the cash rounding to the bill and save. - Review the "Total Rounded" value. Expected Results: The 'Total Rounded' value should be 435.00 Actual Results: The displayed 'Total Rounded' value is 434.40 opw-3235723 opw-3236011 opw-3277942 opw-3271713 task-3257577 closes odoo/odoo#121828 X-original-commit: 80d0dae161f9147d6675e2464310c491a5bd3727 Signed-off-by: hupo-odoo Signed-off-by: William André (wan) Co-authored-by: Nshimiyimana Serge Séna --- addons/account/models/account_move.py | 7 ++- .../account/tests/test_invoice_tax_totals.py | 58 +++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 4f4fef6ab2e..c1d98380c35 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -1194,11 +1194,10 @@ class AccountMove(models.Model): if move.is_invoice(include_receipts=True): base_lines = move.invoice_line_ids.filtered(lambda line: line.display_type == 'product') base_line_values_list = [line._convert_to_tax_base_line_dict() for line in base_lines] - + sign = move.direction_sign if move.id: # The invoice is stored so we can add the early payment discount lines directly to reduce the # tax amount without touching the untaxed amount. - sign = -1 if move.is_inbound(include_receipts=True) else 1 base_line_values_list += [ { **line._convert_to_tax_base_line_dict(), @@ -1252,7 +1251,8 @@ class AccountMove(models.Model): move.tax_totals = self.env['account.tax']._prepare_tax_totals(**kwargs) rounding_line = move.line_ids.filtered(lambda l: l.display_type == 'rounding') if rounding_line: - amount_total_rounded = move.tax_totals['amount_total'] - rounding_line.balance + amount_total_rounded = move.tax_totals['amount_total'] + sign * rounding_line.amount_currency + move.tax_totals['amount_total_rounded'] = amount_total_rounded move.tax_totals['formatted_amount_total_rounded'] = formatLang(self.env, amount_total_rounded, currency_obj=move.currency_id) or '' else: # Non-invoice moves don't support that field (because of multicurrency: all lines of the invoice share the same currency) @@ -1912,6 +1912,7 @@ class AccountMove(models.Model): ''' rounding_line_vals = { 'balance': diff_balance, + 'amount_currency': diff_amount_currency, 'partner_id': self.partner_id.id, 'move_id': self.id, 'currency_id': self.currency_id.id, diff --git a/addons/account/tests/test_invoice_tax_totals.py b/addons/account/tests/test_invoice_tax_totals.py index 8584151abff..ad2f268d72f 100644 --- a/addons/account/tests/test_invoice_tax_totals.py +++ b/addons/account/tests/test_invoice_tax_totals.py @@ -809,3 +809,61 @@ class TestTaxTotals(AccountTestInvoicingCommon): ], 'subtotals_order': ["Untaxed Amount"], }) + + def test_cash_rounding_amount_total_rounded(self): + tax_15 = self.env['account.tax'].create({ + 'name': "tax_15", + 'amount_type': 'percent', + 'amount': 15.0, + }) + cash_rounding = self.env['account.cash.rounding'].create({ + 'name': 'Rounding HALF-UP', + 'rounding': 1, + 'strategy': 'biggest_tax', + 'rounding_method': 'HALF-UP', + }) + + invoice = self.init_invoice('out_invoice', amounts=[378], taxes=tax_15) + invoice.invoice_cash_rounding_id = cash_rounding + self.assertEqual(invoice.tax_totals['amount_total_rounded'], 435) + + bill = self.init_invoice('in_invoice', amounts=[378], taxes=tax_15) + bill.invoice_cash_rounding_id = cash_rounding + self.assertEqual(bill.tax_totals['amount_total_rounded'], 435) + + def test_cash_rounding_amount_total_rounded_foreign_currency(self): + tax_15 = self.env['account.tax'].create({ + 'name': "tax_15", + 'amount_type': 'percent', + 'amount': 15.0, + }) + cash_rounding = self.env['account.cash.rounding'].create({ + 'name': 'Rounding HALF-UP', + 'rounding': 10, + 'strategy': 'biggest_tax', + 'rounding_method': 'HALF-UP', + }) + self.env['res.currency.rate'].create({ + 'name': '2023-01-01', + 'rate': 0.2, + 'currency_id': self.currency_data['currency'].id, + 'company_id': self.env.company.id, + }) + 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': '2023-01-01', + 'currency_id': self.currency_data['currency'].id, + 'invoice_line_ids': [ + Command.create({ + 'name': 'line', + 'display_type': 'product', + 'price_unit': 100, + 'tax_ids': [tax_15.id], + }) + ] + }) + move.invoice_cash_rounding_id = cash_rounding + self.assertEqual(move.tax_totals['amount_total'], 115) + self.assertEqual(move.tax_totals['amount_total_rounded'], 120)