File: test_account_merge_wizard.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 (273 lines) | stat: -rw-r--r-- 11,780 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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
from odoo import Command
from odoo.addons.account.tests.common import TestAccountMergeCommon
from odoo.tests import tagged


@tagged('post_install', '-at_install')
class TestAccountMergeWizard(TestAccountMergeCommon):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.company_data_2 = cls.setup_other_company()

        cls.company_1 = cls.company_data['company']
        cls.company_2 = cls.company_data_2['company']
        cls.accounts = cls.env['account.account']._load_records([
            {
                'xml_id': f'account.{cls.company_1.id}_test_account_1',
                'values': {
                    'name': 'My First Account',
                    'code': '100234',
                    'account_type': 'asset_receivable',
                    'company_ids': [Command.link(cls.company_1.id)],
                    'tax_ids': [Command.link(cls.company_data['default_tax_sale'].id)],
                    'tag_ids': [Command.link(cls.env.ref('account.account_tag_operating').id)],
                },
            },
            {
                'xml_id': f'account.{cls.company_1.id}_test_account_2',
                'values': {
                    'name': 'My Second Account',
                    'code': '100235',
                    'account_type': 'liability_payable',
                    'company_ids': [Command.link(cls.company_1.id)],
                    'tax_ids': [Command.link(cls.company_data['default_tax_sale'].id)],
                    'tag_ids': [Command.link(cls.env.ref('account.account_tag_operating').id)],
                },
            },
            {
                'xml_id': f'account.{cls.company_2.id}_test_account_3',
                'values': {
                    'name': 'My Third Account',
                    'code': '100236',
                    'account_type': 'asset_receivable',
                    'company_ids': [Command.link(cls.company_2.id)],
                    'tax_ids': [Command.link(cls.company_data_2['default_tax_sale'].id)],
                    'tag_ids': [Command.link(cls.env.ref('account.account_tag_investing').id)],
                },
            },
            {
                'xml_id': f'account.{cls.company_2.id}_test_account_4',
                'values': {
                    'name': 'My Fourth Account',
                    'code': '100237',
                    'account_type': 'liability_payable',
                    'company_ids': [Command.link(cls.company_2.id)],
                    'tax_ids': [Command.link(cls.company_data_2['default_tax_sale'].id)],
                    'tag_ids': [Command.link(cls.env.ref('account.account_tag_investing').id)],
                },
            }
        ])

    def _create_hashed_move(self, account, company_data):
        hashed_move = self.env['account.move'].create([
            {
                'journal_id': company_data['default_journal_sale'].id,
                'date': '2024-07-20',
                'line_ids': [
                    Command.create({
                        'account_id': account.id,
                        'balance': 10.0,
                    }),
                    Command.create({
                        'account_id': company_data['default_account_receivable'].id,
                        'balance': -10.0,
                    })
                ]
            },
        ])
        hashed_move.action_post()
        company_data['default_journal_sale'].restrict_mode_hash_table = True
        hashed_move.button_hash()

    def test_merge(self):
        """ Check that you can merge accounts. """
        # 1. Set-up various fields pointing to the accounts to merge
        referencing_records = {
            account: self._create_references_to_account(account)
            for account in self.accounts
        }

        # Also set up different names for the accounts in various languages
        self.env['res.lang']._activate_lang('fr_FR')
        self.env['res.lang']._activate_lang('nl_NL')
        self.accounts[0].with_context({'lang': 'fr_FR'}).name = "Mon premier compte"
        self.accounts[2].with_context({'lang': 'fr_FR'}).name = "Mon troisième compte"
        self.accounts[2].with_context({'lang': 'nl_NL'}).name = "Mijn derde conto"

        # 2. Check that the merge wizard groups accounts 1 and 3 together, and accounts 2 and 4 together.
        wizard = self._create_account_merge_wizard(self.accounts)
        expected_wizard_line_vals = [
            {
                'display_type': 'line_section',
                'account_id': self.accounts[0].id,
                'info': 'Trade Receivable (Reconcilable)',
            },
            {
                'display_type': 'account',
                'account_id': self.accounts[0].id,
                'info': False,
            },
            {
                'display_type': 'account',
                'account_id': self.accounts[2].id,
                'info': False,
            },
            {
                'display_type': 'line_section',
                'account_id': self.accounts[1].id,
                'info': 'Trade Payable (Reconcilable)',
            },
            {
                'display_type': 'account',
                'account_id': self.accounts[1].id,
                'info': False,
            },
            {
                'display_type': 'account',
                'account_id': self.accounts[3].id,
                'info': False,
            },
        ]

        self.assertRecordValues(wizard.wizard_line_ids, expected_wizard_line_vals)

        # 3. Perform the merge
        wizard.action_merge()

        # 4. Check that the accounts other than the ones to merge into are deleted.
        self.assertFalse(self.accounts[2:].exists())

        # 5. Check that the company_ids and codes are correctly merged.
        self.assertRecordValues(
            self.accounts[:2],
            [
                {
                    'company_ids': [self.company_1.id, self.company_2.id],
                    'name': 'My First Account',
                    'code': '100234',
                    'tax_ids': [self.company_data['default_tax_sale'].id, self.company_data_2['default_tax_sale'].id],
                    'tag_ids': [self.env.ref('account.account_tag_operating').id, self.env.ref('account.account_tag_investing').id],
                },
                {
                    'company_ids': [self.company_1.id, self.company_2.id],
                    'name': 'My Second Account',
                    'code': '100235',
                    'tax_ids': [self.company_data['default_tax_sale'].id, self.company_data_2['default_tax_sale'].id],
                    'tag_ids': [self.env.ref('account.account_tag_operating').id, self.env.ref('account.account_tag_investing').id],
                }
            ]
        )
        self.assertRecordValues(
            self.accounts[:2].with_company(self.company_2),
            [{'code': '100236'}, {'code': '100237'}]
        )

        # 6. Check that references to the accounts are merged correctly
        merged_account_by_account = {
            self.accounts[0]: self.accounts[0],
            self.accounts[1]: self.accounts[1],
            self.accounts[2]: self.accounts[0],
            self.accounts[3]: self.accounts[1],
        }
        for account, referencing_records_for_account in referencing_records.items():
            expected_account = merged_account_by_account[account]
            for referencing_record, fname in referencing_records_for_account.items():
                expected_field_value = expected_account.ids if referencing_record._fields[fname].type == 'many2many' else expected_account.id
                self.assertRecordValues(referencing_record, [{fname: expected_field_value}])

        # 7. Check that the xmlids are preserved
        self.assertEqual(self.env['account.chart.template'].ref('test_account_1'), self.accounts[0])
        self.assertEqual(self.env['account.chart.template'].ref('test_account_2'), self.accounts[1])
        self.assertEqual(self.env['account.chart.template'].with_company(self.company_2).ref('test_account_3'), self.accounts[0])
        self.assertEqual(self.env['account.chart.template'].with_company(self.company_2).ref('test_account_4'), self.accounts[1])

        # 8. Check that the name translations are merged correctly
        self.assertRecordValues(self.accounts[0].with_context({'lang': 'fr_FR'}), [{'name': "Mon premier compte"}])
        self.assertRecordValues(self.accounts[0].with_context({'lang': 'nl_NL'}), [{'name': "Mijn derde conto"}])

    def test_cannot_merge_same_company(self):
        """ Check that you cannot merge two accounts belonging to the same company. """
        self.accounts[1].account_type = 'asset_receivable'

        wizard = self._create_account_merge_wizard(self.accounts[:2])

        expected_wizard_line_vals = [
            {
                'display_type': 'line_section',
                'account_id': self.accounts[0].id,
                'info': 'Trade Receivable (Reconcilable)',
            },
            {
                'display_type': 'account',
                'account_id': self.accounts[0].id,
                'info': False,
            },
            {
                'display_type': 'account',
                'account_id': self.accounts[1].id,
                'info': "Belongs to the same company as 100234 My First Account.",
            },
        ]

        self.assertRecordValues(wizard.wizard_line_ids, expected_wizard_line_vals)

    def test_can_merge_accounts_if_one_is_hashed(self):
        """ Check that you can merge two accounts if only one is hashed, but that the hashed account's ID is preserved. """

        # 1. Create hashed move and check that the wizard has no errors
        self._create_hashed_move(self.accounts[2], self.company_data_2)
        wizard = self._create_account_merge_wizard(self.accounts[0] | self.accounts[2])

        expected_wizard_line_vals = [
            {
                'display_type': 'line_section',
                'account_id': self.accounts[0].id,
                'info': 'Trade Receivable (Reconcilable)',
            },
            {
                'display_type': 'account',
                'account_id': self.accounts[0].id,
                'info': False,
            },
            {
                'display_type': 'account',
                'account_id': self.accounts[2].id,
                'info': False,
            },
        ]

        self.assertRecordValues(wizard.wizard_line_ids, expected_wizard_line_vals)

        # 2. Perform the merge
        wizard.action_merge()

        # 3. Check that the non-hashed account is deleted.
        self.assertFalse(self.accounts[0].exists())

    def test_cannot_merge_two_hashed_accounts(self):
        """ Check that you cannot merge two accounts if both are hashed. """
        self._create_hashed_move(self.accounts[0], self.company_data)
        self._create_hashed_move(self.accounts[2], self.company_data_2)

        wizard = self._create_account_merge_wizard(self.accounts[0] | self.accounts[2])

        expected_wizard_line_vals = [
            {
                'display_type': 'line_section',
                'account_id': self.accounts[0].id,
                'info': 'Trade Receivable (Reconcilable)',
            },
            {
                'display_type': 'account',
                'account_id': self.accounts[0].id,
                'info': False,
            },
            {
                'display_type': 'account',
                'account_id': self.accounts[2].id,
                'info': "Contains hashed entries, but 100234 My First Account also has hashed entries.",
            },
        ]

        self.assertRecordValues(wizard.wizard_line_ids, expected_wizard_line_vals)