From cbb9ae539eec2e3e1e61e5404835309e5efd332d Mon Sep 17 00:00:00 2001 From: Laetitia Da Costa Date: Tue, 6 Aug 2024 15:03:53 +0200 Subject: [PATCH] [IMP]import_chart_of_accounts:improve the identification of identical accounts --- import_chart_of_accounts/README.rst | 29 +++++---- import_chart_of_accounts/__manifest__.py | 2 +- .../wizard/import_coa_wizard.py | 61 +++++++++++++++++-- 3 files changed, 73 insertions(+), 19 deletions(-) diff --git a/import_chart_of_accounts/README.rst b/import_chart_of_accounts/README.rst index 60a5ef5..e0c7e27 100644 --- a/import_chart_of_accounts/README.rst +++ b/import_chart_of_accounts/README.rst @@ -14,23 +14,28 @@ Description ============= Pendant l'import, chaque ligne est comparée aux comptes comptables présents dans Odoo -- Si le compte comptable existe déjà dans bdd, seul le nom du compte comptable est mis à jour -- Un compte comptable est déjà existant si les 6 premiers chiffres du code comptable sont identique (par ex: le compte 120000 et 12000000 sont les mêmes comptes) -- Si le compte comptable n'existe pas dans bdd, il est créé. -- Un compte similaire est recherché dans la bdd à partir des 3 premier chiffres du code comptable. -- On recherche tous les comptes qui ont les 3 premiers chiffres de son code en commun avec celui du compte nouvellement créé -- Parmi ces comptes, le compte du lequel les paramètres seront copiés sur le nouveau compte est celui au numéro de code le plus bas. -- On enregistre la valeur des variables 'type' et 'reconcilition' du compte "similaire" dans le nouveau compte comptable -- S'il n'existe "compte similaire" pour ce nouveau compte, aucun paramétrage n'est ajouté lors de l'import +- Si le compte comptable à importer existe déjà dans la base de données, le nom (et éventuellement le code) du compte déjà dans Odoo est mis à jour avec les nouvelles données. Il n'y a pas de création de nouveau compte. +- Un compte comptable de la base de données est considéré comme identique à celui qu'on souhaite importer, si les 2 comptes ont le même code une fois les zéros finaux supprimés. +- Par ex: les comptes 120000 et 12000000 sont considérés identiques (12 = 12), mais les comptes 120000 et 12000001 ne sont pas considérés identiques (12 != 12000001) +- Si le compte comptable à importer n'existe pas dans la bdd, il est créé. +- Un compte similaire au compte nouvellement créé est recherché dans la bdd pour y ajouter les mêmes paramêtres. +- Pour ce faire, on recherche dans la bdd tous les comptes qui ont les 3 premiers chiffres de leur code en commun avec celui du compte nouvellement créé. +- Parmi ces comptes, le compte qui sera concidéré comme 'similaire' et dont on va copié les paramètre sur le nouveau compte est celui au numéro de code le plus bas. +- On enregistre la valeur des variables 'type' et 'reconcilition' du compte 'similaire' dans le compte comptable nouvellement créé. +- S'il n'existe 'compte similaire' pour le nouveau compte, aucun paramétrage n'est ajouté lors de l'import Exemple : -J'importe le compte comptable 607730 Epicerie divers +J'importe le compte comptable '607730 Epicerie divers' Ce compte comptable n'existe pas déjà dans Odoo, il est créé. -Pour le configurer automatiquement, on se fonde sur un compte similaire dans Odoo et avec le code le plus bas parmis les comptes similaires -Ici il s'agit de 607000 Achats de marchandise: +Pour le configurer automatiquement, on se fonde sur un compte similaire dans Odoo et avec le code le plus bas parmi les comptes similaires +Ici il s'agit de '607000 Achats de marchandise': Il a pour Type Charges car c'est une compte de charges et Autoriser le lettrage est à False. -Le compte 607730 Epicerie divers sera donc enregistré dans Odoo avec le même paramétrage. +Le compte '607730 Epicerie divers' sera donc enregistré dans Odoo avec le même paramétrage. + +J'importe le compte comptable '70600000 Prestation de service' +Le compte '706000 Ventes de produits issus de prestation' existe en bdd +Le compte '706000 Ventes de produits issus de prestation' existant est mise à jour pour devenir '70600000 Prestation de service' Usage ===== diff --git a/import_chart_of_accounts/__manifest__.py b/import_chart_of_accounts/__manifest__.py index bb91eef..15a61e8 100644 --- a/import_chart_of_accounts/__manifest__.py +++ b/import_chart_of_accounts/__manifest__.py @@ -1,6 +1,6 @@ { 'name': 'Import chart of accounts', - 'version': '16.0.1.1.0', + 'version': '16.0.1.2.0', 'summary': 'while importing the accounts chart, only update account name of existing accounts and automatise settings for new accounts', 'description': '', 'author': '', diff --git a/import_chart_of_accounts/wizard/import_coa_wizard.py b/import_chart_of_accounts/wizard/import_coa_wizard.py index db7ad51..695d745 100644 --- a/import_chart_of_accounts/wizard/import_coa_wizard.py +++ b/import_chart_of_accounts/wizard/import_coa_wizard.py @@ -27,13 +27,20 @@ class ImportCoaWizard(models.TransientModel): raise UserError(f"The CSV file must contain the following columns: {', '.join(required_columns)}") data_to_import = [row for row in csv_reader] + + #get all accounts already existing + all_existing_accounts = self.rstrip_all_accounts() + for record_data in data_to_import: - # the account is already existing in Odoo if the 6 first digits are identicales - existing_line = self.find_account_with_same_firsts_digits(record_data['code'][:6]) - if existing_line: - existing_line.write(record_data) + # Verify if a identical account already exists in the COA + # Example: 701000 and 70100000 are identical, but 701000 and 70100001 are not. + identical_account_id = self.find_identical_account(all_existing_accounts, record_data['code']) + if identical_account_id: + existing_account = self.env['account.account'].browse(identical_account_id) + existing_account.write(record_data) else: - # the closest account already existing in Odoo has the first tree digits identicales + # find the closest account already existing in Odoo, it has the same first tree digits + # Example : 706100 is the closest account of 706600 closest_account = self.find_account_with_same_firsts_digits(record_data['code'][:3]) if closest_account : record_data['account_type'] = closest_account.account_type @@ -45,6 +52,48 @@ class ImportCoaWizard(models.TransientModel): "res_model": "account.account", "view_mode": "list" } - + def find_account_with_same_firsts_digits(self, code_prefix): + """ + Find an account with the same initial digits of the code. + + :param code_prefix: The initial digits of the code to search for. + :return: The first account found with the same prefix, or None if none is found. + """ return self.env['account.account'].search([('code', '=like', f'{code_prefix}%')],limit=1) + + def find_identical_account(self, all_accounts_without_final_zero, code): + """ + Compare the account code to import with existing accounts stored in Odoo. + + Because 701000 and 70100000 are considered identical, we need to compare their account codes without final zeros. + + Example: 701000 and 70100000 are identical, but 701000 and 70100001 are not. + + Return: The ID of the identical account if it exists; otherwise, return False. + """ + code_strip = code.rstrip('0') + for account_id, stripped_code in all_accounts_without_final_zero.items(): + if stripped_code == code_strip: + return account_id + else: + return False + + def rstrip_all_accounts(self): + """ + Create a dictionary with IDs and acccount codes without trailing zeros for all existing accounts in Odoo. + + :return: A dictionary with account IDs as keys and codes without trailing zeros as values. + """ + all_accounts_without_final_zero = {} + accounts = self.env['account.account'].search([]) + for account in accounts: + code = account.code + account_id = account.id + all_accounts_without_final_zero[account_id] = code.rstrip('0') + return all_accounts_without_final_zero + + + + +