From 741b8f5ca90b8885a2bc9fcca66683d6dcadad47 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Thu, 30 Jun 2022 13:00:23 +0200 Subject: [PATCH] Updating handling of cost centers in accounts --- client/src/i18n/en/account.json | 93 ++++++++++--------- client/src/i18n/en/cost_center.json | 30 +++--- client/src/i18n/fr/account.json | 83 +++++++++-------- client/src/i18n/fr/cost_center.json | 30 +++--- client/src/i18n/fr/report.json | 4 - .../account_reference.ctrl.js | 27 +++++- .../templates/account_list.cell.html | 6 ++ client/src/modules/accounts/accounts.js | 9 +- .../src/modules/accounts/accounts.routes.js | 1 + .../src/modules/cost_center/cost_center.html | 16 ++++ client/src/modules/cost_center/cost_center.js | 12 +++ .../cost_center/cost_center.service.js | 6 ++ server/config/routes.js | 1 + .../finance/accounts/references.js | 23 +++-- server/controllers/finance/cost_center.js | 52 +++++++++++ test/data.sql | 14 +-- test/integration/accountReferences.js | 2 +- 17 files changed, 271 insertions(+), 138 deletions(-) create mode 100644 client/src/modules/account_reference/templates/account_list.cell.html diff --git a/client/src/i18n/en/account.json b/client/src/i18n/en/account.json index c6fce361e2..48d06da06a 100644 --- a/client/src/i18n/en/account.json +++ b/client/src/i18n/en/account.json @@ -1,96 +1,97 @@ { "ACCOUNT":{ - "ALL_CLASSES":"All classes", - "ASSET":"Asset Accounts", - "CHART":"Chart of Accounts", - "COST":"Costs Accounts", - "EQUITY":"Accounts of equity and borrowing more than a year", - "EXP_PROD":"Accounts of other expenses and other products", - "FINC":"Financial Accounts", - "GROUP":"Account Group (Title Account)", - "LIST":"Accounts list", - "REV":"Revenues Accounts", - "STOCKS":"Stocks Accounts", - "THPART":"Third-party accounts and regularize", - "TITLE":"Account Management", - "TYPE":"Account Type", - "BALANCED":"Accounts are balanced", "ADD":"Add Account", "ADD_CHILD":"Add child account", "ALL_ACCOUNT":"All Accounts", + "ALL_CLASSES":"All classes", + "ASSET":"Asset Accounts", + "BALANCED":"Accounts are balanced", + "CHART":"Chart of Accounts", "CLASS":"Accounts class", + "CONFIRM_HIDE" : "Hiding an account removes the account from all account selection elements. It will not affect any pending transactions using the account. Make it hidden?", + "CONFIRM_LOCK" : "Locking an account restricts the ability to post transactions using the account. Are you sure you want to lock it?", + "CONFIRM_UNHIDE" : "This account is currently hidden. Are you sure you want to reveal it for use?", + "CONFIRM_UNLOCK" : "The account is locked. Unlocking it will allow transactions to be posted containing this account. Are you sure you want to unlock it?", + "COST":"Costs Accounts", "COST_CENTER":"Cost Center", "CREATE":"Create New Account", - "CREATE_ANOTHER":"Create another account", "CREATED":"Account record written", + "CREATE_ANOTHER":"Create another account", "DELETED":"Deleted", "DISPLAY_HIDDEN": "Display hidden accounts", - "UPDATED":"Account record updated", + "EQUITY":"Accounts of equity and borrowing more than a year", + "EXCEPT": "except", + "EXP_PROD":"Accounts of other expenses and other products", + "FINC":"Financial Accounts", "GENERATE":"Generate Account Report", + "GROUP":"Account Group (Title Account)", "HELP_TXT_1":"Chart of accounts for", "HELP_TXT_2":"Account information and relationships are shown in the table on the right", "HELP_TXT_3":"Click 'Add Account' to add an account", "HIDE_HIDDEN": "Hide hidden accounts", - "NEW":"New Account", "LABEL":"Account Label", + "LIST":"Accounts list", + "NEW":"New Account", + "NOT_0_AS_ACCOUNT_NOMBER": "You cannot set 0 as account number", "NOT_BALANCED":"Accounts are not balanced", "NOT_FOUND":"No accounts found.", "NOT_POSITIVE":"Contains negative value", - "NOT_0_AS_ACCOUNT_NOMBER": "You cannot set 0 as account number", "NUMBER":"Account Number", "PROFIT_CENTER":"Profit Center", - "TITLE_ACCOUNT":"Title Account", - "SET_ROOT":"Set as root account", - "ROOT_PARENT":"This account is set as a child of the root account. This means it will be at the highest level in the chart of accounts.", "RECORDING":"Create", "RECORD_SAME":"No changes have been made to the form. Update the account details and then press submit.", + "REV":"Revenues Accounts", + "ROOT_PARENT":"This account is set as a child of the root account. This means it will be at the highest level in the chart of accounts.", "SELECT_PARENT":"Select parent account...", + "SET_ROOT":"Set as root account", + "STOCKS":"Stocks Accounts", "SUBMIT_CREATE":"Create Account", "SUBMIT_DELETE":"Delete Account", "SUBMIT_UPDATE":"Update Account", + "THPART":"Third-party accounts and regularize", + "TITLE":"Account Management", + "TITLE_ACCOUNT":"Title Account", + "TYPE":"Account Type", "TYPE_CHANGE_BLOCKED":"You cannot change the type of a title account with children.", - "CONFIRM_HIDE" : "Hiding an account removes the account from all account selection elements. It will not affect any pending transactions using the account. Make it hidden?", - "CONFIRM_UNHIDE" : "This account is currently hidden. Are you sure you want to reveal it for use?", - "CONFIRM_LOCK" : "Locking an account restricts the ability to post transactions using the account. Are you sure you want to lock it?", - "CONFIRM_UNLOCK" : "The account is locked. Unlocking it will allow transactions to be posted containing this account. Are you sure you want to unlock it?", + "UPDATED":"Account record updated", "IMPORT" : { "ACCOUNTS" : "Import Accounts", + "ACCOUNT_LABEL_INFO" : "account_label : the account label", + "ACCOUNT_NUMBER_INFO" : "account_number : the account number", + "ACCOUNT_PARENT_INFO" : "account_parent : the parent account number", + "ACCOUNT_TYPE_INFO" : "account_type : the account type must be either (asset, liability, equity, expense, income, title)", "DESCRIPTION" : "You are about to import the list of accounts from a CSV file", + "DOWNLOAD_TEMPLATE_HERE" : "Clic here to download the template file for importing accounts", "LOAD_DEFAULT_OHADA_ACCOUNTS" : "Use default OHADA accounts", + "LOAD_FROM_FILE" : "Import from a csv file", "LOAD_OHADA_ACCOUNTS" : "Import the list of OHADA accounts of the enterprise", "LOAD_OTHER_ACCOUNTS" : "Import a list of accounts", - "LOAD_FROM_FILE" : "Import from a csv file", - "ACCOUNT_NUMBER_INFO" : "account_number : the account number", - "ACCOUNT_LABEL_INFO" : "account_label : the account label", - "ACCOUNT_TYPE_INFO" : "account_type : the account type must be either (asset, liability, equity, expense, income, title)", - "ACCOUNT_PARENT_INFO" : "account_parent : the parent account number", - "UPLOAD_SUCCESS" : "Successfully sent", - "DOWNLOAD_TEMPLATE_HERE" : "Clic here to download the template file for importing accounts" + "UPLOAD_SUCCESS" : "Successfully sent" }, "REFERENCE":{ - "REFERENCE":"Reference", - "DESCRIPTION":"Description", + "ACCOUNT_LIST":"Account list", + "ADD_REFERENCE":"Add reference", "AMO_DEP":"Amortization", "AMO_DEP_LONG":"Amortization and depreciation", - "ADD_REFERENCE":"Add reference", - "UPDATE_REFERENCE":"Update", "CREATED":"Accounts reference successfully created", - "UPDATED":"Accounts reference successfully updated", "DELETED":"Accounts reference successfully deleted", - "ACCOUNT_LIST":"Account list", - "RECORD_ERROR":"An error occurred during the submission", + "DESCRIPTION":"Description", + "EXCEPTION":"Exception", "PARENT_REFERENCE":"Parent Reference", - "EXCEPTION":"Exception" + "RECORD_ERROR":"An error occurred during the submission", + "REFERENCE":"Reference", + "UPDATED":"Accounts reference successfully updated", + "UPDATE_REFERENCE":"Update" }, "TYPES":{ - "EXPENSE":"Expense", - "BALANCE":"Balance", - "TITLE":"Title", "ASSET":"Asset", - "LIABILITY":"Liability", + "BALANCE":"Balance", "EQUITY":"Equity", + "EXPENSE":"Expense", "INCOME":"Income", - "TIERS":"Others" + "LIABILITY":"Liability", + "TIERS":"Others", + "TITLE":"Title" } } } diff --git a/client/src/i18n/en/cost_center.json b/client/src/i18n/en/cost_center.json index ad44d7a94e..c6ebbb4fdd 100644 --- a/client/src/i18n/en/cost_center.json +++ b/client/src/i18n/en/cost_center.json @@ -1,9 +1,10 @@ { "COST_CENTER" : { - "TITLE" : "Cost Centers", + "ACCOUNTS_UPDATED": "{{ numUpdates }} Accounts updated", + "ADD_ALLOCATION_BASIS": "Add allocation basis", + "ADD_ALLOCATION_BASIS_TOOLTIP": "Add a new cost allocation basis", "ADD_ALLOCATION_KEYS" : "Add Allocation Keys", "ADD_COST_CENTER" : "Add a Cost Center", - "ADD_ALLOCATION_BASIS_TOOLTIP": "Add a new cost allocation basis", "ALLOCATION_BASES":"Allocation Bases", "ALLOCATION_BASIS": "Allocation basis", "ALLOCATION_BASIS_TABLE": "Table of allocation bases", @@ -13,36 +14,39 @@ "AUXILIARY": "Auxiliary Cost Center", "DELETE": "Delete This Cost Center", "DIRECT_COST": "Direct Cost", - "ADD_ALLOCATION_BASIS": "Add allocation basis", "EDIT_ALLOCATION_BASIS": "Edit allocation basis", "EDIT_ALLOCATION_KEYS" : "Edit Allocation Keys", "EDIT_COST_CENTER" : "Update the Cost Center Information", "EDIT_STEP_ORDER" : "Edit order of cost allocation steps", - "PRINCIPAL": "Principal Cost Center", + "INCLUDE_REVENUE_ACCOUNTS" : "Include revenues accounts?", + "INCLUDE_REVENUE_ACCOUNTS_HELP_TEXT" : "This will include also the revenues accounts to expenses accounts list", + "INCLUDE_REVENUE_CENTERS" : "Include revenue with costs?", + "INCLUDE_REVENUE_CENTERS_HELP_TEXT" : "This will include the revenue generated by the revenue centers in addition to their costs.", "NO_COST_CENTER_DEFINED": "** Cost Center Not Defined **", + "ONLY_FOR_EXPLOITATION_ACCOUNTS": "Only for operating accounts (income and expenses). For others accounts, the cost center will not be considered", + "PRINCIPAL": "Principal Cost Center", "SELECT_ALLOCATION_BASIS": "Select allocation basis", "SELECT_COST_CENTER": "Select Cost Center", + "SET_ALLOCATION_QUANTITIES_TOOLTIP": "Define cost center allocation quantities", + "SHOW_ALLOCATIONS_TABLE" : "Show allocations table?", + "SHOW_ALLOCATIONS_TABLE_HELP_TEXT" : "Show the table of allocation basis values for each cost center", "STEP_DOWN_COST_ALLOCATION": "Step-down cost allocation", "STEP_ORDER": "Allocation Step Order", - "ONLY_FOR_EXPLOITATION_ACCOUNTS": "Only for operating accounts (income and expenses). For others accounts, the cost center will not be considered", + "TITLE" : "Cost Centers", + "UPDATE_ACCOUNTS" : "Update accounts", + "UPDATE_ACCOUNTS_TOOLTIP" : "Update the cost center information in all accounts. This operation may take some time.", "UPDATE_ALLOCATION_QUANTITIES": "Update", "UPDATE_ALLOCATION_QUANTITIES_TOOLTIP": "Update system-computed cost center allocation quantities", - "SET_ALLOCATION_QUANTITIES_TOOLTIP": "Define cost center allocation quantities", - "INCLUDE_REVENUE_CENTERS" : "Include revenue with costs?", - "INCLUDE_REVENUE_CENTERS_HELP_TEXT" : "This will include the revenue generated by the revenue centers in addition to their costs.", "USE_REVENUE_CENTERS" : "Show the revenue report?", "USE_REVENUE_CENTERS_HELP_TEXT" : "This will show the revenue generated by the revenue centers", - "INCLUDE_REVENUE_ACCOUNTS" : "Include revenues accounts?", - "INCLUDE_REVENUE_ACCOUNTS_HELP_TEXT" : "This will include also the revenues accounts to expenses accounts list", "REPORT" : { "COST_CENTER_BY_ACCOUNTS" : "Cost center value by accounts", "COST_CENTER_BY_ACCOUNTS_DESCRIPTION" : "This report displays cost center value by accounts", "COST_CENTER_INCOME_AND_EXPENSE" : "Cost center direct revenue and expense", "COST_CENTER_INCOME_AND_EXPENSE_DESCRIPTION" : "This report displays the direct revenue and costs associated with each cost center. To get the total costs and revenue by revenue-generating cost center, please see the step-down analysis report" - }, - "SHOW_ALLOCATIONS_TABLE" : "Show allocations table?", - "SHOW_ALLOCATIONS_TABLE_HELP_TEXT" : "Show the table of allocation basis values for each cost center" + } }, + "ALLOCATION_METHOD": "Allocation method", "ALLOCATION_METHOD_FLAT": "Flat", "ALLOCATION_METHOD_PROPORTIONAL": "Proportional", diff --git a/client/src/i18n/fr/account.json b/client/src/i18n/fr/account.json index fba00b31f8..3991bde409 100644 --- a/client/src/i18n/fr/account.json +++ b/client/src/i18n/fr/account.json @@ -1,96 +1,97 @@ { "ACCOUNT": { - "ALL_CLASSES": "Toutes les classes", - "ASSET": "Comptes des valeurs immobilisées", - "CHART": "Plan Comptable", - "COST": "Comptes des charges et pertes par nature", - "EQUITY": "Comptes des fonds propres et emprunts a plus d'un an", - "EXP_PROD": "Comptes des autres charges et autres produits", - "FINC": "Comptes financiers", - "GROUP": "Groupe des Comptes (Comptes Titres)", - "LIST": "Liste des comptes", - "REV": "Comptes de produits", - "STOCKS": "Comptes des stocks", - "THPART": "Comptes de tiers et à régulariser", - "TYPE": "Type de Compte", "ADD": "Ajouter un Compte", "ADD_CHILD": "Ajouter un Compte fils", "ALL_ACCOUNT": "Tous les comptes", + "ALL_CLASSES": "Toutes les classes", + "ASSET": "Comptes des valeurs immobilisées", "BALANCED": "Comptes balancés", - "COST_CENTER": "Centre des coûts", + "CHART": "Plan Comptable", "CLASS": "Classe de compte", + "CONFIRM_HIDE" : "Masquer un compte supprime le compte de tous les éléments de sélection de compte. Cela n'affectera pas les transactions en attente utilisant le compte. Le rendre caché ?", + "CONFIRM_LOCK" : "Le verrouillage d'un compte limite la possibilité de publier des transactions en utilisant le compte. Êtes-vous sûr de vouloir le verrouiller ?", + "CONFIRM_UNHIDE" : "Ce compte est actuellement caché. Êtes-vous sûr de vouloir le révéler pour l'utiliser ?", + "CONFIRM_UNLOCK" : "Le compte est bloqué. Le débloquer permettra d'afficher des transactions contenant ce compte. Êtes-vous sûr de vouloir le débloquer ?", + "COST": "Comptes des charges et pertes par nature", + "COST_CENTER": "Centre des coûts", "CREATE": "Créer un plan Comptable", "CREATED": "Crée", "CREATE_ANOTHER": "Crée un autre", "DELETED": "Supprimé", "DISPLAY_HIDDEN": "Afficher les comptes cachés", + "EQUITY": "Comptes des fonds propres et emprunts a plus d'un an", + "EXCEPT": "sauf", + "EXP_PROD": "Comptes des autres charges et autres produits", + "FINC": "Comptes financiers", "GENERATE": "Générer un rapport des Comptes", + "GROUP": "Groupe des Comptes (Comptes Titres)", "HELP_TXT_1": "Un Plan Comptable pour", "HELP_TXT_2": "Les informations sur les comptes, ainsi que leurs relations sont visibles sur le tableau à droite", "HELP_TXT_3": "Cliquer 'Ajouter un Compte' pour l'ajout d'un compte", "HIDE_HIDDEN": "Masquer les comptes cachés", "LABEL": "Label", + "LIST": "Liste des comptes", "NEW": "Ajouter un Compte", + "NOT_0_AS_ACCOUNT_NOMBER":"Vous ne pouvez pas enregistrer 0 comme numéro de compte!", "NOT_BALANCED": "Comptes non balancés", "NOT_FOUND": "Aucun compte enregistrés...", "NOT_POSITIVE": "Contiens des valeurs non positives", - "NOT_0_AS_ACCOUNT_NOMBER":"Vous ne pouvez pas enregistrer 0 comme numéro de compte!", "NUMBER": "Numéro de compte", "PROFIT_CENTER": "Centre des profits", "RECORDING": "Enregistrement", "RECORD_SAME": "Aucun changement n'a été apporté au formulaire. Mettez à jour les informations du compte, puis appuyez sur Envoyer.", + "REV": "Comptes de produits", "ROOT_PARENT": "Ce compte est défini comme un enfant du compte root. Cela signifie qu'il sera au plus haut niveau dans la hiérarchie des comptes.", "SELECT_PARENT": "Choisir le compte parent..", "SET_ROOT": "Définir comme un compte parent", + "STOCKS": "Comptes des stocks", "SUBMIT_CREATE": "Créer un compte", "SUBMIT_DELETE": "Supprimer un compte", "SUBMIT_UPDATE": "Mettre à jour un compte", + "THPART": "Comptes de tiers et à régulariser", "TITLE": "Gestion des Comptes", "TITLE_ACCOUNT": "Comptes Titre", + "TYPE": "Type de Compte", "TYPE_CHANGE_BLOCKED": "Vous ne pouvez pas modifier le type d'un compte de titre qui a des sous-comptes.", - "CONFIRM_HIDE" : "Masquer un compte supprime le compte de tous les éléments de sélection de compte. Cela n'affectera pas les transactions en attente utilisant le compte. Le rendre caché ?", - "CONFIRM_UNHIDE" : "Ce compte est actuellement caché. Êtes-vous sûr de vouloir le révéler pour l'utiliser ?", - "CONFIRM_LOCK" : "Le verrouillage d'un compte limite la possibilité de publier des transactions en utilisant le compte. Êtes-vous sûr de vouloir le verrouiller ?", - "CONFIRM_UNLOCK" : "Le compte est bloqué. Le débloquer permettra d'afficher des transactions contenant ce compte. Êtes-vous sûr de vouloir le débloquer ?", + "UPDATED": "Les données du compte ont été mis à jour", "IMPORT" : { "ACCOUNTS" : "Importer les comptes", + "ACCOUNT_LABEL_INFO" : "account_label : le libellé du compte", + "ACCOUNT_NUMBER_INFO" : "account_number : le numéro du compte", + "ACCOUNT_PARENT_INFO" : "account_parent : le numéro du compte parent", + "ACCOUNT_TYPE_INFO" : "account_type : le type de compte doit être soit (asset, liability, equity, expense, income, title)", "DESCRIPTION" : "Vous êtes sur le point d'importer la liste des comptes à partir d'un fichier CSV", + "DOWNLOAD_TEMPLATE_HERE" : "Cliquez ici pour télécharger le fichier modèle pour l'importation des comptes", "LOAD_DEFAULT_OHADA_ACCOUNTS" : "Utiliser les comptes par défaut OHADA", + "LOAD_FROM_FILE" : "Importer à partir d'un fichier", "LOAD_OHADA_ACCOUNTS" : "Importer la liste des comptes OHADA de l'entreprise", "LOAD_OTHER_ACCOUNTS" : "Importer une liste des comptes", - "LOAD_FROM_FILE" : "Importer à partir d'un fichier", - "ACCOUNT_NUMBER_INFO" : "account_number : le numéro du compte", - "ACCOUNT_LABEL_INFO" : "account_label : le libellé du compte", - "ACCOUNT_TYPE_INFO" : "account_type : le type de compte doit être soit (asset, liability, equity, expense, income, title)", - "ACCOUNT_PARENT_INFO" : "account_parent : le numéro du compte parent", - "UPLOAD_SUCCESS" : "Envoi du fichier avec succès", - "DOWNLOAD_TEMPLATE_HERE" : "Cliquez ici pour télécharger le fichier modèle pour l'importation des comptes" + "UPLOAD_SUCCESS" : "Envoi du fichier avec succès" }, "REFERENCE":{ - "REFERENCE":"Référence", - "DESCRIPTION":"Description", + "ACCOUNT_LIST":"Liste des comptes", + "ADD_REFERENCE":"Ajouter reference", "AMO_DEP":"Amortissement", "AMO_DEP_LONG":"Amortissement et dépreciation", - "ADD_REFERENCE":"Ajouter reference", - "UPDATE_REFERENCE":"Mettre à jour", "CREATED":"Référence des comptes crée avec succès", - "UPDATED":"Référence des comptes mise à jour avec succès", "DELETED":"Référence supprimée avec succès", - "ACCOUNT_LIST":"Liste des comptes", - "RECORD_ERROR":"Erreur lors de la soumission", + "DESCRIPTION":"Description", + "EXCEPTION":"Sauf", "PARENT_REFERENCE":"Référence du parent", - "EXCEPTION":"Sauf" + "RECORD_ERROR":"Erreur lors de la soumission", + "REFERENCE":"Référence", + "UPDATED":"Référence des comptes mise à jour avec succès", + "UPDATE_REFERENCE":"Mettre à jour" }, "TYPES": { + "ASSET":"Actif", "BALANCE": "Balance", - "TITLE": "Titre", - "INCOME": "Profit", + "EQUITY":"Capital", "EXPENSE": "Charge", - "ASSET":"Actif", + "INCOME": "Profit", "LIABILITY":"Passif", - "EQUITY":"Capital", - "TIERS":"Tiers" - }, - "UPDATED": "Les données du compte ont été mis à jour" + "TIERS":"Tiers", + "TITLE": "Titre" + } } } diff --git a/client/src/i18n/fr/cost_center.json b/client/src/i18n/fr/cost_center.json index 50b6f62062..880855fe74 100644 --- a/client/src/i18n/fr/cost_center.json +++ b/client/src/i18n/fr/cost_center.json @@ -1,9 +1,10 @@ { "COST_CENTER" : { - "TITLE" : "Centres de coût", + "ACCOUNTS_UPDATED": "{{ numUpdates }} Comptes mis à jour", + "ADD_ALLOCATION_BASIS": "Ajouter une base d'allocation", + "ADD_ALLOCATION_BASIS_TOOLTIP": "Ajouter une nouvelle base d'allocation", "ADD_ALLOCATION_KEYS" : "Ajouter les clés de répartition", "ADD_COST_CENTER" : "Ajouter un centre de coût", - "ADD_ALLOCATION_BASIS_TOOLTIP": "Ajouter une nouvelle base d'allocation", "ALLOCATION_BASES":"Les bases d'allocation", "ALLOCATION_BASIS": "Base d'allocation", "ALLOCATION_BASIS_TABLE": "Tableau des bases d'allocation", @@ -13,36 +14,39 @@ "AUXILIARY": "Centre de coût Auxiliaire", "DELETE": "Supprimer le Centre de coût", "DIRECT_COST": "Cout direct", - "ADD_ALLOCATION_BASIS": "Ajouter une base d'allocation", "EDIT_ALLOCATION_BASIS": "Modifier la base d'allocation", "EDIT_ALLOCATION_KEYS" : "Modifier les clés de répartition", "EDIT_COST_CENTER" : "Mise à jour des informations du centre de coût", "EDIT_STEP_ORDER" : "Modifier l'ordre des étapes de l'allocation des coûts", - "PRINCIPAL": "Centre de coût Principal", + "INCLUDE_REVENUE_ACCOUNTS" : "Inclure les comptes de recette ?", + "INCLUDE_REVENUE_ACCOUNTS_HELP_TEXT" : "Cela inclura également la liste des comptes de revenus à des comptes de dépenses", + "INCLUDE_REVENUE_CENTERS" : "Ajouter les recettes ?", + "INCLUDE_REVENUE_CENTERS_HELP_TEXT" : "Cette option inclurera les recettes avec les couts pour chaque centre.", "NO_COST_CENTER_DEFINED": "** Aucun centre de cout **", + "ONLY_FOR_EXPLOITATION_ACCOUNTS": "Uniquement pour les comptes d'exploitations (produits et charges). Pour les autres comptes, le centre de cout ne sera pas pris en compte", + "PRINCIPAL": "Centre de coût Principal", "SELECT_ALLOCATION_BASIS": "Sélectionnez la base d'allocation", "SELECT_COST_CENTER": "Sélectionnez le centre de coût", + "SET_ALLOCATION_QUANTITIES_TOOLTIP": "Definir les quantités d'allocation pour un centre de coût", + "SHOW_ALLOCATIONS_TABLE" : "Afficher le tableau des allocations ?", + "SHOW_ALLOCATIONS_TABLE_HELP_TEXT" : "Afficher le tableau des valeurs de la base d'allocations pour chaque centre de coûts", "STEP_DOWN_COST_ALLOCATION": "Allocation séquentielle des coûts", "STEP_ORDER": "Ordre des étapes de l'allocation", - "ONLY_FOR_EXPLOITATION_ACCOUNTS": "Uniquement pour les comptes d'exploitations (produits et charges). Pour les autres comptes, le centre de cout ne sera pas pris en compte", + "TITLE" : "Centres de coût", + "UPDATE_ACCOUNTS" : "Mise à jour des comptes", + "UPDATE_ACCOUNTS_TOOLTIP" : "Mettez à jour les informations sur les centres de coûts dans tous les comptes. Cette opération peut prendre un certain temps.", "UPDATE_ALLOCATION_QUANTITIES": "Mettre à jour", "UPDATE_ALLOCATION_QUANTITIES_TOOLTIP": "Mettre à jour les quantités d'allocation des centres de coûts calculées par le système", - "SET_ALLOCATION_QUANTITIES_TOOLTIP": "Definir les quantités d'allocation pour un centre de coût", - "INCLUDE_REVENUE_CENTERS" : "Ajouter les recettes ?", - "INCLUDE_REVENUE_CENTERS_HELP_TEXT" : "Cette option inclurera les recettes avec les couts pour chaque centre.", "USE_REVENUE_CENTERS" : "Afficher le rapport des recettes ?", "USE_REVENUE_CENTERS_HELP_TEXT" : "Cette option affichera la partie des recettes pour chaque centre.", - "INCLUDE_REVENUE_ACCOUNTS" : "Inclure les comptes de recette ?", - "INCLUDE_REVENUE_ACCOUNTS_HELP_TEXT" : "Cela inclura également la liste des comptes de revenus à des comptes de dépenses", "REPORT" : { "COST_CENTER_BY_ACCOUNTS" : "Centre de coût par comptes", "COST_CENTER_BY_ACCOUNTS_DESCRIPTION" : "Ce rapport affiche la valeur des centres de cout par comptes", "COST_CENTER_INCOME_AND_EXPENSE" : "Centre de coût revenu et dépense direct", "COST_CENTER_INCOME_AND_EXPENSE_DESCRIPTION" : "Ce rapport affiche les revenus directs et les coûts associés à chaque centre de coûts. Pour obtenir le total des coûts et des revenus par centre de coûts générateur de revenus, veuillez consulter le rapport d'analyse par étapes" - }, - "SHOW_ALLOCATIONS_TABLE" : "Afficher le tableau des allocations ?", - "SHOW_ALLOCATIONS_TABLE_HELP_TEXT" : "Afficher le tableau des valeurs de la base d'allocations pour chaque centre de coûts" + } }, + "ALLOCATION_METHOD": "Méthode d'allocation séquentielle des coûts", "ALLOCATION_METHOD_FLAT": "Uniform", "ALLOCATION_METHOD_PROPORTIONAL": "Proportionnelle", diff --git a/client/src/i18n/fr/report.json b/client/src/i18n/fr/report.json index ef476e0b97..8af3689fff 100644 --- a/client/src/i18n/fr/report.json +++ b/client/src/i18n/fr/report.json @@ -274,10 +274,6 @@ "TITLE": "Rapport de la Balance des comptes", "DESCRIPTION": "Ce rapport affiche la balance des comptes pour une période donnée" }, - "REPORT_PROFIT_AND_LOSS": { - "TITLE": "Rapport de recettes et depenses", - "DESCRIPTION": "Ce rapport affiche toutes les dépenses et recettes de l'entreprise" - }, "CASH_REPORT": { "TITLE": "Rapport de caisse", "DESCRIPTION": "Ce rapport liste toutes les entrees et sorties d'argent de la caisse au sein de l'entreprise" diff --git a/client/src/modules/account_reference/account_reference.ctrl.js b/client/src/modules/account_reference/account_reference.ctrl.js index 067edc5701..418acc929a 100644 --- a/client/src/modules/account_reference/account_reference.ctrl.js +++ b/client/src/modules/account_reference/account_reference.ctrl.js @@ -2,14 +2,16 @@ angular.module('bhima.controllers') .controller('AccountReferenceController', AccountReferenceController); AccountReferenceController.$inject = [ - '$state', 'AccountReferenceService', 'NotifyService', 'uiGridConstants', '$translate', 'bhConstants', + '$state', 'AccountReferenceService', 'NotifyService', 'uiGridConstants', + 'LanguageService', '$translate', 'bhConstants', ]; /** * AccountReference Controller * This module is responsible for handling the CRUD operation on the account references */ -function AccountReferenceController($state, AccountReferences, Notify, uiGridConstants, $translate, bhConstants) { +function AccountReferenceController($state, AccountReferences, Notify, uiGridConstants, + Language, $translate, bhConstants) { const vm = this; vm.gridApi = {}; vm.filterEnabled = false; @@ -31,43 +33,61 @@ function AccountReferenceController($state, AccountReferences, Notify, uiGridCon field : 'abbr', displayName : 'ACCOUNT.REFERENCE.REFERENCE', headerCellFilter : 'translate', + width : '15%', enableFiltering : true, }, { field : 'accounts', displayName : 'ACCOUNT.REFERENCE.ACCOUNT_LIST', headerCellFilter : 'translate', + cellTemplate : '/modules/account_reference/templates/account_list.cell.html', + width : '20%', enableFiltering : true, }, { field : 'description', displayName : 'ACCOUNT.REFERENCE.DESCRIPTION', headerCellFilter : 'translate', + width : '15%', enableFiltering : true, }, { field : 'parent_abbr', displayName : 'ACCOUNT.REFERENCE.PARENT_REFERENCE', headerCellFilter : 'translate', + headerCellClass : 'wrappingColHeader', + width : '10%', enableFiltering : true, }, { field : 'account_reference_type_label', displayName : 'FORM.LABELS.TYPE', headerCellFilter : 'translate', + width : '10%', + enableFiltering : true, + }, + { + field : 'cost_center', + displayName : 'ACCOUNT.COST_CENTER', + headerCellClass : 'wrappingColHeader', + headerCellFilter : 'translate', + width : '10%', enableFiltering : true, }, { field : 'is_amo_dep', displayName : 'ACCOUNT.REFERENCE.AMO_DEP', + headerTooltip : 'ACCOUNT.REFERENCE.AMO_DEP', headerCellFilter : 'translate', cellTemplate : '/modules/account_reference/templates/is_amo_dep.cell.html', + width : '10%', enableFiltering : true, }, { field : 'action', displayName : '', cellTemplate : '/modules/account_reference/templates/action.cell.html', + width : '10%', enableSorting : false, enableFiltering : false, }, @@ -143,6 +163,9 @@ function AccountReferenceController($state, AccountReferences, Notify, uiGridCon vm.latestViewFilters = AccountReferences.filters.formatView(); const filterSearch = parameters || AccountReferences.filters.formatHTTP(true); + // Insert the languae into the filters + filterSearch.lang = Language.key; + AccountReferences.read(null, filterSearch) .then((references) => { references.forEach((item) => { diff --git a/client/src/modules/account_reference/templates/account_list.cell.html b/client/src/modules/account_reference/templates/account_list.cell.html new file mode 100644 index 0000000000..a721a9050c --- /dev/null +++ b/client/src/modules/account_reference/templates/account_list.cell.html @@ -0,0 +1,6 @@ +
+ {{row.entity.accounts}} +
\ No newline at end of file diff --git a/client/src/modules/accounts/accounts.js b/client/src/modules/accounts/accounts.js index 65280e4d49..0c449c94ca 100644 --- a/client/src/modules/accounts/accounts.js +++ b/client/src/modules/accounts/accounts.js @@ -2,7 +2,7 @@ angular.module('bhima.controllers') .controller('AccountsController', AccountsController); AccountsController.$inject = [ - '$rootScope', '$timeout', 'AccountGridService', 'NotifyService', 'bhConstants', + '$state', '$rootScope', '$timeout', 'AccountGridService', 'NotifyService', 'bhConstants', 'LanguageService', 'uiGridConstants', 'ModalService', 'AccountService', 'GeneralLedgerService', 'moment', ]; @@ -17,8 +17,8 @@ AccountsController.$inject = [ * and connecting it with the Accounts data model. */ function AccountsController( - $rootScope, $timeout, AccountGrid, Notify, Constants, Language, - uiGridConstants, Modal, Accounts, GeneralLedger, moment, + $state, $rootScope, $timeout, AccountGrid, Notify, Constants, + Language, uiGridConstants, Modal, Accounts, GeneralLedger, moment, ) { const vm = this; const columns = gridColumns(); @@ -43,9 +43,10 @@ function AccountsController( vm.setShowHiddenAccounts = setShowHiddenAccounts; vm.Accounts = new AccountGrid(); + function init(initialLoad) { vm.loading = true; - vm.Accounts.settup(initialLoad) + vm.Accounts.settup(initialLoad || $state.params.forceReload) .then(bindGridData) .catch(Notify.handleError) .finally(() => { diff --git a/client/src/modules/accounts/accounts.routes.js b/client/src/modules/accounts/accounts.routes.js index a450954620..d134072fca 100644 --- a/client/src/modules/accounts/accounts.routes.js +++ b/client/src/modules/accounts/accounts.routes.js @@ -24,6 +24,7 @@ function accountStateProvider($stateProvider) { url : '/:id', params : { id : { squash : true, value : null }, + forceReload : { value : null }, }, }) diff --git a/client/src/modules/cost_center/cost_center.html b/client/src/modules/cost_center/cost_center.html index 921805ba25..73e3f3f774 100644 --- a/client/src/modules/cost_center/cost_center.html +++ b/client/src/modules/cost_center/cost_center.html @@ -1,4 +1,12 @@
+ +

+ + FORM.INFO.LOADING +

+
  1. TREE.FINANCE
  2. @@ -27,6 +35,14 @@ + +
  3. + + COST_CENTER.UPDATE_ACCOUNTS + +
  4. diff --git a/client/src/modules/cost_center/cost_center.js b/client/src/modules/cost_center/cost_center.js index c4945158e6..781c5bb7f2 100644 --- a/client/src/modules/cost_center/cost_center.js +++ b/client/src/modules/cost_center/cost_center.js @@ -23,6 +23,7 @@ function CostCenterController(CostCenters, ModalService, Notify, uiGridConstants vm.toggleFilter = toggleFilter; vm.openEditAllocationBasisModal = openEditAllocationBasisModal; vm.editAllocationStepOrder = editAllocationStepOrder; + vm.updateAccounts = updateAccounts; // global variables vm.gridApi = {}; @@ -170,5 +171,16 @@ function CostCenterController(CostCenters, ModalService, Notify, uiGridConstants }).result.catch(angular.noop); } + function updateAccounts() { + CostCenters.updateAccounts() + .then(result => { + const { numUpdates } = result; + const msg = $translate.instant('COST_CENTER.ACCOUNTS_UPDATED', { numUpdates }); + Notify.success(msg); + $state.go('accounts.list', { forceReload : true }); + }) + .catch(Notify.handleError); + } + loadCostCenters(); } diff --git a/client/src/modules/cost_center/cost_center.service.js b/client/src/modules/cost_center/cost_center.service.js index e1fa13a8aa..cee25cc950 100644 --- a/client/src/modules/cost_center/cost_center.service.js +++ b/client/src/modules/cost_center/cost_center.service.js @@ -51,5 +51,11 @@ function CostCenterService(Api, $uibModal) { .then(service.util.unwrapHttpResponse); }; + service.updateAccounts = () => { + const url = '/cost_centers/update_accounts'; + return service.$http.put(url, {}) + .then(service.util.unwrapHttpResponse); + }; + return service; } diff --git a/server/config/routes.js b/server/config/routes.js index b2f182ac45..3eed9bdcdd 100644 --- a/server/config/routes.js +++ b/server/config/routes.js @@ -966,6 +966,7 @@ exports.configure = function configure(app) { app.put('/cost_center/:id', costCenter.update); app.delete('/cost_center/:id', costCenter.delete); app.put('/cost_center/step_order/multi', costCenter.setAllocationStepOrder); + app.put('/cost_centers/update_accounts', costCenter.updateAccounts); // Step-down allocation basis API app.get('/cost_center_allocation_basis', costAllocationBasis.list); diff --git a/server/controllers/finance/accounts/references.js b/server/controllers/finance/accounts/references.js index 81325c42a1..c612a97b17 100644 --- a/server/controllers/finance/accounts/references.js +++ b/server/controllers/finance/accounts/references.js @@ -20,6 +20,7 @@ const _ = require('lodash'); const util = require('../../../lib/util'); const db = require('../../../lib/db'); const FilterParser = require('../../../lib/filter'); +const i18n = require('../../../lib/helpers/translate'); const compute = require('./references.compute'); @@ -52,18 +53,26 @@ async function list(req, res, next) { const params = req.query; try { + // i18n(options.lang)(Stock.fluxLabel[key]), + const filters = new FilterParser(params, { tableAlias : 'ar' }); + const except = i18n(params.lang)('ACCOUNT.EXCEPT'); + const sql = ` SELECT - ar.id, ar.abbr, ar.description, ar.parent, ar.is_amo_dep, arp.abbr as parent_abbr, - GROUP_CONCAT(IF(ari.is_exception = 0, a.number, CONCAT('(sauf ', a.number, ')')) SEPARATOR ', ') AS accounts, - ar.reference_type_id, art.label as account_reference_type_label + ar.id, ar.abbr, ar.description, ar.parent, ar.is_amo_dep, ar.reference_type_id, + arp.abbr AS parent_abbr, + GROUP_CONCAT(IF(ari.is_exception = 0, a.number, CONCAT('(${except} ', a.number, ')')) SEPARATOR ', ') AS accounts, + art.label AS account_reference_type_label, + cc.label AS cost_center FROM account_reference ar - LEFT JOIN account_reference arp ON arp.id = ar.parent - LEFT JOIN account_reference_item ari ON ari.account_reference_id = ar.id - LEFT JOIN account a ON a.id = ari.account_id - LEFT JOIN account_reference_type art ON art.id = ar.reference_type_id + LEFT JOIN account_reference AS arp ON arp.id = ar.parent + LEFT JOIN account_reference_item AS ari ON ari.account_reference_id = ar.id + LEFT JOIN account AS a ON a.id = ari.account_id + LEFT JOIN account_reference_type AS art ON art.id = ar.reference_type_id + LEFT JOIN reference_cost_center AS rcc ON rcc.account_reference_id = ar.id + LEFT JOIN cost_center AS cc ON cc.id = rcc.cost_center_id `; filters.fullText('description'); diff --git a/server/controllers/finance/cost_center.js b/server/controllers/finance/cost_center.js index 6d7286f401..bf0c13f950 100644 --- a/server/controllers/finance/cost_center.js +++ b/server/controllers/finance/cost_center.js @@ -7,6 +7,7 @@ const db = require('../../lib/db'); const NotFound = require('../../lib/errors/NotFound'); const FilterParser = require('../../lib/filter'); +const accountReferences = require('./accounts/references.compute'); // GET /cost_center async function lookupCostCenter(id) { @@ -337,6 +338,56 @@ function setAllocationStepOrder(req, res, next) { .catch(next); } +// PUT /cost_center/update_accounts +async function updateAccounts(req, res, next) { + const { user } = req.session; + + // First clear any old cost center info in all accounts + await db.exec(`UPDATE account SET cost_center_id = NULL WHERE enterprise_id = ${user.enterprise_id}`); + + // Get a list of cost centers + const centersSql = `SELECT id, label FROM cost_center WHERE project_id = ${user.project_id}`; + const centers = await db.exec(centersSql); + const transactions = db.transaction(); + + // Update the accounts for each cost center + // eslint-disable-next-line no-restricted-syntax + for (const center of centers) { + + // Get the account references for this cost center + const accRefsql = ` + SELECT ar.abbr FROM account_reference AS ar + JOIN reference_cost_center as rcc ON rcc.account_reference_id = ar.id + WHERE rcc.cost_center_id = ? + `; + // eslint-disable-next-line no-await-in-loop + const accRefs = await db.exec(accRefsql, [center.id]); + + const updateAccSql = 'UPDATE account SET cost_center_id = ? WHERE id = ?'; + + // eslint-disable-next-line no-restricted-syntax + for (const ref of accRefs) { + + // Get a list of accounts belonging to the cost center + // eslint-disable-next-line no-await-in-loop + const accounts = await accountReferences.getAccountsForReference(ref.abbr); + + // Update the cost center for each account + accounts.forEach(acct => { + transactions.addQuery(updateAccSql, [center.id, acct.account_id]); + }); + } + } + const numUpdates = transactions.queries.length; + + return transactions.execute() + .then(() => { + res.status(200).json({ numUpdates }); + }) + .catch(next) + .done(); +} + // get list of costCenter exports.list = list; // get details of a costCenter @@ -353,3 +404,4 @@ exports.getAllCostCenterAccounts = getAllCostCenterAccounts; exports.assignCostCenterParams = assignCostCenterParams; exports.setAllocationStepOrder = setAllocationStepOrder; +exports.updateAccounts = updateAccounts; diff --git a/test/data.sql b/test/data.sql index 13ce82d033..4cced2d962 100644 --- a/test/data.sql +++ b/test/data.sql @@ -840,13 +840,13 @@ INSERT INTO `account_reference_item` (`id`, `account_reference_id`, `account_id` -- COST CENTER -INSERT INTO `cost_center` (`id`, `label`, `is_principal`, `allocation_method`, `allocation_basis_id`) VALUES - (1, 'Administration', 1, 'proportional', 1), - (2, 'Principale TPA', 1, 'proportional', 2), - (3, 'Principale TPB', 1, 'proportional', 3), - (4, 'Auxiliary 1', 0, 'proportional', 2), - (5, 'Auxiliary 2', 0, 'proportional', 2), - (6, 'Auxiliary 3', 0, 'flat', 2); +INSERT INTO `cost_center` (`id`, `label`, `is_principal`, `project_id`, `allocation_method`, `allocation_basis_id`) VALUES + (1, 'Administration', 1, 1, 'proportional', 1), + (2, 'Principale TPA', 1, 1, 'proportional', 2), + (3, 'Principale TPB', 1, 1, 'proportional', 3), + (4, 'Auxiliary 1', 0, 1, 'proportional', 2), + (5, 'Auxiliary 2', 0, 1, 'proportional', 2), + (6, 'Auxiliary 3', 0, 1, 'flat', 2); -- set test cost center UPDATE account set cost_center_id = 4 WHERE id = 215; diff --git a/test/integration/accountReferences.js b/test/integration/accountReferences.js index 22f1e3c876..2641ac9ca0 100644 --- a/test/integration/accountReferences.js +++ b/test/integration/accountReferences.js @@ -100,7 +100,7 @@ describe('(/accounts/references) Accounts References', () => { .then((res) => { helpers.api.listed(res, numAccountReference); expect(res.body[0]).to.have.all.keys( - 'id', 'abbr', 'account_reference_type_label', 'description', + 'id', 'abbr', 'account_reference_type_label', 'description', 'cost_center', 'parent', 'reference_type_id', 'is_amo_dep', 'accounts', 'parent_abbr', ); })