[FIX] account: Fix missing constrains about multi-companies.

There is actually nothing preventing changing the company of some records even
there is some journal entries/items that are using them.

closes odoo/odoo#41945

X-original-commit: b3b66304eb98819cd87d6e4c7a29ca4803ffc3ff
Signed-off-by: oco-odoo <oco-odoo@users.noreply.github.com>
This commit is contained in:
Laurent Smet
2019-12-16 13:34:45 +00:00
parent b4587e9553
commit e4eb845af5
8 changed files with 311 additions and 2 deletions
+30
View File
@@ -12082,3 +12082,33 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:account.view_bank_statement_form
msgid "→ Count"
msgstr ""
#. module: account
#: code:addons/account/models/account.py:0
#, python-format
msgid "You can't change the company of your account since there are some journal items linked to it."
msgstr ""
#. module: account
#: code:addons/account/models/account.py:0
#, python-format
msgid "You can't change the company of your journal since there are some journal entries linked to it."
msgstr ""
#. module: account
#: code:addons/account/models/account.py:0
#, python-format
msgid "You can't change the company of your tax since there are some journal items linked to it."
msgstr ""
#. module: account
#: code:addons/account/models/account_analytic_line.py:0
#, python-format
msgid "You can't set a different company on your analytic account since there are some journal items linked to it."
msgstr ""
#. module: account
#: code:addons/account/models/account_analytic_line.py:0
#, python-format
msgid "You can't set a different company on your analytic tags since there are some journal items linked to it."
msgstr ""
+58 -1
View File
@@ -406,6 +406,22 @@ class AccountAccount(models.Model):
if ids:
raise ValidationError(_('Some journal items already exist with this account but in other journals than the allowed ones.'))
@api.constrains('company_id')
def _check_company_consistency(self):
if not self:
return
self.flush(['company_id'])
self._cr.execute('''
SELECT line.id
FROM account_move_line line
JOIN account_account account ON account.id = line.account_id
WHERE line.account_id IN %s
AND line.company_id != account.company_id
''', [tuple(self.ids)])
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.depends('code')
def _compute_account_root(self):
# this computes the first 2 digits of the account.
@@ -1059,6 +1075,22 @@ class AccountJournal(models.Model):
if journal.bank_account_id.partner_id != journal.company_id.partner_id:
raise ValidationError(_('The holder of a journal\'s bank account must be the company (%s).') % journal.company_id.name)
@api.constrains('company_id')
def _check_company_consistency(self):
if not self:
return
self.flush(['company_id'])
self._cr.execute('''
SELECT move.id
FROM account_move move
JOIN account_journal journal ON journal.id = move.journal_id
WHERE move.journal_id IN %s
AND move.company_id != journal.company_id
''', [tuple(self.ids)])
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.onchange('default_debit_account_id')
def onchange_debit_account_id(self):
if not self.default_credit_account_id:
@@ -1541,7 +1573,32 @@ class AccountTax(models.Model):
if not tax._check_m2m_recursion('children_tax_ids'):
raise ValidationError(_("Recursion found for tax '%s'.") % (tax.name,))
if not all(child.type_tax_use in ('none', tax.type_tax_use) for child in tax.children_tax_ids):
raise ValidationError(_('The application scope of taxes in a group must be either the same as the group or left empty.'))
raise ValidationError(_('The application scope of taxes in a group must be either the same as the group or left empty.'))\
@api.constrains('company_id')
def _check_company_consistency(self):
if not self:
return
self.flush(['company_id'])
self._cr.execute('''
SELECT line.id
FROM account_move_line line
JOIN account_tax tax ON tax.id = line.tax_line_id
WHERE line.tax_line_id IN %s
AND line.company_id != tax.company_id
UNION ALL
SELECT line.id
FROM account_move_line_account_tax_rel tax_rel
JOIN account_tax tax ON tax.id = tax_rel.account_tax_id
JOIN account_move_line line ON line.id = tax_rel.account_move_line_id
WHERE tax_rel.account_tax_id IN %s
AND line.company_id != tax.company_id
''', [tuple(self.ids)] * 2)
if self._cr.fetchone():
raise UserError(_("You can't change the company of your tax since there are some journal items linked to it."))
@api.returns('self', lambda value: value.id)
def copy(self, default=None):
+48 -1
View File
@@ -1,7 +1,54 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
from math import copysign
from odoo.exceptions import UserError
class AccountAnalyticAccount(models.Model):
_inherit = 'account.analytic.account'
@api.constrains('company_id')
def _check_company_consistency(self):
analytic_accounts = self.filtered('company_id')
if not analytic_accounts:
return
self.flush(['company_id'])
self._cr.execute('''
SELECT line.id
FROM account_move_line line
JOIN account_analytic_account account ON account.id = line.analytic_account_id
WHERE line.analytic_account_id IN %s
AND line.company_id != account.company_id
''', [tuple(analytic_accounts.ids)])
if self._cr.fetchone():
raise UserError(_("You can't set a different company on your analytic account since there are some journal items linked to it."))
class AccountAnalyticTag(models.Model):
_inherit = 'account.analytic.tag'
@api.constrains('company_id')
def _check_company_consistency(self):
analytic_tags = self.filtered('company_id')
if not analytic_tags:
return
self.flush(['company_id'])
self._cr.execute('''
SELECT line.id
FROM account_analytic_tag_account_move_line_rel tag_rel
JOIN account_analytic_tag tag ON tag.id = tag_rel.account_analytic_tag_id
JOIN account_move_line line ON line.id = tag_rel.account_move_line_id
WHERE tag_rel.account_analytic_tag_id IN %s
AND line.company_id != tag.company_id
''', [tuple(analytic_tags.ids)])
if self._cr.fetchone():
raise UserError(_("You can't set a different company on your analytic tags since there are some journal items linked to it."))
class AccountAnalyticLine(models.Model):
+4
View File
@@ -5,6 +5,10 @@ from . import test_account_move_out_refund
from . import test_account_move_in_invoice
from . import test_account_move_in_refund
from . import test_account_move_entry
from . import test_account_journal
from . import test_account_account
from . import test_account_tax
from . import test_account_analytic
from . import test_account_payment
from . import test_account_move_partner_count
from . import test_account_move_rounding
@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
from odoo.tests import tagged
from odoo.exceptions import UserError
@tagged('post_install', '-at_install')
class TestAccountAccount(AccountTestInvoicingCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
# Create another company.
cls.company_data_2 = cls.setup_company_data('company_2_data')
# By default, tests are run with the current user set on the first company.
cls.env.user.company_id = cls.company_data['company']
def test_changing_account_company(self):
''' Ensure you can't change the company of an account.account if there are some journal entries '''
self.env['account.move'].create({
'type': 'entry',
'date': '2019-01-01',
'line_ids': [
(0, 0, {
'name': 'line_debit',
'account_id': self.company_data['default_account_revenue'].id,
}),
(0, 0, {
'name': 'line_credit',
'account_id': self.company_data['default_account_revenue'].id,
}),
],
})
with self.assertRaises(UserError), self.cr.savepoint():
self.company_data['default_account_revenue'].company_id = self.company_data_2['company']
@@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
from odoo.tests import tagged
from odoo.exceptions import UserError
@tagged('post_install', '-at_install')
class TestAccountAnalyticAccount(AccountTestInvoicingCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env.user.write({
'groups_id': [
(4, cls.env.ref('analytic.group_analytic_accounting').id),
(4, cls.env.ref('analytic.group_analytic_tags').id),
],
})
# Create another company.
cls.company_data_2 = cls.setup_company_data('company_2_data')
# By default, tests are run with the current user set on the first company.
cls.env.user.company_id = cls.company_data['company']
cls.test_analytic_account = cls.env['account.analytic.account'].create({'name': 'test_analytic_account'})
cls.test_analytic_tag = cls.env['account.analytic.tag'].create({'name': 'test_analytic_tag'})
def test_changing_analytic_company(self):
''' Ensure you can't change the company of an account.analytic.account if there are some journal entries '''
self.env['account.move'].create({
'type': 'entry',
'date': '2019-01-01',
'line_ids': [
(0, 0, {
'name': 'line_debit',
'account_id': self.company_data['default_account_revenue'].id,
'analytic_account_id': self.test_analytic_account.id,
'analytic_tag_ids': [(6, 0, self.test_analytic_tag.ids)],
}),
(0, 0, {
'name': 'line_credit',
'account_id': self.company_data['default_account_revenue'].id,
}),
],
})
# Set a different company on the analytic account.
with self.assertRaises(UserError), self.cr.savepoint():
self.test_analytic_account.company_id = self.company_data_2['company']
# Making the analytic account not company dependent is allowed.
self.test_analytic_account.company_id = False
# Set a different company on the analytic tag.
with self.assertRaises(UserError), self.cr.savepoint():
self.test_analytic_tag.company_id = self.company_data_2['company']
# Making the analytic tag not company dependent is allowed.
self.test_analytic_tag.company_id = False
@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
from odoo.tests import tagged
from odoo.exceptions import UserError
@tagged('post_install', '-at_install')
class TestAccountJournal(AccountTestInvoicingCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
# Create another company.
cls.company_data_2 = cls.setup_company_data('company_2_data')
# By default, tests are run with the current user set on the first company.
cls.env.user.company_id = cls.company_data['company']
def test_changing_journal_company(self):
''' Ensure you can't change the company of an account.journal if there are some journal entries '''
self.env['account.move'].create({
'type': 'entry',
'date': '2019-01-01',
'journal_id': self.company_data['default_journal_sale'].id,
})
with self.assertRaises(UserError), self.cr.savepoint():
self.company_data['default_journal_sale'].company_id = self.company_data_2['company']
+40
View File
@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
from odoo.tests import tagged
from odoo.exceptions import UserError
@tagged('post_install', '-at_install')
class TestAccountTax(AccountTestInvoicingCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
# Create another company.
cls.company_data_2 = cls.setup_company_data('company_2_data')
# By default, tests are run with the current user set on the first company.
cls.env.user.company_id = cls.company_data['company']
def test_changing_tax_company(self):
''' Ensure you can't change the company of an account.tax if there are some journal entries '''
# Avoid duplicate key value violates unique constraint "account_tax_name_company_uniq".
self.company_data['default_tax_sale'].name = 'test_changing_account_company'
self.env['account.move'].create({
'type': 'out_invoice',
'date': '2019-01-01',
'invoice_line_ids': [
(0, 0, {
'name': 'invoice_line',
'quantity': 1.0,
'price_unit': 100.0,
'tax_ids': [(6, 0, self.company_data['default_tax_sale'].ids)],
}),
],
})
with self.assertRaises(UserError), self.cr.savepoint():
self.company_data['default_tax_sale'].company_id = self.company_data_2['company']