diff --git a/addons/account/i18n/account.pot b/addons/account/i18n/account.pot index 73c99b50d46..4ed3ca33460 100644 --- a/addons/account/i18n/account.pot +++ b/addons/account/i18n/account.pot @@ -11584,6 +11584,14 @@ msgstr "" msgid "The account %s (%s) is deprecated." msgstr "" +#. module: account +#: code:addons/account/models/account_account.py:0 +#, python-format +msgid "" +"This account is configured in %(journal_names)s journal(s) (ids %(journal_ids)s) as payment debit or credit account. " +"This means that this account's type should be reconcilable." +msgstr "" + #. module: account #: code:addons/account/models/account_account.py:0 #, python-format diff --git a/addons/account/models/account_account.py b/addons/account/models/account_account.py index 9a0c3a9d1c0..e722472bbe5 100644 --- a/addons/account/models/account_account.py +++ b/addons/account/models/account_account.py @@ -188,6 +188,32 @@ class AccountAccount(models.Model): if self._cr.fetchone(): raise ValidationError(_("The account is already in use in a 'sale' or 'purchase' journal. This means that the account's type couldn't be 'receivable' or 'payable'.")) + @api.constrains('reconcile') + def _check_used_as_journal_default_debit_credit_account(self): + accounts = self.filtered(lambda a: not a.reconcile) + if not accounts: + return + + self.flush(['reconcile']) + self._cr.execute(''' + SELECT journal.id + FROM account_journal journal + WHERE journal.payment_credit_account_id in %(credit_account)s + OR journal.payment_debit_account_id in %(debit_account)s ; + ''', { + 'credit_account': tuple(accounts.ids), + 'debit_account': tuple(accounts.ids) + }) + + rows = self._cr.fetchall() + if rows: + journals = self.env['account.journal'].browse([r[0] for r in rows]) + raise ValidationError(_( + "This account is configured in %(journal_names)s journal(s) (ids %(journal_ids)s) as payment debit or credit account. This means that this account's type should be reconcilable.", + journal_names=journals.mapped('display_name'), + journal_ids=journals.ids + )) + @api.depends('code') def _compute_account_root(self): # this computes the first 2 digits of the account. diff --git a/addons/account/tests/test_account_account.py b/addons/account/tests/test_account_account.py index 8b7b22bc74f..cded3517c55 100644 --- a/addons/account/tests/test_account_account.py +++ b/addons/account/tests/test_account_account.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from odoo.addons.account.tests.common import AccountTestInvoicingCommon from odoo.tests import tagged -from odoo.exceptions import UserError +from odoo.exceptions import UserError, ValidationError @tagged('post_install', '-at_install') @@ -126,3 +126,12 @@ class TestAccountAccount(AccountTestInvoicingCommon): # Try to set the account as a not-reconcile one. with self.assertRaises(UserError), self.cr.savepoint(): account.reconcile = False + + def test_toggle_reconcile_outstanding_account(self): + ''' Test the feature when the user sets an account as not reconcilable when a journal + is configured with this account as the payment credit or debit account. + Since such an account should be reconcilable by nature, a ValidationError is raised.''' + with self.assertRaises(ValidationError), self.cr.savepoint(): + self.company_data['default_journal_bank'].payment_debit_account_id.reconcile = False + with self.assertRaises(ValidationError), self.cr.savepoint(): + self.company_data['default_journal_bank'].payment_credit_account_id.reconcile = False diff --git a/addons/account/views/account_payment_view.xml b/addons/account/views/account_payment_view.xml index 07e25604a11..5d6f92a4de0 100644 --- a/addons/account/views/account_payment_view.xml +++ b/addons/account/views/account_payment_view.xml @@ -173,6 +173,7 @@ +