From e57e5b64d0df94700bc5bd13cbdac6ef84cf8c0d Mon Sep 17 00:00:00 2001 From: jeremielodi Date: Thu, 20 Aug 2020 11:02:15 +0100 Subject: [PATCH 1/9] Feat(Setting) donor management module closes #4826 --- client/src/i18n/en/form.json | 5 +- client/src/i18n/en/tree.json | 1 + client/src/i18n/fr/form.json | 5 +- client/src/i18n/fr/tree.json | 1 + client/src/modules/donor/donor.ctrl.js | 87 ++ client/src/modules/donor/donor.html | 38 + client/src/modules/donor/donor.routes.js | 9 + client/src/modules/donor/donor.service.js | 15 + .../src/modules/donor/modal/createUpdate.html | 39 + .../src/modules/donor/modal/createUpdate.js | 36 + .../modules/donor/templates/action.cell.html | 28 + server/config/routes.js | 7 + server/controllers/admin/donor.js | 44 + server/models/bhima.sql | 4 +- server/models/migrations/next/migrate.sql | 796 ++++++++++++++++++ test/integration/donor.js | 66 ++ 16 files changed, 1175 insertions(+), 6 deletions(-) create mode 100644 client/src/modules/donor/donor.ctrl.js create mode 100644 client/src/modules/donor/donor.html create mode 100644 client/src/modules/donor/donor.routes.js create mode 100644 client/src/modules/donor/donor.service.js create mode 100644 client/src/modules/donor/modal/createUpdate.html create mode 100644 client/src/modules/donor/modal/createUpdate.js create mode 100644 client/src/modules/donor/templates/action.cell.html create mode 100644 server/controllers/admin/donor.js create mode 100644 test/integration/donor.js diff --git a/client/src/i18n/en/form.json b/client/src/i18n/en/form.json index 1c60c9a781..c0d5c45450 100644 --- a/client/src/i18n/en/form.json +++ b/client/src/i18n/en/form.json @@ -112,8 +112,9 @@ "WARNING": "Warning", "CONFIRM_MODAL": "Confirmation Needed", "DELETE_ROLE": "Do you really want to delete this role?", - "DELETE_SUPPLIER" : "Do you really want to delete this supplier?", - "UNPOST_TRANSACTIONS" : "Do you realy want to unpost transactions?" + "UNPOST_TRANSACTIONS" : "Do you realy want to unpost transactions?", + "DELETE_DONOR": "Do you really want to delete this donor?", + "DELETE_SUPPLIER" : "Do you really want to delete this supplier?" }, "ERRORS": { "AT_LEAST_1_COL": "At least one column must be selected", diff --git a/client/src/i18n/en/tree.json b/client/src/i18n/en/tree.json index 53fa19bf87..a812e78347 100644 --- a/client/src/i18n/en/tree.json +++ b/client/src/i18n/en/tree.json @@ -50,6 +50,7 @@ "DISPLAY_METADATA": "Display Metadata", "DISTRIBUTION_KEYS": "Distribution Keys Management", "DITRIBUTION_AUX_FEES_CENTERS" : "Distribution of Auxiliary Fee Centers", + "DONOR":"Donor", "EMPLOYEE" : "Employee", "EMPLOYEE_REGISTRY" : "Employee Registry", "EMPLOYEE_STANDING_REPORT" : "Employee Standing Report", diff --git a/client/src/i18n/fr/form.json b/client/src/i18n/fr/form.json index 0f883a94f0..dad036e377 100644 --- a/client/src/i18n/fr/form.json +++ b/client/src/i18n/fr/form.json @@ -112,8 +112,9 @@ "WARNING": "Attention", "CONFIRM_MODAL": "La confirmation est nécessaire", "DELETE_ROLE": "Voulez-vous vraiment supprimer ce rôle?", - "DELETE_SUPPLIER" : "Voulez-vous supprimer ce fournisseur?", - "UNPOST_TRANSACTIONS" : "Voulez-vous vraiment déposter les transactions?" + "UNPOST_TRANSACTIONS" : "Voulez-vous vraiment déposter les transactions?", + "DELETE_DONOR": "Voulez-vous vraiment supprimer ce donateur?", + "DELETE_SUPPLIER" : "Voulez-vous supprimer ce fournisseur?" }, "ERRORS": { "AT_LEAST_1_COL": "Au moins une colonne doit être sélectionnée", diff --git a/client/src/i18n/fr/tree.json b/client/src/i18n/fr/tree.json index d14677c436..db939dced2 100644 --- a/client/src/i18n/fr/tree.json +++ b/client/src/i18n/fr/tree.json @@ -42,6 +42,7 @@ "DITRIBUTION_AUX_FEES_CENTERS" : "Répartitions des centres de frais auxiliaires", "DISPLAY_METADATA": "Afficher les métadonnées", "DISTRIBUTION_KEYS": "Gestion des clés de répartitions", + "DONOR":"Donateur", "EMPLOYEE":"Gestion des Employés", "EMPLOYEE_REGISTRY" : "Registre des employés", "EMPLOYEE_STANDING_REPORT" : "Rapport des employés", diff --git a/client/src/modules/donor/donor.ctrl.js b/client/src/modules/donor/donor.ctrl.js new file mode 100644 index 0000000000..5c05a9a9dc --- /dev/null +++ b/client/src/modules/donor/donor.ctrl.js @@ -0,0 +1,87 @@ +angular.module('bhima.controllers') + .controller('DonorController', DonorController); + +DonorController.$inject = [ + '$uibModal', 'DonorService', 'ModalService', + 'NotifyService', 'uiGridConstants', +]; + +function DonorController($uibModal, Donor, Modal, Notify, uiGridConstants) { + const vm = this; + + vm.createUpdateDonorModal = (selectedRole = {}) => { + $uibModal.open({ + templateUrl : 'modules/donor/modal/createUpdate.html', + controller : 'DonorAddController as DonorAddCtrl', + resolve : { data : () => selectedRole }, + }); + }; + + vm.remove = function remove(id) { + const message = 'FORM.DIALOGS.DELETE_DONOR'; + Modal.confirm(message) + .then(confirmResponse => { + if (!confirmResponse) { + return; + } + Donor.delete(id) + .then(() => { + Notify.success('FORM.INFO.DELETE_SUCCESS'); + load(); + }) + .catch(Notify.handleError); + }); + }; + + function load() { + vm.loading = true; + + Donor.read() + .then(roles => { + vm.gridOptions.data = roles; + }) + .catch(Notify.handleError) + .finally(() => { + vm.loading = false; + }); + } + + const columns = [{ + field : 'display_name', + displayName : 'FORM.LABELS.NAME', + headerCellFilter : 'translate', + }, { + field : 'actions', + enableFiltering : false, + width : 100, + displayName : '', + headerCellFilter : 'translate', + cellTemplate : 'modules/donor/templates/action.cell.html', + }]; + + // ng-click=" + vm.gridOptions = { + appScopeProvider : vm, + enableColumnMenus : false, + columnDefs : columns, + enableSorting : true, + data : [], + fastWatch : true, + flatEntityAccess : true, + onRegisterApi : (gridApi) => { + vm.gridApi = gridApi; + }, + }; + + load(); + /** + * @function toggleInlineFilter + * + * @description + * Switches the inline filter on and off. + */ + vm.toggleInlineFilter = function toggleInlineFilter() { + vm.gridOptions.enableFiltering = !vm.gridOptions.enableFiltering; + vm.gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN); + }; +} diff --git a/client/src/modules/donor/donor.html b/client/src/modules/donor/donor.html new file mode 100644 index 0000000000..41ec3d3496 --- /dev/null +++ b/client/src/modules/donor/donor.html @@ -0,0 +1,38 @@ +
+
+
    +
  1. TREE.ADMIN
  2. +
  3. TREE.DONOR
  4. +
+ +
+
+ +
+ + +
+
+
+ + +
+
+
+ + + +
+
+
diff --git a/client/src/modules/donor/donor.routes.js b/client/src/modules/donor/donor.routes.js new file mode 100644 index 0000000000..1b8079142e --- /dev/null +++ b/client/src/modules/donor/donor.routes.js @@ -0,0 +1,9 @@ +angular.module('bhima.routes') + .config(['$stateProvider', function Provider($stateProvider) { + + $stateProvider.state('donors', { + url : '/donors', + templateUrl : 'modules/donor/donor.html', + controller : 'DonorController as DonorCtrl', + }); + }]); diff --git a/client/src/modules/donor/donor.service.js b/client/src/modules/donor/donor.service.js new file mode 100644 index 0000000000..9aa63cd748 --- /dev/null +++ b/client/src/modules/donor/donor.service.js @@ -0,0 +1,15 @@ +angular.module('bhima.services') + .service('DonorService', DonorService); + +DonorService.$inject = ['PrototypeApiService']; + +/** + * Role Service + * + * A service wrapper for the /donors HTTP endpoint. + * + */ +function DonorService(Api) { + const service = new Api('/donors/'); + return service; +} diff --git a/client/src/modules/donor/modal/createUpdate.html b/client/src/modules/donor/modal/createUpdate.html new file mode 100644 index 0000000000..9a5c646981 --- /dev/null +++ b/client/src/modules/donor/modal/createUpdate.html @@ -0,0 +1,39 @@ +
+ + + + + +
diff --git a/client/src/modules/donor/modal/createUpdate.js b/client/src/modules/donor/modal/createUpdate.js new file mode 100644 index 0000000000..93c5fcbdc2 --- /dev/null +++ b/client/src/modules/donor/modal/createUpdate.js @@ -0,0 +1,36 @@ +angular.module('bhima.controllers') + .controller('DonorAddController', DonorAddController); + +DonorAddController.$inject = [ + 'data', '$state', 'DonorService', 'NotifyService', '$uibModalInstance', +]; + +function DonorAddController(data, $state, DonorService, Notify, $uibModalInstance) { + const vm = this; + vm.close = $uibModalInstance.close; + vm.submit = submit; + + vm.donor = angular.copy(data); + vm.isCreate = !vm.donor.uid; + vm.action = vm.isCreate ? 'FORM.LABELS.CREATE' : 'FORM.LABELS.UPDATE'; + + function submit(form) { + if (form.$invalid) { + Notify.danger('FORM.ERRORS.HAS_ERRORS'); + return false; + } + + const operation = (!data.id) + ? DonorService.create(vm.donor) + : DonorService.update(data.id, vm.donor); + + return operation + .then(() => { + Notify.success('FORM.INFO.OPERATION_SUCCESS'); + $state.reload(); + vm.close(); + }) + .catch(Notify.handleError); + + } +} diff --git a/client/src/modules/donor/templates/action.cell.html b/client/src/modules/donor/templates/action.cell.html new file mode 100644 index 0000000000..6a51078e10 --- /dev/null +++ b/client/src/modules/donor/templates/action.cell.html @@ -0,0 +1,28 @@ +
+ + + FORM.BUTTONS.ACTIONS + + + + +
diff --git a/server/config/routes.js b/server/config/routes.js index 137bb6bb3d..8b53e5664d 100644 --- a/server/config/routes.js +++ b/server/config/routes.js @@ -25,6 +25,7 @@ const install = require('../controllers/install'); // admin routes const rolesCtrl = require('../controllers/admin/roles'); const users = require('../controllers/admin/users'); +const donor = require('../controllers/admin/donor'); const projects = require('../controllers/admin/projects'); const enterprises = require('../controllers/admin/enterprises'); const services = require('../controllers/admin/services'); @@ -564,6 +565,12 @@ exports.configure = function configure(app) { app.get('/users/:id/cashboxes', users.cashboxes.list); app.post('/users/:id/cashboxes', users.cashboxes.create); + // donor controller + app.get('/donors', donor.read); + app.post('/donors', donor.create); + app.get('/donors/:id', donor.detail); + app.put('/donors/:id', donor.update); + app.delete('/donors/:id', donor.remove); // projects controller app.get('/projects/:id', projects.detail); app.put('/projects/:id', projects.update); diff --git a/server/controllers/admin/donor.js b/server/controllers/admin/donor.js new file mode 100644 index 0000000000..a591d63aa4 --- /dev/null +++ b/server/controllers/admin/donor.js @@ -0,0 +1,44 @@ +const db = require('../../lib/db'); + +module.exports = { + create, + update, + read, + remove, + detail, +}; + +function create(req, res, next) { + const data = req.body; + db.exec(`INSERT INTO donor SET ?`, data).then(() => { + res.sendStatus(201); + }).catch(next); +} + +function update(req, res, next) { + const data = req.body; + const { id } = req.params; + db.exec(`UPDATE donor SET ? WHERE id=?`, [data, id]).then(() => { + res.sendStatus(200); + }).catch(next); +} + +function read(req, res, next) { + db.exec(`SELECT id, display_name FROM donor`).then(donors => { + res.status(200).json(donors); + }).catch(next); +} + +function detail(req, res, next) { + const { id } = req.params; + db.one(`SELECT id, display_name FROM donor WHERE id=?`, id).then(donor => { + res.status(200).json(donor); + }).catch(next); +} + +function remove(req, res, next) { + const { id } = req.params; + db.exec(`DELETE FROM donor WHERE id=?`, id).then(() => { + res.sendStatus(200); + }).catch(next); +} diff --git a/server/models/bhima.sql b/server/models/bhima.sql index db71e4f885..f890917d00 100644 --- a/server/models/bhima.sql +++ b/server/models/bhima.sql @@ -162,8 +162,8 @@ INSERT INTO unit VALUES (286,'Fee Center Reports','TREE.REPORTS','reports for the fee center modules',218,'/fee_center/reports'), (287,'Inventory Reports','TREE.REPORTS','reports for the inventory modules', 138,'/inventory/reports'), (288, '[Stock] Movement Report','TREE.STOCK_MOVEMENT_REPORT','Stock Movement Report', 282,'/reports/stock_movement_report'), - (289, '[Stock] Expiration report','TREE.STOCK_EXPIRATION_REPORT','Stock expiration report', 282,'/reports/stock_expiration_report'); - + (289, '[Stock] Expiration report','TREE.STOCK_EXPIRATION_REPORT','Stock expiration report', 282,'/reports/stock_expiration_report'), + (290,'Donors','TREE.DONOR','Donors management',1,'/donors'); -- Reserved system account type INSERT INTO `account_category` VALUES (1, 'income', 'ACCOUNT.TYPES.INCOME'), diff --git a/server/models/migrations/next/migrate.sql b/server/models/migrations/next/migrate.sql index e69de29bb2..59022e365a 100644 --- a/server/models/migrations/next/migrate.sql +++ b/server/models/migrations/next/migrate.sql @@ -0,0 +1,796 @@ +/* migration script from the version 1.14.0 to the next */ + +/* +@jeremielodi +2020-08-06 +rename all foreign key constraints +*/ + +-- DROP all foreign keys from a table + +-- usage : CALL drop_constraints('account'); + +DELIMITER $$ + +DROP PROCEDURE IF EXISTS `drop_constraints`$$ +CREATE PROCEDURE `drop_constraints`(IN _table_name VARCHAR(100)) +BEGIN +DECLARE _constraint_name VARCHAR(100); + +DECLARE done BOOLEAN; +DECLARE curs1 CURSOR FOR + SELECT CONSTRAINT_NAME + FROM + INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS + WHERE CONSTRAINT_SCHEMA = DATABASE() + AND TABLE_NAME = _table_name; + + +DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + +OPEN curs1; + read_loop: LOOP + FETCH curs1 INTO _constraint_name; + IF done THEN + LEAVE read_loop; + END IF; + + SET @drop_foreign_key = CONCAT('ALTER TABLE ', _table_name, ' DROP FOREIGN KEY ', _constraint_name); + PREPARE drop_query FROM @drop_foreign_key; + EXECUTE drop_query; + + END LOOP; +CLOSE curs1; +END$$ +DELIMITER ; + + + SET foreign_key_checks = 0; + + CALL drop_constraints('account'); + ALTER TABLE `account` + ADD CONSTRAINT `account__account_type` FOREIGN KEY (`type_id`) REFERENCES `account_type` (`id`), + ADD CONSTRAINT `account__enterprise` FOREIGN KEY (`enterprise_id`) REFERENCES `enterprise` (`id`), + ADD CONSTRAINT `account__reference` FOREIGN KEY (`reference_id`) REFERENCES `reference` (`id`); + + CALL drop_constraints('account_type'); + ALTER TABLE `account_type` ADD + CONSTRAINT `acc_type__acc_category` FOREIGN KEY (`account_category_id`) REFERENCES `account_category` (`id`); + + CALL drop_constraints('account_reference_item'); + ALTER TABLE `account_reference_item` + ADD CONSTRAINT `acc_ref_item__acc_ref` FOREIGN KEY (`account_reference_id`) REFERENCES `account_reference` (`id`), + ADD CONSTRAINT `acc_ref_item__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`); + + CALL drop_constraints('patient_assignment'); + ALTER TABLE `patient_assignment` + ADD CONSTRAINT `patient_assignment__patient_group` FOREIGN KEY (`patient_group_uuid`) REFERENCES `patient_group` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `patient_assignment__patient` FOREIGN KEY (`patient_uuid`) REFERENCES `patient` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE; + + + CALL drop_constraints('invoicing_fee'); + ALTER TABLE `invoicing_fee` + ADD CONSTRAINT `invoicing_fee__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`); + + CALL drop_constraints('budget'); + ALTER TABLE `budget` + ADD CONSTRAINT `budget__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`), + ADD CONSTRAINT `budget__period` FOREIGN KEY (`period_id`) REFERENCES `period` (`id`); + + CALL drop_constraints('cash'); + ALTER TABLE `cash` + ADD CONSTRAINT `cash__project` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`), + ADD CONSTRAINT `cash__currency` FOREIGN KEY (`currency_id`) REFERENCES `currency` (`id`), + ADD CONSTRAINT `cash__debtor` FOREIGN KEY (`debtor_uuid`) REFERENCES `debtor` (`uuid`), + ADD CONSTRAINT `cash__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`), + ADD CONSTRAINT `cash__cashbox` FOREIGN KEY (`cashbox_id`) REFERENCES `cash_box` (`id`); + + CALL drop_constraints('config_rubric_item'); + ALTER TABLE `config_rubric_item` + ADD CONSTRAINT `config_rubric_item__config_rubric` FOREIGN KEY (`config_rubric_id`) REFERENCES `config_rubric` (`id`), + ADD CONSTRAINT `config_rubric_item__rubric_payroll` FOREIGN KEY (`rubric_payroll_id`) REFERENCES `rubric_payroll` (`id`); + + + + CALL drop_constraints('cash_item'); + ALTER TABLE `cash_item` + ADD CONSTRAINT `cash_item__cash`FOREIGN KEY (`cash_uuid`) REFERENCES `cash` (`uuid`) ON DELETE CASCADE; + + CALL drop_constraints('cash_box'); + ALTER TABLE `cash_box` + ADD CONSTRAINT `cashbox__project` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`); + + CALL drop_constraints('payroll_configuration'); + ALTER TABLE `payroll_configuration` + ADD CONSTRAINT `payroll_conf__conf_rubric` FOREIGN KEY (`config_rubric_id`) REFERENCES `config_rubric` (`id`), + ADD CONSTRAINT `payroll_conf__conf_account` FOREIGN KEY (`config_accounting_id`) REFERENCES `config_accounting` (`id`), + ADD CONSTRAINT `payroll_conf__conf_weekend`FOREIGN KEY (`config_weekend_id`) REFERENCES `weekend_config` (`id`), + ADD CONSTRAINT `payroll_conf__conf_employee` FOREIGN KEY (`config_employee_id`) REFERENCES `config_employee` (`id`); + + CALL drop_constraints('rubric_payroll'); + ALTER TABLE `rubric_payroll` + ADD CONSTRAINT `rubric_payroll__debtor_account` FOREIGN KEY (`debtor_account_id`) REFERENCES `account` (`id`), + ADD CONSTRAINT `rubric_payroll__expense_account` FOREIGN KEY (`expense_account_id`) REFERENCES `account` (`id`); +/* + CALL drop_constraints('rubric_payroll_item'); + ALTER TABLE `rubric_payroll_item` + ADD CONSTRAINT `rubric_pay_item__rubric_pay1` FOREIGN KEY (`rubric_payroll_id`) REFERENCES `rubric_payroll` (`id`), + ADD CONSTRAINT `rubric_pay_item__rubric_pay2` FOREIGN KEY (`item_id`) REFERENCES `rubric_payroll` (`id`); + +*/ + CALL drop_constraints('cash_box_account_currency'); + ALTER TABLE `cash_box_account_currency` + ADD CONSTRAINT `cashbox_acc_currency__currency` FOREIGN KEY (`currency_id`) REFERENCES `currency` (`id`), + ADD CONSTRAINT `cashbox_acc_currency__cashbox` FOREIGN KEY (`cash_box_id`) REFERENCES `cash_box` (`id`) ON UPDATE CASCADE ON DELETE CASCADE, + ADD CONSTRAINT `cashbox_acc_currency__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`), + ADD CONSTRAINT `cashbox_acc_currency__transfert_acc` FOREIGN KEY (`transfer_account_id`) REFERENCES `account` (`id`); + + + CALL drop_constraints('config_accounting'); + ALTER TABLE `config_accounting` + ADD CONSTRAINT `config_acc__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`); + + + CALL drop_constraints('config_week_days'); + ALTER TABLE `config_week_days` + ADD CONSTRAINT `config_week_days__weekend_config` FOREIGN KEY (`weekend_config_id`) REFERENCES `weekend_config` (`id`); + + CALL drop_constraints('creditor'); + ALTER TABLE `creditor` + ADD CONSTRAINT `creditor__creditor_group` FOREIGN KEY (`group_uuid`) REFERENCES `creditor_group` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE; + + CALL drop_constraints('creditor_group'); + ALTER TABLE `creditor_group` + ADD CONSTRAINT `creditor_group__enterprise` FOREIGN KEY (`enterprise_id`) REFERENCES `enterprise` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + add CONSTRAINT `creditor_group__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; + + + CALL drop_constraints('debtor'); + ALTER TABLE `debtor` + ADD + CONSTRAINT `debtor__debtor_group` FOREIGN KEY (`group_uuid`) REFERENCES `debtor_group` (`uuid`) ON DELETE CASCADE; + + CALL drop_constraints('debtor_group'); + ALTER TABLE `debtor_group` + ADD CONSTRAINT `debtor_group__enterprise` FOREIGN KEY (`enterprise_id`) REFERENCES `enterprise` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `debtor_group__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `debtor_group__location` FOREIGN KEY (`location_id`) REFERENCES `village` (`uuid`), + ADD CONSTRAINT `debtor_group__pricelist` FOREIGN KEY (`price_list_uuid`) REFERENCES `price_list` (`uuid`); + + + CALL drop_constraints('debtor_group_invoicing_fee'); + ALTER TABLE `debtor_group_invoicing_fee` + ADD CONSTRAINT `ebtor_group_invoicing_fee__invoicing_fee` FOREIGN KEY (`invoicing_fee_id`) REFERENCES `invoicing_fee` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `ebtor_group_invoicing_fee__debtor_group` FOREIGN KEY (`debtor_group_uuid`) REFERENCES `debtor_group` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE; + + + CALL drop_constraints('debtor_group_history'); + ALTER TABLE `debtor_group_history` + ADD CONSTRAINT `debtor_group_history__debtor` FOREIGN KEY (`debtor_uuid`) REFERENCES `debtor` (`uuid`), + ADD CONSTRAINT `debtor_group_history__prev_debtor_group` FOREIGN KEY (`previous_debtor_group`) REFERENCES `debtor_group` (`uuid`), + ADD CONSTRAINT `debtor_group_history__next_debtor_group` FOREIGN KEY (`next_debtor_group`) REFERENCES `debtor_group` (`uuid`), + ADD CONSTRAINT `debtor_group_history__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + + CALL drop_constraints('debtor_group_subsidy'); + ALTER TABLE `debtor_group_subsidy` + ADD CONSTRAINT `debtorgroup_subsidy__subsidy` FOREIGN KEY (`subsidy_id`) REFERENCES `subsidy` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `debtorgroup_subsidy__debtor_group` FOREIGN KEY (`debtor_group_uuid`) REFERENCES `debtor_group` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE; + + + CALL drop_constraints('discount'); + ALTER TABLE `discount` + ADD CONSTRAINT `discount__inventory` FOREIGN KEY (`inventory_uuid`) REFERENCES `inventory` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `discount__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`); + + + CALL drop_constraints('employee'); + ALTER TABLE `employee` + ADD CONSTRAINT `employee__fonction` FOREIGN KEY (`fonction_id`) REFERENCES `fonction` (`id`), + ADD CONSTRAINT `employee__service` FOREIGN KEY (`service_uuid`) REFERENCES `service` (`uuid`), + ADD CONSTRAINT `employee__creditor` FOREIGN KEY (`creditor_uuid`) REFERENCES `creditor` (`uuid`), + ADD CONSTRAINT `employee__grade` FOREIGN KEY (`grade_uuid`) REFERENCES `grade` (`uuid`), + ADD CONSTRAINT `employee__patient` FOREIGN KEY (`patient_uuid`) REFERENCES `patient` (`uuid`); + + CALL drop_constraints('rubric_paiement'); + ALTER TABLE `rubric_paiement` + ADD CONSTRAINT `rubric_paiement__paiement` FOREIGN KEY (`paiement_uuid`) REFERENCES `paiement` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `rubric_paiement__rubric_payroll` FOREIGN KEY (`rubric_payroll_id`) REFERENCES `rubric_payroll` (`id`); + + + + CALL drop_constraints('employee_advantage'); + ALTER TABLE `employee_advantage` + ADD CONSTRAINT `employee_advantage__employee` FOREIGN KEY (`employee_uuid`) REFERENCES `employee` (`uuid`), + ADD CONSTRAINT `employee_advantage__rubric_payroll` FOREIGN KEY (`rubric_payroll_id`) REFERENCES `rubric_payroll` (`id`); + + CALL drop_constraints('enterprise'); + ALTER TABLE `enterprise` + ADD CONSTRAINT `enterprise__currency` FOREIGN KEY (`currency_id`) REFERENCES `currency` (`id`), + ADD CONSTRAINT `enterprise__location` FOREIGN KEY (`location_id`) REFERENCES `village` (`uuid`), + ADD CONSTRAINT `enterprise__gain_account` FOREIGN KEY (`gain_account_id`) REFERENCES `account` (`id`), + ADD CONSTRAINT `enterprise__loss_account` FOREIGN KEY (`loss_account_id`) REFERENCES `account` (`id`); + + + + CALL drop_constraints('enterprise_setting'); + ALTER TABLE `enterprise_setting` + ADD CONSTRAINT `enterprise_setting__enterprise` FOREIGN KEY (`enterprise_id`) REFERENCES `enterprise` (`id`); + + CALL drop_constraints('exchange_rate'); + ALTER TABLE `exchange_rate` + ADD CONSTRAINT `exchange_rate__enterprise` FOREIGN KEY (`enterprise_id`) REFERENCES `enterprise` (`id`), + ADD CONSTRAINT `exchange_rate__currency` FOREIGN KEY (`currency_id`) REFERENCES `currency` (`id`); + + + CALL drop_constraints('fiscal_year'); + ALTER TABLE `fiscal_year` + ADD CONSTRAINT `fiscal_year__enterprise` FOREIGN KEY (`enterprise_id`) REFERENCES `enterprise` (`id`), + ADD CONSTRAINT `fiscal_year__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE; + + + CALL drop_constraints('general_ledger'); + ALTER TABLE `general_ledger` + ADD CONSTRAINT `general_ledger__fiscal_year` FOREIGN KEY (`fiscal_year_id`) REFERENCES `fiscal_year` (`id`), + ADD CONSTRAINT `general_ledger__period` FOREIGN KEY (`period_id`) REFERENCES `period` (`id`), + ADD CONSTRAINT `general_ledger__project` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`) ON UPDATE CASCADE, + ADD CONSTRAINT `general_ledger__currency` FOREIGN KEY (`currency_id`) REFERENCES `currency` (`id`) ON UPDATE CASCADE, + ADD CONSTRAINT `general_ledger__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`), + ADD CONSTRAINT `general_ledger__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE; + + + CALL drop_constraints('holiday'); + ALTER TABLE `holiday` + ADD CONSTRAINT `holiday__employee` FOREIGN KEY (`employee_uuid`) REFERENCES `employee` (`uuid`); + + CALL drop_constraints('holiday_paiement'); + ALTER TABLE `holiday_paiement` + ADD CONSTRAINT `holiday_paiement__paiment` FOREIGN KEY (`paiement_uuid`) REFERENCES `paiement` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `holiday_paiement__holiday` FOREIGN KEY (`holiday_id`) REFERENCES `holiday` (`id`); + + + CALL drop_constraints('offday_paiement'); + ALTER TABLE `offday_paiement` + ADD CONSTRAINT `offday_paiement__paiment` FOREIGN KEY (`paiement_uuid`) REFERENCES `paiement` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `offday_paiement__offday` FOREIGN KEY (`offday_id`) REFERENCES `offday` (`id`); + + CALL drop_constraints('inventory'); + ALTER TABLE `inventory` + ADD CONSTRAINT `inventory__enterprise` FOREIGN KEY (`enterprise_id`) REFERENCES `enterprise` (`id`), + ADD CONSTRAINT `inventory__inventory_group` FOREIGN KEY (`group_uuid`) REFERENCES `inventory_group` (`uuid`), + ADD CONSTRAINT `inventory__enventory_unit` FOREIGN KEY (`unit_id`) REFERENCES `inventory_unit` (`id`), + ADD CONSTRAINT `inventory__inventory_type` FOREIGN KEY (`type_id`) REFERENCES `inventory_type` (`id`); + + + CALL drop_constraints('paiement'); + ALTER TABLE `paiement` + ADD CONSTRAINT `paiement__employee` FOREIGN KEY (`employee_uuid`) REFERENCES `employee` (`uuid`), + ADD CONSTRAINT `paiement__payroll_configuration` FOREIGN KEY (`payroll_configuration_id`) REFERENCES `payroll_configuration` (`id`), + ADD CONSTRAINT `paiement__currency` FOREIGN KEY (`currency_id`) REFERENCES `currency` (`id`), + ADD CONSTRAINT `paiement__pay_status` FOREIGN KEY (`status_id`) REFERENCES `paiement_status` (`id`); + + CALL drop_constraints('stage_payment_indice'); + ALTER TABLE `stage_payment_indice` + ADD CONSTRAINT `stage_pay_indice__employee` FOREIGN KEY (`employee_uuid`) REFERENCES `employee` (`uuid`), + ADD CONSTRAINT `stage_pay_indice__rubric` FOREIGN KEY (`rubric_id`) REFERENCES `rubric_payroll` (`id`), + ADD CONSTRAINT `stage_pay_indice__payroll_config` FOREIGN KEY (`payroll_configuration_id`) REFERENCES `payroll_configuration` (`id`), + ADD CONSTRAINT `stage_pay_indice__currency` FOREIGN KEY (`currency_id`) REFERENCES `currency` (`id`); + + CALL drop_constraints('price_list'); + ALTER TABLE `price_list` + ADD CONSTRAINT `price_list__enterprise` FOREIGN KEY (`enterprise_id`) REFERENCES `enterprise` (`id`); + + CALL drop_constraints('price_list_item'); + ALTER TABLE `price_list_item` + ADD CONSTRAINT `price_list_item__price_list` FOREIGN KEY (`price_list_uuid`) REFERENCES `price_list` (`uuid`) ON DELETE CASCADE, + ADD CONSTRAINT `price_list_item__inventory` FOREIGN KEY (`inventory_uuid`) REFERENCES `inventory` (`uuid`) ON DELETE CASCADE; + + + CALL drop_constraints('patient'); + ALTER TABLE `patient` + ADD CONSTRAINT `patient__project` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`), + ADD CONSTRAINT `patient__debtor` FOREIGN KEY (`debtor_uuid`) REFERENCES `debtor` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `patient__current_location` FOREIGN KEY (`current_location_id`) REFERENCES `village` (`uuid`) ON UPDATE CASCADE, + ADD CONSTRAINT `patient__origin_location` FOREIGN KEY (`origin_location_id`) REFERENCES `village` (`uuid`) ON UPDATE CASCADE, + ADD CONSTRAINT `patient__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + + CALL drop_constraints('patient_document'); + ALTER TABLE `patient_document` + ADD CONSTRAINT `patient_document__patient` FOREIGN KEY (`patient_uuid`) REFERENCES `patient` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `patient_document__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + + + CALL drop_constraints('patient_group'); + ALTER TABLE `patient_group` + ADD CONSTRAINT `patient_group__enterprise` FOREIGN KEY (`enterprise_id`) REFERENCES `enterprise` (`id`), + ADD CONSTRAINT `patient_group__pricelist` FOREIGN KEY (`price_list_uuid`) REFERENCES `price_list` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE; + + + CALL drop_constraints('patient_group_invoicing_fee'); + ALTER TABLE `patient_group_invoicing_fee` + ADD CONSTRAINT `patient_group_inv_fee__iv_fee` FOREIGN KEY (`invoicing_fee_id`) REFERENCES `invoicing_fee` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `patient_group_inv_fee__patient_group` FOREIGN KEY (`patient_group_uuid`) REFERENCES `patient_group` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE; + + + CALL drop_constraints('patient_group_subsidy'); + ALTER TABLE `patient_group_subsidy` + ADD CONSTRAINT `patient_group_subsidy__subsidy` FOREIGN KEY (`subsidy_id`) REFERENCES `subsidy` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `patient_group_subsidy__patient_group` FOREIGN KEY (`patient_group_uuid`) REFERENCES `patient_group` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE; + + CALL drop_constraints('patient_visit'); + ALTER TABLE `patient_visit` + ADD CONSTRAINT `patient_visit__patient` FOREIGN KEY (`patient_uuid`) REFERENCES `patient` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `patient_visit__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `patient_visit__start_diagnosis` FOREIGN KEY (`start_diagnosis_id`) REFERENCES `icd10` (`id`) ON UPDATE CASCADE, + ADD CONSTRAINT `patient_visit__end_diagnosis`FOREIGN KEY (`end_diagnosis_id`) REFERENCES `icd10` (`id`) ON UPDATE CASCADE; + + CALL drop_constraints('patient_visit_service'); + ALTER TABLE `patient_visit_service` + ADD CONSTRAINT `patient_visit_service__patient_visit` FOREIGN KEY (`patient_visit_uuid`) REFERENCES `patient_visit` (`uuid`) ON UPDATE CASCADE, + ADD CONSTRAINT `patient_visit_service__service` FOREIGN KEY (`service_uuid`) REFERENCES `service` (`uuid`) ON UPDATE CASCADE; + + + CALL drop_constraints('patient_hospitalization'); + ALTER TABLE `patient_hospitalization` + ADD CONSTRAINT `patient_hosp__patient_visit` FOREIGN KEY (`patient_visit_uuid`) REFERENCES `patient_visit` (`uuid`) ON UPDATE CASCADE, + ADD CONSTRAINT `patient_hosp__patient` FOREIGN KEY (`patient_uuid`) REFERENCES `patient` (`uuid`) ON UPDATE CASCADE, + ADD CONSTRAINT `patient_hosp__room` FOREIGN KEY (`room_uuid`) REFERENCES `room` (`uuid`) ON UPDATE CASCADE, + ADD CONSTRAINT `patient_hosp__bed` FOREIGN KEY (`bed_id`) REFERENCES `bed` (`id`) ON UPDATE CASCADE; + + + + CALL drop_constraints('period'); + ALTER TABLE `period` + ADD CONSTRAINT `period__fiscal_year` FOREIGN KEY (`fiscal_year_id`) REFERENCES `fiscal_year` (`id`); + + CALL drop_constraints('period_total'); + ALTER TABLE `period_total` + ADD CONSTRAINT `period_total__fiscal_year` FOREIGN KEY (`fiscal_year_id`) REFERENCES `fiscal_year` (`id`), + ADD CONSTRAINT `period_total__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`), + ADD CONSTRAINT `period_total__enterprise` FOREIGN KEY (`enterprise_id`) REFERENCES `enterprise` (`id`), + ADD CONSTRAINT `period_total__period`FOREIGN KEY (`period_id`) REFERENCES `period` (`id`); + + + CALL drop_constraints('permission'); + ALTER TABLE `permission` + ADD CONSTRAINT `permission__unit` FOREIGN KEY (`unit_id`) REFERENCES `unit` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `permission__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; + + CALL drop_constraints('cron_email_report'); + ALTER TABLE `cron_email_report` + ADD CONSTRAINT `cron_email_report__entity_group` FOREIGN KEY (`entity_group_uuid`) REFERENCES `entity_group` (`uuid`) ON UPDATE CASCADE; + + + CALL drop_constraints('posting_journal'); + ALTER TABLE `posting_journal` + ADD CONSTRAINT `pg__fiscal_year` FOREIGN KEY (`fiscal_year_id`) REFERENCES `fiscal_year` (`id`), + ADD CONSTRAINT `pg__period` FOREIGN KEY (`period_id`) REFERENCES `period` (`id`), + ADD CONSTRAINT `pg__project` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`) ON UPDATE CASCADE, + ADD CONSTRAINT `pg__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`), + ADD CONSTRAINT `pg__currency` FOREIGN KEY (`currency_id`) REFERENCES `currency` (`id`) ON UPDATE CASCADE, + ADD CONSTRAINT `pg__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE; + + + CALL drop_constraints('project'); + ALTER TABLE `project` + ADD CONSTRAINT `project__enterprise` FOREIGN KEY (`enterprise_id`) REFERENCES `enterprise` (`id`); + + + + CALL drop_constraints('project_permission'); + ALTER TABLE `project_permission` + ADD CONSTRAINT `project_permission__project` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`), + ADD CONSTRAINT `project_permission__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + + CALL drop_constraints('province'); + ALTER TABLE `province` ADD CONSTRAINT `province__country` FOREIGN KEY (`country_uuid`) REFERENCES `country` (`uuid`); + + + + CALL drop_constraints('purchase'); + ALTER TABLE `purchase` + ADD CONSTRAINT `purchase__project` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`), + ADD CONSTRAINT `purchase__supplier` FOREIGN KEY (`supplier_uuid`) REFERENCES `supplier` (`uuid`), + ADD CONSTRAINT `purchase__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`), + ADD CONSTRAINT `purchase__status` FOREIGN KEY (`status_id`) REFERENCES `purchase_status` (`id`); + + + CALL drop_constraints('purchase_item'); + ALTER TABLE `purchase_item` + ADD CONSTRAINT `purchase_item__purchase` FOREIGN KEY (`purchase_uuid`) REFERENCES `purchase` (`uuid`) ON DELETE CASCADE, + ADD CONSTRAINT `purchase_item__inventory` FOREIGN KEY (`inventory_uuid`) REFERENCES `inventory` (`uuid`); + + CALL drop_constraints('reference_group'); + ALTER TABLE `reference_group` ADD CONSTRAINT `reference_group__section_bilan` FOREIGN KEY (`section_bilan_id`) REFERENCES `section_bilan` (`id`); + + CALL drop_constraints('saved_report'); + ALTER TABLE `saved_report` + ADD CONSTRAINT `saved_report__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`), + ADD CONSTRAINT `saved_report__report` FOREIGN KEY (`report_id`) REFERENCES `report` (`id`); + + CALL drop_constraints('invoice'); + ALTER TABLE `invoice` + ADD CONSTRAINT `invoice__project` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`), + ADD CONSTRAINT `invoice__debtor` FOREIGN KEY (`debtor_uuid`) REFERENCES `debtor` (`uuid`), + ADD CONSTRAINT `invoice__service` FOREIGN KEY (`service_uuid`) REFERENCES `service` (`uuid`), + ADD CONSTRAINT `invoice__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + + CALL drop_constraints('invoice_invoicing_fee'); + ALTER TABLE `invoice_invoicing_fee` + ADD CONSTRAINT `invoice_invoicing_fee__invoice` FOREIGN KEY (`invoice_uuid`) REFERENCES `invoice` (`uuid`) ON DELETE CASCADE, + ADD CONSTRAINT `invoice_invoicing_fee__invoicing_fee` FOREIGN KEY (`invoicing_fee_id`) REFERENCES `invoicing_fee` (`id`); + + + CALL drop_constraints('invoice_item'); + ALTER TABLE `invoice_item` + ADD CONSTRAINT `invoice_item__invoice` FOREIGN KEY (`invoice_uuid`) REFERENCES `invoice` (`uuid`) ON DELETE CASCADE, + ADD CONSTRAINT `invoice_item__inventory` FOREIGN KEY (`inventory_uuid`) REFERENCES `inventory` (`uuid`); + + + CALL drop_constraints('invoice_subsidy'); + ALTER TABLE `invoice_subsidy` + ADD CONSTRAINT `invoice_subsidy__invoice` FOREIGN KEY (`invoice_uuid`) REFERENCES `invoice` (`uuid`) ON DELETE CASCADE, + ADD CONSTRAINT `invoice_subsidy__subsidy` FOREIGN KEY (`subsidy_id`) REFERENCES `subsidy` (`id`); + + CALL drop_constraints('sector'); + ALTER TABLE `sector` ADD CONSTRAINT `sector__province` FOREIGN KEY (`province_uuid`) REFERENCES `province` (`uuid`); + + + CALL drop_constraints('service'); + ALTER TABLE `service` ADD CONSTRAINT `service__enterprise` FOREIGN KEY (`enterprise_id`) REFERENCES enterprise (`id`); + + + CALL drop_constraints('ward'); + ALTER TABLE `ward` ADD CONSTRAINT `ward__service` FOREIGN KEY (`service_uuid`) REFERENCES `service` (`uuid`); + + + CALL drop_constraints('room'); + ALTER TABLE `room` + ADD CONSTRAINT `room__ward` FOREIGN KEY (`ward_uuid`) REFERENCES ward (`uuid`), + ADD CONSTRAINT `room__room_type` FOREIGN KEY (`room_type_id`) REFERENCES room_type (`id`); + + CALL drop_constraints('bed'); + ALTER TABLE `bed` + ADD CONSTRAINT `bed__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE, + ADD CONSTRAINT `bed__room` FOREIGN KEY (`room_uuid`) REFERENCES room (`uuid`); + + CALL drop_constraints('subsidy'); + ALTER TABLE `subsidy` ADD CONSTRAINT `subsidy__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`); + + CALL drop_constraints('supplier'); + ALTER TABLE `supplier` ADD CONSTRAINT `supplier__creditor` FOREIGN KEY (`creditor_uuid`) REFERENCES `creditor` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE; + + CALL drop_constraints('taxe_ipr'); + ALTER TABLE `taxe_ipr` ADD CONSTRAINT `taxe_ipr__currency` FOREIGN KEY (`currency_id`) REFERENCES `currency` (`id`) ON UPDATE CASCADE; + + + CALL drop_constraints('taxe_ipr_configuration'); + ALTER TABLE `taxe_ipr_configuration` ADD CONSTRAINT `taxe_ipr_config__taxe_ipr` FOREIGN KEY (`taxe_ipr_id`) REFERENCES `taxe_ipr` (`id`) ON UPDATE CASCADE; + + CALL drop_constraints('role_actions'); + ALTER TABLE `role_actions` ADD CONSTRAINT `role_actions__action` FOREIGN KEY (`actions_id`) REFERENCES `actions` (`id`) ON UPDATE CASCADE, + ADD CONSTRAINT `role_actions__role` FOREIGN KEY (`role_uuid`) REFERENCES `role` (`uuid`) ON UPDATE CASCADE ON DELETE CASCADE; + + CALL drop_constraints('user_role'); + ALTER TABLE `user_role` + ADD CONSTRAINT `user_role__role` FOREIGN KEY (`role_uuid`) REFERENCES `role` (`uuid`) ON UPDATE CASCADE, + ADD CONSTRAINT `user_role__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE; + + CALL drop_constraints('role_unit'); + ALTER TABLE `role_unit` + ADD CONSTRAINT `role_unit__role` FOREIGN KEY (`role_uuid`) REFERENCES `role` (`uuid`) ON UPDATE CASCADE ON DELETE CASCADE, + ADD CONSTRAINT `role_unit__unit` FOREIGN KEY (`unit_id`) REFERENCES `unit` (`id`) ON UPDATE CASCADE; + + + CALL drop_constraints('village'); + ALTER TABLE `village` + ADD CONSTRAINT `village__sector` FOREIGN KEY (`sector_uuid`) REFERENCES `sector` (`uuid`); + + CALL drop_constraints('voucher'); + ALTER TABLE `voucher` + ADD CONSTRAINT `voucher__project` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`), + ADD CONSTRAINT `voucher__currency` FOREIGN KEY (`currency_id`) REFERENCES `currency` (`id`), + ADD CONSTRAINT `voucher__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + + CALL drop_constraints('voucher_item'); + ALTER TABLE `voucher_item` + ADD CONSTRAINT `voucher_item__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`), + ADD CONSTRAINT `voucher_item__voucher` FOREIGN KEY (`voucher_uuid`) REFERENCES `voucher` (`uuid`) ON DELETE CASCADE; + + CALL drop_constraints('lot'); + ALTER TABLE `lot` ADD CONSTRAINT `lot__inventory` FOREIGN KEY (`inventory_uuid`) REFERENCES `inventory` (`uuid`); + + CALL drop_constraints('stock_assign'); + ALTER TABLE `stock_assign` + ADD CONSTRAINT `stock_assign__lot` FOREIGN KEY (`lot_uuid`) REFERENCES `lot` (`uuid`), + ADD CONSTRAINT `stock_assign__entity` FOREIGN KEY (`entity_uuid`) REFERENCES `entity` (`uuid`), + ADD CONSTRAINT `stock_assign__depot` FOREIGN KEY (`depot_uuid`) REFERENCES `depot` (`uuid`); + + CALL drop_constraints('stock_requisition'); + ALTER TABLE `stock_requisition` ADD CONSTRAINT `stock_requisition__depot` FOREIGN KEY (`depot_uuid`) REFERENCES `depot` (`uuid`); + + CALL drop_constraints('stock_requisition_item'); + ALTER TABLE `stock_requisition_item` ADD CONSTRAINT `stock_req_item__stock_req_item` FOREIGN KEY (`requisition_uuid`) REFERENCES `stock_requisition` (`uuid`); + + + CALL drop_constraints('stock_movement'); + ALTER TABLE `stock_movement` + ADD CONSTRAINT `stock_movement__depot` FOREIGN KEY (`depot_uuid`) REFERENCES `depot` (`uuid`), + ADD CONSTRAINT `stock_movement__lot` FOREIGN KEY (`lot_uuid`) REFERENCES `lot` (`uuid`), + ADD CONSTRAINT `stock_movement__flux` FOREIGN KEY (`flux_id`) REFERENCES `flux` (`id`), + ADD CONSTRAINT `stock_movement__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`), + ADD CONSTRAINT `stock_movement__period` FOREIGN KEY (`period_id`) REFERENCES `period` (`id`); + + CALL drop_constraints('stock_consumption'); + ALTER TABLE `stock_consumption` + ADD CONSTRAINT `stock_consumption__inventory` FOREIGN KEY (`inventory_uuid`) REFERENCES `inventory` (`uuid`), + ADD CONSTRAINT `stock_consumption__depot` FOREIGN KEY (`depot_uuid`) REFERENCES `depot` (`uuid`), + ADD CONSTRAINT `stock_consumption__period` FOREIGN KEY (`period_id`) REFERENCES `period` (`id`); + + CALL drop_constraints('transaction_history'); + ALTER TABLE `transaction_history` ADD CONSTRAINT `transaction_history__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + + + CALL drop_constraints('depot_permission'); + ALTER TABLE `depot_permission` + ADD CONSTRAINT `depot_permission__depot` FOREIGN KEY (`depot_uuid`) REFERENCES `depot` (`uuid`), + ADD CONSTRAINT `depot_permission__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + + + CALL drop_constraints('cashbox_permission'); + ALTER TABLE `cashbox_permission` + ADD CONSTRAINT `cashbox_permission__cashbox` FOREIGN KEY (`cashbox_id`) REFERENCES `cash_box` (`id`), + ADD CONSTRAINT `cashbox_permission__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + + + CALL drop_constraints('config_employee_item'); + ALTER TABLE `config_employee_item` + ADD CONSTRAINT `config_employee_item__config_employee` FOREIGN KEY (`config_employee_id`) REFERENCES `config_employee` (`id`), + ADD CONSTRAINT `config_employee_item__employee` FOREIGN KEY (`employee_uuid`) REFERENCES `employee` (`uuid`); + + + + CALL drop_constraints('reference_fee_center'); + ALTER TABLE `reference_fee_center` + ADD CONSTRAINT `reference_fee_center__fee_center` FOREIGN KEY (`fee_center_id`) REFERENCES `fee_center` (`id`), + ADD CONSTRAINT `reference_fee_center__account_ref` FOREIGN KEY (`account_reference_id`) REFERENCES `account_reference` (`id`); + + CALL drop_constraints('fee_center_distribution'); + ALTER TABLE `fee_center_distribution` + ADD CONSTRAINT `fee_center_distribution__general_ledger` FOREIGN KEY (`row_uuid`) REFERENCES `general_ledger` (`uuid`), + ADD CONSTRAINT `fee_center_distribution__account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`), + ADD CONSTRAINT `fee_center_distribution__auxiliary_fee_center` FOREIGN KEY (`auxiliary_fee_center_id`) REFERENCES `fee_center` (`id`), + ADD CONSTRAINT `fee_center_distribution__principal_fee_center` FOREIGN KEY (`principal_fee_center_id`) REFERENCES `fee_center` (`id`), + ADD CONSTRAINT `fee_center_distribution__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE; + + + + CALL drop_constraints('service_fee_center'); + ALTER TABLE `service_fee_center` + ADD CONSTRAINT `service_fee_center__service` FOREIGN KEY (`service_uuid`) REFERENCES `service` (`uuid`), + ADD CONSTRAINT `service_fee_center__fee_center` FOREIGN KEY (`fee_center_id`) REFERENCES `fee_center` (`id`); + + + CALL drop_constraints('distribution_key'); + ALTER TABLE `distribution_key` + ADD CONSTRAINT `distribution_key__auxiliary_fc` FOREIGN KEY (`auxiliary_fee_center_id`) REFERENCES `fee_center` (`id`), + ADD CONSTRAINT `distribution_key__principal_fc` FOREIGN KEY (`principal_fee_center_id`) REFERENCES `fee_center` (`id`), + ADD CONSTRAINT `distribution_key__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE; + + CALL drop_constraints('indicator'); + ALTER TABLE `indicator` + ADD CONSTRAINT `indicator__period` FOREIGN KEY (`period_id`) REFERENCES `period` (`id`) ON UPDATE CASCADE, + ADD CONSTRAINT `indicator__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE, + ADD CONSTRAINT `indicator__indicator_status` FOREIGN KEY (`status_id`) REFERENCES `indicator_status` (`id`) ON UPDATE CASCADE, + ADD CONSTRAINT `indicator__indicator_type` FOREIGN KEY (`type_id`) REFERENCES `indicator_type` (`id`) ON UPDATE CASCADE; + + + CALL drop_constraints('hospitalization_indicator'); + ALTER TABLE `hospitalization_indicator` ADD CONSTRAINT `hosp_indicator__indicator` FOREIGN KEY (`indicator_uuid`) REFERENCES `indicator` (`uuid`) ON UPDATE CASCADE; + + + CALL drop_constraints('staff_indicator'); + ALTER TABLE `staff_indicator` ADD CONSTRAINT `staff_indicator__indicator` FOREIGN KEY (`indicator_uuid`) REFERENCES `indicator` (`uuid`) ON UPDATE CASCADE; + + + CALL drop_constraints('finance_indicator'); + ALTER TABLE `finance_indicator` ADD CONSTRAINT `finance_indicator__indicator` FOREIGN KEY (`indicator_uuid`) REFERENCES `indicator` (`uuid`) ON UPDATE CASCADE; + + CALL drop_constraints('break_even_reference'); + ALTER TABLE `break_even_reference` ADD + CONSTRAINT `break_even_ref__acc_ref` FOREIGN KEY (`account_reference_id`) REFERENCES `account_reference` (`id`); + + + CALL drop_constraints('inventory_log'); + ALTER TABLE `inventory_log` ADD CONSTRAINT `inventory_log__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + + + + CALL drop_constraints('staffing_indice'); + ALTER TABLE `staffing_indice` + ADD CONSTRAINT `staffing_indice__employee` FOREIGN KEY (`employee_uuid`) REFERENCES `employee` (`uuid`), + ADD CONSTRAINT `staffing_indice__fonction` FOREIGN KEY (`fonction_id`) REFERENCES `fonction` (`id`), + ADD CONSTRAINT `staffing_indice__grade` FOREIGN KEY (`grade_uuid`) REFERENCES `grade` (`uuid`); + + + CALL drop_constraints('staffing_grade_indice'); + ALTER TABLE `staffing_grade_indice` ADD CONSTRAINT `staffing_grade_indice__grade` FOREIGN KEY (`grade_uuid`) REFERENCES `grade` (`uuid`); + + + CALL drop_constraints('staffing_function_indice'); + ALTER TABLE `staffing_function_indice` + ADD CONSTRAINT `staffing_function_indice__fct` FOREIGN KEY (`fonction_id`) REFERENCES `fonction` (`id`); + + CALL drop_constraints('staffing_indice_parameters'); + ALTER TABLE `staffing_indice_parameters` + ADD CONSTRAINT `staffing_indice_param__payrall_config` FOREIGN KEY (`payroll_configuration_id`) REFERENCES `payroll_configuration` (`id`); + + CALL drop_constraints('survey_form'); + ALTER TABLE `survey_form` ADD CONSTRAINT `survey_form__data_collector_management` FOREIGN KEY (`data_collector_management_id`) REFERENCES `data_collector_management` (`id`); + + CALL drop_constraints('survey_data'); + ALTER TABLE `survey_data` + ADD CONSTRAINT `survey_data__data_collector_management` FOREIGN KEY (`data_collector_management_id`) REFERENCES `data_collector_management` (`id`), + ADD CONSTRAINT `survey_data__user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + + CALL drop_constraints('survey_data_item'); + ALTER TABLE `survey_data_item` + ADD CONSTRAINT `survey_data_item__survey_form` FOREIGN KEY (`survey_form_id`) REFERENCES `survey_form` (`id`), + ADD CONSTRAINT `survey_data_item__survey_data` FOREIGN KEY (`survey_data_uuid`) REFERENCES `survey_data` (`uuid`); + + CALL drop_constraints('survey_data_log'); + ALTER TABLE `survey_data_log` + ADD CONSTRAINT `survey_data_log__survey_form` FOREIGN KEY (`survey_form_id`) REFERENCES `survey_form` (`id`), + ADD CONSTRAINT `survey_data_log__survey_data` FOREIGN KEY (`survey_data_uuid`) REFERENCES `survey_data` (`uuid`); + + CALL drop_constraints('medical_sheet'); + ALTER TABLE `medical_sheet` + ADD CONSTRAINT `medical_sheet__survey_data` FOREIGN KEY (`survey_data_uuid`) REFERENCES `survey_data` (`uuid`), + ADD CONSTRAINT `medical_sheet__patient` FOREIGN KEY (`patient_uuid`) REFERENCES `patient` (`uuid`); + + + CALL drop_constraints('configuration_analysis_tools'); + ALTER TABLE `configuration_analysis_tools` + ADD CONSTRAINT `config_analysis_tools__acc_ref` FOREIGN KEY (`account_reference_id`) REFERENCES `account_reference` (`id`), + ADD CONSTRAINT `config_analysis_tools__analysis_tool_type` FOREIGN KEY (`analysis_tool_type_id`) REFERENCES `analysis_tool_type` (`id`); + + SET foreign_key_checks = 1; + + + + +/* +@author : jeremielodi +@date : 2020-07-22 +@subject : Stock expiration report +*/ + +INSERT INTO `report` (`report_key`, `title_key`) VALUES +('stock_expiration_report', 'REPORT.STOCK_EXPIRATION_REPORT.TITLE'); + + INSERT INTO unit VALUES +(289, '[Stock] Expiration report','TREE.STOCK_EXPIRATION_REPORT','Stock expiration report', 282,'/reports/stock_expiration_report'); + +/* + * @author: mbayopanda + * @date: 2020-08-17 + * @description: rename collection capacity to recovery capacity + */ +UPDATE unit SET + `name` = "Recovery Capacity", + `key` = "TREE.RECOVERY_CAPACITY_REPORT", + `description` = "Recovery Capacity Report", + `path` = "/reports/recoveryCapacity" +WHERE id = 271; + +UPDATE `report` SET + `report_key` = "recoveryCapacity", + `title_key` = "REPORT.RECOVERY_CAPACITY.TITLE" +WHERE report_key = "collectionCapacity"; + +/* + * @author: mbayopanda + * @date: 2020-08-17 + * @description: add address field in the enterprise table + */ +ALTER TABLE enterprise ADD COLUMN `address` VARCHAR(200) DEFAULT NULL; + +/* + * @author: mbayopanda + * @date: 2020-07-20 + */ +ALTER TABLE `tags` ADD COLUMN `color` VARCHAR(50) NULL; + +DROP TABLE IF EXISTS `lot_tag`; +CREATE TABLE `lot_tag` ( + `lot_uuid` BINARY(16) NOT NULL, + `tag_uuid` BINARY(16) NOT NULL, + FOREIGN KEY (`lot_uuid`) REFERENCES `lot` (`uuid`), + FOREIGN KEY (`tag_uuid`) REFERENCES `tags` (`uuid`) +) ENGINE=InnoDB DEFAULT CHARACTER SET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; + +/* + * @author: jmcameron + * @date: 2020-08-28 + * @description: add min_months_security_stock to enterprise and depot tables + */ +ALTER TABLE `depot` ADD COLUMN `min_months_security_stock` SMALLINT(5) NOT NULL DEFAULT 2; +ALTER TABLE `enterprise_setting` ADD COLUMN `min_months_security_stock` SMALLINT(5) NOT NULL DEFAULT 2; + + +/* + * @author: jeremielodi + on @jniles PR https://github.com/IMA-WorldHealth/bhima/pull/4866 + * @date: 2020-08-31 + */ +DROP TABLE IF EXISTS `stock_movement_status`; +CREATE TABLE `stock_movement_status` ( + `uuid` BINARY(16) NOT NULL, + `start_date` DATE, + `end_date` DATE, + `quantity` DECIMAL(19,4) NOT NULL, + `in_quantity` DECIMAL(19,4) NOT NULL, + `out_quantity` DECIMAL(19,4) NOT NULL, + `inventory_uuid` BINARY(16) NOT NULL, + `depot_uuid` BINARY(16) NOT NULL, + PRIMARY KEY(`uuid`), + KEY `depot_uuid` (`depot_uuid`), + CONSTRAINT `stock_movement_status__depot` FOREIGN KEY (`depot_uuid`) REFERENCES `depot` (`uuid`), + KEY `inventory_uuid` (`inventory_uuid`), + CONSTRAINT `stock_movment_status__inventory` FOREIGN KEY (`inventory_uuid`) REFERENCES `inventory` (`uuid`) +) ENGINE=InnoDB DEFAULT CHARACTER SET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; + +/* + * @author: mbayopanda + * @date: 2020-09-07 + * @description: Add the importance level column in the inventory table + * the importance value can be : + * NULL -> The inventory doesn't need a particular focus for dashboards + * 1 -> LOW + * 2 -> MID + * 3 -> HIGH + */ +ALTER TABLE inventory ADD COLUMN `importance` SMALLINT(5) NULL COMMENT 'Inventory level of importance : 1 -> LOW, 2 -> MID, 3 -> HIGH'; + + +/* + * @author: jniles + * @date: 2020-09-10 + * @description: add enterprise setting for crediting supplier's invoice on stock + * entry from purchase. + */ +ALTER TABLE `enterprise_setting` ADD COLUMN `enable_supplier_credit` TINYINT(1) NOT NULL DEFAULT 0; + +/* + * @author: mbayopanda + * @date: 2020-09-16 + * @desc: add enterprise setting for strict depot permission which will restrict stock registries to depot owner + */ + ALTER TABLE `enterprise_setting` ADD COLUMN `enable_strict_depot_permission` TINYINT(1) NOT NULL DEFAULT 0; + +/* + * @author: jeremielodi + * @date: 2020-09-18 + * @desc: unpost transactions #4927 + */ +INSERT INTO `actions`(`id`, `description`) VALUES + (2, 'FORM.LABELS.CAN_UNPOST_TRANSACTIONS'); + + +ALTER TABLE `transaction_history` ADD COLUMN `action` VARCHAR(15) DEFAULT 'edit'; + + + +/* +@author : jeremielodi +@subjet : put indicator report into dashboard folder +@date : 2020-09-24 +*/ + +UPDATE unit SET parent = 233 WHERE id = 238; + +/*@author : jeremielodi +@date : 2020-08-19 +@subject : Donor management +*/ +INSERT INTO unit VALUES +(290,'Donors','TREE.DONOR','Donors management',1,'/donors'); diff --git a/test/integration/donor.js b/test/integration/donor.js new file mode 100644 index 0000000000..f13dcb9c28 --- /dev/null +++ b/test/integration/donor.js @@ -0,0 +1,66 @@ +/* eslint no-unused-expressions:off */ +/* global expect, agent */ + +const helpers = require('./helpers'); + +/* + * The /donors API endpoint + * + * This test suite implements full CRUD on the /donor HTTP API endpoint. + */ +describe('(/donors) The donros API endpoint', () => { + + // donor we will add during this test suite. + const newDonor = { + id : 2, + display_name : 'IMA', + }; + + const updatedDonor = { + display_name : 'DFID', + }; + + // default donor in data.sql + it('GET /donors returns a list of one donor', async () => { + try { + const res = await agent.get('/donors'); + expect(res).to.have.status(200); + expect(res.body).to.be.an('array'); + expect(res.body).to.have.length(1); + } catch (error) { + helpers.handler(error); + } + }); + + it('POST /donors add a new donor', async () => { + try { + const res = await agent.post('/donors').send(newDonor); + expect(res).to.have.status(201); + } catch (error) { + helpers.handler(error); + } + + }); + + it('GET /donors/:id find donor by id', async () => { + + try { + const res = await agent.get(`/donors/${newDonor.id}`); + expect(res).to.have.status(200); + expect(newDonor).to.deep.equal(res.body); + } catch (error) { + helpers.handler(error); + } + }); + + it('PUT /donors update donors\'s display_name', async () => { + + try { + const res = await agent.put(`/donors/${newDonor.id}`).send(updatedDonor); + expect(res).to.have.status(200); + } catch (error) { + helpers.handler(error); + } + }); + +}); From eb49ae45706f6fab774aad9be20ac555c4f24a15 Mon Sep 17 00:00:00 2001 From: jeremielodi Date: Mon, 24 Aug 2020 09:56:52 +0100 Subject: [PATCH 2/9] e2e test for donor management --- client/src/modules/donor/donor.ctrl.js | 18 +++++- client/src/modules/donor/donor.html | 2 +- .../src/modules/donor/modal/createUpdate.html | 26 ++++++++ .../generate/stock_entry/stock_entry.html | 16 +++-- server/controllers/admin/donor.js | 4 +- server/models/migrations/next/migrate.sql | 5 ++ server/models/schema.sql | 3 + test/end-to-end/donor/donor.page.js | 63 +++++++++++++++++++ test/end-to-end/donor/donor.spec.js | 47 ++++++++++++++ test/integration/donor.js | 3 + 10 files changed, 179 insertions(+), 8 deletions(-) create mode 100644 test/end-to-end/donor/donor.page.js create mode 100644 test/end-to-end/donor/donor.spec.js diff --git a/client/src/modules/donor/donor.ctrl.js b/client/src/modules/donor/donor.ctrl.js index 5c05a9a9dc..2ea1620498 100644 --- a/client/src/modules/donor/donor.ctrl.js +++ b/client/src/modules/donor/donor.ctrl.js @@ -50,7 +50,23 @@ function DonorController($uibModal, Donor, Modal, Notify, uiGridConstants) { field : 'display_name', displayName : 'FORM.LABELS.NAME', headerCellFilter : 'translate', - }, { + }, + { + field : 'phone', + displayName : 'FORM.LABELS.PHONE', + headerCellFilter : 'translate', + }, + { + field : 'email', + displayName : 'FORM.LABELS.EMAIL', + headerCellFilter : 'translate', + }, + { + field : 'address', + displayName : 'FORM.LABELS.ADDRESS', + headerCellFilter : 'translate', + }, + { field : 'actions', enableFiltering : false, width : 100, diff --git a/client/src/modules/donor/donor.html b/client/src/modules/donor/donor.html index 41ec3d3496..0e24423a6b 100644 --- a/client/src/modules/donor/donor.html +++ b/client/src/modules/donor/donor.html @@ -22,7 +22,7 @@
+ +
+ + +
+
+
+
+ + +
+ + +
+
+
+
+ + +
+ + +
+
+
+
diff --git a/client/src/modules/reports/generate/stock_entry/stock_entry.html b/client/src/modules/reports/generate/stock_entry/stock_entry.html index 7b92a85eac..9464185371 100644 --- a/client/src/modules/reports/generate/stock_entry/stock_entry.html +++ b/client/src/modules/reports/generate/stock_entry/stock_entry.html @@ -43,28 +43,36 @@

REPORT.STOCK.ENTRY_REPORT

diff --git a/server/controllers/admin/donor.js b/server/controllers/admin/donor.js index a591d63aa4..fb22b6e37a 100644 --- a/server/controllers/admin/donor.js +++ b/server/controllers/admin/donor.js @@ -24,14 +24,14 @@ function update(req, res, next) { } function read(req, res, next) { - db.exec(`SELECT id, display_name FROM donor`).then(donors => { + db.exec(`SELECT id, display_name, email, phone, address FROM donor`).then(donors => { res.status(200).json(donors); }).catch(next); } function detail(req, res, next) { const { id } = req.params; - db.one(`SELECT id, display_name FROM donor WHERE id=?`, id).then(donor => { + db.one(`SELECT id, display_name, email, phone, address FROM donor WHERE id=?`, id).then(donor => { res.status(200).json(donor); }).catch(next); } diff --git a/server/models/migrations/next/migrate.sql b/server/models/migrations/next/migrate.sql index 59022e365a..e002a95005 100644 --- a/server/models/migrations/next/migrate.sql +++ b/server/models/migrations/next/migrate.sql @@ -794,3 +794,8 @@ UPDATE unit SET parent = 233 WHERE id = 238; */ INSERT INTO unit VALUES (290,'Donors','TREE.DONOR','Donors management',1,'/donors'); + +ALTER TABLE `donor` + ADD COLUMN `email` VARCHAR(50) DEFAULT NULL, + ADD COLUMN `phone` VARCHAR(50) DEFAULT NULL, + ADD COLUMN `address` VARCHAR(150) DEFAULT NULL; \ No newline at end of file diff --git a/server/models/schema.sql b/server/models/schema.sql index a2413a4e21..52ec75b4a3 100644 --- a/server/models/schema.sql +++ b/server/models/schema.sql @@ -2011,6 +2011,9 @@ DROP TABLE IF EXISTS `donor`; CREATE TABLE `donor` ( `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, `display_name` VARCHAR(191) NOT NULL, + `phone` VARCHAR(50) NULL, + `email` VARCHAR(50) NULL, + `address` VARCHAR(150) NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARACTER SET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; diff --git a/test/end-to-end/donor/donor.page.js b/test/end-to-end/donor/donor.page.js new file mode 100644 index 0000000000..098f57ea5e --- /dev/null +++ b/test/end-to-end/donor/donor.page.js @@ -0,0 +1,63 @@ +/* global element, by, browser */ +const EC = require('protractor').ExpectedConditions; +const FU = require('../shared/FormUtils'); +const GridRow = require('../shared/GridRow'); + +const { bhCheckboxTree } = require('../shared/components'); + +class DonorPage { + constructor() { + this.gridId = 'donor-grid'; + this.donorName = element(by.model('DonorAddCtrl.donor.display_name')); + this.donorPhone = element(by.model('DonorAddCtrl.donor.phone')); + this.donorEmail = element(by.model('DonorAddCtrl.donor.email')); + this.donorAddress = element(by.model('DonorAddCtrl.donor.address')); + } + + submit() { + return FU.modal.submit(); + } + + setName(txt) { + return this.donorName.clear().sendKeys(txt); + } + + setPhone(txt) { + return this.donorPhone.clear().sendKeys(txt); + } + + setEmail(txt) { + return this.donorEmail.clear().sendKeys(txt); + } + + setAddress(txt) { + return this.donorAddress.clear().sendKeys(txt); + } + + async openDropdownMenu(label) { + const row = new GridRow(label); + await row.dropdown().click(); + return row; + } + + async editDonor(displayName) { + const row = await this.openDropdownMenu(displayName); + await row.edit().click(); + } + + async deleteDonor(displayName) { + const row = await this.openDropdownMenu(displayName); + await row.remove().click(); + } + + async checkAllPermissions() { + await browser.wait(EC.presenceOf($(bhCheckboxTree.selector)), 1500); + await bhCheckboxTree.toggleAllCheckboxes(); + } + + openCreateModal() { + return FU.buttons.create(); + } +} + +module.exports = DonorPage; diff --git a/test/end-to-end/donor/donor.spec.js b/test/end-to-end/donor/donor.spec.js new file mode 100644 index 0000000000..cf0f0d1b1f --- /dev/null +++ b/test/end-to-end/donor/donor.spec.js @@ -0,0 +1,47 @@ +const helpers = require('../shared/helpers'); +const DonorsPage = require('./donor.page'); +const components = require('../shared/components'); + +// the page object +const page = new DonorsPage(); + +function donorsManagementTests() { + + // navigate to the page + before(() => helpers.navigate('#/donors')); + + it('should add a new donor', async () => { + await page.openCreateModal(); + await page.setName('DFD'); + await page.setEmail('dfid@imaworld.com'); + await page.setPhone('+100000202'); + await page.setAddress('232 USA ..'); + await page.submit(); + await components.notification.hasSuccess(); + }); + + it('should add a edit donor', async () => { + await page.editDonor('DFD'); + await page.setName('DFID'); + await page.submit(); + await components.notification.hasSuccess(); + }); + + it('should add a test donor', async () => { + await page.openCreateModal(); + await page.setName('Test donor'); + await page.submit(); + await components.notification.hasSuccess(); + }); + + it('should delete the test donor', async () => { + await page.deleteDonor('Test donor'); + await page.submit(); + await components.notification.hasSuccess(); + }); + +} + +describe('donor Management Tests', () => { + describe('donor Management', donorsManagementTests); +}); diff --git a/test/integration/donor.js b/test/integration/donor.js index f13dcb9c28..5401bbc33c 100644 --- a/test/integration/donor.js +++ b/test/integration/donor.js @@ -14,6 +14,9 @@ describe('(/donors) The donros API endpoint', () => { const newDonor = { id : 2, display_name : 'IMA', + email : 'ima@gmail.com', + phone : '+243810000001', + address : '289 Kinshasa, RDC', }; const updatedDonor = { From 54abcc2db8230ac7f81c5d0691bb0cdd519ae8ff Mon Sep 17 00:00:00 2001 From: jeremielodi Date: Mon, 24 Aug 2020 14:07:01 +0100 Subject: [PATCH 3/9] (stock entry) find donation modal --- client/src/modules/donor/donation.service.js | 15 +++ client/src/modules/stock/entry/entry.js | 25 ++-- .../entry/modals/findDonation.modal.html | 54 ++++++++ .../stock/entry/modals/findDonation.modal.js | 117 ++++++++++++++++++ client/src/modules/stock/stock.service.js | 14 +++ server/config/routes.js | 9 ++ server/controllers/admin/donation.js | 60 +++++++++ 7 files changed, 283 insertions(+), 11 deletions(-) create mode 100644 client/src/modules/donor/donation.service.js create mode 100644 client/src/modules/stock/entry/modals/findDonation.modal.html create mode 100644 client/src/modules/stock/entry/modals/findDonation.modal.js create mode 100644 server/controllers/admin/donation.js diff --git a/client/src/modules/donor/donation.service.js b/client/src/modules/donor/donation.service.js new file mode 100644 index 0000000000..342fc0c559 --- /dev/null +++ b/client/src/modules/donor/donation.service.js @@ -0,0 +1,15 @@ +angular.module('bhima.services') + .service('DonationService', DonationService); + +DonationService.$inject = ['PrototypeApiService']; + +/** + * Role Service + * + * A service wrapper for the /donors HTTP endpoint. + * + */ +function DonationService(Api) { + const service = new Api('/donations/'); + return service; +} diff --git a/client/src/modules/stock/entry/entry.js b/client/src/modules/stock/entry/entry.js index 24d351c4eb..70a4cafc12 100644 --- a/client/src/modules/stock/entry/entry.js +++ b/client/src/modules/stock/entry/entry.js @@ -260,7 +260,7 @@ function StockEntryController( * @description * set movement information according the selected entity and populate the grid */ - function handleSelectedEntity(_entities, _type) { + function handleSelectedEntity(_entities, _type, noPopulate = false) { if (!_entities || !_entities.length) { resetSelectedEntity(); return; @@ -276,7 +276,10 @@ function StockEntryController( setDescription(vm.movement.entity); // populate the grid - populate(_entities); + if (!noPopulate) { + populate(_entities); + } + } /** @@ -348,9 +351,17 @@ function StockEntryController( function handleDonationSelection() { const description = $translate.instant('STOCK.RECEPTION_DONATION'); initSelectedEntity(description); + if (vm.gridOptions.data.length === 0) { vm.addItems(1); } + + StockModal.openFindDonation() + .then((donation) => { + handleSelectedEntity(donation, 'donation', true); + setSelectedEntity(vm.movement.entity.instance); + }) + .catch(Notify.handleError); } /** @@ -505,7 +516,6 @@ function StockEntryController( .catch(Notify.handleError); } - /** * @method submitIntegration * @description prepare the stock movement and send data to the server as new stock integration @@ -547,14 +557,7 @@ function StockEntryController( user_id : vm.stockForm.details.user_id, }; - /* - the origin_uuid of lots is set on the client - because donation table depends on donor, and donor management - is not yet implemented in the application - - TODO: add a donor management module - */ - movement.lots = Stock.processLotsFromStore(vm.stockForm.store.data, Uuid()); + movement.lots = Stock.processLotsFromStore(vm.stockForm.store.data, vm.movement.entity.uuid); return Stock.stocks.create(movement) .then((document) => { diff --git a/client/src/modules/stock/entry/modals/findDonation.modal.html b/client/src/modules/stock/entry/modals/findDonation.modal.html new file mode 100644 index 0000000000..b64d4eb99a --- /dev/null +++ b/client/src/modules/stock/entry/modals/findDonation.modal.html @@ -0,0 +1,54 @@ +
+ + + + + + + +
\ No newline at end of file diff --git a/client/src/modules/stock/entry/modals/findDonation.modal.js b/client/src/modules/stock/entry/modals/findDonation.modal.js new file mode 100644 index 0000000000..af636fac79 --- /dev/null +++ b/client/src/modules/stock/entry/modals/findDonation.modal.js @@ -0,0 +1,117 @@ +angular.module('bhima.controllers') + .controller('StockFindDonationModalController', StockFindDonationModalController); + +StockFindDonationModalController.$inject = [ + '$uibModalInstance', 'DonationService', 'NotifyService', + 'uiGridConstants', 'GridFilteringService', 'ReceiptModal', + 'bhConstants', +]; + +function StockFindDonationModalController( + Instance, Donation, Notify, + uiGridConstants, Filtering, Receipts, bhConstants, +) { + const vm = this; + + // global + vm.selectedRow = {}; + + /* ======================= Grid configurations ============================ */ + vm.filterEnabled = false; + vm.gridOptions = { appScopeProvider : vm }; + + const filtering = new Filtering(vm.gridOptions); + + const columns = [ + { + field : 'reference', + displayName : 'TABLE.COLUMNS.REFERENCE', + headerCellFilter : 'translate', + cellTemplate : 'modules/stock/entry/modals/templates/purchase_reference.tmpl.html', + }, + + { + field : 'date', + cellFilter : 'date:"'.concat(bhConstants.dates.format, '"'), + filter : { condition : filtering.filterByDate }, + displayName : 'TABLE.COLUMNS.DATE', + headerCellFilter : 'translate', + sort : { priority : 0, direction : 'desc' }, + }, + + { + field : 'display_name', + displayName : 'TREE.DONOR', + headerCellFilter : 'translate', + }, + { + field : 'project_name', + displayName : 'FORM.LABELS.PROJECT', + headerCellFilter : 'translate', + }, + { + field : 'description', + displayName : 'FORM.LABELS.DESCRIPTION', + headerCellFilter : 'translate', + }, + ]; + + vm.gridOptions.columnDefs = columns; + vm.gridOptions.multiSelect = false; + vm.gridOptions.enableFiltering = vm.filterEnabled; + vm.gridOptions.onRegisterApi = onRegisterApi; + vm.toggleFilter = toggleFilter; + + // bind methods + vm.submit = submit; + vm.cancel = cancel; + vm.showReceipt = showReceipt; + + function onRegisterApi(gridApi) { + vm.gridApi = gridApi; + vm.gridApi.selection.on.rowSelectionChanged(null, rowSelectionCallback); + } + + function rowSelectionCallback(row) { + vm.selectedRow = row.entity; + } + + /** toggle filter */ + function toggleFilter() { + vm.filterEnabled = !vm.filterEnabled; + vm.gridOptions.enableFiltering = vm.filterEnabled; + vm.gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN); + } + + /** get purchase document */ + function showReceipt(uuid) { + Receipts.purchase(uuid); + } + + /* ======================= End Grid ======================================== */ + function load() { + vm.loading = true; + Donation.read() + .then(donations => { + vm.gridOptions.data = donations; + }) + .catch(() => { + vm.hasError = true; + }) + .finally(() => { + vm.loading = false; + }); + } + + // submit + function submit() { + if (!vm.selectedRow || (vm.selectedRow && !vm.selectedRow.uuid)) { return null; } + return Instance.close([].concat(vm.selectedRow)); + } + // cancel + function cancel() { + Instance.close(); + } + + load(); +} diff --git a/client/src/modules/stock/stock.service.js b/client/src/modules/stock/stock.service.js index 629b24d264..7a0704dee7 100644 --- a/client/src/modules/stock/stock.service.js +++ b/client/src/modules/stock/stock.service.js @@ -24,6 +24,7 @@ function StockModalService(Modal) { service.openFindService = openFindService; service.openFindDepot = openFindDepot; service.openFindPurchase = openFindPurchase; + service.openFindDonation = openFindDonation; service.openDefineLots = openDefineLots; service.openFindTansfer = openFindTansfer; service.openActionStockAssign = openActionStockAssign; @@ -226,6 +227,19 @@ function StockModalService(Modal) { return instance.result; } + /** search donation */ + function openFindDonation(request) { + const params = angular.extend(modalParameters, { + templateUrl : 'modules/stock/entry/modals/findDonation.modal.html', + controller : 'StockFindDonationModalController', + controllerAs : '$ctrl', + resolve : { data : () => request }, + }); + + const instance = Modal.open(params); + return instance.result; + } + /** search transfer */ function openFindTansfer(request) { const params = angular.extend(modalParameters, { diff --git a/server/config/routes.js b/server/config/routes.js index 8b53e5664d..670060494b 100644 --- a/server/config/routes.js +++ b/server/config/routes.js @@ -26,6 +26,7 @@ const install = require('../controllers/install'); const rolesCtrl = require('../controllers/admin/roles'); const users = require('../controllers/admin/users'); const donor = require('../controllers/admin/donor'); +const donation = require('../controllers/admin/donation'); const projects = require('../controllers/admin/projects'); const enterprises = require('../controllers/admin/enterprises'); const services = require('../controllers/admin/services'); @@ -571,6 +572,14 @@ exports.configure = function configure(app) { app.get('/donors/:id', donor.detail); app.put('/donors/:id', donor.update); app.delete('/donors/:id', donor.remove); + + // donor controller + app.get('/donations', donation.read); + app.post('/donations', donation.create); + app.get('/donations/:uuid', donation.detail); + app.put('/donations/:uuid', donation.update); + app.delete('/donations/:uuid', donation.remove); + // projects controller app.get('/projects/:id', projects.detail); app.put('/projects/:id', projects.update); diff --git a/server/controllers/admin/donation.js b/server/controllers/admin/donation.js new file mode 100644 index 0000000000..d3c008b03d --- /dev/null +++ b/server/controllers/admin/donation.js @@ -0,0 +1,60 @@ +const db = require('../../lib/db'); + +module.exports = { + create, + update, + read, + remove, + detail, +}; + +function create(req, res, next) { + const data = req.body; + data.uuid = data.uuid ? db.bid(data.uuid) : db.uuid(); + + db.exec(`INSERT INTO donation SET ?`, data).then(() => { + res.sendStatus(201); + }).catch(next); +} + +function update(req, res, next) { + const data = req.body; + const { uuid } = req.params; + db.exec(`UPDATE donation SET ? WHERE uuid=?`, [data, db.bid(uuid)]).then(() => { + res.sendStatus(200); + }).catch(next); +} + +function read(req, res, next) { + const sql = ` + SELECT BUID(dt.uuid) as uuid, dt.reference, dt.project_id, + dt.description, + dt.date, + dt.donor_id, d.display_name, p.name as project_name + FROM donation dt + JOIN project p ON p.id= dt.project_id + JOIN donor d ON d.id= dt.donor_id + `; + + db.exec(sql).then(donations => { + res.status(200).json(donations); + }).catch(next); +} + +function detail(req, res, next) { + const sql = ` + SELECT BUID(uuid) as uuid, reference, project_id, description, date, donor_id + FROM donation + WHERE uuid=?`; + const { uuid } = req.params; + db.one(sql, db.bid(uuid)).then(donation => { + res.status(200).json(donation); + }).catch(next); +} + +function remove(req, res, next) { + const { uuid } = req.params; + db.exec(`DELETE FROM donation WHERE uuid=?`, db.bid(uuid)).then(() => { + res.sendStatus(200); + }).catch(next); +} From 2e5a5331f328d92e6939b7a686c9b9c7514387eb Mon Sep 17 00:00:00 2001 From: jeremielodi Date: Thu, 3 Sep 2020 11:35:16 +0100 Subject: [PATCH 4/9] add donation items --- client/src/i18n/en/form.json | 1 + client/src/i18n/fr/form.json | 1 + client/src/js/components/bhDateEditor.js | 1 + .../entry/modals/findDonation.modal.html | 101 ++++++++- .../stock/entry/modals/findDonation.modal.js | 208 +++++++++++++++++- client/src/modules/stock/stock.service.js | 1 + .../modules/templates/bhDateEditor.tmpl.html | 2 +- server/controllers/admin/donation.js | 33 ++- server/models/migrations/next/migrate.sql | 16 +- server/models/schema.sql | 14 ++ 10 files changed, 358 insertions(+), 20 deletions(-) diff --git a/client/src/i18n/en/form.json b/client/src/i18n/en/form.json index c0d5c45450..bd42f0d186 100644 --- a/client/src/i18n/en/form.json +++ b/client/src/i18n/en/form.json @@ -912,6 +912,7 @@ "DATE_INTERVAL": "Select a date interval", "DEBTOR_GROUP": "Select a Debtor Group", "DEPOT": "Select a Depot", + "DONOR": "Select a donor", "ENTERPRISE": "Select an Enterprise", "FEE_CENTER": "Select a Fee Center", "FISCAL_YEAR": "Select a Fiscal Year", diff --git a/client/src/i18n/fr/form.json b/client/src/i18n/fr/form.json index dad036e377..61c141ac8d 100644 --- a/client/src/i18n/fr/form.json +++ b/client/src/i18n/fr/form.json @@ -913,6 +913,7 @@ "DATE_INTERVAL": "Sélectionner un intervalle de date", "DEBTOR_GROUP": "Sélectionner un Groupe Débiteur", "DEPOT": "Sélectionner un dépôt", + "DONOR": "Sélectionner un donateur", "ENTERPRISE": "Sélectionner une entreprise", "FEE_CENTER": "Sélectionner un centre de frais", "FISCAL_YEAR": "Sélectionner une année fiscale", diff --git a/client/src/js/components/bhDateEditor.js b/client/src/js/components/bhDateEditor.js index a3820d6799..5c92b4535a 100644 --- a/client/src/js/components/bhDateEditor.js +++ b/client/src/js/components/bhDateEditor.js @@ -9,6 +9,7 @@ angular.module('bhima.components') maxDate : 'FORM.LABELS.SEARCH STOCK.ENTRY_DONATION
- -
+
+
+
+
+ +
+
+
diff --git a/server/controllers/admin/donation.js b/server/controllers/admin/donation.js index c94b5f4bc3..f334d8111e 100644 --- a/server/controllers/admin/donation.js +++ b/server/controllers/admin/donation.js @@ -28,13 +28,6 @@ function create(req, res, next) { transaction.addQuery(`INSERT INTO donation_item SET ?`, item); }); - transaction.addQuery(` - INSERT INTO document_map - SELECT do.uuid, CONCAT_WS('.', 'DO', project.abbr, do.reference) - FROM donation do - JOIN project where project.id = do.project_id AND do.uuid=? - `, donation.uuid); - transaction.execute().then(() => { res.status(201).json({ uuid : uuidString }); }).catch(next); @@ -54,14 +47,12 @@ function read(req, res, next) { const filters = new FilterParser(data, { tableAlias : 'dt' }); const sql = ` - SELECT BUID(dt.uuid) as uuid, dt.project_id, dm.text as reference, + SELECT BUID(dt.uuid) as uuid, dt.reference, dt.description, dt.date, - dt.donor_id, d.display_name, p.name as project_name + dt.donor_id, d.display_name FROM donation dt - JOIN project p ON p.id= dt.project_id JOIN donor d ON d.id= dt.donor_id - JOIN document_map dm ON dm.uuid = dt.uuid `; filters.equals('uuid'); @@ -76,7 +67,7 @@ function read(req, res, next) { function detail(req, res, next) { const sql = ` - SELECT BUID(uuid) as uuid, reference, project_id, description, date, donor_id + SELECT BUID(uuid) as uuid, reference, description, date, donor_id FROM donation WHERE uuid=?`; const { uuid } = req.params; @@ -96,18 +87,23 @@ function donationBalance(req, res, next) { const FROM_DONATION_ID = flux.FROM_DONATION; const donationUuid = db.bid(req.params.uuid); const sql = ` - SELECT x.* FROM ( - SELECT dt.uuid as uuid, dt.project_id, dm.text as reference, + SELECT BUID(x.uuid) as uuid, x.reference, + x.description, x.inventory_uuid, + x.quantity, x.unit_price, x.date, + x.donor_id, x.display_name, + x.distributed_quantity, + x.balance + + FROM ( + SELECT dt.uuid as uuid, dt.reference, dt.description, BUID(dti.inventory_uuid) AS inventory_uuid, dti.quantity, dti.unit_price, dt.date, - dt.donor_id, d.display_name, p.name as project_name, + dt.donor_id, d.display_name, IFNULL(distributed.quantity, 0) AS distributed_quantity, (dti.quantity - IFNULL(distributed.quantity, 0)) AS balance FROM donation dt - JOIN project p ON p.id= dt.project_id JOIN donor d ON d.id= dt.donor_id JOIN donation_item dti ON dti.donation_uuid = dt.uuid - JOIN document_map dm ON dm.uuid = dt.uuid LEFT JOIN ( SELECT l.label, SUM(IFNULL(m.quantity, 0)) AS quantity, l.inventory_uuid, l.origin_uuid diff --git a/server/models/admin.sql b/server/models/admin.sql index ab290be589..2f209631c4 100644 --- a/server/models/admin.sql +++ b/server/models/admin.sql @@ -58,11 +58,6 @@ BEGIN SELECT purchase.uuid, CONCAT_WS('.', 'PO', project.abbr, purchase.reference) FROM purchase JOIN project where project.id = purchase.project_id; - -- donations - INSERT INTO document_map - SELECT donation.uuid, CONCAT_WS('.', 'DO', project.abbr, donation.reference) - FROM donation JOIN project where project.id = donation.project_id; - -- vouchers INSERT INTO document_map SELECT voucher.uuid, CONCAT_WS('.', 'VO', project.abbr, voucher.reference) diff --git a/server/models/schema.sql b/server/models/schema.sql index cb403630f8..cf134c592d 100644 --- a/server/models/schema.sql +++ b/server/models/schema.sql @@ -2022,7 +2022,6 @@ DROP TABLE IF EXISTS `donation`; CREATE TABLE `donation` ( `uuid` BINARY(16) NOT NULL, `reference` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `project_id` SMALLINT(5) UNSIGNED NOT NULL, `description` TEXT NULL, `date` DATE NOT NULL, `donor_id` INT(11) NOT NULL, diff --git a/test/data.sql b/test/data.sql index 2720d03b04..5c1b8a639b 100644 --- a/test/data.sql +++ b/test/data.sql @@ -3422,5 +3422,5 @@ INSERT INTO `village` (`uuid`, `name`, `sector_uuid`, `longitude`, `latitude`) V INSERT INTO `donor`(`id`, `display_name`) VALUES(1, 'Jeremie LODI'); -INSERT INTO `donation`(`uuid`, `project_id`, `date`, `donor_id`) -VALUES(HUID('ae735e99-8faf-417b-aa63-9b404fca390d'), 1, NOW(), 1); +INSERT INTO `donation`(`uuid`, `date`, `donor_id`) +VALUES(HUID('ae735e99-8faf-417b-aa63-9b404fca390d'), NOW(), 1); diff --git a/test/end-to-end/fillForm/fillForm.page.js b/test/end-to-end/fillForm/fillForm.page.js index 13fcf08029..0cca75ace5 100644 --- a/test/end-to-end/fillForm/fillForm.page.js +++ b/test/end-to-end/fillForm/fillForm.page.js @@ -42,6 +42,7 @@ class FillFormManagementPage { await browser.findElement(by.css('[name="nombreFois"]')).sendKeys(fillForm.nombreFois); await components.dateEditor.set(new Date(fillForm.date), null, '.title'); await browser.findElement(by.css('[name="voie"]')).sendKeys(fillForm.voie); + components.dateEditor.set(new Date(fillForm.date)); await browser.findElement(by.css('[ng-model="hours"]')).sendKeys(fillForm.hours); await browser.findElement(by.css('[ng-model="minutes"]')).sendKeys(fillForm.minutes); diff --git a/test/end-to-end/shared/components/bhDateEditor.js b/test/end-to-end/shared/components/bhDateEditor.js index dcabf53277..d1f7724b37 100644 --- a/test/end-to-end/shared/components/bhDateEditor.js +++ b/test/end-to-end/shared/components/bhDateEditor.js @@ -14,8 +14,6 @@ module.exports = { * * @param {Date} date - a date object * @param {String} id - a CSS id to select on. - * @param {String} elementClick - determine a css class that will clicked to - * close the selection component Dates. */ set : async function set(date, id, elementClick) { const elementCloseComponent = elementClick || '.header-image'; From cfd838d50ddbb9c08890a7792bbd8350aa9ea267 Mon Sep 17 00:00:00 2001 From: jeremielodi Date: Wed, 9 Sep 2020 13:30:17 +0100 Subject: [PATCH 7/9] fix bh-date-editor test bug --- client/src/modules/templates/bhDateEditor.tmpl.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/modules/templates/bhDateEditor.tmpl.html b/client/src/modules/templates/bhDateEditor.tmpl.html index ea4ebeb30d..3a62978eba 100644 --- a/client/src/modules/templates/bhDateEditor.tmpl.html +++ b/client/src/modules/templates/bhDateEditor.tmpl.html @@ -15,7 +15,7 @@ ng-class="{ 'has-error' : DateEditorForm.$submitted && DateEditorForm.$invalid } " data-date-editor> -