diff --git a/.fabmanager-version b/.fabmanager-version index 752a79ef3..158349812 100644 --- a/.fabmanager-version +++ b/.fabmanager-version @@ -1 +1 @@ -2.4.8 \ No newline at end of file +2.4.9 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 81f6f2238..f8cbe8c54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog Fab Manager +## v2.4.9 2017 January 4 + +- Mask new notifications alerts when more than 3 +- Added an asterisk on group select in admin's member form +- Statistics custom aggregations can handle custom filtering +- Statistics about hours available for machine reservations and tickets available for training reservations, now handle custom filtering on date and type +- Fix a bug: display more than 15 unread notifications (number on the bell icon & full list) +- Fix a bug: in invoice configuration panel, VAT amount and total excl. taxes are inverted +- Fix a bug: unable to compute user's age when they were born on february 29th and current year is not a leap year +- Fix a bug: wrong statistics about hours available for machines reservation. Fix requires user action (1) +- Fix a bug: when regenerating statistics, previous values are not fully removed (only 10 firsts), resulting in wrong statistics generation (2) +- Fix a bug: when deleting an availability just after its creation, the indexer workers crash and retries for a month +- [TODO DEPLOY] remove possible value `application/` in `ALLOWED_MIME_TYPES` list, in environment variable +- [TODO DEPLOY] `rails runner StatisticCustomAggregation.destroy_all`, then `rake db:seed`, then `rake fablab:es_build_availabilities_index` (1) +- [TODO DEPLOY] `fablab:generate_stats[1095]` if you already has regenerated the statistics in the past, then they are very likely corrupted. Run this task to fix (2) + ## v2.4.8 2016 December 15 - Added asterisks on mandatory fields in member's form diff --git a/app/assets/javascripts/controllers/admin/graphs.coffee b/app/assets/javascripts/controllers/admin/graphs.coffee index 8c23e69c7..6100e20e8 100644 --- a/app/assets/javascripts/controllers/admin/graphs.coffee +++ b/app/assets/javascripts/controllers/admin/graphs.coffee @@ -363,6 +363,7 @@ Application.Controllers.controller "GraphsController", ["$scope", "$state", "$ro "type": esType "searchType": "count" "stat-type": statType + "custom-query": '' "start-date": moment($scope.datePickerStart.selected).format() "end-date": moment($scope.datePickerEnd.selected).format() "body": buildElasticAggregationsQuery(statType, $scope.display.interval, moment($scope.datePickerStart.selected), moment($scope.datePickerEnd.selected)) diff --git a/app/assets/javascripts/controllers/admin/statistics.coffee.erb b/app/assets/javascripts/controllers/admin/statistics.coffee.erb index 53d289217..b99297b21 100644 --- a/app/assets/javascripts/controllers/admin/statistics.coffee.erb +++ b/app/assets/javascripts/controllers/admin/statistics.coffee.erb @@ -380,6 +380,7 @@ Application.Controllers.controller "StatisticsController", ["$scope", "$state", "size": RESULTS_PER_PAGE "scroll": ES_SCROLL_TIME+'m' "stat-type": type + "custom-query": if custom then JSON.stringify(Object.assign({exclude: custom.exclude}, buildElasticCustomCriterion(custom))) else '' "start-date": moment($scope.datePickerStart.selected).format() "end-date": moment($scope.datePickerEnd.selected).format() "body": buildElasticDataQuery(type, custom, $scope.agePicker.start, $scope.agePicker.end, moment($scope.datePickerStart.selected), moment($scope.datePickerEnd.selected), $scope.sorting) @@ -427,15 +428,7 @@ Application.Controllers.controller "StatisticsController", ["$scope", "$state", "lte": ageMax # optional criterion if custom - criterion = { - "match" : {} - } - switch $scope.getCustomValueInputType($scope.customFilter.criterion) - when 'input_date' then criterion.match[custom.key] = moment(custom.value).format('YYYY-MM-DD') - when 'input_select' then criterion.match[custom.key] = custom.value.key - when 'input_list' then criterion.match[custom.key+".name"] = custom.value - else criterion.match[custom.key] = custom.value - + criterion = buildElasticCustomCriterion(custom) if (custom.exclude) q = "query": { "filtered": { @@ -470,6 +463,27 @@ Application.Controllers.controller "StatisticsController", ["$scope", "$state", + ## + # Build the elasticSearch query DSL to match the selected cutom filter + # @param custom {Object} if custom is empty or undefined, an empty string will be returned + # @returns {{match:{*}}|string} + ## + buildElasticCustomCriterion = (custom) -> + if (custom) + criterion = { + "match" : {} + } + switch $scope.getCustomValueInputType($scope.customFilter.criterion) + when 'input_date' then criterion.match[custom.key] = moment(custom.value).format('YYYY-MM-DD') + when 'input_select' then criterion.match[custom.key] = custom.value.key + when 'input_list' then criterion.match[custom.key+".name"] = custom.value + else criterion.match[custom.key] = custom.value + criterion + else + '' + + + ## # Parse the provided criteria array and return the corresponding elasticSearch syntax # @param criteria {Array} array of {key_to_sort:order} diff --git a/app/assets/javascripts/controllers/application.coffee.erb b/app/assets/javascripts/controllers/application.coffee.erb index 51c42a6a3..645b6e6cb 100644 --- a/app/assets/javascripts/controllers/application.coffee.erb +++ b/app/assets/javascripts/controllers/application.coffee.erb @@ -260,7 +260,9 @@ Application.Controllers.controller 'ApplicationController', ["$rootScope", "$sco getNotifications = -> $rootScope.toCheckNotifications = true unless $rootScope.checkNotificationsIsInit or !$rootScope.currentUser - $scope.notifications = Notification.query {is_read: false} + setTimeout -> + $scope.notifications = Notification.query {is_read: false} + , 2000 $scope.$watch 'notifications', (newValue, oldValue) -> diff = [] angular.forEach newValue, (value) -> @@ -273,6 +275,9 @@ Application.Controllers.controller 'ApplicationController', ["$rootScope", "$sco unless find diff.push(value) + remain = 3 + if diff.length >= remain + diff.splice(remain, (diff.length - remain), {message: {description: _t('and_NUMBER_other_notifications', {NUMBER: diff.length - remain})}}) angular.forEach diff, (notification, key) -> growl.info(notification.message.description) diff --git a/app/assets/templates/admin/invoices/index.html.erb b/app/assets/templates/admin/invoices/index.html.erb index c4e47ff7d..a421d2286 100644 --- a/app/assets/templates/admin/invoices/index.html.erb +++ b/app/assets/templates/admin/invoices/index.html.erb @@ -157,11 +157,11 @@