'use strict' Application.Controllers.controller "PlansIndexController", ["$scope", "$rootScope", "$state", '$uibModal', 'Auth', 'dialogs', 'growl', 'plansPromise', 'groupsPromise', 'Subscription', 'Member', 'subscriptionExplicationsPromise', '_t', 'Wallet', 'helpers' , ($scope, $rootScope, $state, $uibModal, Auth, dialogs, growl, plansPromise, groupsPromise, Subscription, Member, subscriptionExplicationsPromise, _t, Wallet, helpers) -> ### PUBLIC SCOPE ### ## list of groups $scope.groups = groupsPromise ## default : do not show the group changing form ## group ID of the current/selected user $scope.group = change: false id: null ## list of plans, classified by group $scope.plansClassifiedByGroup = [] for group in groupsPromise groupObj = { id: group.id, name: group.name, plans: [] } for plan in plansPromise groupObj.plans.push(plan) if plan.group_id == group.id $scope.plansClassifiedByGroup.push(groupObj) ## user to deal with $scope.ctrl = member: null member_id: null ## already subscribed plan of the current user $scope.paid = plan: null ## plan to subscribe (shopping cart) $scope.selectedPlan = null ## Discount coupon to apply to the basket, if any $scope.coupon = applied: null ## Storage for the total price (plan price + coupon, if any) $scope.cart = total: null ## text that appears in the bottom-right box of the page (subscriptions rules details) $scope.subscriptionExplicationsAlert = subscriptionExplicationsPromise.setting.value ## # Callback to deal with the subscription of the user selected in the dropdown list instead of the current user's # subscription. (admins only) ## $scope.updateMember = -> $scope.selectedPlan = null $scope.paid.plan = null $scope.group.change = false Member.get {id: $scope.ctrl.member.id}, (member) -> $scope.ctrl.member = member $scope.group.id = $scope.ctrl.member.group_id ## # Add the provided plan to the shopping basket # @param plan {Object} The plan to subscribe to ## $scope.selectPlan = (plan) -> if $scope.isAuthenticated() if $scope.selectedPlan != plan $scope.selectedPlan = plan updateCartPrice() else $scope.selectedPlan = null else $scope.login() ## # Callback to trigger the payment process of the subscription ## $scope.openSubscribePlanModal = -> Wallet.getWalletByUser {user_id: $scope.ctrl.member.id}, (wallet) -> amountToPay = helpers.getAmountToPay($scope.cart.total, wallet.amount) if $scope.currentUser.role isnt 'admin' and amountToPay > 0 payByStripe() else if $scope.currentUser.role is 'admin' or amountToPay is 0 payOnSite() ## # Return the group object, identified by the ID set in $scope.group.id ## $scope.getUserGroup = -> for group in $scope.groups if group.id == $scope.group.id return group ## # Change the group of the current/selected user to the one set in $scope.group.id ## $scope.selectGroup = -> Member.update {id: $scope.ctrl.member.id}, {user: {group_id: $scope.group.id}}, (user) -> $scope.ctrl.member = user $scope.group.change = false if $scope.currentUser.role isnt 'admin' $rootScope.currentUser = user Auth._currentUser.group_id = user.group_id growl.success(_t('your_group_was_successfully_changed')) else growl.success(_t('the_user_s_group_was_successfully_changed')) , (err) -> if $scope.currentUser.role isnt 'admin' growl.error(_t('an_error_prevented_your_group_from_being_changed')) else growl.error(_t('an_error_prevented_to_change_the_user_s_group')) console.error(err) ## # Return an enumerable meaninful string for the gender of the provider user # @param user {Object} Database user record # @return {string} 'male' or 'female' ## $scope.getGender = (user) -> if user and user.profile if user.profile.gender == "true" then 'male' else 'female' else 'other' ## # Test if the provided date is in the future # @param dateTime {Date} # @return {boolean} ## $scope.isInFuture = (dateTime)-> if moment().diff(moment(dateTime)) < 0 true else false ### PRIVATE SCOPE ### ## # Kind of constructor: these actions will be realized first when the controller is loaded ## initialize = -> if $scope.currentUser if $scope.currentUser.role isnt 'admin' $scope.ctrl.member = $scope.currentUser $scope.paid.plan = $scope.currentUser.subscribed_plan $scope.group.id = $scope.currentUser.group_id $scope.$on 'devise:new-session', (event, user)-> $scope.ctrl.member = user # watch when a coupon is applied to re-compute the total price $scope.$watch 'coupon.applied', (newValue, oldValue) -> unless newValue == null and oldValue == null updateCartPrice() ## # Compute the total amount for the current reservation according to the previously set parameters # and assign the result in $scope.reserve.amountTotal ## updateCartPrice = -> # first we check that a user was selected if Object.keys($scope.ctrl.member).length > 0 $scope.cart.total = $scope.selectedPlan.amount # apply the coupon if any if $scope.coupon.applied if $scope.coupon.applied.type == 'percent_off' discount = $scope.cart.total * $scope.coupon.applied.percent_off / 100 else if $scope.coupon.applied.type == 'amount_off' discount = $scope.coupon.applied.amount_off $scope.cart.total -= discount else $scope.reserve.amountTotal = null ## # Open a modal window which trigger the stripe payment process ## payByStripe = -> $uibModal.open templateUrl: '<%= asset_path "stripe/payment_modal.html" %>' size: 'md' resolve: selectedPlan: -> $scope.selectedPlan member: -> $scope.ctrl.member price: -> $scope.cart.total wallet: -> Wallet.getWalletByUser({user_id: $scope.ctrl.member.id}).$promise coupon: -> $scope.coupon.applied controller: ['$scope', '$uibModalInstance', '$state', 'selectedPlan', 'member', 'price', 'Subscription', 'CustomAsset', 'wallet', 'helpers', '$filter', 'coupon', ($scope, $uibModalInstance, $state, selectedPlan, member, price, Subscription, CustomAsset, wallet, helpers, $filter, coupon) -> # User's wallet amount $scope.walletAmount = wallet.amount # Final price to pay by the user $scope.amount = helpers.getAmountToPay(price, wallet.amount) # The plan that the user is about to subscribe $scope.selectedPlan = selectedPlan # Used in wallet info template to interpolate some translations $scope.numberFilter = $filter('number') # retrieve the CGV CustomAsset.get {name: 'cgv-file'}, (cgv) -> $scope.cgv = cgv.custom_asset ## # Callback for click on the 'proceed' button. # Handle the stripe's card tokenization process response and save the subscription to the API with the # card token just created. ## $scope.payment = (status, response) -> if response.error growl.error(response.error.message) else $scope.attempting = true Subscription.save coupon_code: (coupon.code if coupon) subscription: plan_id: selectedPlan.id user_id: member.id card_token: response.id , (data, status) -> # success $uibModalInstance.close(data) , (data, status) -> # failed $scope.alerts = [] $scope.alerts.push({msg: _t('an_error_occured_during_the_payment_process_please_try_again_later'), type: 'danger' }) $scope.attempting = false ] .result['finally'](null).then (subscription)-> $scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan) Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan) $scope.paid.plan = angular.copy($scope.selectedPlan) $scope.selectedPlan = null $scope.coupon.applied = null ## # Open a modal window which trigger the local payment process ## payOnSite = -> $uibModal.open templateUrl: '<%= asset_path "plans/payment_modal.html" %>' size: 'sm' resolve: selectedPlan: -> $scope.selectedPlan member: -> $scope.ctrl.member price: -> $scope.cart.total wallet: -> Wallet.getWalletByUser({user_id: $scope.ctrl.member.id}).$promise coupon: -> $scope.coupon.applied controller: ['$scope', '$uibModalInstance', '$state', 'selectedPlan', 'member', 'price', 'Subscription', 'wallet', 'helpers', '$filter', 'coupon', ($scope, $uibModalInstance, $state, selectedPlan, member, price, Subscription, wallet, helpers, $filter, coupon) -> # user wallet amount $scope.walletAmount = wallet.amount # subcription price, coupon subtracted if any $scope.price = price # price to pay $scope.amount = helpers.getAmountToPay($scope.price, wallet.amount) # Used in wallet info template to interpolate some translations $scope.numberFilter = $filter('number') # The plan that the user is about to subscribe $scope.plan = selectedPlan # The member who is subscribing a plan $scope.member = member # Button label if $scope.amount > 0 $scope.validButtonName = _t('confirm_payment_of_html', {ROLE:$scope.currentUser.role, AMOUNT:$filter('currency')($scope.amount)}, "messageformat") else if price.price > 0 and $scope.walletAmount == 0 $scope.validButtonName = _t('confirm_payment_of_html', {ROLE:$scope.currentUser.role, AMOUNT:$filter('currency')(price.price)}, "messageformat") else $scope.validButtonName = _t('confirm') ## # Callback for the 'proceed' button. # Save the subscription to the API ## $scope.ok = -> $scope.attempting = true Subscription.save coupon_code: (coupon.code if coupon) subscription: plan_id: selectedPlan.id user_id: member.id , (data, status) -> # success $uibModalInstance.close(data) , (data, status) -> # failed $scope.alerts = [] $scope.alerts.push({msg: _t('an_error_occured_during_the_payment_process_please_try_again_later'), type: 'danger' }) $scope.attempting = false ## # Callback for the 'cancel' button. # Close the modal box. ## $scope.cancel = -> $uibModalInstance.dismiss('cancel') ] .result['finally'](null).then (reservation)-> $scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan) Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan) $scope.ctrl.member = null $scope.paid.plan = angular.copy($scope.selectedPlan) $scope.selectedPlan = null $scope.coupon.applied = null ## !!! MUST BE CALLED AT THE END of the controller initialize() ]