From de2d70270c96827fad95a93a0fbbf624adee0106 Mon Sep 17 00:00:00 2001 From: Chris Lomame Date: Tue, 15 Oct 2019 13:11:05 +0100 Subject: [PATCH 01/30] Resolve Conflict with branch master --- client/src/i18n/en/form.json | 2 + client/src/i18n/en/tree.json | 2 + client/src/i18n/fr/form.json | 2 + client/src/i18n/fr/tree.json | 2 + client/src/js/services/color.js | 142 +++++++++++++++++- .../data_collector_management.html | 45 ++++++ .../data_collector_management.js | 126 ++++++++++++++++ .../data_collector_management.routes.js | 42 ++++++ .../data_collector_management.service.js | 17 +++ .../data_collector_management.modals.html | 98 ++++++++++++ .../data_collector_management.modals.js | 74 +++++++++ .../templates/action.cell.html | 28 ++++ .../templates/color.cell.html | 3 + .../templates/consultation.cell.html | 20 +++ .../templates/is_related_patient.cell.html | 5 + .../templates/is_related_patient.tmpl.html | 7 + server/config/routes.js | 12 ++ .../admin/dataCollectorManagement.js | 127 ++++++++++++++++ server/models/bhima.sql | 14 +- server/models/schema.sql | 10 ++ .../dataCollectorManagement.page.js | 78 ++++++++++ .../dataCollectorManagement.spec.js | 39 +++++ test/integration/dataCollectorManagement.js | 75 +++++++++ 23 files changed, 967 insertions(+), 3 deletions(-) create mode 100644 client/src/modules/data_collector_management/data_collector_management.html create mode 100644 client/src/modules/data_collector_management/data_collector_management.js create mode 100644 client/src/modules/data_collector_management/data_collector_management.routes.js create mode 100644 client/src/modules/data_collector_management/data_collector_management.service.js create mode 100644 client/src/modules/data_collector_management/modals/data_collector_management.modals.html create mode 100644 client/src/modules/data_collector_management/modals/data_collector_management.modals.js create mode 100644 client/src/modules/data_collector_management/templates/action.cell.html create mode 100644 client/src/modules/data_collector_management/templates/color.cell.html create mode 100644 client/src/modules/data_collector_management/templates/consultation.cell.html create mode 100644 client/src/modules/data_collector_management/templates/is_related_patient.cell.html create mode 100644 client/src/modules/data_collector_management/templates/is_related_patient.tmpl.html create mode 100644 server/controllers/admin/dataCollectorManagement.js create mode 100644 test/end-to-end/dataCollectorManagement/dataCollectorManagement.page.js create mode 100644 test/end-to-end/dataCollectorManagement/dataCollectorManagement.spec.js create mode 100644 test/integration/dataCollectorManagement.js diff --git a/client/src/i18n/en/form.json b/client/src/i18n/en/form.json index 5805568aeb..6338b1e428 100644 --- a/client/src/i18n/en/form.json +++ b/client/src/i18n/en/form.json @@ -180,6 +180,7 @@ "IS_DISCOUNT": "Is it a deduction or an addition?", "IS_MEMBERSHIP_FEE": "Is it a membership fee?", "IS_PERCENT" : "This rubric is expressed in Percentage", + "IS_RELATED_PATIENT": "Is related to the patient", "IS_TAX" : "Is it a Tax?", "ITEMS_FULL": "There are no additional inventory items that be assigned to this invoice.", "LOADING": "Loading", @@ -706,6 +707,7 @@ "VALUE": "Value", "VARIABLE_CHARGE": "Variable cost", "VARIANCE" : "Variance", + "VERSION": "Version", "VILLAGE": "Village/Township", "VILLAGE_NAME": "Village/Township Name", "VILLE": "Township/Commune", diff --git a/client/src/i18n/en/tree.json b/client/src/i18n/en/tree.json index f2ef6910f2..f73ac4a7b5 100644 --- a/client/src/i18n/en/tree.json +++ b/client/src/i18n/en/tree.json @@ -28,6 +28,8 @@ "CREDIT_NOTE" : "Credit Note", "CREDITOR_GROUP" : "Creditor Group Management", "CURRENCY" : "Currency", + "DATA_COLLECTOR_MANAGEMENT": "Data Collector Management", + "DATA_KIT": "Data collection kit", "DEPARTMENT_MANAGEMENT" : "Department Management", "DEBTOR_GROUP" : "Debtor Group Management", "DEPOTS" : "Depots", diff --git a/client/src/i18n/fr/form.json b/client/src/i18n/fr/form.json index 2040242a4c..48724271be 100644 --- a/client/src/i18n/fr/form.json +++ b/client/src/i18n/fr/form.json @@ -181,6 +181,7 @@ "IS_DISCOUNT": "Est ce une déduction ou bien une addition ?", "IS_MEMBERSHIP_FEE": "Est ce une cotisation ?", "IS_PERCENT" : "Cette rubrique s'exprime en Pourcentage", + "IS_RELATED_PATIENT": "Est liée au patient", "IS_TAX" : "Est ce une taxe", "LOADING": "Chargement en cours", "MAX_LOT_REACHED": "Lot maximal atteint", @@ -707,6 +708,7 @@ "VALUE": "Valeur", "VARIABLE_CHARGE": "Charge variable", "VARIANCE" : "Variance", + "VERSION": "Version", "VILLAGE": "Village/Commune", "VILLAGE_NAME": "Nom du Village/Commune", "VILLE": "Ville/Commune", diff --git a/client/src/i18n/fr/tree.json b/client/src/i18n/fr/tree.json index 15c9af9b2f..bdcaa40d21 100644 --- a/client/src/i18n/fr/tree.json +++ b/client/src/i18n/fr/tree.json @@ -28,6 +28,8 @@ "CREDIT_NOTE":"Note de Crédit", "CREDITOR_GROUP":"Gestion des Groupes Créditeurs", "CURRENCY":"Monnaie", + "DATA_COLLECTOR_MANAGEMENT": "Gestion des collecteurs de données", + "DATA_KIT": "Kit de collecte de données", "DEPARTMENT_MANAGEMENT" : "Gestion des Departements", "DEBTOR_GROUP":"Gestion des Groupes Débiteurs", "DEPOTS":"Dépôts", diff --git a/client/src/js/services/color.js b/client/src/js/services/color.js index be9343393b..17cfb87ac6 100644 --- a/client/src/js/services/color.js +++ b/client/src/js/services/color.js @@ -17,6 +17,146 @@ function ColorService($translate) { { name : $translate.instant('COLORS.MAROON'), value : '#800000' }, { name : $translate.instant('COLORS.CRIMSON'), value : '#dc143c' }, { name : $translate.instant('COLORS.BLUEVIOLET'), value : '#8A2BE2' }, - ]; + { name : $translate.instant('COLORS.AQUA'), value : '#00ffff' }, + { name : $translate.instant('COLORS.GRAY'), value : '#808080' }, + { name : $translate.instant('COLORS.FORESTGREEN'), value : '#228b22' }, + { name : $translate.instant('COLORS.LIME'), value : '#00ff00' }, + { name : $translate.instant('COLORS.RED'), value : '#ff0000' }, + { name : $translate.instant('COLORS.YELLOW'), value : '#ffff00' }, + { name : $translate.instant('COLORS.YELLOWGREEN'), value : '#9acd32' }, + { name : $translate.instant('COLORS.SLATEBLUE'), value : '#6a5acd' }, + { name : $translate.instant('COLORS.MAROON'), value : '#800000' }, + { name : $translate.instant('COLORS.CRIMSON'), value : '#dc143c' }, + { name : $translate.instant('COLORS.BLUEVIOLET'), value : '#8A2BE2' }, + { name : 'aliceblue', value : '#F0F8FF'}, + { name : 'antiquewhite', value : '#FAEBD7'}, + { name : 'aquamarine', value : '#7FFFD4'}, + { name : 'azure', value : '#F0FFFF'}, + { name : 'beige', value : '#F5F5DC'}, + { name : 'bisque', value : '#FFE4C4'}, + { name : 'blanchedalmond', value : '#FFEBCD'}, + { name : 'blue', value : '#0000FF'}, + { name : 'brown', value : '#A52A2A'}, + { name : 'burlywood', value : '#DEB887'}, + { name : 'cadetblue', value : '#5F9EA0'}, + { name : 'chartreuse', value : '#7FFF00'}, + { name : 'chocolate', value : '#D2691E'}, + { name : 'coral', value : '#FF7F50'}, + { name : 'cornflowerblue', value : '#6495ED'}, + { name : 'cornsilk', value : '#FFF8DC'}, + { name : 'cyan', value : '#00FFFF'}, + { name : 'darkblue', value : '#00008B'}, + { name : 'darkcyan', value : '#008B8B'}, + { name : 'darkgoldenrod', value : '#B8860B'}, + { name : 'darkgray', value : '#A9A9A9'}, + { name : 'darkgreen', value : '#006400'}, + { name : 'darkkhaki', value : '#BDB76B'}, + { name : 'darkmagenta', value : '#8B008B'}, + { name : 'darkolivegreen', value : '#556B2F'}, + { name : 'darkorange', value : '#FF8C00'}, + { name : 'darkorchid', value : '#9932CC'}, + { name : 'darkred', value : '#8B0000'}, + { name : 'darksalmon', value : '#E9967A'}, + { name : 'darkseagreen', value : '#8FBC8F'}, + { name : 'darkslateblue', value : '#483D8B'}, + { name : 'darkslategray', value : '#2F4F4F'}, + { name : 'darkturquoise', value : '#00CED1'}, + { name : 'darkviolet', value : '#9400D3'}, + { name : 'deeppink', value : '#FF1493'}, + { name : 'deepskyblue', value : '#00BFFF'}, + { name : 'dimgray', value : '#696969'}, + { name : 'dodgerblue', value : '#1E90FF'}, + { name : 'firebrick', value : '#B22222'}, + { name : 'floralwhite', value : '#FFFAF0'}, + { name : 'fuchsia', value : '#FF00FF'}, + { name : 'gainsboro', value : '#DCDCDC'}, + { name : 'ghostwhite', value : '#F8F8FF'}, + { name : 'gold', value : '#FFD700'}, + { name : 'goldenrod', value : '#DAA520'}, + { name : 'gray', value : '#808080'}, + { name : 'green', value : '#008000'}, + { name : 'greenyellow', value : '#ADFF2F'}, + { name : 'honeydew', value : '#F0FFF0'}, + { name : 'hotpink', value : '#FF69B4'}, + { name : 'indianred', value : '#CD5C5C'}, + { name : 'indigo', value : '#4B0082'}, + { name : 'ivory', value : '#FFFFF0'}, + { name : 'khaki', value : '#F0E68C'}, + { name : 'lavender', value : '#E6E6FA'}, + { name : 'lavenderblush', value : '#FFF0F5'}, + { name : 'lawngreen', value : '#7CFC00'}, + { name : 'lemonchiffon', value : '#FFFACD'}, + { name : 'lightblue', value : '#ADD8E6'}, + { name : 'lightcoral', value : '#F08080'}, + { name : 'lightcyan', value : '#E0FFFF'}, + { name : 'lightgoldenrodyellow', value : '#FAFAD2'}, + { name : 'lightgreen', value : '#90EE90'}, + { name : 'lightgrey', value : '#D3D3D3'}, + { name : 'lightpink', value : '#FFB6C1'}, + { name : 'lightsalmon', value : '#FFA07A'}, + { name : 'lightseagreen', value : '#20B2AA'}, + { name : 'lightskyblue', value : '#87CEFA'}, + { name : 'lightslategray', value : '#778899'}, + { name : 'lightsteelblue', value : '#B0C4DE'}, + { name : 'lightyellow', value : '#FFFFE0'}, + { name : 'limegreen', value : '#32CD32'}, + { name : 'linen', value : '#FAF0E6'}, + { name : 'magenta', value : '#FF00FF'}, + { name : 'mediumaquamarine', value : '#66CDAA'}, + { name : 'mediumblue', value : '#0000CD'}, + { name : 'mediumorchid', value : '#BA55D3'}, + { name : 'mediumpurple', value : '#9370DB'}, + { name : 'mediumseagreen', value : '#3CB371'}, + { name : 'mediumslateblue', value : '#7B68EE'}, + { name : 'mediumspringgreen', value : '#00FA9A'}, + { name : 'mediumturquoise', value : '#48D1CC'}, + { name : 'mediumvioletred', value : '#C71585'}, + { name : 'midnightblue', value : '#191970'}, + { name : 'mintcream', value : '#F5FFFA'}, + { name : 'mistyrose', value : '#FFE4E1'}, + { name : 'moccasin', value : '#FFE4B5'}, + { name : 'navajowhite', value : '#FFDEAD'}, + { name : 'navy', value : '#000080'}, + { name : 'oldlace', value : '#FDF5E6'}, + { name : 'olive', value : '#808000'}, + { name : 'olivedrab', value : '#6B8E23'}, + { name : 'orange', value : '#FFA500'}, + { name : 'orangered', value : '#FF4500'}, + { name : 'orchid', value : '#DA70D6'}, + { name : 'palegoldenrod', value : '#EEE8AA'}, + { name : 'palegreen', value : '#98FB98'}, + { name : 'paleturquoise ', value : '#AFEEEE'}, + { name : 'palevioletred', value : '#DB7093'}, + { name : 'papayawhip', value : '#FFEFD5'}, + { name : 'peachpuff', value : '#FFDAB9'}, + { name : 'peru', value : '#CD853F'}, + { name : 'pink', value : '#FFC0CB'}, + { name : 'plum', value : '#DDA0DD'}, + { name : 'powderblue', value : '#B0E0E6'}, + { name : 'purple', value : '#800080'}, + { name : 'rosybrown', value : '#BC8F8F'}, + { name : 'royalblue', value : '#4169E1'}, + { name : 'saddlebrown', value : '#8B4513'}, + { name : 'salmon', value : '#FA8072'}, + { name : 'sandybrown', value : '#F4A460'}, + { name : 'seagreen', value : '#2E8B57'}, + { name : 'seashell', value : '#FFF5EE'}, + { name : 'sienna', value : '#A0522D'}, + { name : 'silver', value : '#C0C0C0'}, + { name : 'skyblue', value : '#87CEEB'}, + { name : 'slategray', value : '#708090'}, + { name : 'snow', value : '#FFFAFA'}, + { name : 'springgreen', value : '#00FF7F'}, + { name : 'steelblue', value : '#4682B4'}, + { name : 'tan', value : '#D2B48C'}, + { name : 'teal', value : '#008080'}, + { name : 'thistle', value : '#D8BFD8'}, + { name : 'tomato', value : '#FF6347'}, + { name : 'turquoise', value : '#40E0D0'}, + { name : 'violet', value : '#EE82EE'}, + { name : 'wheat', value : '#F5DEB3'}, + { name : 'white', value : '#FFFFFF'}, + { name : 'whitesmoke', value : '#F5F5F5'}]; + return service; } diff --git a/client/src/modules/data_collector_management/data_collector_management.html b/client/src/modules/data_collector_management/data_collector_management.html new file mode 100644 index 0000000000..6808ce570a --- /dev/null +++ b/client/src/modules/data_collector_management/data_collector_management.html @@ -0,0 +1,45 @@ +
+
+
    +
  1. TREE.ADMIN
  2. +
  3. TREE.DATA_COLLECTOR_MANAGEMENT
  4. +
+ +
+
+ +
+ +
+ +
+
+
+
+ + +
+
+
+ + + +
+
+
diff --git a/client/src/modules/data_collector_management/data_collector_management.js b/client/src/modules/data_collector_management/data_collector_management.js new file mode 100644 index 0000000000..58c14c31ea --- /dev/null +++ b/client/src/modules/data_collector_management/data_collector_management.js @@ -0,0 +1,126 @@ +angular.module('bhima.controllers') + .controller('DataCollectorManagementController', DataCollectorManagementController); + +DataCollectorManagementController.$inject = [ + '$state', 'DataCollectorManagementService', 'NotifyService', 'uiGridConstants', 'ModalService', +]; + +/** + * Data Collector Management Controller + * This module is responsible for handling the CRUD operation on Data Collector Management + */ + +function DataCollectorManagementController($state, DataCollectorManagement, Notify, uiGridConstants, ModalService) { + const vm = this; + vm.gridApi = {}; + vm.filterEnabled = false; + vm.toggleFilter = toggleFilter; + + // options for the UI grid + vm.gridOptions = { + appScopeProvider : vm, + enableColumnMenus : false, + fastWatch : true, + flatEntityAccess : true, + enableSorting : true, + onRegisterApi : onRegisterApiFn, + columnDefs : [ + { + field : 'label', + width : 300, + displayName : 'FORM.LABELS.DESIGNATION', + enableFiltering : 'true', + headerCellFilter : 'translate', + }, + { + field : 'description', + displayName : 'FORM.LABELS.DETAILS', + enableFiltering : 'true', + headerCellFilter : 'translate', + }, + { + field : 'version_number', + displayName : 'FORM.LABELS.VERSION', + width : 100, + enableFiltering : 'true', + headerCellFilter : 'translate', + }, + { + field : 'is_related_patient', + displayName : 'FORM.INFO.IS_RELATED_PATIENT', + width : 300, + enableFiltering : 'true', + headerCellFilter : 'translate', + cellTemplate : '/modules/data_collector_management/templates/is_related_patient.cell.html', + }, + { + field : 'color', + displayName : '', + width : 100, + enableFiltering : 'true', + headerCellFilter : 'translate', + cellTemplate : '/modules/data_collector_management/templates/color.cell.html', + }, + { + field : 'action', + displayName : '', + width : 100, + enableFiltering : 'false', + cellTemplate : '/modules/data_collector_management/templates/action.cell.html', + }, + ], + }; + function onRegisterApiFn(gridApi) { + vm.gridApi = gridApi; + } + + function toggleFilter() { + vm.filterEnabled = !vm.filterEnabled; + vm.gridOptions.enableFiltering = vm.filterEnabled; + vm.gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN); + } + + // bind methods + vm.edit = edit; + vm.remove = remove; + + function edit(dataCollectorManagement) { + $state.go('data_collector_management.edit', { id : dataCollectorManagement.id }); + } + + function remove(id) { + ModalService.confirm('FORM.DIALOGS.CONFIRM_DELETE') + .then(() => { + DataCollectorManagement.delete(id) + .then(() => { + Notify.success('FORM.INFO.DELETE_SUCCESS'); + loadGrid(); + }) + .catch(Notify.handleError); + }); + } + function handleError(error) { + vm.hasError = true; + Notify.handleError(error); + } + + // load user grid + function loadGrid() { + toggleLoadingIndicator(); + vm.hasError = false; + vm.loading = true; + + DataCollectorManagement.read() + .then((dataCollectorManagement) => { + vm.gridOptions.data = dataCollectorManagement; + }) + .catch(handleError) + .finally(toggleLoadingIndicator); + } + + function toggleLoadingIndicator() { + vm.loading = false; + } + + loadGrid(); +} diff --git a/client/src/modules/data_collector_management/data_collector_management.routes.js b/client/src/modules/data_collector_management/data_collector_management.routes.js new file mode 100644 index 0000000000..875fac9f2b --- /dev/null +++ b/client/src/modules/data_collector_management/data_collector_management.routes.js @@ -0,0 +1,42 @@ +angular.module('bhima.routes') + .config(['$stateProvider', $stateProvider => { + $stateProvider + .state('data_collector_management', { + url : '/data_collector_management', + controller : 'DataCollectorManagementController as DataCollectorManagementCtrl', + templateUrl : 'modules/data_collector_management/data_collector_management.html', + }) + + .state('data_collector_management.create', { + url : '/create', + params : { + data_collector_management : { value : null }, + creating : { value : true }, + }, + onEnter : ['$uibModal', dataCollectorManagementModal], + onExit : ['$uibModalStack', closeModal], + }) + + .state('data_collector_management.edit', { + url : '/:id/edit', + params : { + data_collector_management : { value : null }, + creating : { value : false }, + }, + onEnter : ['$uibModal', dataCollectorManagementModal], + onExit : ['$uibModalStack', closeModal], + }); + }]); + +function dataCollectorManagementModal($modal) { + $modal.open({ + keyboard : false, + backdrop : 'static', + templateUrl : 'modules/data_collector_management/modals/data_collector_management.modals.html', + controller : 'DataCollectorManagementModalController as DataCollectorManagementModalCtrl', + }); +} + +function closeModal(ModalStack) { + ModalStack.dismissAll(); +} diff --git a/client/src/modules/data_collector_management/data_collector_management.service.js b/client/src/modules/data_collector_management/data_collector_management.service.js new file mode 100644 index 0000000000..728b941ae6 --- /dev/null +++ b/client/src/modules/data_collector_management/data_collector_management.service.js @@ -0,0 +1,17 @@ +angular.module('bhima.services') + .service('DataCollectorManagementService', DataCollectorManagementService); + +DataCollectorManagementService.$inject = ['PrototypeApiService']; + +/** + * @class DataCollectorManagementService + * @extends PrototypeApiService + * + * @description + * Encapsulates common requests to the /data_collector_management/ URL. + */ +function DataCollectorManagementService(Api) { + const service = new Api('/data_collector_management/'); + + return service; +} diff --git a/client/src/modules/data_collector_management/modals/data_collector_management.modals.html b/client/src/modules/data_collector_management/modals/data_collector_management.modals.html new file mode 100644 index 0000000000..a24808b5af --- /dev/null +++ b/client/src/modules/data_collector_management/modals/data_collector_management.modals.html @@ -0,0 +1,98 @@ +
+ + + + + +
diff --git a/client/src/modules/data_collector_management/modals/data_collector_management.modals.js b/client/src/modules/data_collector_management/modals/data_collector_management.modals.js new file mode 100644 index 0000000000..dc8ca34467 --- /dev/null +++ b/client/src/modules/data_collector_management/modals/data_collector_management.modals.js @@ -0,0 +1,74 @@ +angular.module('bhima.controllers') + .controller('DataCollectorManagementModalController', DataCollectorManagementModalController); + +DataCollectorManagementModalController.$inject = [ + '$state', 'DataCollectorManagementService', 'NotifyService', 'appcache', 'ColorService', +]; + +/** + * Data Collector Management Modal Controller + */ + +function DataCollectorManagementModalController($state, DataCollectorManagement, Notify, AppCache, Color) { + const vm = this; + const cache = AppCache('AccountReferenceModal'); + + vm.dataCollector = {}; + vm.stateParams = {}; + vm.colors = Color.list; + + // exposed methods + vm.submit = submit; + vm.closeModal = closeModal; + vm.clear = clear; + + if ($state.params.creating || $state.params.id) { + cache.stateParams = $state.params; + vm.stateParams = cache.stateParams; + } else { + vm.stateParams = cache.stateParams; + } + vm.isCreating = vm.stateParams.creating; + + if (!vm.isCreating) { + DataCollectorManagement.read(vm.stateParams.id) + .then(data => { + vm.dataCollector = data; + }) + .catch(Notify.handleError); + } + + // load Data Collector Management + DataCollectorManagement.read() + .then(dataCollectors => { + vm.dataCollectors = dataCollectors; + }) + .catch(Notify.handleError); + + // submit the data to the server from all two forms (update, create) + function submit(dataCollectorManagementForm) { + vm.hasNoChange = dataCollectorManagementForm.$submitted && dataCollectorManagementForm.$pristine && !vm.isCreating; + if (dataCollectorManagementForm.$invalid) { return null; } + if (!dataCollectorManagementForm.$dirty) { return null; } + + const promise = (vm.isCreating) + ? DataCollectorManagement.create(vm.dataCollector) + : DataCollectorManagement.update(vm.dataCollector.id, vm.dataCollector); + + return promise + .then(() => { + const translateKey = (vm.isCreating) ? 'FORM.INFO.CREATE_SUCCESS' : 'FORM.INFO.UPDATE_SUCCESS'; + Notify.success(translateKey); + $state.go('data_collector_management', null, { reload : true }); + }) + .catch(Notify.handleError); + } + + function clear(value) { + vm.dataCollectors[value] = null; + } + + function closeModal() { + $state.transitionTo('data_collector_management'); + } +} diff --git a/client/src/modules/data_collector_management/templates/action.cell.html b/client/src/modules/data_collector_management/templates/action.cell.html new file mode 100644 index 0000000000..0ba1f5fe49 --- /dev/null +++ b/client/src/modules/data_collector_management/templates/action.cell.html @@ -0,0 +1,28 @@ +
+ + FORM.BUTTONS.ACTIONS + + + + +
diff --git a/client/src/modules/data_collector_management/templates/color.cell.html b/client/src/modules/data_collector_management/templates/color.cell.html new file mode 100644 index 0000000000..a58d95151c --- /dev/null +++ b/client/src/modules/data_collector_management/templates/color.cell.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/client/src/modules/data_collector_management/templates/consultation.cell.html b/client/src/modules/data_collector_management/templates/consultation.cell.html new file mode 100644 index 0000000000..a8fd6d63fc --- /dev/null +++ b/client/src/modules/data_collector_management/templates/consultation.cell.html @@ -0,0 +1,20 @@ +
+ + FORM.BUTTONS.ACTIONS + + + + +
diff --git a/client/src/modules/data_collector_management/templates/is_related_patient.cell.html b/client/src/modules/data_collector_management/templates/is_related_patient.cell.html new file mode 100644 index 0000000000..59b288fbe8 --- /dev/null +++ b/client/src/modules/data_collector_management/templates/is_related_patient.cell.html @@ -0,0 +1,5 @@ +
+
+ FORM.LABELS.YES +
+
diff --git a/client/src/modules/data_collector_management/templates/is_related_patient.tmpl.html b/client/src/modules/data_collector_management/templates/is_related_patient.tmpl.html new file mode 100644 index 0000000000..48ef2fdbf4 --- /dev/null +++ b/client/src/modules/data_collector_management/templates/is_related_patient.tmpl.html @@ -0,0 +1,7 @@ +
+
+ + FORM.LABELS.YES + +
+
\ No newline at end of file diff --git a/server/config/routes.js b/server/config/routes.js index 2b04c462a6..1f88e93d90 100644 --- a/server/config/routes.js +++ b/server/config/routes.js @@ -142,6 +142,10 @@ const lots = require('../controllers/stock/lots'); // todo: the indicator folder must not be inside the finance folder const dashboard = require('../controllers/finance/indicator/dashboard'); const indicatorRerpor = require('../controllers/finance/indicator/dashboard/report'); + +// Data Kit +const dataCollectorManagement = require('../controllers/admin/dataCollectorManagement'); + // expose routes to the server. exports.configure = function configure(app) { debug('configuring routes.'); @@ -975,4 +979,12 @@ exports.configure = function configure(app) { app.post('/cron_email_reports', cronEmailReport.create); app.post('/cron_email_reports/:id', cronEmailReport.send); app.delete('/cron_email_reports/:id', cronEmailReport.remove); + + // API for Data Collector Management routes crud + app.get('/data_collector_management', dataCollectorManagement.list); + app.get('/data_collector_management/:id', dataCollectorManagement.detail); + app.post('/data_collector_management', dataCollectorManagement.create); + app.put('/data_collector_management/:id', dataCollectorManagement.update); + app.delete('/data_collector_management/:id', dataCollectorManagement.delete); + }; diff --git a/server/controllers/admin/dataCollectorManagement.js b/server/controllers/admin/dataCollectorManagement.js new file mode 100644 index 0000000000..be78a61d19 --- /dev/null +++ b/server/controllers/admin/dataCollectorManagement.js @@ -0,0 +1,127 @@ +/** +* Data Collector Management Controller +* +* This controller exposes an API to the client for reading and writing Data Collector Management +*/ + +const db = require('../../lib/db'); +const NotFound = require('../../lib/errors/NotFound'); +const FilterParser = require('../../lib/filter'); + +// GET /data_collector_management +function lookupDataCollectorManagement(id) { + const sql = ` + SELECT id, label, description, version_number, color, is_related_patient FROM data_collector_management + WHERE data_collector_management.id = ? + `; + + return db.one(sql, [id]); +} + + +// List +function list(req, res, next) { + const filters = new FilterParser(req.query); + + const sql = `SELECT id, label, description, version_number, color, is_related_patient + FROM data_collector_management`; + + filters.equals('label'); + filters.equals('description'); + filters.equals('version_number'); + filters.equals('is_related_patient'); + filters.setOrder('ORDER BY label ASC'); + filters.setOrder('ORDER BY version_number'); + + const query = filters.applyQuery(sql); + const parameters = filters.parameters(); + + db.exec(query, parameters) + .then((rows) => { + res.status(200).json(rows); + }) + .catch(next) + .done(); +} + +/** +* GET /data_collector_management/:ID +* +* Returns the detail of a single data_collector_management +*/ +function detail(req, res, next) { + const { id } = req.params; + + lookupDataCollectorManagement(id) + .then((record) => { + res.status(200).json(record); + }) + .catch(next) + .done(); +} + + +// POST /data_collector_management +function create(req, res, next) { + const sql = `INSERT INTO data_collector_management SET ?`; + const data = req.body; + + db.exec(sql, [data]) + .then((row) => { + res.status(201).json({ id : row.insertId }); + }) + .catch(next) + .done(); +} + + +// PUT /data_collector_management /:id +function update(req, res, next) { + const sql = `UPDATE data_collector_management SET ? WHERE id = ?;`; + + db.exec(sql, [req.body, req.params.id]) + .then(() => { + return lookupDataCollectorManagement(req.params.id); + }) + .then((record) => { + // all updates completed successfull, return full object to client + res.status(200).json(record); + }) + .catch(next) + .done(); +} + +// DELETE /data_collector_management/:id +function remove(req, res, next) { + const sql = `DELETE FROM data_collector_management WHERE id = ?;`; + + db.exec(sql, [req.params.id]) + .then((row) => { + // if nothing happened, let the client know via a 404 error + if (row.affectedRows === 0) { + throw new NotFound(`Could not find a function with id ${req.params.id}`); + } + + res.status(204).json(); + }) + .catch(next) + .done(); +} + +// get list of dataCollectorManagement +exports.list = list; + +// get details of a dataCollectorManagement +exports.detail = detail; + +// create a new dataCollectorManagement +exports.create = create; + +// update dataCollectorManagement informations +exports.update = update; + +// Delete a dataCollectorManagement +exports.delete = remove; + +// lookup Data Collector Management +exports.lookupDataCollectorManagement = lookupDataCollectorManagement; diff --git a/server/models/bhima.sql b/server/models/bhima.sql index b9df7abe47..31bb1da7f0 100644 --- a/server/models/bhima.sql +++ b/server/models/bhima.sql @@ -133,11 +133,16 @@ INSERT INTO unit VALUES (246, 'Client debts report', 'TREE.CLIENT_DEBTS_REPORT', 'Client debts report', 144, '/modules/reports/clientDebts', '/reports/clientDebts'), (247, 'Client support report', 'TREE.CLIENT_SUPPORT_REPORT', 'Client support report', 144, '/modules/reports/clientSupport', '/reports/clientSupport'), (248, 'Analysis of cashboxes', 'REPORT.ANALYSIS_AUX_CASHBOXES.TITLE', 'Analysis of auxiliary cashboxes', 144, '/modules/reports/analysisAuxiliaryCash', '/reports/analysisAuxiliaryCash'), +<<<<<<< f8e1631cbe2732b5c563dc66426c38e20c035ebe (249, 'Realized Profit Report', 'TREE.REALIZED_PROFIT_REPORT', 'Realized profit report', 144, '/modules/reports/realizedProfit', '/reports/realizedProfit'), (250, 'Sytem usage statistic', 'REPORT.SYSTEM_USAGE_STAT.TITLE', 'Sytem usage statistic', 144, '/modules/reports/systemUsageStat', '/reports/systemUsageStat'), (251, 'indexes', 'TREE.INDEXES','The payrall-index', 57,'/modules/finance/','/PAYROLL_INDEX_FOLDER'), (252, 'Staffing indexes management','TREE.STAFFING_INDICES_MANAGEMENT','Staffing indices management',251 ,'/modules/payroll/staffing_indice','/staffing_indices'), (253, 'Multiple Payroll by indice','TREE.MULTI_PAYROLL_INDICE','Multiple Payroll (indice)', 251,'/modules/multiple_payroll_indice','/multiple_payroll_indice'); +======= + (249, 'Data Kit', 'TREE.DATA_KIT', 'Data Kit', 0, '/modules/data_kit', '/data_kit'), + (250, 'Data Collector Management', 'TREE.DATA_COLLECTOR_MANAGEMENT', '', 246, '/modules/data_collector_management', '/data_collector_management'); +>>>>>>> Resolve conflict s1 -- Reserved system account type INSERT INTO `account_category` VALUES @@ -358,8 +363,13 @@ INSERT INTO `indicator_type`(`id`, `text`,`translate_key`)VALUES (3, 'fianance', 'DASHBOARD.FINANCE'); -- cron -INSERT INTO `cron` (`label`, `value`) VALUES +INSERT INTO `cron` (`label`, `value`) VALUES ('CRON.DAILY', '0 1 * * *'), ('CRON.WEEKLY', '0 1 * * 0'), ('CRON.MONTHLY', '0 1 30 * *'), - ('CRON.YEARLY', '0 1 31 12 *'); \ No newline at end of file + ('CRON.YEARLY', '0 1 31 12 *'), + ('CRON.EACH_MINUTE', '* * * * *'); + +-- data_collector_management +INSERT INTO `data_collector_management` (`label`, `description`, `version_number`, `color`, `is_related_patient`) VALUES + ('Fiche Kardex', 'Fiche de consommation Medicament', '1.0', '#E0FFFF', 1); diff --git a/server/models/schema.sql b/server/models/schema.sql index e03ce15cf5..aaf78d756a 100644 --- a/server/models/schema.sql +++ b/server/models/schema.sql @@ -2358,6 +2358,16 @@ CREATE TABLE `staffing_indice_parameters` ( PRIMARY KEY (`uuid`), UNIQUE KEY `payroll_config_id`(`payroll_configuration_id`), FOREIGN KEY (`payroll_configuration_id`) REFERENCES `payroll_configuration` (`id`) +DROP TABLE IF EXISTS `data_collector_management`; +CREATE TABLE `data_collector_management` ( + `id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT, + `label` VARCHAR(100) NOT NULL, + `description` TEXT, + `version_number` INT(11) UNSIGNED NOT NULL, + `color` VARCHAR(8) NULL, + `is_related_patient` TINYINT(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + UNIQUE KEY `data_collector_management_1` (`label`, `version_number`) ) ENGINE=InnoDB DEFAULT CHARACTER SET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; SET foreign_key_checks = 1; diff --git a/test/end-to-end/dataCollectorManagement/dataCollectorManagement.page.js b/test/end-to-end/dataCollectorManagement/dataCollectorManagement.page.js new file mode 100644 index 0000000000..6d612a9b46 --- /dev/null +++ b/test/end-to-end/dataCollectorManagement/dataCollectorManagement.page.js @@ -0,0 +1,78 @@ +/* global element, by */ +/* eslint */ + +/** + * This class is represents a payroll configuration page in term of structure and + * behaviour so it is a payroll configuration page object + */ + +/* loading grid actions */ +const GA = require('../shared/GridAction'); +const GU = require('../shared/GridUtils'); +const GridRow = require('../shared/GridRow'); +const FU = require('../shared/FormUtils'); +const components = require('../shared/components'); + +class DataCollectorManagementPage { + constructor() { + this.gridId = 'data-collector-management-grid'; + this.rubricGrid = element(by.id(this.gridId)); + this.actionLinkColumn = 5; + } + + /** + * simulate the create PayrollConfig button click to show the dialog of creation + */ + async create(dataCollectorManagement) { + await FU.buttons.create(); + await FU.input('DataCollectorManagementModalCtrl.dataCollector.label', dataCollectorManagement.label); + await FU.input('DataCollectorManagementModalCtrl.dataCollector.description', + dataCollectorManagement.description, this.modal); + await FU.input('DataCollectorManagementModalCtrl.dataCollector.version_number', + dataCollectorManagement.version_number, this.modal); + await FU.uiSelect('DataCollectorManagementModalCtrl.dataCollector.color', dataCollectorManagement.color); + await element(by.id('is_related_patient')).click(); + await FU.buttons.submit(); + await components.notification.hasSuccess(); + } + + /** + * block creation without the function name + */ + async errorOnCreate() { + await FU.buttons.create(); + await FU.buttons.submit(); + await FU.validation.error('DataCollectorManagementModalCtrl.dataCollector.label'); + await FU.buttons.cancel(); + } + + /** + * simulate a click on the edit link of a function + */ + async edit(label, updateDataCollector) { + const row = new GridRow(label); + row.dropdown().click(); + row.edit().click(); + + await FU.input('DataCollectorManagementModalCtrl.dataCollector.label', updateDataCollector.label); + await FU.input('DataCollectorManagementModalCtrl.dataCollector.version_number', updateDataCollector.version_number); + await FU.uiSelect('DataCollectorManagementModalCtrl.dataCollector.color', updateDataCollector.color); + + await FU.buttons.submit(); + await components.notification.hasSuccess(); + } + + /** + * simulate a click on the delete link of a function + */ + async delete(label) { + const row = new GridRow(label); + await row.dropdown().click(); + await row.remove().click(); + + await FU.modal.submit(); + await components.notification.hasSuccess(); + } +} + +module.exports = DataCollectorManagementPage; diff --git a/test/end-to-end/dataCollectorManagement/dataCollectorManagement.spec.js b/test/end-to-end/dataCollectorManagement/dataCollectorManagement.spec.js new file mode 100644 index 0000000000..34eb57a41f --- /dev/null +++ b/test/end-to-end/dataCollectorManagement/dataCollectorManagement.spec.js @@ -0,0 +1,39 @@ +const helpers = require('../shared/helpers'); +const DataCollectorManagement = require('./dataCollectorManagement.page'); + +describe.only('Data Collector Management', () => { + // navigate to the page + before(() => helpers.navigate('#!/data_collector_management')); + + const Page = new DataCollectorManagement(); + + const newDataCollector = { + label : 'Consultations externes', + description : '2. CONSULTATIONS / 2.1. Consultations externes', + version_number : '1', + color : 'burlywood', + is_related_patient : '1', + }; + + const updateDataCollector = { + label : 'Consultations aux urgences', + version_number : '1', + color : 'chartreuse', + }; + + it('successfully creates a new Data Collector Management', async () => { + await Page.create(newDataCollector); + }); + + it('successfully edits a Data Collector Management', async () => { + await Page.edit(newDataCollector.label, updateDataCollector); + }); + + it('don\'t create when incorrect Data Collector Management', async () => { + await Page.errorOnCreate(); + }); + + it('successfully delete a Configuration Payroll Period', async () => { + await Page.delete(updateDataCollector.label); + }); +}); diff --git a/test/integration/dataCollectorManagement.js b/test/integration/dataCollectorManagement.js new file mode 100644 index 0000000000..7bb627ecf9 --- /dev/null +++ b/test/integration/dataCollectorManagement.js @@ -0,0 +1,75 @@ +/* global expect, agent */ +const helpers = require('./helpers'); + +describe('(/data_collector_management) Data Collector Management', () => { + const numDataCollector = 2; + + const newDataCollector = { + label : 'Consultations externes', + description : '2. CONSULTATIONS / 2.1. Consultations externes', + version_number : '1', + color : '#ADD8E6', + is_related_patient : '1', + }; + + const updateAccountReferenceType = { + label : 'Consultations aux urgences', + version_number : '1', + is_related_patient : '0', + }; + + it('POST /data_collector_management add Data Collector Management', () => { + return agent.post('/data_collector_management') + .send(newDataCollector) + .then((res) => { + helpers.api.created(res); + newDataCollector.id = res.body.id; + }) + .catch(helpers.handler); + }); + + it('GET /data_collector_management/:id returns one Data Collector Management as detail', () => { + return agent.get(`/data_collector_management/${newDataCollector.id}`) + .then((res) => { + expect(res).to.have.status(200); + + expect(res).to.be.a('object'); + expect(res.body).to.have.all.keys('id', 'label', 'description', + 'version_number', 'color', 'is_related_patient'); + }) + .catch(helpers.handler); + }); + + it('PUT /data_collector_management/:id updates the newly added Data Collector Management', () => { + return agent.put(`/data_collector_management/${newDataCollector.id}`) + .send(updateAccountReferenceType) + .then((res) => { + expect(res).to.have.status(200); + expect(res).to.be.a('object'); + expect(res.body.id).to.equal(newDataCollector.id); + }) + .catch(helpers.handler); + }); + + it('GET /data_collector_management returns all Data Collector Management', () => { + return agent.get(`/data_collector_management/`) + .then((res) => { + helpers.api.listed(res, numDataCollector); + expect(res.body[0]).to.have.all.keys('id', 'label', 'description', + 'version_number', 'color', 'is_related_patient'); + }) + .catch(helpers.handler); + }); + + it('DELETE /data_collector_management/:id deletes a Data Collector Management', () => { + return agent.delete(`/data_collector_management/${newDataCollector.id}`) + .then((res) => { + helpers.api.deleted(res); + return agent.get(`/data_collector_management/${newDataCollector.id}`); + }) + .then((res) => { + helpers.api.errored(res, 404); + }) + .catch(helpers.handler); + }); +}); From ecbe79fefa50f12e05b844722e7b4bacd1c1b9da Mon Sep 17 00:00:00 2001 From: Chris Lomame Date: Tue, 15 Oct 2019 13:13:13 +0100 Subject: [PATCH 02/30] Rebase with branch Master --- client/src/i18n/en/form.json | 6 + client/src/i18n/en/tree.json | 2 + client/src/i18n/fr/form.json | 6 + client/src/i18n/fr/tree.json | 2 + .../src/js/components/bhChoiseListSelect.js | 64 +++++++++ .../choises_list_management.html | 38 ++++++ .../choises_list_management.js | 113 ++++++++++++++++ .../choises_list_management.routes.js | 43 ++++++ .../choises_list_management.service.js | 100 ++++++++++++++ .../choises_list_management.modals.html | 103 +++++++++++++++ .../modals/choises_list_management.modals.js | 84 ++++++++++++ .../templates/action.cell.tmpl.html | 37 ++++++ .../templates/gridLabels.tmpl.html | 12 ++ .../templates/gridName.tmpl.html | 8 ++ .../templates/is_title.tmpl.html | 5 + .../data_collector_management.modals.html | 2 +- .../templates/bhChoiseListSelect.tmpl.html | 31 +++++ server/config/routes.js | 11 +- .../admin/choisesListManagement.js | 125 ++++++++++++++++++ server/models/bhima.sql | 24 ++++ server/models/schema.sql | 14 ++ .../choiseListManagement.page.js | 77 +++++++++++ .../choiseListManagement.spec.js | 44 ++++++ .../dataCollectorManagement.page.js | 8 +- .../dataCollectorManagement.spec.js | 4 +- .../shared/components/bhChoiseListSelect.js | 17 +++ test/end-to-end/shared/components/index.js | 1 + test/integration/choiseListManagement.js | 76 +++++++++++ 28 files changed, 1048 insertions(+), 9 deletions(-) create mode 100644 client/src/js/components/bhChoiseListSelect.js create mode 100644 client/src/modules/choises_list_management/choises_list_management.html create mode 100644 client/src/modules/choises_list_management/choises_list_management.js create mode 100644 client/src/modules/choises_list_management/choises_list_management.routes.js create mode 100644 client/src/modules/choises_list_management/choises_list_management.service.js create mode 100644 client/src/modules/choises_list_management/modals/choises_list_management.modals.html create mode 100644 client/src/modules/choises_list_management/modals/choises_list_management.modals.js create mode 100644 client/src/modules/choises_list_management/templates/action.cell.tmpl.html create mode 100644 client/src/modules/choises_list_management/templates/gridLabels.tmpl.html create mode 100644 client/src/modules/choises_list_management/templates/gridName.tmpl.html create mode 100644 client/src/modules/choises_list_management/templates/is_title.tmpl.html create mode 100644 client/src/modules/templates/bhChoiseListSelect.tmpl.html create mode 100644 server/controllers/admin/choisesListManagement.js create mode 100644 test/end-to-end/choiseListManagement/choiseListManagement.page.js create mode 100644 test/end-to-end/choiseListManagement/choiseListManagement.spec.js create mode 100644 test/end-to-end/shared/components/bhChoiseListSelect.js create mode 100644 test/integration/choiseListManagement.js diff --git a/client/src/i18n/en/form.json b/client/src/i18n/en/form.json index 6338b1e428..3c3f49e80f 100644 --- a/client/src/i18n/en/form.json +++ b/client/src/i18n/en/form.json @@ -178,10 +178,12 @@ "INVOICES": "Invoices", "IS_ASSOCIATED_EMPLOYEE" : "will be associated with the employee ID", "IS_DISCOUNT": "Is it a deduction or an addition?", + "IS_GROUP": "Is it a group", "IS_MEMBERSHIP_FEE": "Is it a membership fee?", "IS_PERCENT" : "This rubric is expressed in Percentage", "IS_RELATED_PATIENT": "Is related to the patient", "IS_TAX" : "Is it a Tax?", + "IS_TITLE": "Is title", "ITEMS_FULL": "There are no additional inventory items that be assigned to this invoice.", "LOADING": "Loading", "MAX_LOT_REACHED": "Max Lot reached", @@ -312,6 +314,7 @@ "CAUTION": "Caution", "CAUTION_AMOUNT": "Prepayment Amount", "CHARGE": "Cost", + "CHOISE_LIST": "Choise list", "CLIENT": "Client", "CLIENT_ID": "Client ID", "CLIENT_TO_IGNORE": "Client(s) to ignore", @@ -706,6 +709,7 @@ "INDICATOR_HOSPITALIZATION" : "Indicator's hospitalization", "VALUE": "Value", "VARIABLE_CHARGE": "Variable cost", + "VARIABLE_NAME": "Variable Name", "VARIANCE" : "Variance", "VERSION": "Version", "VILLAGE": "Village/Township", @@ -865,6 +869,8 @@ "ROOT_ACCOUNT": "Select a Root Account", "RUBRIC_CONFIGURATION": "Select Rubrics Configuration", "SECTOR": "Select a sector", + "SELECT_GROUP": "Select Group Label", + "SELECT_PARENT": "Select a Parent", "SELECT_PERIOD": "Select a payment period", "SERVICE": "Select a Service", "SEX": "Select a Sex", diff --git a/client/src/i18n/en/tree.json b/client/src/i18n/en/tree.json index f73ac4a7b5..af96c386c0 100644 --- a/client/src/i18n/en/tree.json +++ b/client/src/i18n/en/tree.json @@ -23,6 +23,7 @@ "CASHFLOW_BY_SERVICE" : "Cashflow by Service", "CASH_PAYMENT_REGISTRY" : "Cash Payment Registry", "CASH_WINDOW" : "Cash Window", + "CHOISES_LIST_MANAGEMENT" : "Choises List Management", "COMPLEX_JOURNAL_VOUCHER" : "Journal Vouchers", "COST_CENTER_MGMT" : "Cost Center Management", "CREDIT_NOTE" : "Credit Note", @@ -128,6 +129,7 @@ "STOCK_MOVEMENTS" : "Stock Movements", "SUBSIDY" : "Subsidy Management", "STAFFING_INDICES_MANAGEMENT" : "Staffing indices management", + "SURVEY_FORM": "Survey Form", "TRANSACTION_TYPE" : "Transaction Type Management", "TAGS" : "Tags Management", "USERS" : "User Management", diff --git a/client/src/i18n/fr/form.json b/client/src/i18n/fr/form.json index 48724271be..92be20c2e3 100644 --- a/client/src/i18n/fr/form.json +++ b/client/src/i18n/fr/form.json @@ -179,10 +179,12 @@ "ITEMS_FULL": "Il n'y a pas d'articles supplémentaires qui seront affectés à cette facture.", "IS_ASSOCIATED_EMPLOYEE" : "sera associé à l'identifiant de l'employé", "IS_DISCOUNT": "Est ce une déduction ou bien une addition ?", + "IS_GROUP": "Est ce un groupe?", "IS_MEMBERSHIP_FEE": "Est ce une cotisation ?", "IS_PERCENT" : "Cette rubrique s'exprime en Pourcentage", "IS_RELATED_PATIENT": "Est liée au patient", "IS_TAX" : "Est ce une taxe", + "IS_TITLE": "Est ce un titre", "LOADING": "Chargement en cours", "MAX_LOT_REACHED": "Lot maximal atteint", "NO_CHANGE":"Aucun changement n'a été apporté sur le formulaire", @@ -315,6 +317,7 @@ "CAUTION": "Caution", "CAUTION_AMOUNT": "Total de la Caution", "CHARGE": "Charge", + "CHOISE_LIST": "Liste de choix", "CLIENT": "Client", "CLIENT_ID": "Identifiant client", "CLIENT_TO_IGNORE": "Client(s) à ignorer", @@ -707,6 +710,7 @@ "VALIDATED": "Validé", "VALUE": "Valeur", "VARIABLE_CHARGE": "Charge variable", + "VARIABLE_NAME": "Nom de la variable", "VARIANCE" : "Variance", "VERSION": "Version", "VILLAGE": "Village/Commune", @@ -866,6 +870,8 @@ "RUBRIC_CONFIGURATION": "Sélectionner la configuration des rubriques", "PROJECTS": "Sélection des projets", "SECTOR": "Sélectionner un secteur", + "SELECT_GROUP": "Sélectionner l'étiquette du groupe", + "SELECT_PARENT": "Sélectionner un Parent", "SELECT_PERIOD": "Sélectionner une période de paiement", "SERVICE": "Sélectionner un Service", "SEX": "Sélectionner le sexe", diff --git a/client/src/i18n/fr/tree.json b/client/src/i18n/fr/tree.json index bdcaa40d21..c186a0487b 100644 --- a/client/src/i18n/fr/tree.json +++ b/client/src/i18n/fr/tree.json @@ -23,6 +23,7 @@ "CASHFLOW_BY_SERVICE": "Journal de Ventilation", "CASH_PAYMENT_REGISTRY":"Registre des paiements", "CASH_WINDOW":"Paiements", + "CHOISES_LIST_MANAGEMENT" : "Gestion des listes de choix", "COMPLEX_JOURNAL_VOUCHER":"Ajout de transactions", "COST_CENTER_MGMT":"Centres de coûts", "CREDIT_NOTE":"Note de Crédit", @@ -126,6 +127,7 @@ "STOCK_LOTS":"Lots en stock", "STOCK_VALUE" : "[Stock] Valeur de stock", "STOCK_MOVEMENTS":"Movements de stock", + "SURVEY_FORM": "Formulaires d'enquêtes", "TRANSACTION_TYPE":"Types de Transaction", "TAGS" : "Gestion des étiquettes", "SUBSIDY":"Gestion des subventions", diff --git a/client/src/js/components/bhChoiseListSelect.js b/client/src/js/components/bhChoiseListSelect.js new file mode 100644 index 0000000000..d3bd6edbe3 --- /dev/null +++ b/client/src/js/components/bhChoiseListSelect.js @@ -0,0 +1,64 @@ +angular.module('bhima.components') + .component('bhChoiseListSelect', { + templateUrl : 'modules/templates/bhChoiseListSelect.tmpl.html', + controller : ChoiseListController, + transclude : true, + bindings : { + onSelectCallback : '&', + list : ' { + $ctrl.lists = lists; + }) + .catch(Notify.handleError); + }; + + $ctrl.$onChanges = (changes) => { + if (changes.parentId && changes.parentId.currentValue) { + $ctrl.parentId = parseInt(changes.parentId.currentValue, 10); + + const query = { + is_title : $ctrl.isTitle, + is_group : $ctrl.isGroup, + parent : $ctrl.parentId || null, + group_label : $ctrl.groupLabel || null, + }; + + ChoisesList.read(null, query) + .then(lists => { + $ctrl.lists = lists; + }) + .catch(Notify.handleError); + } + }; + + + $ctrl.onSelect = list => $ctrl.onSelectCallback({ list }); +} diff --git a/client/src/modules/choises_list_management/choises_list_management.html b/client/src/modules/choises_list_management/choises_list_management.html new file mode 100644 index 0000000000..d68af8a343 --- /dev/null +++ b/client/src/modules/choises_list_management/choises_list_management.html @@ -0,0 +1,38 @@ +
+
+
    +
  1. TREE.ADMIN
  2. +
  3. TREE.CHOISES_LIST_MANAGEMENT
  4. +
+ +
+
+ +
+ +
+ +
+
+
+
+ + +
+
+
+ + + +
+
+
\ No newline at end of file diff --git a/client/src/modules/choises_list_management/choises_list_management.js b/client/src/modules/choises_list_management/choises_list_management.js new file mode 100644 index 0000000000..ce5e17a36a --- /dev/null +++ b/client/src/modules/choises_list_management/choises_list_management.js @@ -0,0 +1,113 @@ +angular.module('bhima.controllers') + .controller('ChoisesListManagementController', ChoisesListManagementController); + +ChoisesListManagementController.$inject = [ + '$state', 'ChoisesListManagementService', 'NotifyService', 'uiGridConstants', 'ModalService', +]; + +/** + * CHOISES LIST MANAGEMENT Controller + * This module is responsible for handling the CRUD operation on CHOISES LIST MANAGEMENT + */ + +function ChoisesListManagementController($state, ChoisesListManagement, Notify, uiGridConstants, ModalService) { + const vm = this; + vm.gridApi = {}; + vm.filterEnabled = false; + vm.toggleFilter = toggleFilter; + + // options for the UI grid + vm.gridOptions = { + appScopeProvider : vm, + enableColumnMenus : false, + fastWatch : true, + flatEntityAccess : true, + showTreeExpandNoChildren : false, + enableSorting : true, + onRegisterApi : onRegisterApiFn, + columnDefs : [ + { + field : 'name', + displayName : 'FORM.LABELS.VARIABLE_NAME', + enableFiltering : 'true', + headerCellFilter : 'translate', + cellTemplate : '/modules/choises_list_management/templates/gridName.tmpl.html', + }, + { + field : 'label', + displayName : 'FORM.LABELS.DESIGNATION', + enableFiltering : 'true', + headerCellFilter : 'translate', + cellTemplate : '/modules/choises_list_management/templates/gridLabels.tmpl.html', + }, + { + field : 'is_title', + displayName : 'FORM.LABELS.TITLE', + enableFiltering : 'true', + headerCellFilter : 'translate', + cellTemplate : '/modules/choises_list_management/templates/is_title.tmpl.html', + }, + { + field : 'action', + displayName : '', + enableFiltering : 'false', + cellTemplate : '/modules/choises_list_management/templates/action.cell.tmpl.html', + }, + ], + }; + + function onRegisterApiFn(gridApi) { + vm.gridApi = gridApi; + } + + + function toggleFilter() { + vm.filterEnabled = !vm.filterEnabled; + vm.gridOptions.enableFiltering = vm.filterEnabled; + vm.gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN); + } + + // bind methods + vm.edit = edit; + vm.remove = remove; + + function edit(choisesListManagement) { + $state.go('choises_list_management.edit', { id : choisesListManagement.id }); + } + + function remove(id) { + ModalService.confirm('FORM.DIALOGS.CONFIRM_DELETE') + .then(() => { + ChoisesListManagement.delete(id) + .then(() => { + Notify.success('FORM.INFO.DELETE_SUCCESS'); + loadGrid(); + }) + .catch(Notify.handleError); + }); + } + function handleError(error) { + vm.hasError = true; + Notify.handleError(error); + } + + // load user grid + function loadGrid() { + vm.hasError = false; + vm.loading = true; + + ChoisesListManagement.read() + .then((data) => { + const dataTree = ChoisesListManagement.formatStore(data); + vm.gridOptions.data = dataTree; + }) + .catch(handleError) + .finally(toggleLoadingIndicator); + } + + function toggleLoadingIndicator() { + vm.loading = false; + } + + loadGrid(); +} diff --git a/client/src/modules/choises_list_management/choises_list_management.routes.js b/client/src/modules/choises_list_management/choises_list_management.routes.js new file mode 100644 index 0000000000..66b75993d6 --- /dev/null +++ b/client/src/modules/choises_list_management/choises_list_management.routes.js @@ -0,0 +1,43 @@ +angular.module('bhima.routes') + .config(['$stateProvider', $stateProvider => { + $stateProvider + .state('choises_list_management', { + url : '/choises_list_management', + controller : 'ChoisesListManagementController as ChoisesListManagementCtrl', + templateUrl : 'modules/choises_list_management/choises_list_management.html', + }) + + .state('choises_list_management.create', { + url : '/create', + params : { + choises_list_management : { value : null }, + creating : { value : true }, + parentId : { value : null }, + }, + onEnter : ['$uibModal', choisesListManagementModal], + onExit : ['$uibModalStack', closeModal], + }) + + .state('choises_list_management.edit', { + url : '/:id/edit', + params : { + choises_list_management : { value : null }, + creating : { value : false }, + }, + onEnter : ['$uibModal', choisesListManagementModal], + onExit : ['$uibModalStack', closeModal], + }); + }]); + +function choisesListManagementModal($modal) { + $modal.open({ + keyboard : false, + backdrop : 'static', + templateUrl : 'modules/choises_list_management/modals/choises_list_management.modals.html', + controller : 'ChoisesListManagementModalController as ChoisesListManagementModalCtrl', + }); +} + +function closeModal(ModalStack) { + ModalStack.dismissAll(); +} diff --git a/client/src/modules/choises_list_management/choises_list_management.service.js b/client/src/modules/choises_list_management/choises_list_management.service.js new file mode 100644 index 0000000000..831eb98642 --- /dev/null +++ b/client/src/modules/choises_list_management/choises_list_management.service.js @@ -0,0 +1,100 @@ +angular.module('bhima.services') + .service('ChoisesListManagementService', ChoisesListManagementService); + +ChoisesListManagementService.$inject = ['PrototypeApiService']; + +/** + * @class ChoisesListManagementService + * @extends PrototypeApiService + * + * @description + * Encapsulates common requests to the /choises_list_management/ URL. + */ +function ChoisesListManagementService(Api) { + const service = new Api('/choises_list_management/'); + + service.formatStore = formatStore; + + function formatStore(data) { + const storeData = order(data); + return storeData; + } + + /** + * @method order + * + * @description + * Creates a proper choise list ordering by first creating an choise list tree and + * then flattening in place. + * + * @param {Array} lists - a list of choises lists objects + * @returns {Array} - the properly ordered list of choises lists objects + */ + + function order(data) { + // NOTE: we assume the root node is 0 + const ROOT_NODE = 0; + + // build the choises list tree + const tree = getChildren(data, ROOT_NODE); + + // return a flattened tree (in order) + return flatten(tree); + } + + /** + * @method getChildren + * + * @description + * This method builds a tree data structure of Choises lists and children of a + * specified parentId. + * + * @returns {Array} - an array of children + */ + function getChildren(data, parentId) { + // base case: There are no child Choises list + if (data.length === 0) { return null; } + + // returns all List where the parent is the + // parentId + const children = data.filter(handleParent); + + // recursively call getChildren on all child accounts + // and attach them as childen of their parent account + children.forEach(handleChildren); + + function handleParent(choiseList) { + return choiseList.parent === parentId; + } + + function handleChildren(choiseList) { + choiseList.children = getChildren(data, choiseList.id); + } + + return children; + } + + /** + * @method flatten + * + * @description + * Flattens a tree data structure (must have `children` property) in place. + * + * @returns {Array} - the flattened array + */ + function flatten(_tree, _depth) { + const tree = _tree || []; + let depth = (!angular.isDefined(_depth) || Number.isNaN(_depth)) ? -1 : _depth; + depth += 1; + + function handleTreeLevel(array, node) { + const items = [node].concat(node.children ? flatten(node.children, depth) : []); + node.$$treeLevel = depth; + return array.concat(items); + } + + return tree.reduce(handleTreeLevel, []); + } + + return service; +} diff --git a/client/src/modules/choises_list_management/modals/choises_list_management.modals.html b/client/src/modules/choises_list_management/modals/choises_list_management.modals.html new file mode 100644 index 0000000000..b9905fddc9 --- /dev/null +++ b/client/src/modules/choises_list_management/modals/choises_list_management.modals.html @@ -0,0 +1,103 @@ +
+ + + + + +
\ No newline at end of file diff --git a/client/src/modules/choises_list_management/modals/choises_list_management.modals.js b/client/src/modules/choises_list_management/modals/choises_list_management.modals.js new file mode 100644 index 0000000000..dfa7922343 --- /dev/null +++ b/client/src/modules/choises_list_management/modals/choises_list_management.modals.js @@ -0,0 +1,84 @@ +angular.module('bhima.controllers') + .controller('ChoisesListManagementModalController', ChoisesListManagementModalController); + +ChoisesListManagementModalController.$inject = [ + '$state', 'ChoisesListManagementService', 'NotifyService', 'appcache', +]; + +/** + * CHOISES LIST MANAGEMENT Modal Controller + */ + +function ChoisesListManagementModalController($state, ChoisesListManagement, Notify, AppCache) { + const vm = this; + const cache = AppCache('ChoisesListManagementModal'); + + vm.choise = {}; + vm.stateParams = {}; + + // exposed methods + vm.submit = submit; + vm.closeModal = closeModal; + vm.clear = clear; + vm.onSelectParent = onSelectParent; + vm.onSelectGroup = onSelectGroup; + + if ($state.params.creating || $state.params.id) { + cache.stateParams = $state.params; + vm.stateParams = cache.stateParams; + vm.choise.parent = $state.params.parentId; + } else { + vm.stateParams = cache.stateParams; + } + vm.isCreating = vm.stateParams.creating; + + if (!vm.isCreating) { + ChoisesListManagement.read(vm.stateParams.id) + .then(data => { + vm.choise = data; + }) + .catch(Notify.handleError); + } + + // load CHOISES LIST MANAGEMENT + ChoisesListManagement.read() + .then(choisesList => { + vm.choisesList = choisesList; + }) + .catch(Notify.handleError); + + // submit the data to the server from all two forms (update, create) + function submit(choisesListManagementForm) { + vm.hasNoChange = choisesListManagementForm.$submitted && choisesListManagementForm.$pristine && !vm.isCreating; + if (choisesListManagementForm.$invalid) { return null; } + if (!choisesListManagementForm.$dirty) { return null; } + + const promise = (vm.isCreating) + ? ChoisesListManagement.create(vm.choise) + : ChoisesListManagement.update(vm.choise.id, vm.choise); + + return promise + .then(() => { + const translateKey = (vm.isCreating) ? 'FORM.INFO.CREATE_SUCCESS' : 'FORM.INFO.UPDATE_SUCCESS'; + Notify.success(translateKey); + $state.go('choises_list_management', null, { reload : true }); + }) + .catch(Notify.handleError); + } + + function onSelectParent(parent) { + vm.choise.parent = parent.id; + } + + function onSelectGroup(group) { + vm.choise.group_label = group.id; + } + + function clear(value) { + vm.choise[value] = 0; + } + + function closeModal() { + $state.transitionTo('choises_list_management'); + } +} diff --git a/client/src/modules/choises_list_management/templates/action.cell.tmpl.html b/client/src/modules/choises_list_management/templates/action.cell.tmpl.html new file mode 100644 index 0000000000..202a12548a --- /dev/null +++ b/client/src/modules/choises_list_management/templates/action.cell.tmpl.html @@ -0,0 +1,37 @@ + diff --git a/client/src/modules/choises_list_management/templates/gridLabels.tmpl.html b/client/src/modules/choises_list_management/templates/gridLabels.tmpl.html new file mode 100644 index 0000000000..a9775414d8 --- /dev/null +++ b/client/src/modules/choises_list_management/templates/gridLabels.tmpl.html @@ -0,0 +1,12 @@ +
+ + {{ row.entity.label}} + + + {{ row.entity.label}} + + + + +
diff --git a/client/src/modules/choises_list_management/templates/gridName.tmpl.html b/client/src/modules/choises_list_management/templates/gridName.tmpl.html new file mode 100644 index 0000000000..32f0a9ccb5 --- /dev/null +++ b/client/src/modules/choises_list_management/templates/gridName.tmpl.html @@ -0,0 +1,8 @@ +
+ + {{ row.entity.label}} + + + {{ row.entity.name}} + +
\ No newline at end of file diff --git a/client/src/modules/choises_list_management/templates/is_title.tmpl.html b/client/src/modules/choises_list_management/templates/is_title.tmpl.html new file mode 100644 index 0000000000..6b6045df96 --- /dev/null +++ b/client/src/modules/choises_list_management/templates/is_title.tmpl.html @@ -0,0 +1,5 @@ +
+
+ FORM.LABELS.YES +
+
diff --git a/client/src/modules/data_collector_management/modals/data_collector_management.modals.html b/client/src/modules/data_collector_management/modals/data_collector_management.modals.html index a24808b5af..b022321086 100644 --- a/client/src/modules/data_collector_management/modals/data_collector_management.modals.html +++ b/client/src/modules/data_collector_management/modals/data_collector_management.modals.html @@ -50,7 +50,7 @@
- COO {{ DataCollectorManagementModalCtrl.dataCollector.color }} + diff --git a/client/src/modules/templates/bhChoiseListSelect.tmpl.html b/client/src/modules/templates/bhChoiseListSelect.tmpl.html new file mode 100644 index 0000000000..3f0a3f3b98 --- /dev/null +++ b/client/src/modules/templates/bhChoiseListSelect.tmpl.html @@ -0,0 +1,31 @@ +
+
+ + + + + + {{ $select.selected.label }} + + + + + + +
+
+
+
+
diff --git a/server/config/routes.js b/server/config/routes.js index 1f88e93d90..09b031c255 100644 --- a/server/config/routes.js +++ b/server/config/routes.js @@ -145,6 +145,7 @@ const indicatorRerpor = require('../controllers/finance/indicator/dashboard/repo // Data Kit const dataCollectorManagement = require('../controllers/admin/dataCollectorManagement'); +const choisesListManagement = require('../controllers/admin/choisesListManagement'); // expose routes to the server. exports.configure = function configure(app) { @@ -985,6 +986,14 @@ exports.configure = function configure(app) { app.get('/data_collector_management/:id', dataCollectorManagement.detail); app.post('/data_collector_management', dataCollectorManagement.create); app.put('/data_collector_management/:id', dataCollectorManagement.update); - app.delete('/data_collector_management/:id', dataCollectorManagement.delete); + app.delete('/data_collector_management/:id', dataCollectorManagement.delete); + + // API for CHOISES LIST MANAGEMENT routes crud + app.get('/choises_list_management', choisesListManagement.list); + app.get('/choises_list_management/:id', choisesListManagement.detail); + app.post('/choises_list_management', choisesListManagement.create); + app.put('/choises_list_management/:id', choisesListManagement.update); + app.delete('/choises_list_management/:id', choisesListManagement.delete); + }; diff --git a/server/controllers/admin/choisesListManagement.js b/server/controllers/admin/choisesListManagement.js new file mode 100644 index 0000000000..03afcbba0d --- /dev/null +++ b/server/controllers/admin/choisesListManagement.js @@ -0,0 +1,125 @@ +/** +* CHOISES LIST MANAGEMENT Controller +* +* This controller exposes an API to the client for reading and writing CHOISES LIST MANAGEMENT +*/ + +const db = require('../../lib/db'); +const NotFound = require('../../lib/errors/NotFound'); +const FilterParser = require('../../lib/filter'); + +// GET /choises_list_management +function lookupChoisesListManagement(id) { + const sql = ` + SELECT id, name, label, fixed, group_label, parent, is_title, is_group + FROM choises_list_management + WHERE choises_list_management.id = ?`; + + return db.one(sql, [id]); +} + +function list(req, res, next) { + const filters = new FilterParser(req.query); + + const sql = ` + SELECT id, name, label, fixed, group_label, parent, is_title, is_group + FROM choises_list_management + `; + + filters.equals('is_title'); + filters.equals('is_group'); + filters.equals('parent'); + filters.equals('group_label'); + filters.setOrder('ORDER BY label'); + + const query = filters.applyQuery(sql); + const parameters = filters.parameters(); + + db.exec(query, parameters) + .then((rows) => { + res.status(200).json(rows); + }) + .catch(next) + .done(); +} + +/** +* GET /choises_list_management/:ID +* +* Returns the detail of a single choises_list_management +*/ +function detail(req, res, next) { + const { id } = req.params; + + lookupChoisesListManagement(id) + .then((record) => { + res.status(200).json(record); + }) + .catch(next) + .done(); +} + + +// POST /choises_list_management +function create(req, res, next) { + const sql = `INSERT INTO choises_list_management SET ?`; + const data = req.body; + // Set 0 (root) like default parent + data.parent = data.parent || 0; + + db.exec(sql, [data]) + .then((row) => { + res.status(201).json({ id : row.insertId }); + }) + .catch(next) + .done(); +} + + +// PUT /choises_list_management /:id +function update(req, res, next) { + const sql = `UPDATE choises_list_management SET ? WHERE id = ?;`; + + db.exec(sql, [req.body, req.params.id]) + .then(() => { + return lookupChoisesListManagement(req.params.id); + }) + .then((record) => { + // all updates completed successfull, return full object to client + res.status(200).json(record); + }) + .catch(next) + .done(); +} + +// DELETE /choises_list_management/:id +function remove(req, res, next) { + const sql = `DELETE FROM choises_list_management WHERE id = ?;`; + + db.exec(sql, [req.params.id]) + .then((row) => { + // if nothing happened, let the client know via a 404 error + if (row.affectedRows === 0) { + throw new NotFound(`Could not find a function with id ${req.params.id}`); + } + + res.status(204).json(); + }) + .catch(next) + .done(); +} + +// get list of choisesListManagement +exports.list = list; + +// get details of a choisesListManagement +exports.detail = detail; + +// create a new choisesListManagement +exports.create = create; + +// update choisesListManagement informations +exports.update = update; + +// Delete a choisesListManagement +exports.delete = remove; diff --git a/server/models/bhima.sql b/server/models/bhima.sql index 31bb1da7f0..ef0b8f5662 100644 --- a/server/models/bhima.sql +++ b/server/models/bhima.sql @@ -373,3 +373,27 @@ INSERT INTO `cron` (`label`, `value`) VALUES -- data_collector_management INSERT INTO `data_collector_management` (`label`, `description`, `version_number`, `color`, `is_related_patient`) VALUES ('Fiche Kardex', 'Fiche de consommation Medicament', '1.0', '#E0FFFF', 1); + +-- choises_list_management +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (1, 'genre', 'Genre', 0, 0, 0, 1, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (2, 'm', 'Masculin', 0, 1, 1, 0, 0); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (3, 'f', 'Féminin', 0, 1, 1, 0, 0); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (4, 'pays', 'Pays', 0, 0, 0, 1, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (5, 'province', 'Province', 0, 4, 0, 1, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (6, 'districte', 'Districte', 0, 5, 0, 1, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (7, 'ville', 'Ville', 0, 6, 0, 1, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (8, 'commune', 'Commune', 0, 7, 0, 1, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (9, 'quartier', 'Quartier', 0, 8, 0, 1, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (10, 'rdc', 'RD Congo', 0, 0, 4, 0, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (11, 'kin', 'Kinshasa', 0, 10, 4, 0, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (12, 'mont_amba', 'Mont Amba', 0, 11, 6, 0, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (13, 'lemba', 'Lemba', 0, 12, 8, 0, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (14, 'salongo', 'Salongo', 0, 13, 9, 0, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (15, 'avenue', 'Avenue', 0, 9, 0, 1, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (16, 'bypass', 'By Pass', 0, 14, 15, 0, 0); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (17, 'kalala', 'Kalala', 0, 14, 0, 0, 0); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (18, 'funa', 'Funa', 0, 11, 6, 0, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (19, 'kv', 'Kasa vubu', 0, 18, 8, 0, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (20, 'mtg', 'Matonge', 0, 19, 9, 0, 1); +INSERT INTO `choises_list_management` (`id`, `name`, `label`, `fixed`, `parent`, `group_label`, `is_group`, `is_title`) VALUES (21, 'masimanimba', 'Masimanimba', 0, 20, 15, 0, 0); + diff --git a/server/models/schema.sql b/server/models/schema.sql index aaf78d756a..06f6c21301 100644 --- a/server/models/schema.sql +++ b/server/models/schema.sql @@ -2370,4 +2370,18 @@ CREATE TABLE `data_collector_management` ( UNIQUE KEY `data_collector_management_1` (`label`, `version_number`) ) ENGINE=InnoDB DEFAULT CHARACTER SET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; +DROP TABLE IF EXISTS `choises_list_management`; +CREATE TABLE `choises_list_management` ( + `id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT, + `name` VARCHAR(100) NOT NULL, + `label` VARCHAR(100) NOT NULL, + `fixed` tinyint(1) DEFAULT 0, + `parent` MEDIUMINT(8) UNSIGNED DEFAULT 0, + `group_label` MEDIUMINT(8) UNSIGNED DEFAULT 0, + `is_group` tinyint(1) NOT NULL DEFAULT 0, + `is_title` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + UNIQUE KEY `choises_list_management_1` (`label`, `name`, `parent`) +) ENGINE=InnoDB DEFAULT CHARACTER SET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; + SET foreign_key_checks = 1; diff --git a/test/end-to-end/choiseListManagement/choiseListManagement.page.js b/test/end-to-end/choiseListManagement/choiseListManagement.page.js new file mode 100644 index 0000000000..97d7323f37 --- /dev/null +++ b/test/end-to-end/choiseListManagement/choiseListManagement.page.js @@ -0,0 +1,77 @@ +/* global element, by */ +/* eslint */ + +/** + * This class is represents a Choise List Management page in term of structure and + * behaviour so it is a Choise List Management page object + */ + +/* loading grid actions */ +const GridRow = require('../shared/GridRow'); +const FU = require('../shared/FormUtils'); +const components = require('../shared/components'); + +class ChoiseListManagementPage { + constructor() { + this.gridId = 'choises-list-management-grid'; + this.rubricGrid = element(by.id(this.gridId)); + this.actionLinkColumn = 5; + } + + /** + * simulate the create PayrollConfig button click to show the dialog of creation + */ + async create(ChoiseListElement) { + await FU.buttons.create(); + await FU.input('ChoisesListManagementModalCtrl.choise.label', ChoiseListElement.label); + await FU.input('ChoisesListManagementModalCtrl.choise.name', ChoiseListElement.name); + await element(by.id('is_title')).click(); + await element(by.id('is_group')).click(); + + + await FU.buttons.submit(); + await components.notification.hasSuccess(); + } + + /** + * block creation without the function name + */ + async errorOnCreate() { + await FU.buttons.create(); + await FU.buttons.submit(); + await FU.validation.error('ChoisesListManagementModalCtrl.choise.label'); + await FU.buttons.cancel(); + } + + /** + * simulate a click on the edit link of a function + */ + async edit(label, updateDataCollector) { + const row = new GridRow(label); + row.dropdown().click(); + row.edit().click(); + + await components.choiseListSelect.set(updateDataCollector.parent, 'parent'); + await components.choiseListSelect.set(updateDataCollector.group_label, 'group_label'); + + await element(by.id('is_title')).click(); + await element(by.id('is_group')).click(); + + await FU.buttons.submit(); + await components.notification.hasSuccess(); + } + + /** + * simulate a click on the delete link of a function + */ + async delete(label) { + const row = new GridRow(label); + await row.dropdown().click(); + await row.remove().click(); + + await FU.modal.submit(); + await components.notification.hasSuccess(); + } +} + +module.exports = ChoiseListManagementPage; diff --git a/test/end-to-end/choiseListManagement/choiseListManagement.spec.js b/test/end-to-end/choiseListManagement/choiseListManagement.spec.js new file mode 100644 index 0000000000..5d14267002 --- /dev/null +++ b/test/end-to-end/choiseListManagement/choiseListManagement.spec.js @@ -0,0 +1,44 @@ +const helpers = require('../shared/helpers'); +const ChoiseListManagement = require('./choiseListManagement.page'); + +describe.only('Choise List Management', () => { + // navigate to the page + before(() => helpers.navigate('#!/choises_list_management')); + + const Page = new ChoiseListManagement(); + + const newChoiseListElement = { + name : 'oshwe', + label : 'OSHWE', + }; + + const deleteListElement = { + name : 'fruit', + label : 'Fruit', + }; + + const updateChoiseListElement = { + parent : 'Matonge', + group_label : 'Avenue', + }; + + it('successfully creates a new Choise List Management', async () => { + await Page.create(newChoiseListElement); + }); + + it('successfully edits a Choise List Management', async () => { + await Page.edit(newChoiseListElement.label, updateChoiseListElement); + }); + + it('don\'t create when incorrect Choise List Management', async () => { + await Page.errorOnCreate(); + }); + + it('successfully creates a deletable element', async () => { + await Page.create(deleteListElement); + }); + + it('successfully delete a list Element', async () => { + await Page.delete(deleteListElement.label); + }); +}); diff --git a/test/end-to-end/dataCollectorManagement/dataCollectorManagement.page.js b/test/end-to-end/dataCollectorManagement/dataCollectorManagement.page.js index 6d612a9b46..490cbb7d5d 100644 --- a/test/end-to-end/dataCollectorManagement/dataCollectorManagement.page.js +++ b/test/end-to-end/dataCollectorManagement/dataCollectorManagement.page.js @@ -2,13 +2,11 @@ /* eslint */ /** - * This class is represents a payroll configuration page in term of structure and - * behaviour so it is a payroll configuration page object + * This class is represents a Data Collector page in term of structure and + * behaviour so it is a Data Collector Management page object */ /* loading grid actions */ -const GA = require('../shared/GridAction'); -const GU = require('../shared/GridUtils'); const GridRow = require('../shared/GridRow'); const FU = require('../shared/FormUtils'); const components = require('../shared/components'); @@ -21,7 +19,7 @@ class DataCollectorManagementPage { } /** - * simulate the create PayrollConfig button click to show the dialog of creation + * simulate the create Data Collector button click to show the dialog of creation */ async create(dataCollectorManagement) { await FU.buttons.create(); diff --git a/test/end-to-end/dataCollectorManagement/dataCollectorManagement.spec.js b/test/end-to-end/dataCollectorManagement/dataCollectorManagement.spec.js index 34eb57a41f..144570729d 100644 --- a/test/end-to-end/dataCollectorManagement/dataCollectorManagement.spec.js +++ b/test/end-to-end/dataCollectorManagement/dataCollectorManagement.spec.js @@ -1,7 +1,7 @@ const helpers = require('../shared/helpers'); const DataCollectorManagement = require('./dataCollectorManagement.page'); -describe.only('Data Collector Management', () => { +describe('Data Collector Management', () => { // navigate to the page before(() => helpers.navigate('#!/data_collector_management')); @@ -33,7 +33,7 @@ describe.only('Data Collector Management', () => { await Page.errorOnCreate(); }); - it('successfully delete a Configuration Payroll Period', async () => { + it('successfully delete a Data Collector Management', async () => { await Page.delete(updateDataCollector.label); }); }); diff --git a/test/end-to-end/shared/components/bhChoiseListSelect.js b/test/end-to-end/shared/components/bhChoiseListSelect.js new file mode 100644 index 0000000000..eee5ca5275 --- /dev/null +++ b/test/end-to-end/shared/components/bhChoiseListSelect.js @@ -0,0 +1,17 @@ +/* global element, by */ + +const FU = require('../FormUtils'); + +module.exports = { + selector : '[bh-choise-list-select]', + set : async function set(list, id) { + const locator = (id) ? by.id(id) : by.css(this.selector); + const target = element(locator); + + // hack to make sure previous 'blur' event fires if we are using + // ngModelOptions updateOn 'blur' for every input + await target.click(); + + await FU.uiSelect('$ctrl.list', list, target); + }, +}; diff --git a/test/end-to-end/shared/components/index.js b/test/end-to-end/shared/components/index.js index a1cf22ab2f..d63d862136 100644 --- a/test/end-to-end/shared/components/index.js +++ b/test/end-to-end/shared/components/index.js @@ -71,4 +71,5 @@ module.exports = { diagnosisSelect : require('./bhDiagnosisSelect'), entityGroupSelect : require('./bhEntityGroupSelect'), cronSelect : require('./bhCronSelect'), + choiseListSelect : require('./bhChoiseListSelect'), }; diff --git a/test/integration/choiseListManagement.js b/test/integration/choiseListManagement.js new file mode 100644 index 0000000000..df6b21a4b6 --- /dev/null +++ b/test/integration/choiseListManagement.js @@ -0,0 +1,76 @@ +/* global expect, agent */ +const helpers = require('./helpers'); + +describe('(/choises_list_management) Choise List Management', () => { + const numListElement = 22; + + const newElementList = { + name : 'oshwe', + label : 'OSHWE', + fixed : 0, + parent : 0, + group_label : 0, + is_group : 0, + is_title : 0, + }; + + const updateElementList = { + parent : 20, + group_label : 15, + }; + + it('POST /choises_list_management add Choise List Element', () => { + return agent.post('/choises_list_management') + .send(newElementList) + .then((res) => { + helpers.api.created(res); + newElementList.id = res.body.id; + }) + .catch(helpers.handler); + }); + + it('GET /choises_list_management/:id returns one Choise List Management as detail', () => { + return agent.get(`/choises_list_management/${newElementList.id}`) + .then((res) => { + expect(res).to.have.status(200); + + expect(res).to.be.a('object'); + expect(res.body).to.have.all.keys('id', 'name', 'label', 'fixed', 'parent', + 'group_label', 'is_group', 'is_title'); + }) + .catch(helpers.handler); + }); + + it('PUT /choises_list_management/:id updates the newly added Choise List Management', () => { + return agent.put(`/choises_list_management/${newElementList.id}`) + .send(updateElementList) + .then((res) => { + expect(res).to.have.status(200); + expect(res).to.be.a('object'); + expect(res.body.id).to.equal(newElementList.id); + }) + .catch(helpers.handler); + }); + + it('GET /choises_list_management returns all Choise List Management', () => { + return agent.get(`/choises_list_management/`) + .then((res) => { + helpers.api.listed(res, numListElement); + expect(res.body[0]).to.have.all.keys('id', 'name', 'label', 'fixed', 'parent', + 'group_label', 'is_group', 'is_title'); + }) + .catch(helpers.handler); + }); + + it('DELETE /choises_list_management/:id deletes a Choise List Management', () => { + return agent.delete(`/choises_list_management/${newElementList.id}`) + .then((res) => { + helpers.api.deleted(res); + return agent.get(`/choises_list_management/${newElementList.id}`); + }) + .then((res) => { + helpers.api.errored(res, 404); + }) + .catch(helpers.handler); + }); +}); From 7d3eec255c91ec2c7f2818c3caf9596a676d3836 Mon Sep 17 00:00:00 2001 From: Chris Lomame Date: Mon, 16 Sep 2019 16:24:35 +0100 Subject: [PATCH 03/30] Resolve conflict s3 --- client/src/i18n/en/form.json | 2 +- client/src/i18n/en/tree.json | 2 +- client/src/i18n/fr/form.json | 2 +- client/src/i18n/fr/tree.json | 2 +- ...iseListSelect.js => bhChoiceListSelect.js} | 16 ++-- .../choices_list_management.html} | 16 ++-- .../choices_list_management.js} | 30 +++---- .../choices_list_management.routes.js | 43 ++++++++++ .../choices_list_management.service.js} | 32 +++---- .../choices_list_management.modals.html} | 56 ++++++------- .../modals/choices_list_management.modals.js | 84 +++++++++++++++++++ .../templates/action.cell.tmpl.html | 0 .../templates/gridLabels.tmpl.html | 2 +- .../templates/gridName.tmpl.html | 0 .../templates/is_title.tmpl.html | 0 .../choises_list_management.routes.js | 43 ---------- .../modals/choises_list_management.modals.js | 84 ------------------- ...tmpl.html => bhChoiceListSelect.tmpl.html} | 10 +-- server/config/routes.js | 12 +-- ...Management.js => choicesListManagement.js} | 44 +++++----- server/models/bhima.sql | 44 +++++----- server/models/schema.sql | 6 +- .../choiceListManagement.page.js} | 22 ++--- .../choiceListManagement.spec.js | 44 ++++++++++ .../choiseListManagement.spec.js | 44 ---------- ...iseListSelect.js => bhChoiceListSelect.js} | 2 +- test/end-to-end/shared/components/index.js | 2 +- ...tManagement.js => choiceListManagement.js} | 24 +++--- 28 files changed, 334 insertions(+), 334 deletions(-) rename client/src/js/components/{bhChoiseListSelect.js => bhChoiceListSelect.js} (79%) rename client/src/modules/{choises_list_management/choises_list_management.html => choices_list_management/choices_list_management.html} (65%) rename client/src/modules/{choises_list_management/choises_list_management.js => choices_list_management/choices_list_management.js} (74%) create mode 100644 client/src/modules/choices_list_management/choices_list_management.routes.js rename client/src/modules/{choises_list_management/choises_list_management.service.js => choices_list_management/choices_list_management.service.js} (66%) rename client/src/modules/{choises_list_management/modals/choises_list_management.modals.html => choices_list_management/modals/choices_list_management.modals.html} (53%) create mode 100644 client/src/modules/choices_list_management/modals/choices_list_management.modals.js rename client/src/modules/{choises_list_management => choices_list_management}/templates/action.cell.tmpl.html (100%) rename client/src/modules/{choises_list_management => choices_list_management}/templates/gridLabels.tmpl.html (88%) rename client/src/modules/{choises_list_management => choices_list_management}/templates/gridName.tmpl.html (100%) rename client/src/modules/{choises_list_management => choices_list_management}/templates/is_title.tmpl.html (100%) delete mode 100644 client/src/modules/choises_list_management/choises_list_management.routes.js delete mode 100644 client/src/modules/choises_list_management/modals/choises_list_management.modals.js rename client/src/modules/templates/{bhChoiseListSelect.tmpl.html => bhChoiceListSelect.tmpl.html} (72%) rename server/controllers/admin/{choisesListManagement.js => choicesListManagement.js} (69%) rename test/end-to-end/{choiseListManagement/choiseListManagement.page.js => choiceListManagement/choiceListManagement.page.js} (69%) create mode 100644 test/end-to-end/choiceListManagement/choiceListManagement.spec.js delete mode 100644 test/end-to-end/choiseListManagement/choiseListManagement.spec.js rename test/end-to-end/shared/components/{bhChoiseListSelect.js => bhChoiceListSelect.js} (91%) rename test/integration/{choiseListManagement.js => choiceListManagement.js} (67%) diff --git a/client/src/i18n/en/form.json b/client/src/i18n/en/form.json index 3c3f49e80f..40fddb4f54 100644 --- a/client/src/i18n/en/form.json +++ b/client/src/i18n/en/form.json @@ -314,7 +314,7 @@ "CAUTION": "Caution", "CAUTION_AMOUNT": "Prepayment Amount", "CHARGE": "Cost", - "CHOISE_LIST": "Choise list", + "CHOICE_LIST": "Choice list", "CLIENT": "Client", "CLIENT_ID": "Client ID", "CLIENT_TO_IGNORE": "Client(s) to ignore", diff --git a/client/src/i18n/en/tree.json b/client/src/i18n/en/tree.json index af96c386c0..0f20938537 100644 --- a/client/src/i18n/en/tree.json +++ b/client/src/i18n/en/tree.json @@ -23,7 +23,7 @@ "CASHFLOW_BY_SERVICE" : "Cashflow by Service", "CASH_PAYMENT_REGISTRY" : "Cash Payment Registry", "CASH_WINDOW" : "Cash Window", - "CHOISES_LIST_MANAGEMENT" : "Choises List Management", + "CHOICES_LIST_MANAGEMENT" : "Choices List Management", "COMPLEX_JOURNAL_VOUCHER" : "Journal Vouchers", "COST_CENTER_MGMT" : "Cost Center Management", "CREDIT_NOTE" : "Credit Note", diff --git a/client/src/i18n/fr/form.json b/client/src/i18n/fr/form.json index 92be20c2e3..cf75210fee 100644 --- a/client/src/i18n/fr/form.json +++ b/client/src/i18n/fr/form.json @@ -317,7 +317,7 @@ "CAUTION": "Caution", "CAUTION_AMOUNT": "Total de la Caution", "CHARGE": "Charge", - "CHOISE_LIST": "Liste de choix", + "CHOICE_LIST": "Liste de choix", "CLIENT": "Client", "CLIENT_ID": "Identifiant client", "CLIENT_TO_IGNORE": "Client(s) à ignorer", diff --git a/client/src/i18n/fr/tree.json b/client/src/i18n/fr/tree.json index c186a0487b..ac36fd9228 100644 --- a/client/src/i18n/fr/tree.json +++ b/client/src/i18n/fr/tree.json @@ -23,7 +23,7 @@ "CASHFLOW_BY_SERVICE": "Journal de Ventilation", "CASH_PAYMENT_REGISTRY":"Registre des paiements", "CASH_WINDOW":"Paiements", - "CHOISES_LIST_MANAGEMENT" : "Gestion des listes de choix", + "CHOICES_LIST_MANAGEMENT" : "Gestion des listes de choix", "COMPLEX_JOURNAL_VOUCHER":"Ajout de transactions", "COST_CENTER_MGMT":"Centres de coûts", "CREDIT_NOTE":"Note de Crédit", diff --git a/client/src/js/components/bhChoiseListSelect.js b/client/src/js/components/bhChoiceListSelect.js similarity index 79% rename from client/src/js/components/bhChoiseListSelect.js rename to client/src/js/components/bhChoiceListSelect.js index d3bd6edbe3..4a811d4845 100644 --- a/client/src/js/components/bhChoiseListSelect.js +++ b/client/src/js/components/bhChoiceListSelect.js @@ -1,7 +1,7 @@ angular.module('bhima.components') - .component('bhChoiseListSelect', { - templateUrl : 'modules/templates/bhChoiseListSelect.tmpl.html', - controller : ChoiseListController, + .component('bhChoiceListSelect', { + templateUrl : 'modules/templates/bhChoiceListSelect.tmpl.html', + controller : ChoiceListController, transclude : true, bindings : { onSelectCallback : '&', @@ -16,12 +16,12 @@ angular.module('bhima.components') }, }); -ChoiseListController.$inject = ['ChoisesListManagementService', 'NotifyService']; +ChoiceListController.$inject = ['ChoicesListManagementService', 'NotifyService']; /** - * Choise List + * Choice List */ -function ChoiseListController(ChoisesList, Notify) { +function ChoiceListController(ChoicesList, Notify) { const $ctrl = this; $ctrl.$onInit = function onInit() { @@ -33,7 +33,7 @@ function ChoiseListController(ChoisesList, Notify) { group_label : $ctrl.groupLabel || null, }; - ChoisesList.read(null, query) + ChoicesList.read(null, query) .then(lists => { $ctrl.lists = lists; }) @@ -51,7 +51,7 @@ function ChoiseListController(ChoisesList, Notify) { group_label : $ctrl.groupLabel || null, }; - ChoisesList.read(null, query) + ChoicesList.read(null, query) .then(lists => { $ctrl.lists = lists; }) diff --git a/client/src/modules/choises_list_management/choises_list_management.html b/client/src/modules/choices_list_management/choices_list_management.html similarity index 65% rename from client/src/modules/choises_list_management/choises_list_management.html rename to client/src/modules/choices_list_management/choices_list_management.html index d68af8a343..ca15e7a362 100644 --- a/client/src/modules/choises_list_management/choises_list_management.html +++ b/client/src/modules/choices_list_management/choices_list_management.html @@ -2,20 +2,20 @@
  1. TREE.ADMIN
  2. -
  3. TREE.CHOISES_LIST_MANAGEMENT
  4. +
  5. TREE.CHOICES_LIST_MANAGEMENT
-
-
@@ -26,12 +26,12 @@
-
- +
diff --git a/client/src/modules/choises_list_management/choises_list_management.js b/client/src/modules/choices_list_management/choices_list_management.js similarity index 74% rename from client/src/modules/choises_list_management/choises_list_management.js rename to client/src/modules/choices_list_management/choices_list_management.js index ce5e17a36a..b6739155e6 100644 --- a/client/src/modules/choises_list_management/choises_list_management.js +++ b/client/src/modules/choices_list_management/choices_list_management.js @@ -1,16 +1,16 @@ angular.module('bhima.controllers') - .controller('ChoisesListManagementController', ChoisesListManagementController); + .controller('ChoicesListManagementController', ChoicesListManagementController); -ChoisesListManagementController.$inject = [ - '$state', 'ChoisesListManagementService', 'NotifyService', 'uiGridConstants', 'ModalService', +ChoicesListManagementController.$inject = [ + '$state', 'ChoicesListManagementService', 'NotifyService', 'uiGridConstants', 'ModalService', ]; /** - * CHOISES LIST MANAGEMENT Controller - * This module is responsible for handling the CRUD operation on CHOISES LIST MANAGEMENT + * CHOICES LIST MANAGEMENT Controller + * This module is responsible for handling the CRUD operation on CHOICES LIST MANAGEMENT */ -function ChoisesListManagementController($state, ChoisesListManagement, Notify, uiGridConstants, ModalService) { +function ChoicesListManagementController($state, ChoicesListManagement, Notify, uiGridConstants, ModalService) { const vm = this; vm.gridApi = {}; vm.filterEnabled = false; @@ -31,27 +31,27 @@ function ChoisesListManagementController($state, ChoisesListManagement, Notify, displayName : 'FORM.LABELS.VARIABLE_NAME', enableFiltering : 'true', headerCellFilter : 'translate', - cellTemplate : '/modules/choises_list_management/templates/gridName.tmpl.html', + cellTemplate : '/modules/choices_list_management/templates/gridName.tmpl.html', }, { field : 'label', displayName : 'FORM.LABELS.DESIGNATION', enableFiltering : 'true', headerCellFilter : 'translate', - cellTemplate : '/modules/choises_list_management/templates/gridLabels.tmpl.html', + cellTemplate : '/modules/choices_list_management/templates/gridLabels.tmpl.html', }, { field : 'is_title', displayName : 'FORM.LABELS.TITLE', enableFiltering : 'true', headerCellFilter : 'translate', - cellTemplate : '/modules/choises_list_management/templates/is_title.tmpl.html', + cellTemplate : '/modules/choices_list_management/templates/is_title.tmpl.html', }, { field : 'action', displayName : '', enableFiltering : 'false', - cellTemplate : '/modules/choises_list_management/templates/action.cell.tmpl.html', + cellTemplate : '/modules/choices_list_management/templates/action.cell.tmpl.html', }, ], }; @@ -71,14 +71,14 @@ function ChoisesListManagementController($state, ChoisesListManagement, Notify, vm.edit = edit; vm.remove = remove; - function edit(choisesListManagement) { - $state.go('choises_list_management.edit', { id : choisesListManagement.id }); + function edit(choicesListManagement) { + $state.go('choices_list_management.edit', { id : choicesListManagement.id }); } function remove(id) { ModalService.confirm('FORM.DIALOGS.CONFIRM_DELETE') .then(() => { - ChoisesListManagement.delete(id) + ChoicesListManagement.delete(id) .then(() => { Notify.success('FORM.INFO.DELETE_SUCCESS'); loadGrid(); @@ -96,9 +96,9 @@ function ChoisesListManagementController($state, ChoisesListManagement, Notify, vm.hasError = false; vm.loading = true; - ChoisesListManagement.read() + ChoicesListManagement.read() .then((data) => { - const dataTree = ChoisesListManagement.formatStore(data); + const dataTree = ChoicesListManagement.formatStore(data); vm.gridOptions.data = dataTree; }) .catch(handleError) diff --git a/client/src/modules/choices_list_management/choices_list_management.routes.js b/client/src/modules/choices_list_management/choices_list_management.routes.js new file mode 100644 index 0000000000..8fb0daf5a7 --- /dev/null +++ b/client/src/modules/choices_list_management/choices_list_management.routes.js @@ -0,0 +1,43 @@ +angular.module('bhima.routes') + .config(['$stateProvider', $stateProvider => { + $stateProvider + .state('choices_list_management', { + url : '/choices_list_management', + controller : 'ChoicesListManagementController as ChoicesListManagementCtrl', + templateUrl : 'modules/choices_list_management/choices_list_management.html', + }) + + .state('choices_list_management.create', { + url : '/create', + params : { + choices_list_management : { value : null }, + creating : { value : true }, + parentId : { value : null }, + }, + onEnter : ['$uibModal', choicesListManagementModal], + onExit : ['$uibModalStack', closeModal], + }) + + .state('choices_list_management.edit', { + url : '/:id/edit', + params : { + choices_list_management : { value : null }, + creating : { value : false }, + }, + onEnter : ['$uibModal', choicesListManagementModal], + onExit : ['$uibModalStack', closeModal], + }); + }]); + +function choicesListManagementModal($modal) { + $modal.open({ + keyboard : false, + backdrop : 'static', + templateUrl : 'modules/choices_list_management/modals/choices_list_management.modals.html', + controller : 'ChoicesListManagementModalController as ChoicesListManagementModalCtrl', + }); +} + +function closeModal(ModalStack) { + ModalStack.dismissAll(); +} diff --git a/client/src/modules/choises_list_management/choises_list_management.service.js b/client/src/modules/choices_list_management/choices_list_management.service.js similarity index 66% rename from client/src/modules/choises_list_management/choises_list_management.service.js rename to client/src/modules/choices_list_management/choices_list_management.service.js index 831eb98642..6077b8dc89 100644 --- a/client/src/modules/choises_list_management/choises_list_management.service.js +++ b/client/src/modules/choices_list_management/choices_list_management.service.js @@ -1,17 +1,17 @@ angular.module('bhima.services') - .service('ChoisesListManagementService', ChoisesListManagementService); + .service('ChoicesListManagementService', ChoicesListManagementService); -ChoisesListManagementService.$inject = ['PrototypeApiService']; +ChoicesListManagementService.$inject = ['PrototypeApiService']; /** - * @class ChoisesListManagementService + * @class ChoicesListManagementService * @extends PrototypeApiService * * @description - * Encapsulates common requests to the /choises_list_management/ URL. + * Encapsulates common requests to the /choices_list_management/ URL. */ -function ChoisesListManagementService(Api) { - const service = new Api('/choises_list_management/'); +function ChoicesListManagementService(Api) { + const service = new Api('/choices_list_management/'); service.formatStore = formatStore; @@ -24,18 +24,18 @@ function ChoisesListManagementService(Api) { * @method order * * @description - * Creates a proper choise list ordering by first creating an choise list tree and + * Creates a proper choice list ordering by first creating an choice list tree and * then flattening in place. * - * @param {Array} lists - a list of choises lists objects - * @returns {Array} - the properly ordered list of choises lists objects + * @param {Array} lists - a list of choices lists objects + * @returns {Array} - the properly ordered list of choices lists objects */ function order(data) { // NOTE: we assume the root node is 0 const ROOT_NODE = 0; - // build the choises list tree + // build the choices list tree const tree = getChildren(data, ROOT_NODE); // return a flattened tree (in order) @@ -46,13 +46,13 @@ function ChoisesListManagementService(Api) { * @method getChildren * * @description - * This method builds a tree data structure of Choises lists and children of a + * This method builds a tree data structure of Choices lists and children of a * specified parentId. * * @returns {Array} - an array of children */ function getChildren(data, parentId) { - // base case: There are no child Choises list + // base case: There are no child Choices list if (data.length === 0) { return null; } // returns all List where the parent is the @@ -63,12 +63,12 @@ function ChoisesListManagementService(Api) { // and attach them as childen of their parent account children.forEach(handleChildren); - function handleParent(choiseList) { - return choiseList.parent === parentId; + function handleParent(choiceList) { + return choiceList.parent === parentId; } - function handleChildren(choiseList) { - choiseList.children = getChildren(data, choiseList.id); + function handleChildren(choiceList) { + choiceList.children = getChildren(data, choiceList.id); } return children; diff --git a/client/src/modules/choises_list_management/modals/choises_list_management.modals.html b/client/src/modules/choices_list_management/modals/choices_list_management.modals.html similarity index 53% rename from client/src/modules/choises_list_management/modals/choises_list_management.modals.html rename to client/src/modules/choices_list_management/modals/choices_list_management.modals.html index b9905fddc9..c82653f328 100644 --- a/client/src/modules/choises_list_management/modals/choises_list_management.modals.html +++ b/client/src/modules/choices_list_management/modals/choices_list_management.modals.html @@ -1,15 +1,15 @@ -
-
+
{ if (key === element.surveyName) { + // This is a hack to avoid apostrophes in the search parameter + findParameters[key] = findParameters[key].replace(`'`, `''`); + if (element.type === '1') { filterCondition += ` ${element.surveyName} = '${findParameters[key]}' ${andCondition}`; } else if (element.type === '2' || element.type === '7' || element.type === '9') { From 944a6c53e386c8fce352bac491547c2d6897700f Mon Sep 17 00:00:00 2001 From: Chris Lomame Date: Mon, 16 Sep 2019 10:21:55 +0100 Subject: [PATCH 16/30] refactor(Data Collector) - Added the listHint property to display information about the component selection lists bhChoiceListMultipleSelect and bhChoiceListSelect - Using function downloadPDF and Using an object instead of a function with multiple parameters - Using Mao from the survey array for mere efficient --- .../components/bhChoiceListMultipleSelect.js | 1 + .../src/js/components/bhChoiceListSelect.js | 1 + .../display_metadata/display_metadata.html | 78 ++++++++++--------- .../display_metadata/display_metadata.js | 20 ++++- .../display_metadata.service.js | 54 +++++++------ .../display_metadata/modals/search.modal.html | 2 + .../display_metadata/modals/search.modal.js | 3 +- .../fill_form/modals/fill_form.modals.html | 5 +- .../bhChoiceListMultipleSelect.tmpl.html | 2 +- .../templates/bhChoiceListSelect.tmpl.html | 2 +- server/controllers/admin/displayMetadata.js | 6 +- .../controllers/admin/metadataReport/index.js | 1 + 12 files changed, 100 insertions(+), 75 deletions(-) diff --git a/client/src/js/components/bhChoiceListMultipleSelect.js b/client/src/js/components/bhChoiceListMultipleSelect.js index f695147a0e..b01fd7475c 100644 --- a/client/src/js/components/bhChoiceListMultipleSelect.js +++ b/client/src/js/components/bhChoiceListMultipleSelect.js @@ -8,6 +8,7 @@ angular.module('bhima.components') label : '@?', required : '
- +
+
+ + + + + +
+
+
+ +
-
- +
+ +
diff --git a/client/src/modules/display_metadata/display_metadata.js b/client/src/modules/display_metadata/display_metadata.js index 8a88447bd1..785316969a 100644 --- a/client/src/modules/display_metadata/display_metadata.js +++ b/client/src/modules/display_metadata/display_metadata.js @@ -26,11 +26,12 @@ function DisplayMetadataController($state, DisplayMetadata, DataCollectorManagem vm.onRemove = onRemove; vm.displayData = displayData; vm.patient = {}; + vm.options = {}; vm.downloadPDF = function downloadPDF() { - vm.patient.uuid = vm.patient ? vm.patient.uuid : ''; + vm.options.renderer = 'pdf'; - return DisplayMetadata.download('pdf', vm.changes, vm.collectorId, vm.filterElements, vm.patient.uuid, vm.patient); + return DisplayMetadata.download(vm.options); }; const cache = new AppCache('display_metadata'); @@ -130,6 +131,12 @@ function DisplayMetadataController($state, DisplayMetadata, DataCollectorManagem .then((survey) => { vm.filterElements = DisplayMetadata.displayFilters(survey, vm.changes); + vm.options = { + changes : vm.changes, + data_collector_management_id : vm.collectorId, + filterClient : vm.filterElements, + }; + vm.params = { data_collector_management_id : vm.collectorId, changes : vm.changes, @@ -179,6 +186,15 @@ function DisplayMetadataController($state, DisplayMetadata, DataCollectorManagem }) .then((survey) => { vm.filterElements = DisplayMetadata.displayFilters(survey, vm.changes); + + vm.options = { + changes : vm.changes, + data_collector_management_id : vm.collectorId, + filterClient : vm.filterElements, + patient_uuid : vm.patient.uuid, + patient : vm.patient, + }; + }) .catch(handleError) .finally(toggleLoadingIndicator); diff --git a/client/src/modules/display_metadata/display_metadata.service.js b/client/src/modules/display_metadata/display_metadata.service.js index ee82796b48..95012ffb9f 100644 --- a/client/src/modules/display_metadata/display_metadata.service.js +++ b/client/src/modules/display_metadata/display_metadata.service.js @@ -18,16 +18,16 @@ function DisplayMetadataService(Api, Modal, moment, $translate, $httpParamSerial service.displayFilters = displayFilters; service.download = download; - function download(type, changes, id, filterClient, patientUuid, patient) { + function download(opts) { const options = { - renderer : type, - changes, + renderer : opts.renderer, + changes : opts.changes, lang : Languages.key, - patient_uuid : patientUuid || null, + patient_uuid : opts.patient_uuid, downloadMode : true, - data_collector_management_id : id, - filterClient, - patient, + data_collector_management_id : opts.data_collector_management_id, + filterClient : opts.filterClient, + patient : opts.patient, }; // return serialized options @@ -35,7 +35,7 @@ function DisplayMetadataService(Api, Modal, moment, $translate, $httpParamSerial } function listSurveyformtype() { - const url = ''.concat('listSurveyformtype'); + const url = 'listSurveyformtype'; return Api.read.call(service, url); } @@ -60,6 +60,7 @@ function DisplayMetadataService(Api, Modal, moment, $translate, $httpParamSerial function displayFilters(survey, search) { let filters = ``; + const surveyMap = new Map(survey.map(item => ([item.name, item]))); const dateLabel = $translate.instant('FORM.LABELS.DATE'); if (search.searchDateFrom) { @@ -71,23 +72,21 @@ function DisplayMetadataService(Api, Modal, moment, $translate, $httpParamSerial - ${moment(search.searchDateTo[key]).format('DD MMM YYYY')}])`; } - survey.forEach(item => { - if (item.name === key) { - filters += ` // ( ${item.label} [${moment(search.searchDateFrom[key]).format('DD MMM YYYY')} - - ${moment(search.searchDateTo[key]).format('DD MMM YYYY')}])`; - } - }); + const item = surveyMap.get(key); + if (item) { + filters += ` // ( ${item.label} [${moment(search.searchDateFrom[key]).format('DD MMM YYYY')} + - ${moment(search.searchDateTo[key]).format('DD MMM YYYY')}])`; + } }); } } if (search.loggedChanges) { search.loggedChanges.forEach(element => { - survey.forEach(item => { - if (item.name === element.key) { - filters += ` // ${item.label} : ${element.value} `; - } - }); + const item = surveyMap.get(element.key); + if (item) { + filters += ` // ${item.label} : ${element.value} `; + } }); } @@ -95,16 +94,15 @@ function DisplayMetadataService(Api, Modal, moment, $translate, $httpParamSerial const multipleChoiceLength = Object.keys(search.multipleChoice).length; if (multipleChoiceLength) { Object.keys(search.multipleChoice).forEach((key) => { - survey.forEach(item => { - if (item.name === key) { - let multiChoice = ''; - for (let i = 0; i < search.multipleChoice[key].length; i++) { - multiChoice += ` ${search.multipleChoice[key][i]}, `; - } - - filters += ` // ${item.label} : ( ${multiChoice} )`; + const item = surveyMap.get(key); + if (item) { + let multiChoice = ''; + for (let i = 0; i < search.multipleChoice[key].length; i++) { + multiChoice += ` ${search.multipleChoice[key][i]}, `; } - }); + + filters += ` // ${item.label} : ( ${multiChoice} )`; + } }); } } diff --git a/client/src/modules/display_metadata/modals/search.modal.html b/client/src/modules/display_metadata/modals/search.modal.html index bf838168ae..7ec553d68d 100644 --- a/client/src/modules/display_metadata/modals/search.modal.html +++ b/client/src/modules/display_metadata/modals/search.modal.html @@ -73,6 +73,7 @@ list="$ctrl.searchQueries[formItem.name]" name="{{ formItem.name }}" list-label="{{ formItem.label }}" + list-hint="{{ formItem.hint }}" group-label="formItem.choice_list_id" on-select-callback="$ctrl.onSelectList(list, formItem.name)"> @@ -88,6 +89,7 @@ name="{{ formItem.name }}" required="formItem.valueRequired" list-label="{{ formItem.label }}" + list-hint="{{ formItem.hint }}" group-label="formItem.choice_list_id" on-change="$ctrl.onSelectMultiple(lists, formItem.name)"> diff --git a/client/src/modules/display_metadata/modals/search.modal.js b/client/src/modules/display_metadata/modals/search.modal.js index 48d93d95f9..5fdb089d2b 100644 --- a/client/src/modules/display_metadata/modals/search.modal.js +++ b/client/src/modules/display_metadata/modals/search.modal.js @@ -52,7 +52,7 @@ function DisplayMetadataSearchModalController( return ChoicesList.read(); }) .then(choicesLists => { - vm.choicsLists = choicesLists; + vm.choicesLists = choicesLists; }) .catch(Notify.handleError); } @@ -80,6 +80,7 @@ function DisplayMetadataSearchModalController( } }); + const multipleChoiceLength = Object.keys(vm.multipleChoice).length; if (multipleChoiceLength) { Object.keys(vm.multipleChoice).forEach((key) => { diff --git a/client/src/modules/fill_form/modals/fill_form.modals.html b/client/src/modules/fill_form/modals/fill_form.modals.html index 6128c04f65..df504ccbe8 100644 --- a/client/src/modules/fill_form/modals/fill_form.modals.html +++ b/client/src/modules/fill_form/modals/fill_form.modals.html @@ -157,7 +157,6 @@
- {{ formItem.hint }} name="{{ formItem.name }}" required="formItem.valueRequired" list-label="{{ formItem.label }}" + list-hint="{{ formItem.hint }}" group-label="formItem.choice_list_id" on-select-callback="FillFormModalCtrl.onSelectList(list, formItem.name)"> @@ -176,6 +176,7 @@
list="FillFormModalCtrl.form[formItem.name]" required="formItem.valueRequired" list-label="{{ formItem.label }}" + list-hint="{{ formItem.hint }}" parent-id="FillFormModalCtrl.form[formItem.filterLabel]" group-label="formItem.choice_list_id" on-select-callback="FillFormModalCtrl.onSelectList(list, formItem.name)"> @@ -186,7 +187,6 @@
- {{ formItem.hint }} name="{{ formItem.name }}" required="formItem.valueRequired" list-label="{{ formItem.label }}" + list-hint="{{ formItem.hint }}" group-label="formItem.choice_list_id" on-change="FillFormModalCtrl.onSelectMultiple(lists, formItem.name)"> diff --git a/client/src/modules/templates/bhChoiceListMultipleSelect.tmpl.html b/client/src/modules/templates/bhChoiceListMultipleSelect.tmpl.html index d1a19d27d3..e9709cc68d 100644 --- a/client/src/modules/templates/bhChoiceListMultipleSelect.tmpl.html +++ b/client/src/modules/templates/bhChoiceListMultipleSelect.tmpl.html @@ -15,7 +15,7 @@ close-on-select="false" ng-required="$ctrl.required"> - + {{ $item.label }} diff --git a/client/src/modules/templates/bhChoiceListSelect.tmpl.html b/client/src/modules/templates/bhChoiceListSelect.tmpl.html index 99d3e8dc39..6b8ea3a99a 100644 --- a/client/src/modules/templates/bhChoiceListSelect.tmpl.html +++ b/client/src/modules/templates/bhChoiceListSelect.tmpl.html @@ -14,7 +14,7 @@ ng-model= "$ctrl.list" ng-required="$ctrl.required" on-select="$ctrl.onSelect($item, $model)"> - + {{ $select.selected.label }} { if (key === element.surveyName) { - // This is a hack to avoid apostrophes in the search parameter - findParameters[key] = findParameters[key].replace(`'`, `''`); + // if (findParameters[key]) { + // // This is a hack to avoid apostrophes in the search parameter + // findParameters[key] = findParameters[key].replace(`'`, `''`); + // } if (element.type === '1') { filterCondition += ` ${element.surveyName} = '${findParameters[key]}' ${andCondition}`; diff --git a/server/controllers/admin/metadataReport/index.js b/server/controllers/admin/metadataReport/index.js index db3c449b7b..851b3cd880 100644 --- a/server/controllers/admin/metadataReport/index.js +++ b/server/controllers/admin/metadataReport/index.js @@ -162,6 +162,7 @@ function reportMetadata(req, res, next) { let report; const options = { + orientation : 'landscape', footerRight : '[page] / [toPage]', lang : req.query.lang, renderer : req.query.renderer, From 17169e883c89ac5565657c6321525a484083cc7f Mon Sep 17 00:00:00 2001 From: Chris Lomame Date: Mon, 16 Sep 2019 16:12:30 +0100 Subject: [PATCH 17/30] Improve and sanitaze code --- .../display_metadata/display_metadata.html | 14 +++---- .../display_metadata/display_metadata.js | 41 +++++++++++++------ .../display_metadata.service.js | 17 ++++---- .../display_metadata/modals/search.modal.html | 2 +- .../display_metadata/modals/search.modal.js | 2 + 5 files changed, 47 insertions(+), 29 deletions(-) diff --git a/client/src/modules/display_metadata/display_metadata.html b/client/src/modules/display_metadata/display_metadata.html index a92d2cecd4..8e29385af0 100644 --- a/client/src/modules/display_metadata/display_metadata.html +++ b/client/src/modules/display_metadata/display_metadata.html @@ -20,7 +20,6 @@ - .$dirty - Sanitaze and Clear Code --- .../components/bhChoiceListMultipleSelect.js | 2 +- .../src/js/components/bhChoiceListSelect.js | 2 +- .../account_reference.modal.js | 4 +-- .../modals/account_reference_type.modal.js | 4 +-- .../modules/accounts/edit/accounts.edit.js | 2 +- .../modals/break_even_reference.modal.js | 4 +-- .../modals/choices_list_management.modals.js | 4 +-- .../templates/action.cell.tmpl.html | 2 +- .../templates/gridLabels.tmpl.html | 2 +- .../templates/gridName.tmpl.html | 2 +- .../data_collector_management.modals.html | 26 ++++++++----------- .../data_collector_management.modals.js | 6 ++--- .../templates/action.cell.html | 2 +- .../templates/action.cell.html | 2 +- .../fill_form/modals/fill_form.modals.js | 6 ++--- .../modules/services/modals/service.modal.js | 4 +-- .../survey_form/modals/survey_form.modals.js | 6 ++--- .../survey_form/templates/action.cell.html | 2 +- .../modules/users/UserEditPasswordModal.js | 2 +- 19 files changed, 40 insertions(+), 44 deletions(-) diff --git a/client/src/js/components/bhChoiceListMultipleSelect.js b/client/src/js/components/bhChoiceListMultipleSelect.js index b01fd7475c..643dd7b6e2 100644 --- a/client/src/js/components/bhChoiceListMultipleSelect.js +++ b/client/src/js/components/bhChoiceListMultipleSelect.js @@ -11,7 +11,7 @@ angular.module('bhima.components') listHint : '@?', isTitle : '
  • diff --git a/client/src/modules/choices_list_management/templates/gridLabels.tmpl.html b/client/src/modules/choices_list_management/templates/gridLabels.tmpl.html index e97f4e2e16..19466a734c 100644 --- a/client/src/modules/choices_list_management/templates/gridLabels.tmpl.html +++ b/client/src/modules/choices_list_management/templates/gridLabels.tmpl.html @@ -2,7 +2,7 @@ {{ row.entity.label}} - + {{ row.entity.label}} {{ row.entity.label}} - + {{ row.entity.name}}
    \ No newline at end of file diff --git a/client/src/modules/data_collector_management/modals/data_collector_management.modals.html b/client/src/modules/data_collector_management/modals/data_collector_management.modals.html index b022321086..de22e6125b 100644 --- a/client/src/modules/data_collector_management/modals/data_collector_management.modals.html +++ b/client/src/modules/data_collector_management/modals/data_collector_management.modals.html @@ -25,27 +25,23 @@
    -
    - -
    -
    -
    + +
    +
    -
    - -
    -
    -
    + +
    +
    diff --git a/client/src/modules/data_collector_management/modals/data_collector_management.modals.js b/client/src/modules/data_collector_management/modals/data_collector_management.modals.js index dc8ca34467..f0f4d85d27 100644 --- a/client/src/modules/data_collector_management/modals/data_collector_management.modals.js +++ b/client/src/modules/data_collector_management/modals/data_collector_management.modals.js @@ -11,7 +11,7 @@ DataCollectorManagementModalController.$inject = [ function DataCollectorManagementModalController($state, DataCollectorManagement, Notify, AppCache, Color) { const vm = this; - const cache = AppCache('AccountReferenceModal'); + const cache = AppCache('DataCollectorManagementModal'); vm.dataCollector = {}; vm.stateParams = {}; @@ -49,7 +49,7 @@ function DataCollectorManagementModalController($state, DataCollectorManagement, function submit(dataCollectorManagementForm) { vm.hasNoChange = dataCollectorManagementForm.$submitted && dataCollectorManagementForm.$pristine && !vm.isCreating; if (dataCollectorManagementForm.$invalid) { return null; } - if (!dataCollectorManagementForm.$dirty) { return null; } + if (dataCollectorManagementForm.$pristine) { return null; } const promise = (vm.isCreating) ? DataCollectorManagement.create(vm.dataCollector) @@ -69,6 +69,6 @@ function DataCollectorManagementModalController($state, DataCollectorManagement, } function closeModal() { - $state.transitionTo('data_collector_management'); + $state.go('data_collector_management'); } } diff --git a/client/src/modules/data_collector_management/templates/action.cell.html b/client/src/modules/data_collector_management/templates/action.cell.html index 0ba1f5fe49..9580b0e10d 100644 --- a/client/src/modules/data_collector_management/templates/action.cell.html +++ b/client/src/modules/data_collector_management/templates/action.cell.html @@ -6,7 +6,7 @@