From fd0d8770cb71ba7367e58487278c6fb0135dc405 Mon Sep 17 00:00:00 2001 From: Jorge Pinna Puissant Date: Wed, 11 Dec 2019 10:04:41 +0000 Subject: [PATCH] [FIX] account: avoid receivable and payable accounts in sale and purchase journals When an account of type receivable or payable is used as default debit account or default credit account of a journal of type sale or purchases, an error is raised. Now, constraints are added to avoid this. opw-2151924 closes odoo/odoo#42817 X-original-commit: 0c90eb50b352ee003d52ef927260d1b9310ec69f Related: odoo/enterprise#7562 Signed-off-by: Jorge Pinna Puissant (jpp) --- addons/account/i18n/account.pot | 16 ++++++++++++ addons/account/models/account.py | 27 +++++++++++++++++++++ addons/account/tests/test_reconciliation.py | 13 ++++------ 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/addons/account/i18n/account.pot b/addons/account/i18n/account.pot index ba0010f0906..b1666894a09 100644 --- a/addons/account/i18n/account.pot +++ b/addons/account/i18n/account.pot @@ -10027,6 +10027,14 @@ msgstr "" msgid "The account %s (%s) is deprecated." msgstr "" +#. module: account +#: code:addons/account/models/account.py:0 +#, python-format +msgid "" +"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'." +msgstr "" + #. module: account #: code:addons/account/models/account_move.py:0 #, python-format @@ -10586,6 +10594,14 @@ msgstr "" msgid "The tie-breaking rule used for float rounding operations" msgstr "" +#. module: account +#: code:addons/account/models/account.py:0 +#, python-format +msgid "" +"The type of the journal's default credit/debit account shouldn't be " +"'receivable' or 'payable'." +msgstr "" + #. module: account #: model_terms:ir.ui.view,arch_db:account.portal_my_invoices msgid "There are currently no invoices and payments for your account." diff --git a/addons/account/models/account.py b/addons/account/models/account.py index 0315cb3c5a9..928c31c1267 100644 --- a/addons/account/models/account.py +++ b/addons/account/models/account.py @@ -422,6 +422,26 @@ class AccountAccount(models.Model): if self._cr.fetchone(): raise UserError(_("You can't change the company of your account since there are some journal items linked to it.")) + @api.constrains('user_type_id') + def _check_user_type_id(self): + if not self: + return + + self.flush(['user_type_id']) + self._cr.execute(''' + SELECT account.id + FROM account_account account + JOIN account_account_type acc_type ON account.user_type_id = acc_type.id + JOIN account_journal journal ON journal.default_credit_account_id = account.id OR journal.default_debit_account_id = account.id + WHERE account.id IN %s + AND acc_type.type IN ('receivable', 'payable') + AND journal.type IN ('sale', 'purchase') + LIMIT 1; + ''', [tuple(self.ids)]) + + 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.depends('code') def _compute_account_root(self): # this computes the first 2 digits of the account. @@ -1091,6 +1111,13 @@ class AccountJournal(models.Model): if self._cr.fetchone(): raise UserError(_("You can't change the company of your journal since there are some journal entries linked to it.")) + @api.constrains('type', 'default_credit_account_id', 'default_debit_account_id') + def _check_type_default_credit_account_id_type(self): + journals_to_check = self.filtered(lambda journal: journal.type in ('sale', 'purchase')) + accounts_to_check = journals_to_check.mapped('default_debit_account_id') + journals_to_check.mapped('default_credit_account_id') + if any(account.user_type_id.type in ('receivable', 'payable') for account in accounts_to_check): + raise ValidationError(_("The type of the journal's default credit/debit account shouldn't be 'receivable' or 'payable'.")) + @api.onchange('default_debit_account_id') def onchange_debit_account_id(self): if not self.default_credit_account_id: diff --git a/addons/account/tests/test_reconciliation.py b/addons/account/tests/test_reconciliation.py index e1cd2c627c9..e0959e39d97 100644 --- a/addons/account/tests/test_reconciliation.py +++ b/addons/account/tests/test_reconciliation.py @@ -483,11 +483,8 @@ class TestReconciliationExec(TestAccountReconciliationCommon): # Counterpart Credit goes in Exchange diff dest_journal_id = self.env['account.journal'].search([('type', '=', 'purchase'), ('company_id', '=', self.company.id)], limit=1) - - self.bank_journal_euro.write({'default_debit_account_id': self.account_rsa.id, - 'default_credit_account_id': self.account_rsa.id}) - dest_journal_id.write({'default_debit_account_id': self.account_rsa.id, - 'default_credit_account_id': self.account_rsa.id}) + dest_journal_id.write({'default_debit_account_id': self.bank_journal_euro.default_credit_account_id, + 'default_credit_account_id': self.bank_journal_euro.default_credit_account_id}) # Setting up rates for USD (main_company is in EUR) self.env['res.currency.rate'].create({'name': time.strftime('%Y') + '-' + '07' + '-01', 'rate': 0.5, @@ -569,9 +566,9 @@ class TestReconciliationExec(TestAccountReconciliationCommon): payment_c.post() # Assigning payments to invoices - debit_line_a = payment_a.move_line_ids.filtered(lambda l: l.debit and l.account_id == dest_journal_id.default_debit_account_id) - debit_line_b = payment_b.move_line_ids.filtered(lambda l: l.debit and l.account_id == dest_journal_id.default_debit_account_id) - debit_line_c = payment_c.move_line_ids.filtered(lambda l: l.debit and l.account_id == dest_journal_id.default_debit_account_id) + debit_line_a = payment_a.move_line_ids.filtered(lambda l: l.debit and l.account_id == self.account_rsa) + debit_line_b = payment_b.move_line_ids.filtered(lambda l: l.debit and l.account_id == self.account_rsa) + debit_line_c = payment_c.move_line_ids.filtered(lambda l: l.debit and l.account_id == self.account_rsa) invoice_a.js_assign_outstanding_line(debit_line_a.id) invoice_a.js_assign_outstanding_line(debit_line_b.id)