File: test_analytic_account.py

package info (click to toggle)
odoo 18.0.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 878,716 kB
  • sloc: javascript: 927,937; python: 685,670; xml: 388,524; sh: 1,033; sql: 415; makefile: 26
file content (212 lines) | stat: -rw-r--r-- 11,095 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# -*- coding: utf-8 -*-

from odoo.tests import Form, tagged
from odoo import Command

from odoo.addons.analytic.tests.common import AnalyticCommon


@tagged('post_install', '-at_install')
class TestAnalyticAccount(AnalyticCommon):

    @classmethod
    def setUpClass(cls):
        super().setUpClass()

        cls.partner_a = cls.env['res.partner'].create({'name': 'partner_a', 'company_id': False})
        cls.partner_b = cls.env['res.partner'].create({'name': 'partner_b', 'company_id': False})

        cls.distribution_1, cls.distribution_2 = cls.env['account.analytic.distribution.model'].create([
            {
                'partner_id': cls.partner_a.id,
                'analytic_distribution': {cls.analytic_account_3.id: 100}
            },
            {
                'partner_id': cls.partner_b.id,
                'analytic_distribution': {cls.analytic_account_2.id: 100}
            },
        ])
        cls.company_b_branch = cls.env['res.company'].create({'name': "B Branch", 'parent_id': cls.company.id})

    def test_aggregates(self):
        # debit and credit are hidden by the group when account is installed
        fields_to_agg = ['balance', 'debit', 'credit'] if self.env.user.has_group('account.group_account_readonly') else ['balance']
        model = self.env['account.analytic.account']
        self.assertEqual(
            model.fields_get(fields_to_agg, ['aggregator']),
            dict.fromkeys(fields_to_agg, {'aggregator': 'sum'}),
            f"Fields {', '.join(f for f in fields_to_agg)} must be flagged as aggregatable.",
        )

    def test_get_plans_without_options(self):
        """ Test that the plans with the good appliability are returned without if no options are given """
        kwargs = {}
        plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
        self.assertEqual(1, len(plans_json) - self.analytic_plan_offset, "Only the Default plan and the demo data plans should be available")

        self.analytic_plan_1.write({'default_applicability': 'mandatory'})
        plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
        self.assertEqual(2, len(plans_json) - self.analytic_plan_offset, "All root plans should be available")

    def test_get_plans_with_option(self):
        """ Test the plans returned with applicability rules and options """
        kwargs = {'business_domain': 'general'}
        plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
        self.assertEqual(1, len(plans_json) - self.analytic_plan_offset, "Only the Default plan and the demo data plans should be available")

        applicability = self.env['account.analytic.applicability'].create({
            'business_domain': 'general',
            'analytic_plan_id': self.analytic_plan_1.id,
            'applicability': 'mandatory'
        })
        plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
        self.assertEqual(2, len(plans_json) - self.analytic_plan_offset, "All root plans should be available")

        self.analytic_plan_1.write({'default_applicability': 'mandatory'})
        applicability.write({'applicability': 'unavailable'})
        plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
        self.assertEqual(1, len(plans_json) - self.analytic_plan_offset, "Plan 1 should be unavailable")

        kwargs = {'business_domain': 'purchase_order'}
        plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
        self.assertEqual(2, len(plans_json) - self.analytic_plan_offset, "Both plans should be available")

        kwargs = {'applicability': 'optional'}
        plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
        self.assertEqual(2, len(plans_json) - self.analytic_plan_offset, "All root plans should be available")

    def test_analytic_distribution_model(self):
        """ Test the distribution returned from the distribution model """
        distribution_json = self.env['account.analytic.distribution.model']._get_distribution({})
        self.assertEqual(distribution_json, {}, "No distribution should be given")
        distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
            "partner_id": self.partner_a.id,
            "company_id": self.company.id,
        })
        self.assertEqual(distribution_json, {str(self.analytic_account_3.id): 100}, "Distribution 1 should be given")
        distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
            "partner_id": self.partner_b.id,
            "company_id": self.company.id,
        })
        self.assertEqual(distribution_json, {str(self.analytic_account_2.id): 100}, "Distribution 2 should be given")

    def test_order_analytic_distribution_model(self):
        """ Test the distribution returned with company field"""
        distribution_3 = self.env['account.analytic.distribution.model'].create({
            'partner_id': self.partner_a.id,
            'analytic_distribution': {self.analytic_account_1.id: 100},
            'company_id': self.company.id,
        })
        distribution_json = self.env['account.analytic.distribution.model']._get_distribution({})
        self.assertEqual(distribution_json, {}, "No distribution should be given")

        distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
            "partner_id": self.partner_a.id,
            "company_id": self.company.id,
        })
        self.assertEqual(distribution_json, distribution_3.analytic_distribution | self.distribution_1.analytic_distribution,
                         "Distribution 3 & 1 should be given, as the company and partner are specified in the models")

        distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
            "partner_id": self.partner_b.id,
            "company_id": self.company.id,
        })
        self.assertEqual(distribution_json, {str(self.analytic_account_2.id): 100},
                         "Distribution 2 should be given, for the partner")

        partner_category = self.env['res.partner.category'].create({'name': 'partner_categ'})
        self.partner_a.write({
            'category_id': [Command.set([partner_category.id])]
        })

        distribution_4 = self.env['account.analytic.distribution.model'].create({
            'partner_id': self.partner_a.id,
            'analytic_distribution': {self.analytic_account_1.id: 100, self.analytic_account_2.id: 100},
            'partner_category_id': partner_category.id,
            'sequence': 1,
        })

        distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
            "partner_id": self.partner_a.id,
            "company_id": self.company.id,
            "partner_category_id": partner_category.ids,
        })

        self.assertEqual(distribution_json, distribution_4.analytic_distribution | self.distribution_1.analytic_distribution,
                         "Distribution 4 & 1 should be given based on sequence")

    def test_analytic_plan_account_child(self):
        """
        Check that when an analytic account is set to the third (or more) child,
        the root plan is correctly retrieved.
        """
        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})
        self.env['account.analytic.account'].create({'name': 'Child Account', 'plan_id': self.analytic_sub_plan.id})
        self.env['account.analytic.account'].create({'name': 'Grand Child Account', 'plan_id': self.analytic_sub_sub_plan.id})
        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)

    def test_create_analytic_with_minimal_access(self):
        analyst_partner = self.env['res.partner'].create({'name': 'analyst'})
        analyst = self.env['res.users'].create({
            'login': 'analyst',
            'groups_id': [Command.set(self.env.ref('analytic.group_analytic_accounting').ids)],
            'partner_id': analyst_partner.id
        })
        plan = self.env['account.analytic.plan'].with_user(analyst).create({'name': 'test plan'})
        self.assertEqual(plan.create_uid, analyst)

    def test_analytic_account_branches(self):
        """
        Test that an analytic account defined in a parent company is accessible in its branches (children)
        """
        # timesheet adds a rule to forcer a project_id; account overrides it
        timesheet_user = self.env.ref('hr_timesheet.group_hr_timesheet_user', raise_if_not_found=False)
        account_user = self.env.ref('account.analytic.model_account_analytic_line', raise_if_not_found=False)
        if timesheet_user and not account_user:
            self.skipTest("`hr_timesheet` overrides analytic rights. Without `account` the test would crash")

        self.analytic_account_1.company_id = self.company
        self.env['account.analytic.line'].create({
            'name': 'company specific account',
            'account_id': self.analytic_account_1.id,
            'amount': 100,
            'company_id': self.company_b_branch.id,
        })