Skip to content

Commit

Permalink
Merge pull request #7662 from lomamech/importPayrollConfigurationFrom…
Browse files Browse the repository at this point in the history
…Excel

Import payroll configuration from excel
  • Loading branch information
jmcameron authored Jul 16, 2024
2 parents 7161784 + 937187e commit 58f4feb
Show file tree
Hide file tree
Showing 16 changed files with 2,156 additions and 2,084 deletions.
4 changes: 4 additions & 0 deletions client/src/i18n/en/errors.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
"UNAUTHORIZED" : "You have submitted a bad username or password combination. Please login in with valid credentials to continue.",
"UNKNOWN" : "An error occurred.",
"OVERPAID_INVOICE" : "You have overpaid the invoices.",
"ER_BAD_CSV_FILE" : "Warning: The CSV file you have selected does not match the selected payroll period. Please download the template again, configure it correctly, and re-upload the file.",
"ER_BAD_CSV_FILE_EMP" : "Warning: The configured list of employees does not match the initially configured list. Please download the template again, configure it correctly, and re-upload the file.",
"ER_CSV_MORE_COLUMN" : "Error: The uploaded CSV file contains more columns than expected. Please ensure that the file matches the required format with the correct number of columns and try again.",
"ER_CSV_FEW_COLUMN" : "Error: The uploaded CSV file contains fewer columns than expected. Please ensure that the file matches the required format with the correct number of columns and try again.",
"ER_DATE_RANGE" : "The end date cannot be before the start date!",
"ER_DUP_KEY" : "A key collided in a unique database field. Please retry your action. If the problem persists, contact the developers.",
"ER_DUP_ENTRY" : "You have duplicated a value in a unique field! Please make sure that the necessary values are unique.",
Expand Down
4 changes: 4 additions & 0 deletions client/src/i18n/en/form.json
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@
"GROUPS_DEBTOR": "Assign a new debtor group from the options below. Press 'confirm' to permanently update the patient's debtor group",
"GROUPS_PATIENT": "Assign the patient to patient groups from the options below. Press 'confirm' to permanently update the patient's subscribed groups.",
"IMPORT_SUCCESS": "Successfully Imported",
"IMPORT_PAYROLL_CONFIGURATION": "Import payroll configuration",
"INCLUDE_PATIENT_DATA": "include patient data",
"INVOICES": "Invoices",
"IS_ASSOCIATED_EMPLOYEE" : "will be associated with the employee ID",
Expand All @@ -214,6 +215,7 @@
"NO_CHANGE":"No changes have been made to the form",
"NOT_CONFIGURED": "The accounts for this currency have not been configured yet.",
"NO_DESTINATION": "No destination defined",
"NO_FILE_SELECTED": "No file is selected",
"NO_FILTERS_APPLIED": "No filters applied",
"NO_INVENTORY_PO": "No products in stock have reached their re-order limit.",
"NO_INVOICES_SELECTED": "No invoices selected",
Expand Down Expand Up @@ -467,6 +469,7 @@
"DOB_ABBREV": "DOB",
"DOB": "Date of Birth",
"DOCUMENT": "Document",
"DOWN_TEMPLATE_FILE": "Payroll Configuration Template",
"DUE": "Payment Due",
"DUPLICATE_LOTS": "Duplicate Lots",
"EDIT": "Edit",
Expand Down Expand Up @@ -591,6 +594,7 @@
"LEVEL_OF_STUDY" : "Level of study",
"LIMIT": "Limit",
"LIST_STRUCTURE": "List structure",
"LOAD_FROM_FILE": "Import data from a CSV file",
"LOCATION_REGISTER": "Location Register",
"LOCKED": "Locked",
"LOGIN": "Login",
Expand Down
4 changes: 4 additions & 0 deletions client/src/i18n/fr/errors.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
"UNAUTHORIZED" : "Vous avez soumis un mauvais nom ou mot de passe. Entrez un nom ou un mot de passe valid pour continuer.",
"UNKNOWN" : "Une erreur est survenue.",
"OVERPAID_INVOICE" : "Vous avez payé trop aux factures.",
"ER_BAD_CSV_FILE" : "Avertissement : Le fichier CSV que vous avez sélectionné ne correspond pas à la période de paie sélectionnée. Veuillez télécharger à nouveau le modèle, le configurer correctement et retélécharger le fichier.",
"ER_BAD_CSV_FILE_EMP" : "Avertissement : La liste des employés configurée ne correspond pas à la liste initialement configurée. Veuillez télécharger à nouveau le modèle, le configurer correctement et retélécharger le fichier.",
"ER_CSV_MORE_COLUMN" : "Erreur : Le fichier CSV téléchargé contient plus de colonnes que prévu. Veuillez vous assurer que le fichier correspond au format requis avec le nombre correct de colonnes et réessayez.",
"ER_CSV_FEW_COLUMN" : "Erreur : Le fichier CSV téléchargé contient moins de colonnes que prévu. Veuillez vous assurer que le fichier correspond au format requis avec le nombre correct de colonnes et réessayez.",
"ER_DATE_RANGE" : "La date de fin ne peut pas être antérieure à la date de début !",
"ER_DUP_KEY" : "Il ya déjà un enregistrement avec cette clé. Veuillez réessayer votre action. Si le problème persiste, contactez les développeurs.",
"ER_DUP_ENTRY" : "Vous avez dupliqué une valeur dans un champ unique! Assurez-vous que les valeurs nécessaires sont uniques.",
Expand Down
6 changes: 5 additions & 1 deletion client/src/i18n/fr/form.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@
"CONFIRM_CANCEL": "Confirmer Annulation",
"CONFIRM": "Confirmer",
"CONNECTION": "Se connecter",
"DOWNLOAD": "Télécharger",
"DELETE_RECORD": "Supprimer Enregistrement",
"DELETE": "Supprimer",
"DEPOT_MANAGEMENT": "Gestion des dépôts",
"DEPOT_SUPERVISION": "Supervision des dépôts",
"DISMISS": "Rejeter",
"DISPLAY_DATA": "Afficher les données",
"DOWNLOAD": "Télécharger",
"EDIT": "Éditer",
"EDIT_PERMISSIONS": "Éditer permission",
"EDIT_TITLE": "Éditer une profession",
Expand Down Expand Up @@ -195,6 +195,7 @@
"GRID_STATE_SUCCESS": "Enregistrement avec succès",
"GROUPS_DEBTOR": "Attribuez un nouveau Groupe Débiteur parmi les options ci-dessous. Appuyez sur 'confirmer' pour une mise à jour permanente du Groupe Débiteur du patient",
"GROUPS_PATIENT": "Attribuer le patient à des groupes parmi les options ci-dessous. Appuyez sur 'confirmer' pour une mise à jour permanente des groupes souscrites du patient.",
"IMPORT_PAYROLL_CONFIGURATION": "Importer la configuration du payroll",
"IMPORT_SUCCESS": "Importation avec succes",
"INCLUDE_PATIENT_DATA": "inclure les données du patient",
"INVOICES": "Factures",
Expand All @@ -214,6 +215,7 @@
"NOTE": "Note",
"NOT_CONFIGURED": "Les comptes ne sont pas configurés.",
"NO_DESTINATION": "Aucune destination définie",
"NO_FILE_SELECTED": "Aucun fichier n'est sélectionné",
"NO_FILTERS_APPLIED": "Aucun filtrage des données",
"NO_INVENTORY_PO": "Aucun Article en Stock nécessite une commande d'achat",
"NO_INVOICES_SELECTED": "Aucune facture sélectionnée",
Expand Down Expand Up @@ -470,6 +472,7 @@
"DOB": "Date de Naissance",
"DOB_ABBREV": "DDN",
"DOCUMENT": "Document",
"DOWN_TEMPLATE_FILE": "Modèle de configuration de paie",
"DUE": "Paiement dû",
"DUPLICATE_LOTS": "Lots en double",
"EDIT": "Éditer",
Expand Down Expand Up @@ -594,6 +597,7 @@
"LEVEL_OF_STUDY" : "Niveau d'étude",
"LIMIT": "Limite",
"LIST_STRUCTURE": "Liste",
"LOAD_FROM_FILE": "Importer des données à partir d'un fichier CSV",
"LOCATION_REGISTER": "Enregistrer une localisation",
"LOCKED": "Bloqué(e)",
"LOGIN": "Login",
Expand Down
32 changes: 24 additions & 8 deletions client/src/modules/multiple_payroll/modals/search.modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,6 @@ function MultiPayrollSearchModalController(

let statusText = '/';

// displayValues will be an id:displayValue pair
const displayValues = {};
const lastDisplayValues = MultiplePayroll.filters.formatView().defaultFilters;

lastDisplayValues.forEach((last) => {
lastValues[last._key] = last._displayValue;
});

vm.filters = filters;
// searchQueries is the same id:value pair
vm.searchQueries = {};
Expand All @@ -49,6 +41,17 @@ function MultiPayrollSearchModalController(
// Default to enterprise currency
vm.searchQueries.currency_id = vm.enterpriseCurrencyId;

// displayValues will be an id:displayValue pair
const displayValues = {};
const lastDisplayValues = MultiplePayroll.filters.formatView().defaultFilters;

if (lastDisplayValues.length) {
lastDisplayValues.forEach((last) => {
lastValues[last._key] = last._displayValue;
vm.searchQueries[last._key] = last._value;
});
}

// load all Paiement Status
Payroll.paymentStatus()
.then((paymentStatus) => {
Expand Down Expand Up @@ -96,6 +99,19 @@ function MultiPayrollSearchModalController(
vm.submit = function submit(form) {
if (form.$invalid) { return 0; }

const checkDisplayValuesLength = Object.keys(displayValues).length;
const lastDisplayValuesLength = lastDisplayValues.length;

if (lastDisplayValuesLength !== checkDisplayValuesLength) {
lastDisplayValues.forEach(it => {
Object.keys(vm.searchQueries).forEach(key => {
if ((it._key === key) && (it._value === vm.searchQueries[key])) {
displayValues[it._key] = it.displayValue;
}
});
});
}

const loggedChanges = SearchModal.getChanges(vm.searchQueries, changes, displayValues, lastDisplayValues);
return ModalInstance.close(loggedChanges);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<form name="ModalForm" bh-submit="$ctrl.submit(ModalForm)" novalidate>
<div class="modal-header">
<ol class="headercrumb">
<li class="static" translate>TREE.MULTI_PAYROLL_INDICE</li>
<li class="title" translate>FORM.INFO.IMPORT_PAYROLL_CONFIGURATION</li>
</ol>
</div>

<div class="modal-body">
<div class="row">
<div class="col-sm-12">
<div class="form-group marginTop1ex"
ng-class="{ 'has-error' : $ctrl.noSelectedFile }">
<label translate>FORM.LABELS.LOAD_FROM_FILE</label>
<input
id="import-input"
accept=".csv"
class="form-control"
type="file"
name="file"
ng-model="$ctrl.file"
ngf-select="$ctrl.select($ctrl.file)">
<div class="help-block" data-error-message ng-show="$ctrl.noSelectedFile">
<i class="fa fa-warning"></i> <span translate>FORM.INFO.NO_FILE_SELECTED</span>
</div>
</div>
</div>
</div>
</div>

<div class="modal-footer">
<button data-method="cancel" type="button" class="btn btn-default" ng-click="$ctrl.close()">
<span translate>FORM.BUTTONS.CANCEL</span>
</button>

<bh-loading-button disabled="!$ctrl.file" loading-state="ModalForm.$loading">
</bh-loading-button>
</div>
</form>
59 changes: 59 additions & 0 deletions client/src/modules/multiple_payroll_indice/modals/import.modal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
angular.module('bhima.controllers')
.controller('MultiPayrollIndiceImportModalController', MultiPayrollIndiceImportModalController);

MultiPayrollIndiceImportModalController.$inject = [
'data', 'NotifyService', '$uibModalInstance', 'Upload', '$state', 'LanguageService',
];

function MultiPayrollIndiceImportModalController(data, Notify, Instance, Upload, $state, Language) {
const vm = this;

vm.close = Instance.close;
vm.param = {};
vm.configuration = data;

vm.select = (file) => {
vm.noSelectedFile = !file;
};

vm.submit = () => {
// send data only when a file is selected
if (!vm.file) {
vm.noSelectedFile = true;
return;
}

uploadFile(vm.file);
};

/**
* upload the file to server
* @param {string} file - name of file to upload
*/
function uploadFile(file) {
vm.uploadState = 'uploading';
const params = {
url : `/multiple_payroll_indice/upload/${vm.configuration.payroll_configuration_id}?lang=${Language.key}`,
data : { file },
};

// upload the file to the server
Upload.upload(params)
.then(handleSuccess, Notify.handleError, handleProgress);

// success upload handler
function handleSuccess() {
vm.uploadState = 'uploaded';
Notify.success('FORM.INFO.OPERATION_SUCCESS');
$state.go('multiple_payroll_indice', null, { reload : true });
Instance.close();
}

// progress handler
// @TODO : does this work ??? Is it necessary?
function handleProgress(evt) {
file.progress = Math.min(100, parseInt((100.0 * evt.loaded) / evt.total, 10));
vm.progressStyle = { width : String(file.progress).concat('%') };
}
}
}
48 changes: 24 additions & 24 deletions client/src/modules/multiple_payroll_indice/modals/search.modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ angular.module('bhima.controllers')

MultiPayrollIndiceSearchModalController.$inject = [
'$uibModalInstance', 'filters', 'NotifyService', 'Store', 'util',
'MultiplePayrollService', 'PayrollConfigurationService',
'MultipleIndicesPayrollService', 'PayrollConfigurationService',
'$translate', 'SessionService', 'SearchModalUtilService',
];

Expand All @@ -17,27 +17,20 @@ MultiPayrollIndiceSearchModalController.$inject = [
*/
function MultiPayrollIndiceSearchModalController(
ModalInstance, filters, Notify, Store, util,
MultiplePayroll, Payroll, $translate, Session, SearchModal,
MultipleIndicesPayrollService, Payroll, $translate, Session, SearchModal,
) {
const vm = this;
vm.enterpriseCurrencyId = Session.enterprise.currency_id;

const changes = new Store({ identifier : 'key' });
const searchQueryOptions = [
'payroll_configuration_id', 'currency_id',
'display_name', 'code', 'status_id',
];
const lastValues = {};

let statusText = '/';

// displayValues will be an id:displayValue pair
const displayValues = {};
const lastDisplayValues = MultiplePayroll.filters.formatView().defaultFilters;

lastDisplayValues.forEach((last) => {
lastValues[last._key] = last._displayValue;
});
const lastDisplayValues = MultipleIndicesPayrollService.filters.formatView().defaultFilters;

vm.filters = filters;
// searchQueries is the same id:value pair
Expand All @@ -46,6 +39,13 @@ function MultiPayrollIndiceSearchModalController(
// assign already defined custom filters to searchQueries object
vm.searchQueries = util.maskObjectFromKeys(filters, searchQueryOptions);

if (lastDisplayValues.length) {
lastDisplayValues.forEach((last) => {
lastValues[last._key] = last._displayValue;
vm.searchQueries[last._key] = last._value;
});
}

// load all Paiement Status
Payroll.paymentStatus()
.then((paymentStatus) => {
Expand All @@ -63,27 +63,14 @@ function MultiPayrollIndiceSearchModalController(
vm.onSelectPayrollPeriod = function onSelectPayrollPeriod(period) {
vm.searchQueries.payroll_configuration_id = period.id;
displayValues.payroll_configuration_id = period.label;
vm.periodLabel = period.label;
};

vm.setCurrency = function setCurrency(currency) {
displayValues.currency_id = currency.label;
vm.searchQueries.currency_id = currency.id;
};

vm.onPayrollStatusChange = function onPayrollStatusChange(paymentStatus) {
vm.searchQueries.status_id = paymentStatus;

paymentStatus.forEach((statusId) => {
vm.paymentStatus.forEach((status) => {
if (statusId === status.id) {
statusText += `${status.plainText} / `;
}
});
});

displayValues.status_id = statusText;
};

// deletes a filter from the custom filter object, this key will no longer be written to changes on exit
vm.clear = function clear(key) {
delete vm.searchQueries[key];
Expand All @@ -93,6 +80,19 @@ function MultiPayrollIndiceSearchModalController(
vm.submit = function submit(form) {
if (form.$invalid) { return 0; }

const checkDisplayValuesLength = Object.keys(displayValues).length;
const lastDisplayValuesLength = lastDisplayValues.length;

if (lastDisplayValuesLength !== checkDisplayValuesLength) {
lastDisplayValues.forEach(it => {
Object.keys(vm.searchQueries).forEach(key => {
if ((it._key === key) && (it._value === vm.searchQueries[key])) {
displayValues[it._key] = it.displayValue;
}
});
});
}

const loggedChanges = SearchModal.getChanges(vm.searchQueries, changes, displayValues, lastDisplayValues);
return ModalInstance.close(loggedChanges);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ function MultipleIndicesPayrollService(
service.remove = Transactions.remove;
service.openSearchModal = openSearchModal;
service.staffingParametersModal = staffingParametersModal;
service.importConfigModal = importConfigModal;

service.filters = multiplePayrollFilters;
service.cacheFilters = cacheFilters;
Expand Down Expand Up @@ -71,13 +72,6 @@ function MultipleIndicesPayrollService(
{ key : 'currency_id', label : 'FORM.LABELS.CURRENCY' },
]);

multiplePayrollFilters.registerCustomFilters([
{ key : 'display_name', label : 'FORM.LABELS.EMPLOYEE_NAME' },
{ key : 'code', label : 'FORM.LABELS.CODE' },
{ key : 'status_id', label : 'FORM.LABELS.STATUS' },
{ key : 'conversion_rate', label : 'FORM.LABELS.CONVERSION_RATE' },
]);

if (filterCache.filters) {
multiplePayrollFilters.loadCache(filterCache.filters);
}
Expand Down Expand Up @@ -135,5 +129,20 @@ function MultipleIndicesPayrollService(
controller : 'MultiPayrollIndiceParamModalController as $ctrl',
}).result;
}

function importConfigModal(configuration) {
return Modal.open({
templateUrl : 'modules/multiple_payroll_indice/modals/import.modal.html',
size : 'md',
animation : false,
keyboard : false,
backdrop : 'static',
controller : 'MultiPayrollIndiceImportModalController as $ctrl',
resolve : {
data : () => configuration,
},
}).result;
}

return service;
}
Loading

0 comments on commit 58f4feb

Please sign in to comment.