diff --git a/.fabmanager-version b/.fabmanager-version index 62e64205b..48a6b508d 100644 --- a/.fabmanager-version +++ b/.fabmanager-version @@ -1 +1 @@ -2.4.6 \ No newline at end of file +2.4.7 \ No newline at end of file diff --git a/.gitignore b/.gitignore index ee0e0fc32..9a35a3571 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ # Ignore all logfiles and tempfiles. /log/*.log /tmp +/coverage /public/uploads /public/assets @@ -39,5 +40,8 @@ .vagrant .docker +# Do not versionate coveralls token +.coveralls.yml + # Plugins are versioned is their own repository /plugins/* diff --git a/CHANGELOG.md b/CHANGELOG.md index ed68f9cc0..e2922cf17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,18 @@ # Changelog Fab Manager -## v2.4.6 2016 Novembre 30 +## v2.4.7 2016 December 14 + +- Improved automated testing +- Added an information notice about the processing time of deleting an administrator +- Ability to change the expiration date of a coupon after its creation +- Ability to generate a refund invoice when crediting user's wallet +- Fix a bug: unable to run rake db:migrate on first install +- Fix a bug: unable to create or edit a coupon of type 'percentage' + +## v2.4.6 2016 November 30 - Change display of message about coupon application status -- Fix a bug: compute price API return error 500 if reservable_id is not provided +- Fix a bug: compute price API return error 500 if reservable_id is not provided ## v2.4.5 2016 November 29 @@ -25,8 +34,8 @@ ## v2.4.3 2016 November 21 - Export user's invoicing status in members' excel export -- Fix a bug: Next events descriptions, shown on the home page, display raw html -- Fix a bug: number of reserved seats for an event is always of 1 in the excel export of reservations +- Fix a bug: Next events descriptions, shown on the home page, display raw html +- Fix a bug: number of reserved seats for an event is always of 1 in the excel export of reservations - Fix a bug: conflict between similar translations around "reservations" - Fix a bug: later occurrences of recurrent events does not have the initially configured theme and age range - Fix a bug: some graphs do not display: events, users, trainings and machine hours @@ -44,18 +53,18 @@ ## v2.4.1 2016 October 11 -- Fix a bug: unable to share a project/event without image on social networks +- Fix a bug: unable to share a project/event without image on social networks - Fix a bug: after creating an element in the admin calendar, browsing through the calendar and coming back cause the element to appear duplicated - Fix a bug: after deleting an element in the admin calendar, the confirmation message is wrong and an error is logged in the console - Fix a bug: erroneous syntax in docker env example file ## v2.4.0 2016 October 4 - + - RSS feeds to follow new projects and events published - Use slugs in projects URL opened from notifications - Ask for confirmation on machine deletion from the public view - Ability to delete a training from the public view for an admin -- Project images will show in full-size on a click +- Project images will show in full-size on a click - Add a checkbox "I accept to receive informations from the FabLab" on Sign-up dialog and user's profile - Share project with Facebook/Twitter - Display fab-manager's version in "Powered by" label, when logged as admin @@ -70,14 +79,14 @@ - Trainings are associated with a picture and an HTML textual description - Public gallery of trainings with ability to view details or to book a training on its own calendar - Ability to switch back to all trainings booking view -- Rename "Courses and Workshops" to "Events" +- Rename "Courses and Workshops" to "Events" - Admin: Events can be associated with a theme and an age range - Admin: Event categories, themes and age ranges can be customized - Filter events by category, theme and age range in public view - Ability to customise price's categories for the events - Events can be associated with many custom price's categories, instead of only one "reduced price" - Statistics views can trigger and display custom aggregations from ElasticSearch -- Machine hours/Trainings statistics: display number of tickets/hours available for booking +- Machine hours/Trainings statistics: display number of tickets/hours available for booking - Statistics will include informations abouts events category, theme and age range - Ability to export the current statistics table to an Excel file - Ability to export every statistics on a given dates range to an Excel file @@ -93,16 +102,16 @@ - More file types allowed as project CAD attachements - Project CAD attachements are now checked by MIME type in addition of extension check - Project CAD attachement allowed are now configured in environment variables -- Project CAD attachement extensions allowed are shown next to input field +- Project CAD attachement extensions allowed are shown next to input field - Display strategy's name in SSO providers list - SSO: documentation improved with an usage example - SSO: mapped fields display their data type. Integers, booleans and dates allow some transformations. - Fix a bug: project drafts are shown on public profiles - Fix a bug: event category disappear when editing the event -- Fix a bug: machine name is not shown in plan edition +- Fix a bug: machine name is not shown in plan edition - Fix a bug: machine slots with tags are not displayed correctly on reservation calendar - Fix a bug: avatar, address and organization details mapping from SSO were broken -- Fix a bug: in SSO configuration some valid endpoints were recognized as erroneous +- Fix a bug: in SSO configuration some valid endpoints were recognized as erroneous - Fix a bug: clicking on the text in stripe's payment modal, does not validate the checkbox - Fix a bug: move event reservation is not limited by admin settings (prior-delay & disable) - Fix a bug: UI issues on small devices (dashboard + admin views) @@ -134,7 +143,7 @@ - [TODO DEPLOY] `bundle install` and `rake db:migrate` ## v2.2.2 2016 June 23 -- Fix some bugs: users with uncompleted account (sso imported) won't appear in statistics, in listings and in searches. Moreover, they won't block statistics generation +- Fix some bugs: users with uncompleted account (sso imported) won't appear in statistics, in listings and in searches. Moreover, they won't block statistics generation - Fix a bug: unable to display next results in statistics tables - Admin: Category is mandatory when creating an event @@ -150,7 +159,7 @@ - User public profile: UI re-design with possible admin's customization - Admin: Invoices list and users list are now loaded per 10 items to improve pages load time - Admin: select member (eg. to buy a subscription for a member) is now loading the user's list dynamically when you type -- Project collaborators selection is now using a list dynamically loaded as you type +- Project collaborators selection is now using a list dynamically loaded as you type - Admin: select a training before monitoring its reservations -> improves page load time - API: GET /api/trainings do not load nor send the associated availabilities until they are requested - List of members is now loaded 10 members by 10, to improve page load time diff --git a/Gemfile b/Gemfile index b0250b9a7..a2394f4fc 100644 --- a/Gemfile +++ b/Gemfile @@ -52,6 +52,8 @@ group :development do gem 'capistrano-maintenance', '0.0.5', require: false gem 'active_record_query_trace' + + gem 'coveralls', require: false end group :test do @@ -62,6 +64,7 @@ group :test do gem 'webmock' gem 'vcr' gem 'byebug' + gem 'pdf-reader' end group :production do diff --git a/Gemfile.lock b/Gemfile.lock index 6e602afad..0eab18efc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,7 @@ GEM remote: https://rubygems.org/ specs: + Ascii85 (1.0.2) aasm (4.1.0) actionmailer (4.2.5) actionpack (= 4.2.5) @@ -41,6 +42,7 @@ GEM thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) addressable (2.3.8) + afm (0.2.2) ansi (1.5.0) api-pagination (4.3.0) apipie-rails (0.3.6) @@ -118,6 +120,12 @@ GEM sass-rails (<= 5.0.1) sprockets (< 2.13) connection_pool (2.2.0) + coveralls (0.8.16) + json (>= 1.8, < 3) + simplecov (~> 0.12.0) + term-ansicolor (~> 1.3.0) + thor (~> 0.19.1) + tins (>= 1.6.0, < 2) crack (0.4.3) safe_yaml (~> 1.0.0) database_cleaner (1.4.1) @@ -133,6 +141,7 @@ GEM warden (~> 1.2.3) devise-async (0.9.0) devise (~> 3.2) + docile (1.1.5) domain_name (0.5.25) unf (>= 0.0.5, < 1.0.0) elasticsearch (1.0.12) @@ -177,6 +186,7 @@ GEM has_secure_token (1.0.0) activerecord (>= 3.0) hashdiff (0.3.0) + hashery (2.1.2) hashie (3.4.2) highline (1.7.1) hike (1.2.3) @@ -265,6 +275,12 @@ GEM httparty (~> 0.13) orm_adapter (0.5.0) pdf-core (0.5.1) + pdf-reader (1.4.0) + Ascii85 (~> 1.0.0) + afm (~> 0.2.1) + hashery (~> 2.0) + ruby-rc4 + ttfunk pg (0.18.1) pkg-config (1.1.7) prawn (2.0.1) @@ -335,6 +351,7 @@ GEM netrc (~> 0.7) rolify (4.0.0) ruby-progressbar (1.7.5) + ruby-rc4 (0.1.5) rubyzip (1.1.7) rufus-scheduler (3.0.9) tzinfo @@ -365,6 +382,11 @@ GEM sidekiq (>= 2.17.3) tilt (< 2.0.0) simple_oauth (0.3.1) + simplecov (0.12.0) + docile (~> 1.1.0) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) sinatra (1.4.6) rack (~> 1.4) rack-protection (~> 1.4) @@ -382,6 +404,8 @@ GEM stripe (1.30.2) json (~> 1.8.1) rest-client (~> 1.4) + term-ansicolor (1.3.2) + tins (~> 1.0) test_after_commit (1.0.0) activerecord (>= 3.2) therubyracer (0.12.0) @@ -392,6 +416,7 @@ GEM tilt (1.4.1) timers (4.0.1) hitimes + tins (1.13.0) ttfunk (1.4.0) twitter (5.14.0) addressable (~> 2.3) @@ -462,6 +487,7 @@ DEPENDENCIES chroma coffee-rails (~> 4.1.0) compass-rails (= 2.0.4) + coveralls database_cleaner devise devise-async @@ -488,6 +514,7 @@ DEPENDENCIES omniauth omniauth-oauth2 openlab_ruby + pdf-reader pg prawn prawn-table @@ -522,4 +549,4 @@ DEPENDENCIES webmock BUNDLED WITH - 1.12.5 + 1.13.1 diff --git a/app/assets/javascripts/controllers/admin/coupons.coffee b/app/assets/javascripts/controllers/admin/coupons.coffee index 21e0a65ae..c62693e80 100644 --- a/app/assets/javascripts/controllers/admin/coupons.coffee +++ b/app/assets/javascripts/controllers/admin/coupons.coffee @@ -58,8 +58,8 @@ Application.Controllers.controller "NewCouponController", ["$scope", "$state", ' ## # Controller used in the coupon edition page ## -Application.Controllers.controller "EditCouponController", ["$scope", "$state", 'Coupon', 'couponPromise', '_t' -, ($scope, $state, Coupon, couponPromise, _t) -> +Application.Controllers.controller "EditCouponController", ["$scope", "$state", 'Coupon', 'couponPromise', '_t', 'growl' +, ($scope, $state, Coupon, couponPromise, _t, growl) -> ### PUBLIC SCOPE ### @@ -73,6 +73,9 @@ Application.Controllers.controller "EditCouponController", ["$scope", "$state", ## Options for the validity per user $scope.validities = userValidities + ## Mapping for validation errors + $scope.errors = {} + ## Default parameters for AngularUI-Bootstrap datepicker (used for coupon validity limit selection) $scope.datePicker = format: Fablab.uibDateFormat @@ -98,11 +101,12 @@ Application.Controllers.controller "EditCouponController", ["$scope", "$state", # Callback to save the coupon's changes to the API ## $scope.updateCoupon = -> + $scope.errors = {} Coupon.update {id: $scope.coupon.id}, coupon: $scope.coupon, (coupon) -> $state.go('app.admin.pricing') , (err)-> growl.error(_t('unable_to_update_the_coupon_an_error_occurred')) - console.error(err) + $scope.errors = err.data diff --git a/app/assets/javascripts/controllers/admin/members.coffee.erb b/app/assets/javascripts/controllers/admin/members.coffee.erb index 9c37206d8..14b2c42a9 100644 --- a/app/assets/javascripts/controllers/admin/members.coffee.erb +++ b/app/assets/javascripts/controllers/admin/members.coffee.erb @@ -105,8 +105,8 @@ class MembersController ## # Controller used in the members/groups management page ## -Application.Controllers.controller "AdminMembersController", ["$scope", 'membersPromise', 'adminsPromise', 'growl', 'Admin', 'dialogs', '_t', 'Member', 'Export' -, ($scope, membersPromise, adminsPromise, growl, Admin, dialogs, _t, Member, Export) -> +Application.Controllers.controller "AdminMembersController", ["$scope","$sce", 'membersPromise', 'adminsPromise', 'growl', 'Admin', 'dialogs', '_t', 'Member', 'Export' +, ($scope, $sce, membersPromise, adminsPromise, growl, Admin, dialogs, _t, Member, Export) -> @@ -177,7 +177,7 @@ Application.Controllers.controller "AdminMembersController", ["$scope", 'members resolve: object: -> title: _t('confirmation_required') - msg: _t('do_you_really_want_to_delete_this_administrator_this_cannot_be_undone') + msg: $sce.trustAsHtml(_t('do_you_really_want_to_delete_this_administrator_this_cannot_be_undone') + '

' +_t('this_may_take_a_while_please_wait')) , -> # cancel confirmed Admin.delete id: admin.id, -> admins.splice(findAdminIdxById(admins, admin.id), 1) @@ -423,11 +423,40 @@ Application.Controllers.controller "EditMemberController", ["$scope", "$state", templateUrl: '<%= asset_path "wallet/credit_modal.html" %>' controller: ['$scope', '$uibModalInstance', 'Wallet', ($scope, $uibModalInstance, Wallet) -> + # default: do not generate a refund invoice + $scope.generate_avoir = false + + # date of the generated refund invoice + $scope.avoir_date = null + + # optional description shown on the refund invoice + $scope.description = '' + + # default configuration for the avoir date selector widget + $scope.datePicker = + format: Fablab.uibDateFormat + opened: false + options: + startingDay: Fablab.weekStartingDay + + ## + # Callback to open/close the date picker + ## + $scope.toggleDatePicker = ($event) -> + $event.preventDefault() + $event.stopPropagation() + $scope.datePicker.opened = !$scope.datePicker.opened + ## # Modal dialog validation callback ## $scope.ok = -> - Wallet.credit { id: wallet.id }, { amount: $scope.amount }, (_wallet)-> + Wallet.credit { id: wallet.id }, + amount: $scope.amount + avoir: $scope.generate_avoir + avoir_date: $scope.avoir_date + avoir_description: $scope.description + , (_wallet)-> growl.success(_t('wallet_credit_successfully')) $uibModalInstance.close(_wallet) diff --git a/app/assets/templates/admin/coupons/_form.html.erb b/app/assets/templates/admin/coupons/_form.html.erb index 4cc92c9f6..9a54b7995 100644 --- a/app/assets/templates/admin/coupons/_form.html.erb +++ b/app/assets/templates/admin/coupons/_form.html.erb @@ -81,7 +81,7 @@ {{ 'validity_per_user_is_required' }} -
+
+ {{ errors['valid_until'].join(' ; ') }} - - {{ 'leave_empty_for_no_limit' | translate }} - + + {{ 'leave_empty_for_no_limit' | translate }} +
@@ -114,7 +114,7 @@ min="0"/> {{ 'max_usages_must_be_equal_or_greater_than_0' }} - + {{ 'leave_empty_for_no_limit' | translate }}
diff --git a/app/assets/templates/shared/confirm_modal.html.erb b/app/assets/templates/shared/confirm_modal.html.erb index 250bb78c1..b32db0943 100644 --- a/app/assets/templates/shared/confirm_modal.html.erb +++ b/app/assets/templates/shared/confirm_modal.html.erb @@ -3,7 +3,7 @@

{{object.title}}