[FIX] account: fill the journal code for general journal type

Currently, when a journal is created during import, we just use the journal name as the code.
However, that gets truncated to 5 characters on create, which can conflict with existing journals.
The import should be as flexible as possible, as it's better to let users import and fix things
after the import rather than debug the import file.
- If there is a journal with a shortcode that matches the truncated name of the new journal,
  just use the existing journal (enterprise PR)
- If the shortcode conflict arises within the imported file
  (so the journals don't exist before the import), keep track of the codes in `vals_list`.
  The `get_next_bank_cash_default_code` is modified to avoid duplicating code.

See also odoo/enterprise#46101

closes odoo/odoo#135051

X-original-commit: 1161307dc59d0c98eb1352fd80d95da7dc98e700
Related: odoo/enterprise#47242
Signed-off-by: Laurent Smet (las) <las@odoo.com>
Signed-off-by: Aliya Tastemirova (alta) <alta@odoo.com>
This commit is contained in:
aliya
2023-09-11 22:41:13 +00:00
parent 3faa9ab0a5
commit d914e60b2c
3 changed files with 35 additions and 9 deletions
+9
View File
@@ -3111,6 +3111,15 @@ msgstr ""
msgid "Cannot generate an unused account code."
msgstr ""
#. module: account
#. odoo-python
#: code:addons/account/models/account_journal.py:0
#, python-format
msgid ""
"Cannot generate an unused journal code. Please change the name for journal "
"%s."
msgstr ""
#. module: account
#. odoo-python
#: code:addons/account/models/account_report.py:0
+18 -9
View File
@@ -596,16 +596,18 @@ class AccountJournal(models.Model):
return self.env['mail.alias']._sanitize_alias_name(alias_name)
@api.model
def get_next_bank_cash_default_code(self, journal_type, company, cache=None):
journal_code_base = (journal_type == 'cash' and 'CSH' or 'BNK')
def get_next_bank_cash_default_code(self, journal_type, company, cache=None, protected_codes=False):
prefix_map = {'cash': 'CSH', 'general': 'GEN', 'bank': 'BNK'}
journal_code_base = prefix_map.get(journal_type)
existing_codes = set(self.env['account.journal'].with_context(active_test=False).search([
*self.env['account.journal']._check_company_domain(company),
('code', 'like', journal_code_base + '%'),
]).mapped('code') + (cache or []))
for num in range(1, 100):
# journal_code has a maximal size of 5, hence we can enforce the boundary num < 100
journal_code = journal_code_base + str(num)
if journal_code not in existing_codes:
if journal_code not in existing_codes and (protected_codes and journal_code not in protected_codes or not protected_codes):
return journal_code
@api.model
@@ -619,12 +621,11 @@ class AccountJournal(models.Model):
}
@api.model
def _fill_missing_values(self, vals):
def _fill_missing_values(self, vals, protected_codes=False):
journal_type = vals.get('type')
if 'import_file' in self.env.context and not journal_type:
vals['type'] = 'general'
if not vals.get('code'):
vals['code'] = vals.get('name')
is_import = 'import_file' in self.env.context
if is_import and not journal_type:
vals['type'] = journal_type = 'general'
# 'type' field is required.
if not journal_type:
@@ -664,6 +665,12 @@ class AccountJournal(models.Model):
if journal_type in ('cash', 'bank') and not has_loss_account:
vals['loss_account_id'] = company.default_cash_difference_expense_account_id.id
if is_import and not vals.get('code'):
code = vals['name'][:5]
vals['code'] = code if not protected_codes or code not in protected_codes else self.get_next_bank_cash_default_code(journal_type, company, protected_codes)
if not vals['code']:
raise UserError(_("Cannot generate an unused journal code. Please change the name for journal %s.", vals['name']))
# === Fill missing refund_sequence ===
if 'refund_sequence' not in vals:
vals['refund_sequence'] = vals['type'] in ('sale', 'purchase')
@@ -677,7 +684,9 @@ class AccountJournal(models.Model):
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
self._fill_missing_values(vals)
# have to keep track of new journal codes when importing
codes = [vals['code'] for vals in vals_list if 'code' in vals] if 'import_file' in self.env.context else False
self._fill_missing_values(vals, protected_codes=codes)
journals = super(AccountJournal, self.with_context(mail_create_nolog=True)).create(vals_list)
@@ -140,6 +140,14 @@ class TestAccountJournal(AccountTestInvoicingCommon):
self.assertFalse(second_method.exists())
def test_account_journal_duplicates(self):
new_journals = self.env["account.journal"].with_context(import_file=True).create([
{"name": "OD_BLABLA"},
{"name": "OD_BLABLU"},
])
self.assertEqual(sorted(new_journals.mapped("code")), ["GEN1", "OD_BL"], "The journals should be set correctly")
@tagged('post_install', '-at_install', 'mail_alias')
class TestAccountJournalAlias(AccountTestInvoicingCommon, MailCommon):