[FIX] account: right accounts in account group

Steps to reproduce:

- Create an account group for a range for example from 100000 to 200000
- Now edit the group to have a range from 100000 to 150000

Issue:

The accounts with code > 150000 are still in the account group

Solution

Adding an other intermediary table to the query in order to take into
account the accounts which have no group_id

opw-2695533

closes odoo/odoo#82023

X-original-commit: 05c3cb8dbb7a9bf0f438d5ee687b92e8d934f26b
Signed-off-by: Laurent Smet <las@odoo.com>
Signed-off-by: Guillaume Vanleynseele <guva@odoo.com>
This commit is contained in:
Guillaume (guva)
2021-12-29 14:24:14 +00:00
parent d20c0044e9
commit 5f721aab73
2 changed files with 44 additions and 18 deletions
+26 -18
View File
@@ -702,29 +702,37 @@ class AccountGroup(models.Model):
The most specific is the one with the longest prefixes and with the starting
prefix being smaller than the account code and the ending prefix being greater.
"""
if not self and not account_ids:
company_ids = account_ids.company_id.ids if account_ids else self.company_id.ids
account_ids = account_ids.ids if account_ids else []
if not company_ids and not account_ids:
return
self.env['account.group'].flush(self.env['account.group']._fields)
self.env['account.account'].flush(self.env['account.account']._fields)
query = """
WITH relation AS (
SELECT DISTINCT FIRST_VALUE(agroup.id) OVER (PARTITION BY account.id ORDER BY char_length(agroup.code_prefix_start) DESC, agroup.id) AS group_id,
account.id AS account_id
FROM account_group agroup
JOIN account_account account
account_where_clause = ''
where_params = [tuple(company_ids)]
if account_ids:
account_where_clause = 'AND account.id IN %s'
where_params.append(tuple(account_ids))
self._cr.execute(f'''
WITH candidates_account_groups AS (
SELECT
account.id AS account_id,
ARRAY_AGG(agroup.id ORDER BY char_length(agroup.code_prefix_start) DESC, agroup.id) AS group_ids
FROM account_account account
LEFT JOIN account_group agroup
ON agroup.code_prefix_start <= LEFT(account.code, char_length(agroup.code_prefix_start))
AND agroup.code_prefix_end >= LEFT(account.code, char_length(agroup.code_prefix_end))
AND agroup.company_id = account.company_id
WHERE account.company_id IN %(company_ids)s {where_account}
AND agroup.code_prefix_end >= LEFT(account.code, char_length(agroup.code_prefix_end))
AND agroup.company_id = account.company_id
WHERE account.company_id IN %s {account_where_clause}
GROUP BY account.id
)
UPDATE account_account account
SET group_id = relation.group_id
FROM relation
WHERE relation.account_id = account.id;
""".format(
where_account=account_ids and 'AND account.id IN %(account_ids)s' or ''
)
self.env.cr.execute(query, {'company_ids': tuple((self.company_id or account_ids.company_id).ids), 'account_ids': account_ids and tuple(account_ids.ids)})
UPDATE account_account
SET group_id = rel.group_ids[1]
FROM candidates_account_groups rel
WHERE account_account.id = rel.account_id
''', where_params)
self.env['account.account'].invalidate_cache(fnames=['group_id'])
def _adapt_parent_account_group(self):
@@ -135,3 +135,21 @@ class TestAccountAccount(AccountTestInvoicingCommon):
self.company_data['default_journal_bank'].company_id.account_journal_payment_debit_account_id.reconcile = False
with self.assertRaises(ValidationError), self.cr.savepoint():
self.company_data['default_journal_bank'].company_id.account_journal_payment_credit_account_id.reconcile = False
def test_remove_account_from_account_group(self):
"""Test if an account is well removed from account group"""
group = self.env['account.group'].create({
'name': 'test_group',
'code_prefix_start': 401000,
'code_prefix_end': 402000,
'company_id': self.env.company.id
})
account_1 = self.company_data['default_account_revenue'].copy({'code': 401000})
account_2 = self.company_data['default_account_revenue'].copy({'code': 402000})
self.assertRecordValues(account_1 + account_2, [{'group_id': group.id}] * 2)
group.code_prefix_end = 401000
self.assertRecordValues(account_1 + account_2, [{'group_id': group.id}, {'group_id': False}])