From 84c14fde05a013323882b5eed747cb706ebb815f Mon Sep 17 00:00:00 2001 From: oco-odoo Date: Fri, 9 Oct 2020 15:21:31 +0000 Subject: [PATCH] [IMP] account: better handling of journal codes when duplicating Before that, even though the code contained something about it, the duplication of account.journal objects handled their code field pretty poorly (as it was trimmed to 5 characters), leading to situations where journals could have the same code, leading to possibility for account moves to have the same name. This commit improves the SQL constraint testing journal codes so that they must now be unique per company. We also recompute the code in a more advanced way so that journal duplications works as smoothly as possible. Task 2346404 closes odoo/odoo#59791 Related: odoo/enterprise#14447 Related: odoo/upgrade#1880 Signed-off-by: Laurent Smet --- addons/account/models/account_journal.py | 24 ++++++++++++++++++++++-- addons/account/tests/common.py | 4 ++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/addons/account/models/account_journal.py b/addons/account/models/account_journal.py index 2d6c1a92d94..bb3671608fb 100644 --- a/addons/account/models/account_journal.py +++ b/addons/account/models/account_journal.py @@ -209,7 +209,7 @@ class AccountJournal(models.Model): readonly=True, copy=False) _sql_constraints = [ - ('code_company_uniq', 'unique (code, name, company_id)', 'The code and name of the journal must be unique per company !'), + ('code_company_uniq', 'unique (code, company_id)', 'Journal codes must be unique per company.'), ] @api.depends('type') @@ -403,9 +403,29 @@ class AccountJournal(models.Model): @api.returns('self', lambda value: value.id) def copy(self, default=None): default = dict(default or {}) + + # Find a unique code for the copied journal + read_codes = self.env['account.journal'].with_context(active_test=False).search_read([('company_id', '=', self.company_id.id)], ['code']) + all_journal_codes = {code_data['code'] for code_data in read_codes} + + copy_code = self.code + code_prefix = re.sub(r'\d+', '', self.code).strip() + counter = 1 + while counter <= len(all_journal_codes) and copy_code in all_journal_codes: + counter_str = str(counter) + copy_prefix = code_prefix[:self._fields['code'].size - len(counter_str)] + copy_code = ("%s%s" % (copy_prefix, counter_str)) + + counter += 1 + + if counter > len(all_journal_codes): + # Should never happen, but put there just in case. + raise UserError(_("Could not compute any code for the copy automatically. Please create it manually.")) + default.update( - code=_("%s (copy)") % (self.code or ''), + code=copy_code, name=_("%s (copy)") % (self.name or '')) + return super(AccountJournal, self).copy(default) def _update_mail_alias(self, vals): diff --git a/addons/account/tests/common.py b/addons/account/tests/common.py index d70d84ef89d..293320b6ba4 100644 --- a/addons/account/tests/common.py +++ b/addons/account/tests/common.py @@ -569,8 +569,8 @@ class TestAccountReconciliationCommon(AccountTestInvoicingCommon): # Journals cls.purchase_journal = cls.company_data['default_journal_purchase'] cls.cash_basis_journal = cls.env['account.journal'].create({ - 'name': 'CABA', - 'code': 'CABA', + 'name': 'Test CABA', + 'code': 'tCABA', 'type': 'general', }) cls.general_journal = cls.company_data['default_journal_misc']