From 8a455d851900bde9c3a1fce16fb201ca3617dd83 Mon Sep 17 00:00:00 2001 From: aliya Date: Tue, 21 Jun 2022 12:57:49 +0000 Subject: [PATCH] [IMP] account: make account creation easier Task 2888204 - Name is automatically split into code and name - account_type is computed based on the closest parent of the code prefix (and can be changed) - _onchange_name is needed to split name into code and name when creating from a related model's form closes odoo/odoo#94171 Signed-off-by: Quentin De Paoli --- addons/account/models/account_account.py | 40 +++++++++++++++++++ addons/account/tests/test_account_account.py | 32 +++++++++++++++ .../account/views/account_journal_views.xml | 5 +++ 3 files changed, 77 insertions(+) diff --git a/addons/account/models/account_account.py b/addons/account/models/account_account.py index 521234e05bc..a671ea9654a 100644 --- a/addons/account/models/account_account.py +++ b/addons/account/models/account_account.py @@ -2,7 +2,10 @@ from odoo import api, fields, models, _, tools from odoo.osv import expression from odoo.exceptions import UserError, ValidationError +from bisect import bisect_left +import re +ACCOUNT_REGEX = re.compile(r'(?:(\S*\d+\S*)\s)?(.*)') class AccountAccount(models.Model): _name = "account.account" @@ -58,6 +61,7 @@ class AccountAccount(models.Model): ], string="Type", tracking=True, required=True, + compute='_compute_account_type', store=True, readonly=False, precompute=True, help="Account Type is used for information purpose, to generate country-specific legal reports, and set the rules to close a fiscal year and generate opening entries." ) include_initial_balance = fields.Boolean(string="Bring Accounts Balance Forward", @@ -366,6 +370,19 @@ class AccountAccount(models.Model): record.opening_credit = res['credit'] record.opening_balance = res['balance'] + @api.depends('code') + def _compute_account_type(self): + """ Compute the account type based on the account code. + Search for the closest parent account code and sets the account type according to the parent. + """ + accounts_to_process = self.filtered(lambda r: r.code and not r.account_type) + accounts_with_codes = {r['code']: r['account_type'] for r in self.search_read(domain=[( + 'code', '!=', False), ('company_id', '=', self.company_id.id)], fields=['code', 'account_type'])} + codes_list = list(accounts_with_codes.keys()) + for account in accounts_to_process: + closest_index = bisect_left(codes_list, account.code) - 1 + account.account_type = accounts_with_codes[codes_list[closest_index]] + @api.depends('internal_group') def _compute_is_off_balance(self): for account in self: @@ -513,6 +530,18 @@ class AccountAccount(models.Model): elif self.internal_group == 'expense' and not self.tax_ids: self.tax_ids = self.company_id.account_purchase_tax_id + def _split_code_name(self, code_name): + # We only want to split the name on the first word if there is a digit in it + code, name = ACCOUNT_REGEX.match(code_name or '').groups() + return code, name.strip() + + @api.onchange('name') + def _onchange_name(self): + code, name = self._split_code_name(self.name) + if code: + self.name = name + self.code = code + def name_get(self): result = [] for account in self: @@ -592,6 +621,17 @@ class AccountAccount(models.Model): """ self.env.cr.execute(query, [tuple(self.ids)]) + @api.model + def name_create(self, name): + """ Split the account name into account code and account name in import. + When importing a file with accounts, the account code and name may be both entered in the name column. + In this case, the name will be split into code and name. + """ + if 'import_file' in self.env.context: + code, name = self._split_code_name(name) + return self.create({'code': code, 'name': name}).name_get()[0] + raise ValueError(_("The values for the created account need to be verified.")) + def write(self, vals): # Do not allow changing the company_id when account_move_line already exist if vals.get('company_id', False): diff --git a/addons/account/tests/test_account_account.py b/addons/account/tests/test_account_account.py index 3b83e8c20d3..bb1794033c4 100644 --- a/addons/account/tests/test_account_account.py +++ b/addons/account/tests/test_account_account.py @@ -153,3 +153,35 @@ class TestAccountAccount(AccountTestInvoicingCommon): group.code_prefix_end = 401000 self.assertRecordValues(account_1 + account_2, [{'group_id': group.id}, {'group_id': False}]) + + def test_name_create(self): + """name_create should only be possible when importing + Code and Name should be split + """ + with self.assertRaises(ValueError): + self.env['account.account'].name_create('550003 Existing Account') + account_id = self.env['account.account'].with_context(import_file=True).name_create('550003 Existing Account')[0] + account = self.env['account.account'].browse(account_id) + self.assertEqual(account.code, "550003") + self.assertEqual(account.name, "Existing Account") + + def test_compute_account_type(self): + existing_account = self.env['account.account'].search([], limit=1) + # account_type should be computed + new_account_code = self.env['account.account']._search_new_account_code( + company=existing_account.company_id, + digits=len(existing_account.code), + prefix=existing_account.code[:-1]) + new_account = self.env['account.account'].create({ + 'code': new_account_code, + 'name': 'A new account' + }) + self.assertEqual(new_account.account_type, existing_account.account_type) + # account_type should not be altered + alternate_account = self.env['account.account'].search([('account_type', '!=', existing_account.account_type)], limit=1) + alternate_code = self.env['account.account']._search_new_account_code( + company=alternate_account.company_id, + digits=len(alternate_account.code), + prefix=alternate_account.code[:-1]) + new_account.code = alternate_code + self.assertEqual(new_account.account_type, existing_account.account_type) diff --git a/addons/account/views/account_journal_views.xml b/addons/account/views/account_journal_views.xml index 428359a8708..ff4647fda9c 100644 --- a/addons/account/views/account_journal_views.xml +++ b/addons/account/views/account_journal_views.xml @@ -56,24 +56,29 @@