diff --git a/addons/analytic/models/analytic_plan.py b/addons/analytic/models/analytic_plan.py index 803626bf7c3..fc482c0e0af 100644 --- a/addons/analytic/models/analytic_plan.py +++ b/addons/analytic/models/analytic_plan.py @@ -147,15 +147,27 @@ class AccountAnalyticPlan(models.Model): @api.depends('account_ids', 'children_ids') def _compute_all_analytic_account_count(self): + # Get all children_ids from each plan + self.env.cr.execute(""" + SELECT parent.id, + array_agg(child.id) as children_ids + FROM account_analytic_plan parent + JOIN account_analytic_plan child ON child.parent_path LIKE parent.parent_path || '%%' + WHERE parent.id IN %s + GROUP BY parent.id + """, [tuple(self.ids)]) + all_children_ids = dict(self.env.cr.fetchall()) + plans_count = dict( self.env['account.analytic.account']._read_group( - domain=[('root_plan_id', 'in', self.ids)], + domain=[('plan_id', 'child_of', self.ids)], aggregates=['id:count'], - groupby=['root_plan_id'] + groupby=['plan_id'] ) ) + plans_count = {k.id: v for k, v in plans_count.items()} for plan in self: - plan.all_account_count = plans_count.get(plan, 0) + plan.all_account_count = sum(plans_count.get(child_id, 0) for child_id in all_children_ids.get(plan.id, [])) @api.depends('children_ids') def _compute_children_count(self): diff --git a/addons/analytic/tests/test_analytic_account.py b/addons/analytic/tests/test_analytic_account.py index c599dbfcada..ee2bb581e0e 100644 --- a/addons/analytic/tests/test_analytic_account.py +++ b/addons/analytic/tests/test_analytic_account.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from odoo.tests import tagged -from odoo.tests.common import TransactionCase +from odoo.tests.common import Form, TransactionCase from odoo import Command @@ -186,3 +186,28 @@ class TestAnalyticAccount(TransactionCase): plans_json = self.env['account.analytic.plan'].get_relevant_plans() self.assertEqual(2, len(plans_json) - self.analytic_plan_offset, "The parent plan should be available even if the analytic account is set on child of third generation") + + def test_all_account_count_with_subplans(self): + self.analytic_plan = self.env['account.analytic.plan'].create({ + 'name': 'Parent Plan', + }) + self.analytic_sub_plan = self.env['account.analytic.plan'].create({ + 'name': 'Sub Plan', + 'parent_id': self.analytic_plan.id, + }) + self.analytic_sub_sub_plan = self.env['account.analytic.plan'].create({ + 'name': 'Sub Sub Plan', + 'parent_id': self.analytic_sub_plan.id, + }) + + self.env['account.analytic.account'].create([ + {'name': 'Account', 'plan_id': self.analytic_plan.id}, + {'name': 'Child Account', 'plan_id': self.analytic_sub_plan.id}, + {'name': 'Grand Child Account', 'plan_id': self.analytic_sub_sub_plan.id} + ]) + + expected_values = {self.analytic_plan: 3, self.analytic_sub_plan: 2, self.analytic_sub_sub_plan: 1} + for plan, expected_value in expected_values.items(): + with self.subTest(plan=plan.name, expected_count=expected_value): + with Form(plan) as plan_form: + self.assertEqual(plan_form.record.all_account_count, expected_value)