From 04e10c8bb64daaf482066454e91eac9a3dcb268e Mon Sep 17 00:00:00 2001 From: Sylvain Date: Thu, 24 Nov 2016 13:58:41 +0100 Subject: [PATCH] check cash coupons does not exceed cart amount for trainings & machines --- app/assets/javascripts/controllers/machines.coffee.erb | 4 ++++ app/assets/javascripts/controllers/trainings.coffee.erb | 7 +++++++ app/assets/javascripts/directives/coupon.coffee.erb | 7 +++---- app/assets/templates/machines/reserve.html.erb | 2 +- app/assets/templates/trainings/reserve.html.erb | 2 +- app/controllers/api/coupons_controller.rb | 2 +- app/models/coupon.rb | 7 ++++++- app/models/price.rb | 3 ++- app/views/api/prices/compute.json.jbuilder | 1 + config/locales/app.shared.en.yml | 1 + config/locales/app.shared.fr.yml | 1 + 11 files changed, 28 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/controllers/machines.coffee.erb b/app/assets/javascripts/controllers/machines.coffee.erb index 5d4f9b9b4..83042d7ce 100644 --- a/app/assets/javascripts/controllers/machines.coffee.erb +++ b/app/assets/javascripts/controllers/machines.coffee.erb @@ -315,6 +315,9 @@ Application.Controllers.controller "ReserveMachineController", ["$scope", "$stat ## total amount of the bill to pay $scope.amountTotal = 0 + ## total amount of the elements in the cart, without considering any coupon + $scope.totalNoCoupon = 0 + ## Discount coupon to apply to the basket, if any $scope.coupon = applied: null @@ -661,6 +664,7 @@ Application.Controllers.controller "ReserveMachineController", ["$scope", "$stat r = mkReservation($scope.ctrl.member, $scope.eventsReserved, $scope.selectedPlan) Price.compute mkRequestParams(r, $scope.coupon.applied), (res) -> $scope.amountTotal = res.price + $scope.totalNoCoupon = res.price_without_coupon setSlotsDetails(res.details) else # otherwise we alert, this error musn't occur when the current user is not admin diff --git a/app/assets/javascripts/controllers/trainings.coffee.erb b/app/assets/javascripts/controllers/trainings.coffee.erb index f9785ed6a..ccb9a65f6 100644 --- a/app/assets/javascripts/controllers/trainings.coffee.erb +++ b/app/assets/javascripts/controllers/trainings.coffee.erb @@ -137,6 +137,12 @@ Application.Controllers.controller "ReserveTrainingController", ["$scope", "$sta $scope.coupon = applied: null + ## Total price of the cart, that the user will pay + $scope.amountTotal = 0 + + ## Total amount of the elements in the cart, without considering any coupon + $scope.totalNoCoupon = 0 + ## fullCalendar (v2) configuration $scope.calendarConfig = CalendarConfig minTime: moment.duration(moment(settingsPromise.booking_window_start).format('HH:mm:ss')) @@ -353,6 +359,7 @@ Application.Controllers.controller "ReserveTrainingController", ["$scope", "$sta r = mkReservation($scope.ctrl.member, $scope.selectedTraining, $scope.selectedPlan) Price.compute mkRequestParams(r, $scope.coupon.applied), (res) -> $scope.amountTotal = res.price + $scope.totalNoCoupon = res.price_without_coupon else $scope.amountTotal = null diff --git a/app/assets/javascripts/directives/coupon.coffee.erb b/app/assets/javascripts/directives/coupon.coffee.erb index 531116100..357c72d74 100644 --- a/app/assets/javascripts/directives/coupon.coffee.erb +++ b/app/assets/javascripts/directives/coupon.coffee.erb @@ -4,6 +4,7 @@ Application.Directives.directive 'coupon', [ 'Coupon', 'growl', '_t', (Coupon, g scope: show: '=' coupon: '=' + total: '@' userId: '@' templateUrl: '<%= asset_path "shared/_coupon.html" %>' link: ($scope, element, attributes) -> @@ -15,11 +16,9 @@ Application.Directives.directive 'coupon', [ 'Coupon', 'growl', '_t', (Coupon, g # Available status are: 'pending', 'valid', 'invalid' $scope.status = 'pending' - # Binding for the code inputed + # Binding for the code inputed (see the attached template) $scope.couponCode = null - - ## # Callback to validate the code ## @@ -28,7 +27,7 @@ Application.Directives.directive 'coupon', [ 'Coupon', 'growl', '_t', (Coupon, g $scope.status = 'pending' $scope.coupon = null else - Coupon.validate {code: $scope.couponCode, user_id: $scope.userId}, (res) -> + Coupon.validate {code: $scope.couponCode, user_id: $scope.userId, amount: $scope.total}, (res) -> $scope.status = 'valid' $scope.coupon = res growl.success(_t('the_coupon_has_been_applied_you_get_PERCENT_discount', {PERCENT: res.percent_off})) diff --git a/app/assets/templates/machines/reserve.html.erb b/app/assets/templates/machines/reserve.html.erb index f80ffb700..79464edef 100644 --- a/app/assets/templates/machines/reserve.html.erb +++ b/app/assets/templates/machines/reserve.html.erb @@ -78,7 +78,7 @@
{{ 'remove_this_slot' }}
- +
diff --git a/app/assets/templates/trainings/reserve.html.erb b/app/assets/templates/trainings/reserve.html.erb index 5f03078f4..3cbad9955 100644 --- a/app/assets/templates/trainings/reserve.html.erb +++ b/app/assets/templates/trainings/reserve.html.erb @@ -82,7 +82,7 @@ {{ 'remove_this_slot' }}
- +
diff --git a/app/controllers/api/coupons_controller.rb b/app/controllers/api/coupons_controller.rb index 0c25c6d83..3149e1c10 100644 --- a/app/controllers/api/coupons_controller.rb +++ b/app/controllers/api/coupons_controller.rb @@ -30,7 +30,7 @@ class API::CouponsController < API::ApiController _user_id = params[:user_id] end - status = @coupon.status(_user_id) + status = @coupon.status(_user_id, params[:amount]) if status != 'active' render json: {status: status}, status: :unprocessable_entity else diff --git a/app/models/coupon.rb b/app/models/coupon.rb index d34f69b1f..b4fe0a7f8 100644 --- a/app/models/coupon.rb +++ b/app/models/coupon.rb @@ -26,12 +26,15 @@ class Coupon < ActiveRecord::Base # - may has expired because the validity date has been reached, # - may have been used the maximum number of times it was allowed # - may have already been used by the provided user, if the coupon is configured to allow only one use per user, + # - may exceed the current cart's total amount, if the coupon is configured to discount an amount (and not a percentage) # - may be available for use # @param [user_id] {Number} if provided and if the current coupon's validity_per_user == 'once', check that the coupon # was already used by the provided user + # @param [amount] {Number} if provided and if the current coupon's type == 'amont_off' check that the coupon + # does not exceed the cart total price # @return {String} status identifier ## - def status(user_id = nil) + def status(user_id = nil, amount = nil) if not active? 'disabled' elsif (!valid_until.nil?) and valid_until.at_end_of_day < DateTime.now @@ -40,6 +43,8 @@ class Coupon < ActiveRecord::Base 'sold_out' elsif (!user_id.nil?) and validity_per_user == 'once' and users_ids.include?(user_id.to_i) 'already_used' + elsif (!amount.nil?) and type == 'amount_off' and amount_off > amount.to_f + 'amount_exceeded' else 'active' end diff --git a/app/models/price.rb b/app/models/price.rb index 9544c755b..ddb95a6d3 100644 --- a/app/models/price.rb +++ b/app/models/price.rb @@ -111,10 +111,11 @@ class Price < ActiveRecord::Base end # === apply Coupon if any === + _amount_no_coupon = _amount _amount = CouponApplyService.new.(_amount, coupon_code) # return result - {elements: _elements, total: _amount} + {elements: _elements, total: _amount, before_coupon: _amount_no_coupon} end private diff --git a/app/views/api/prices/compute.json.jbuilder b/app/views/api/prices/compute.json.jbuilder index 752ac43ac..0a268bfd3 100644 --- a/app/views/api/prices/compute.json.jbuilder +++ b/app/views/api/prices/compute.json.jbuilder @@ -1,4 +1,5 @@ json.price @amount[:total] / 100.00 +json.price_without_coupon @amount[:before_coupon] / 100.00 json.details do json.slots @amount[:elements][:slots] do |slot| json.start_at slot[:start_at] diff --git a/config/locales/app.shared.en.yml b/config/locales/app.shared.en.yml index 50b7d7670..053fd6a65 100644 --- a/config/locales/app.shared.en.yml +++ b/config/locales/app.shared.en.yml @@ -372,4 +372,5 @@ en: unable_to_apply_the_coupon_because_expired: "Unable to apply the coupon: this code has expired." unable_to_apply_the_coupon_because_sold_out: "Unable to apply the coupon: this code reached its quota." unable_to_apply_the_coupon_because_already_used: "Unable to apply the coupon: you have already used this code once before." + unable_to_apply_the_coupon_because_amount_exceeded: "Unable to apply the coupon: the discount exceed the total amount of this purchase." unable_to_apply_the_coupon_because_rejected: "This code does not exists." diff --git a/config/locales/app.shared.fr.yml b/config/locales/app.shared.fr.yml index 3472ab59c..068f2d539 100644 --- a/config/locales/app.shared.fr.yml +++ b/config/locales/app.shared.fr.yml @@ -372,4 +372,5 @@ fr: unable_to_apply_the_coupon_because_expired: "Impossible d'appliquer la réduction : ce code promo a expiré." unable_to_apply_the_coupon_because_sold_out: "Impossible d'appliquer la réduction : ce code promo a atteint son quota." unable_to_apply_the_coupon_because_already_used: "Impossible d'appliquer la réduction : vous avez déjà utilisé ce code promo par le passé." + unable_to_apply_the_coupon_because_amount_exceeded: "Impossible d'appliquer la réduction : la réduction dépasse le total de cet achat." unable_to_apply_the_coupon_because_rejected: "Ce code promo n'existe pas." \ No newline at end of file