diff --git a/client/src/i18n/en/form.json b/client/src/i18n/en/form.json index 82d9a6524f..b184d94660 100644 --- a/client/src/i18n/en/form.json +++ b/client/src/i18n/en/form.json @@ -182,6 +182,7 @@ "DISTRIBUTION_INVALID": "The distribution is invalid. The sum of distributed values must be equal to the amount of the transaction.", "DISTRIBUTION_PERCENT_INVALID": "The distribution is invalid. The sum of percentage values must be equal to 100%", "DISTRIBUTION_SUCCESSFULLY": "Distributed successfully", + "DO_WANT_PUT_WAITING_LIST": "Do you actually want to place the selected employees in the payment waiting list?", "EDITED" : "Edited", "EMPLOYEE_NOT_FOUND" : "Employee Not Found", "ENTITY_NOT_FOUND": "Entity (Debtor/Creditor) Not Found", @@ -222,6 +223,7 @@ "NO_SOURCE": "No source defined", "NO_SUPPLIER": "A purchase order must have a supplier before specifying items.", "NUM_TRANSACTION": "Number of transactions", + "NUMBER_EMPLOYEES_SELECTED": "Number of employees selected", "NUMBER_PACKAGE_INFO" : "For products or items that come with packaging, you must enter the total number of packages or boxes, this quantity multiplied by the size of the packaging to obtain the global quantity by the smallest unit.", "OF": "of", "OPERATION_SUCCESS": "Operation performed successfully", @@ -235,6 +237,7 @@ "PATIENT_INVOICE_FOUND": "Invoice found", "PATIENT_INVOICE_NOT_FOUND": "No invoices found for the patient: {{name}}", "PAYMENT": "Cash Payment", + "PAYMENT_PERIOD": "Payment period", "PER": "per", "PREVIOUS": "Previous", "RECORD_SAME":"No changes have been made to the form", @@ -1156,6 +1159,7 @@ "OVERRUN_DISTRIBUTION": "There is a {{value}} % overrun", "PAGE_NOT_FOUND": "The page you requested could not be found", "PERCENTAGE_BREACKDOWN": "Percentage breakdown is not possible when selecting transactions that belong to different expense centers", + "PUTTING_WAITING_LIST": "Putting in the waiting list is an irreversible operation, and the transactions resulting from this operation are recorded in the entry journal on the date of the end of the pay period.", "REMAINS_DISTRIBUTION": "It remains {{ value }}", "NO_CHANGES": "You haven't changed any form values. Nothing will be submitted to the server.", "ONLY_500_TAG_NUMBERS_CAN_BE_GENERATED": "Only a max of 500 labels can be generated at a time" diff --git a/client/src/i18n/fr/form.json b/client/src/i18n/fr/form.json index e36a882f22..836b082fc3 100644 --- a/client/src/i18n/fr/form.json +++ b/client/src/i18n/fr/form.json @@ -182,6 +182,7 @@ "DELETE_SUCCESS": "Suppression avec succès", "DISABLED_CURRENCY": "Cette monnaie est inutilisable car il n'y a pas de compte fixée pour elle. Utilisez le module Box Cash Management pour définir un compte pour cette monnaie et caisse.", "DISPLAY_NAME" : "Le nom complet de l'utilisateur, il est affiché sur tous les documents formels ou reçus traités par le système.", + "DO_WANT_PUT_WAITING_LIST": "Voulez vous effectivement placer les employés sélectionnées dans la liste d'attente de paiement?", "ENTITY_NOT_FOUND": "Entité (Débiteur/Créditeur) Non Trouvé", "EMAIL_SUCCESS": "Email envoyé avec succès.", "EXPORT_SUCCESS": "Exportation avec succes", @@ -222,6 +223,7 @@ "NO_SOURCE": "Aucune source définie", "NO_SUPPLIER": "Un ordre d'achat doit avoir un fournisseur avant de préciser les éléments.", "NUM_TRANSACTION": "Nombres des transactions", + "NUMBER_EMPLOYEES_SELECTED": "Nombre des employés sélectionnés", "NUMBER_PACKAGE_INFO" : "Pour les produits ou articles qui se présentent avec un conditionnement, il faut renseigner le nombre total des paquets ou boites, cette quantité multipliée par la taille de l'emballage pour obtenir la quantité global par la plus petite unitée", "OF": "de", "OPERATION_SUCCESS": "Opération effectuée avec succès", @@ -235,6 +237,7 @@ "PATIENT_INVOICE_FOUND": "La facture a été trouvée", "PATIENT_INVOICE_NOT_FOUND": "La facture est inexistante pour le patient: {{name}}", "PAYMENT": "Référence du Paiement", + "PAYMENT_PERIOD": "Période de paiement", "PER": "par", "PREVIOUS": "Précédent", "RECORD_SAME":"Aucun changement n'a été apporté sur le formulaire", @@ -1156,6 +1159,7 @@ "OVERRUN_DISTRIBUTION": "Il y a un dépassement de {{value}}", "PAGE_NOT_FOUND": "La page demandée n'a pas été trouvée", "PERCENTAGE_BREACKDOWN": "La ventilation par pourcentage n'est pas possible lorsqu'on selectionne des transactions qui appartienent à des centres des frais différents", + "PUTTING_WAITING_LIST": "La mise en attente dans la liste d'attente est une opération irréversible, et les transactions issues de cette opération sont enregistrées dans le journal de saisie à la date de la fin de la période de paie.", "REMAINS_DISTRIBUTION": "Il reste {{ value }}", "NO_CHANGES": "Vous n'avez pas changé les données dans le formulaire. Rien a été submis au server.", "ONLY_500_TAG_NUMBERS_CAN_BE_GENERATED": "Seulement 500 étiquettes maximum peuvent être générées à la fois" diff --git a/client/src/modules/multiple_payroll/modals/waitingListConfirmation.html b/client/src/modules/multiple_payroll/modals/waitingListConfirmation.html new file mode 100644 index 0000000000..96abdb5c9f --- /dev/null +++ b/client/src/modules/multiple_payroll/modals/waitingListConfirmation.html @@ -0,0 +1,51 @@ +
diff --git a/client/src/modules/multiple_payroll/modals/waitingListConfirmation.js b/client/src/modules/multiple_payroll/modals/waitingListConfirmation.js new file mode 100644 index 0000000000..0971d2f8a0 --- /dev/null +++ b/client/src/modules/multiple_payroll/modals/waitingListConfirmation.js @@ -0,0 +1,25 @@ +angular.module('bhima.controllers') + .controller('ModalWaitingListConfirmationController', ModalWaitingListConfirmationController); + +ModalWaitingListConfirmationController.$inject = [ + 'data', 'bhConstants', 'SessionService', '$uibModalInstance', +]; + +function ModalWaitingListConfirmationController( + data, bhConstants, Session, Instance, +) { + const vm = this; + vm.Constants = bhConstants; + vm.submit = submit; + vm.cancel = () => Instance.close(false); + + vm.enterprise = Session.enterprise; + + vm.employeesNumber = data.employeesNumber; + vm.paiementPeriodLabel = data.paiementPeriodLabel; + vm.totalNetSalary = data.totalNetSalary; + + function submit() { + Instance.close(true); + } +} diff --git a/client/src/modules/multiple_payroll/multiple_payroll.js b/client/src/modules/multiple_payroll/multiple_payroll.js index e7d4687711..1422ebcfd8 100644 --- a/client/src/modules/multiple_payroll/multiple_payroll.js +++ b/client/src/modules/multiple_payroll/multiple_payroll.js @@ -5,7 +5,7 @@ angular.module('bhima.controllers') MultiplePayrollController.$inject = [ 'MultiplePayrollService', 'NotifyService', 'GridSortingService', 'GridColumnService', 'GridStateService', '$state', - 'ReceiptModal', 'uiGridConstants', 'SessionService', + 'ReceiptModal', 'uiGridConstants', 'SessionService', 'ModalService', ]; /** @@ -18,7 +18,7 @@ MultiplePayrollController.$inject = [ */ function MultiplePayrollController( MultiplePayroll, Notify, Sorting, Columns, GridState, $state, - Receipts, uiGridConstants, Session, + Receipts, uiGridConstants, Session, Modal, ) { const vm = this; const cacheKey = 'multiple-payroll-grid'; @@ -210,17 +210,31 @@ function MultiplePayrollController( const isNotConfigured = employee => parseInt(employee.status_id, 10) !== 2; const invalid = employees.some(isNotConfigured); + let totalNetSalary = 0; + employees.forEach(emp => { + totalNetSalary += emp.net_salary; + }); + if (invalid) { Notify.warn('FORM.WARNINGS.ATTENTION_WAITING_LIST'); } else { - vm.activePosting = false; - - const idPeriod = vm.latestViewFilters.defaultFilters[0]._value; - MultiplePayroll.paymentCommitment(idPeriod, employeesUuid) - .then(() => { - Notify.success('FORM.INFO.CONFIGURED_SUCCESSFULLY'); - vm.activePosting = true; - $state.go('multiple_payroll', null, { reload : true }); + const employeesNumber = employeesUuid.length; + const paiementPeriodLabel = vm.latestViewFilters.defaultFilters[0].displayValue; + + MultiplePayroll.openModalWaitingListConfirmation(employeesNumber, paiementPeriodLabel, totalNetSalary) + .then(success => { + if (success) { + vm.activePosting = false; + + const idPeriod = vm.latestViewFilters.defaultFilters[0]._value; + MultiplePayroll.paymentCommitment(idPeriod, employeesUuid) + .then(() => { + Notify.success('FORM.INFO.CONFIGURED_SUCCESSFULLY'); + vm.activePosting = true; + $state.go('multiple_payroll', null, { reload : true }); + }) + .catch(Notify.handleError); + } }) .catch(Notify.handleError); } diff --git a/client/src/modules/multiple_payroll/multiple_payroll.service.js b/client/src/modules/multiple_payroll/multiple_payroll.service.js index dbd6268cb7..4f22506263 100644 --- a/client/src/modules/multiple_payroll/multiple_payroll.service.js +++ b/client/src/modules/multiple_payroll/multiple_payroll.service.js @@ -2,8 +2,8 @@ angular.module('bhima.services') .service('MultiplePayrollService', MultiplePayrollService); MultiplePayrollService.$inject = [ - 'PrototypeApiService', 'TransactionTypeStoreService', '$uibModal', - 'FilterService', 'PeriodService', 'LanguageService', '$httpParamSerializer', + 'PrototypeApiService', '$uibModal', + 'FilterService', 'LanguageService', '$httpParamSerializer', 'appcache', 'TransactionService', ]; @@ -16,7 +16,7 @@ MultiplePayrollService.$inject = [ * includes some utilities that are useful for Multiple Payroll pages. */ function MultiplePayrollService( - Api, TransactionTypeStore, Modal, Filters, Periods, Languages, + Api, Modal, Filters, Languages, $httpParamSerializer, AppCache, Transactions, ) { const service = new Api('/multiple_payroll/'); @@ -35,6 +35,7 @@ function MultiplePayrollService( service.setConfiguration = setConfiguration; service.paymentCommitment = paymentCommitment; service.configurations = configurations; + service.openModalWaitingListConfirmation = openModalWaitingListConfirmation; // loads the Payroll Configuration function getConfiguration(id, params) { @@ -125,5 +126,18 @@ function MultiplePayrollService( }).result; } + // open a dialog box to put employees in waiting list + function openModalWaitingListConfirmation(employeesNumber, paiementPeriodLabel, totalNetSalary) { + return Modal.open({ + templateUrl : 'modules/multiple_payroll/modals/waitingListConfirmation.html', + resolve : { data : { employeesNumber, paiementPeriodLabel, totalNetSalary } }, + size : 'md', + animation : true, + keyboard : false, + backdrop : 'static', + controller : 'ModalWaitingListConfirmationController as ModalCtrl', + }, true).result; + } + return service; } diff --git a/test/end-to-end/payrollProcess/payroll_process.spec.js b/test/end-to-end/payrollProcess/payroll_process.spec.js index ac559a7e25..cb893a36c0 100644 --- a/test/end-to-end/payrollProcess/payroll_process.spec.js +++ b/test/end-to-end/payrollProcess/payroll_process.spec.js @@ -83,6 +83,10 @@ test.describe('Payroll Process Management', () => { await TU.locator('[data-action="open-menu"]').click(); await TU.locator('[data-method="put-waiting"]').click(); + // Wait for confirmation dialog + await TU.waitForSelector('.modal-dialog form[name="ModalForm"]'); + await TU.modal.submit(); + await components.notification.hasSuccess(); });