From 9f5578289aa4287fc7719d4ed6b8550cb5ecfa27 Mon Sep 17 00:00:00 2001 From: arsi Date: Tue, 7 Mar 2023 13:20:20 +0000 Subject: [PATCH] [FIX] account: compute bills to pay sum based on amount_residual_signed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case the journal currency is set on the company currency, we should compute the 'Bills to Pay' sum on amount_residual_signed as it is the residual amount in the company currency. In the current state, you can have differences between the sum in the dashboard and the sum showed in the list view from the 'Bills To Pay' button. Steps to reproduce (clean db with accounting): -Set a foreign currency with 2 different rates (significant if you want to see the issue clearly). -Create an invoice in a sale/purchase journal which has no currency set (like Vendor Bills), with the foreign currency and with an invoice_date corresponding to one of the rate. -Register a payment for that invoice, with a date corresponding to the other rate and having an amount lower (like half) than the invoice, so the invoice is partially reconciled. -> Go to the accounting dashboard, the amount next to 'Bills to Pay' is different than the amount (the sum of the column 'Amount Due') in the list view generated after clicking that button. These two values should be the same. They are currently different because the dashboard takes the amount_residual, which is expressed in the invoice currency, and apply the exchange rate to get the residual in the journal currency. But if the target currency is the company currency, the field amount_residual_signed is already the residual amount in the company currency. Unfortunately, in case of partial reconciliation, it is not always equal to amount_residual expressed in the company currency anymore. Because amount_residual and amount_residual_signed are substracted by the payment amount, expressed in each currency, using the payment date exchange rate. opw-3184567 closes odoo/odoo#125150 X-original-commit: d71d8e90667ccc9c5428cc15b927747b4b3556cd Signed-off-by: William André (wan) Signed-off-by: Arnaud-Sibille (arsi) --- .../models/account_journal_dashboard.py | 2 +- .../tests/test_account_journal_dashboard.py | 69 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/addons/account/models/account_journal_dashboard.py b/addons/account/models/account_journal_dashboard.py index f8057d064e3..792655f8e9d 100644 --- a/addons/account/models/account_journal_dashboard.py +++ b/addons/account/models/account_journal_dashboard.py @@ -404,7 +404,7 @@ class account_journal(models.Model): field_list = [ "account_move.journal_id", "(CASE WHEN account_move.move_type IN ('out_refund', 'in_refund') THEN -1 ELSE 1 END) * account_move.amount_residual AS amount_total", - "account_move.amount_residual_signed AS amount_total_company", + "(CASE WHEN account_move.move_type IN ('in_invoice', 'in_refund', 'in_receipt') THEN -1 ELSE 1 END) * account_move.amount_residual_signed AS amount_total_company", "account_move.currency_id AS currency", "account_move.move_type", "account_move.invoice_date", diff --git a/addons/account/tests/test_account_journal_dashboard.py b/addons/account/tests/test_account_journal_dashboard.py index 138389ac51b..e23d9fc6460 100644 --- a/addons/account/tests/test_account_journal_dashboard.py +++ b/addons/account/tests/test_account_journal_dashboard.py @@ -3,6 +3,7 @@ from freezegun import freeze_time from odoo.addons.account.tests.common import AccountTestInvoicingCommon from odoo.tests import tagged +from odoo.tools.misc import format_amount @tagged('post_install', '-at_install') class TestAccountJournalDashboard(AccountTestInvoicingCommon): @@ -93,3 +94,71 @@ class TestAccountJournalDashboard(AccountTestInvoicingCommon): dashboard_data = journal.get_journal_dashboard_datas() self.assertEqual(dashboard_data['number_late'], 2) self.assertIn('78.42', dashboard_data['sum_late']) + + def test_sale_purchase_journal_for_multi_currency_purchase(self): + currency = self.currency_data['currency'] + company_currency = self.company_data['currency'] + + invoice = self.env['account.move'].create({ + 'move_type': 'in_invoice', + 'invoice_date': '2017-01-01', + 'date': '2017-01-01', + 'partner_id': self.partner_a.id, + 'currency_id': currency.id, + 'invoice_line_ids': [ + (0, 0, {'name': 'test', 'price_unit': 200}) + ], + }) + invoice.action_post() + + payment = self.env['account.payment'].create({ + 'amount': 90.0, + 'date': '2016-01-01', + 'payment_type': 'outbound', + 'partner_type': 'supplier', + 'partner_id': self.partner_a.id, + 'currency_id': currency.id, + }) + payment.action_post() + + (invoice + payment.move_id).line_ids.filtered_domain([ + ('account_id', '=', self.company_data['default_account_payable'].id) + ]).reconcile() + + dashboard_data = self.company_data['default_journal_purchase'].get_journal_dashboard_datas() + self.assertEqual(format_amount(self.env, 55, company_currency), dashboard_data['sum_waiting']) + self.assertEqual(format_amount(self.env, 55, company_currency), dashboard_data['sum_late']) + + def test_sale_purchase_journal_for_multi_currency_sale(self): + currency = self.currency_data['currency'] + company_currency = self.company_data['currency'] + + invoice = self.env['account.move'].create({ + 'move_type': 'out_invoice', + 'invoice_date': '2017-01-01', + 'date': '2017-01-01', + 'partner_id': self.partner_a.id, + 'currency_id': currency.id, + 'invoice_line_ids': [ + (0, 0, {'name': 'test', 'price_unit': 200}) + ], + }) + invoice.action_post() + + payment = self.env['account.payment'].create({ + 'amount': 90.0, + 'date': '2016-01-01', + 'payment_type': 'inbound', + 'partner_type': 'customer', + 'partner_id': self.partner_a.id, + 'currency_id': currency.id, + }) + payment.action_post() + + (invoice + payment.move_id).line_ids.filtered_domain([ + ('account_id', '=', self.company_data['default_account_receivable'].id) + ]).reconcile() + + dashboard_data = self.company_data['default_journal_sale'].get_journal_dashboard_datas() + self.assertEqual(format_amount(self.env, 55, company_currency), dashboard_data['sum_waiting']) + self.assertEqual(format_amount(self.env, 55, company_currency), dashboard_data['sum_late'])