diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee index 9b812d8d17..fd5b6accc4 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee @@ -8,6 +8,7 @@ Settings = require 'settings-sharelatex' logger = require('logger-sharelatex') GeoIpLookup = require("../../infrastructure/GeoIpLookup") SubscriptionDomainHandler = require("./SubscriptionDomainHandler") +UserGetter = require "../User/UserGetter" module.exports = SubscriptionController = @@ -21,14 +22,27 @@ module.exports = SubscriptionController = if req.query.v? viewName = "#{viewName}_#{req.query.v}" logger.log viewName:viewName, "showing plans page" + currentUser = null GeoIpLookup.getCurrencyCode req.query?.ip || req.ip, (err, recomendedCurrency)-> return next(err) if err? - res.render viewName, - title: "plans_and_pricing" - plans: plans - baseUrl: baseUrl - gaExperiments: Settings.gaExperiments.plansPage - recomendedCurrency:recomendedCurrency + render = () -> + res.render viewName, + title: "plans_and_pricing" + plans: plans + baseUrl: baseUrl + gaExperiments: Settings.gaExperiments.plansPage + recomendedCurrency:recomendedCurrency + shouldABTestPlans: currentUser == null or (currentUser?.signUpDate? and currentUser.signUpDate >= (new Date('2011-10-18'))) + user_id = AuthenticationController.getLoggedInUserId(req) + if user_id? + console.log '>> user is logged in' + UserGetter.getUser user_id, {signUpDate: 1}, (err, user) -> + return next(err) if err? + currentUser = user + render() + else + console.log '>> not logged in' + render() #get to show the recurly.js page paymentPage: (req, res, next) -> diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee index 44c31c8d60..8e2fc2032e 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee @@ -44,7 +44,7 @@ module.exports = allPlans = {} plans.forEach (plan)-> allPlans[plan.planCode] = plan - + result = allPlans: allPlans @@ -54,7 +54,7 @@ module.exports = result.studentAccounts = _.filter plans, (plan)-> plan.planCode.indexOf("student") != -1 - + result.groupMonthlyPlans = _.filter plans, (plan)-> plan.groupPlan and !plan.annual @@ -68,4 +68,3 @@ module.exports = !plan.groupPlan and plan.annual and plan.planCode.indexOf("student") == -1 return result - diff --git a/services/web/app/views/subscriptions/dashboard.jade b/services/web/app/views/subscriptions/dashboard.jade index 34493e5a8c..175c8d1e4f 100644 --- a/services/web/app/views/subscriptions/dashboard.jade +++ b/services/web/app/views/subscriptions/dashboard.jade @@ -12,8 +12,8 @@ block scripts mixin printPlan(plan) -if (!plan.hideFromUsers) - tr(ng-controller="ChangePlanFormController") - td(ng-init="plan=#{JSON.stringify(plan)}") + tr(ng-controller="ChangePlanFormController", ng-init="plan=#{JSON.stringify(plan)}", ng-show="shouldShowPlan(plan.planCode)") + td strong #{plan.name} td {{refreshPrice(plan.planCode)}} -if (plan.annual) @@ -46,8 +46,8 @@ block content |   | #{translate("your_billing_details_were_saved")} .card(ng-if="view == 'overview'") - .page-header - h1 #{translate("your_subscription")} + .page-header(x-current-plan="#{subscription.planCode}") + h1 #{translate("your_subscription")} - if (subscription && user._id+'' == subscription.admin_id+'') case subscription.state @@ -56,7 +56,8 @@ block content when "active" p !{translate("currently_subscribed_to_plan", {planName:"" + subscription.name + ""})} - a(href, ng-click="changePlan = true") !{translate("change_plan")}. + span(ng-show="!isNextGenPlan") + a(href, ng-click="changePlan = true") !{translate("change_plan")}. p !{translate("next_payment_of_x_collectected_on_y", {paymentAmmount:"" + subscription.price + "", collectionDate:"" + subscription.nextPaymentDueAt + ""})} p.pull-right p diff --git a/services/web/app/views/subscriptions/plans.jade b/services/web/app/views/subscriptions/plans.jade index 9db21fa3a6..256951a064 100644 --- a/services/web/app/views/subscriptions/plans.jade +++ b/services/web/app/views/subscriptions/plans.jade @@ -3,6 +3,7 @@ block scripts script(type='text/javascript'). window.recomendedCurrency = '#{recomendedCurrency}' window.abCurrencyFlag = '#{abCurrencyFlag}' + window.shouldABTestPlans = #{shouldABTestPlans || false} script(type='text/javascript'). (function() {var s=document.createElement('script'); s.type='text/javascript';s.async=true; @@ -56,133 +57,138 @@ block content ng-click="changeCurreny(currency)" ) {{currency}} ({{value['symbol']}}) - .row(ng-cloak) - .col-md-10.col-md-offset-1 - .row - .card-group.text-centered(ng-if="ui.view == 'monthly' || ui.view == 'annual'") - .col-md-4 - .card.card-first - .card-header - h2 #{translate("personal")} - .circle #{translate("free")} - ul.list-unstyled - li #{translate("one_collaborator")} - li   - li   - li   - li - br - a.btn.btn-info( - href="/register" - style=(getLoggedInUserId() === undefined ? "" : "visibility: hidden") - ) #{translate("sign_up_now")} - .col-md-4 - .card.card-highlighted - .card-header - h2 #{translate("collaborator")} - .circle - span(ng-if="ui.view == 'monthly'") - | {{plans[currencyCode]['collaborator']['monthly']}} - span.small /mo - span(ng-if="ui.view == 'annual'") - | {{plans[currencyCode]['collaborator']['annual']}} - span.small /yr - ul.list-unstyled - li - strong #{translate("collabs_per_proj", {collabcount:10})} - li #{translate("full_doc_history")} - li #{translate("sync_to_dropbox")} - li #{translate("sync_to_github")} - li - br - a.btn.btn-info( + div + .row(ng-cloak) + .col-md-10.col-md-offset-1 + .row + .card-group.text-centered(ng-if="ui.view == 'monthly' || ui.view == 'annual'") + .col-md-4 + .card.card-first + .card-header + h2 #{translate("personal")} + .circle #{translate("free")} + ul.list-unstyled + li #{translate("one_collaborator")} + li   + li   + li   + li + br + a.btn.btn-info( + href="/register" + style=(getLoggedInUserId() === undefined ? "" : "visibility: hidden") + ) #{translate("sign_up_now")} + .col-md-4 + .card.card-highlighted + .card-header + h2 #{translate("collaborator")} + .circle + span(ng-if="ui.view == 'monthly'") + | {{plans[currencyCode]['collaborator']['monthly']}} + span.small /mo + span(ng-if="ui.view == 'annual'") + | {{plans[currencyCode]['collaborator']['annual']}} + span.small /yr + ul.list-unstyled + li + strong #{translate("collabs_per_proj", {collabcount:10})} + li #{translate("full_doc_history")} + li #{translate("sync_to_dropbox")} + li #{translate("sync_to_github")} + li + br + a.btn.btn-info( + + ng-href="#{baseUrl}/user/subscription/new?planCode=collaborator{{ (ui.view == 'annual' ? '-annual' : '') + (plansVariant == 'default' ? planQueryString : '_'+plansVariant)}}¤cy={{currencyCode}}", ng-click="signUpNowClicked('collaborator')" + ) + span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")} + span(ng-show="ui.view == 'annual'") #{translate("buy_now")} + .col-md-4 + .card.card-last + .card-header + h2 #{translate("professional")} + .circle + span(ng-if="ui.view == 'monthly'") + | {{plans[currencyCode]['professional']['monthly']}} + span.small /mo + span(ng-if="ui.view == 'annual'") + | {{plans[currencyCode]['professional']['annual']}} + span.small /yr + ul.list-unstyled + li + strong #{translate("unlimited_collabs")} + li #{translate("full_doc_history")} + li #{translate("sync_to_dropbox")} + li #{translate("sync_to_github")} + li + br + a.btn.btn-info( + ng-href="#{baseUrl}/user/subscription/new?planCode=professional{{ ui.view == 'annual' && '-annual' || planQueryString}}¤cy={{currencyCode}}", ng-click="signUpNowClicked('professional')" + ) + span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")} + span(ng-show="ui.view == 'annual'") #{translate("buy_now")} + + .card-group.text-centered(ng-if="ui.view == 'student'") + .col-md-4 + .card.card-first + .card-header + h2 #{translate("personal")} + .circle #{translate("free")} + ul.list-unstyled + li #{translate("one_collaborator")} + li   + li   + li   + li + br + a.btn.btn-info( + href="/register" + style=(getLoggedInUserId() === undefined ? "" : "visibility: hidden") + ) #{translate("sign_up_now")} + + .col-md-4 + .card.card-highlighted + .card-header + h2 #{translate("student")} + .circle + span + | {{plans[currencyCode]['student']['monthly']}} + span.small /mo + ul.list-unstyled + li + strong #{translate("collabs_per_proj", {collabcount:6})} + li #{translate("full_doc_history")} + li #{translate("sync_to_dropbox")} + li #{translate("sync_to_github")} + li + br + a.btn.btn-info( + ng-href="#{baseUrl}/user/subscription/new?planCode=student{{ plansVariant == 'default' ? planQueryString : '_'+plansVariant }}¤cy={{currencyCode}}", + ng-click="signUpNowClicked('student')" + ) #{translate("start_free_trial")} + + .col-md-4 + .card.card-last + .card-header + h2 #{translate("student")} (#{translate("annual")}) + .circle + span + | {{plans[currencyCode]['student']['annual']}} + span.small /yr + ul.list-unstyled + li + strong #{translate("collabs_per_proj", {collabcount:6})} + li #{translate("full_doc_history")} + li #{translate("sync_to_dropbox")} + li #{translate("sync_to_github")} + li + br + a.btn.btn-info( + ng-href="#{baseUrl}/user/subscription/new?planCode=student-annual{{ plansVariant == 'default' ? '' : '_'+plansVariant }}¤cy={{currencyCode}}", + ng-click="signUpNowClicked('student')" + ) #{translate("buy_now")} - ng-href="#{baseUrl}/user/subscription/new?planCode=collaborator{{ ui.view == 'annual' && '-annual' || planQueryString}}¤cy={{currencyCode}}", ng-click="signUpNowClicked('collaborator')" - ) - span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")} - span(ng-show="ui.view == 'annual'") #{translate("buy_now")} - .col-md-4 - .card.card-last - .card-header - h2 #{translate("professional")} - .circle - span(ng-if="ui.view == 'monthly'") - | {{plans[currencyCode]['professional']['monthly']}} - span.small /mo - span(ng-if="ui.view == 'annual'") - | {{plans[currencyCode]['professional']['annual']}} - span.small /yr - ul.list-unstyled - li - strong #{translate("unlimited_collabs")} - li #{translate("full_doc_history")} - li #{translate("sync_to_dropbox")} - li #{translate("sync_to_github")} - li - br - a.btn.btn-info( - ng-href="#{baseUrl}/user/subscription/new?planCode=professional{{ ui.view == 'annual' && '-annual' || planQueryString}}¤cy={{currencyCode}}", ng-click="signUpNowClicked('professional')" - ) - span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")} - span(ng-show="ui.view == 'annual'") #{translate("buy_now")} - .card-group.text-centered(ng-if="ui.view == 'student'") - .col-md-4 - .card.card-first - .card-header - h2 #{translate("personal")} - .circle #{translate("free")} - ul.list-unstyled - li #{translate("one_collaborator")} - li   - li   - li   - li - br - a.btn.btn-info( - href="/register" - style=(getLoggedInUserId() === undefined ? "" : "visibility: hidden") - ) #{translate("sign_up_now")} - - .col-md-4 - .card.card-highlighted - .card-header - h2 #{translate("student")} - .circle - span - | {{plans[currencyCode]['student']['monthly']}} - span.small /mo - ul.list-unstyled - li - strong #{translate("collabs_per_proj", {collabcount:6})} - li #{translate("full_doc_history")} - li #{translate("sync_to_dropbox")} - li #{translate("sync_to_github")} - li - br - a.btn.btn-info( - ng-href="#{baseUrl}/user/subscription/new?planCode=student{{planQueryString}}¤cy={{currencyCode}}", ng-click="signUpNowClicked('student')" - ) #{translate("start_free_trial")} - - .col-md-4 - .card.card-last - .card-header - h2 #{translate("student")} (#{translate("annual")}) - .circle - span - | {{plans[currencyCode]['student']['annual']}} - span.small /yr - ul.list-unstyled - li - strong #{translate("collabs_per_proj", {collabcount:6})} - li #{translate("full_doc_history")} - li #{translate("sync_to_dropbox")} - li #{translate("sync_to_github")} - li - br - a.btn.btn-info( - ng-href="#{baseUrl}/user/subscription/new?planCode=student-annual¤cy={{currencyCode}}", ng-click="signUpNowClicked('student')" - ) #{translate("buy_now")} .row.row-spaced(ng-cloak) p.text-centered #{translate("choose_plan_works_for_you", {len:'{{trial_len}}'})} diff --git a/services/web/public/coffee/ide.coffee b/services/web/public/coffee/ide.coffee index 607b8556aa..4e7721badd 100644 --- a/services/web/public/coffee/ide.coffee +++ b/services/web/public/coffee/ide.coffee @@ -66,6 +66,18 @@ define [ pdfLayout: 'sideBySide' } $scope.user = window.user + + + $scope.startTrialPlanCode = 'collaborator_free_trial_7_days' + $scope.shouldABTestPlans = false + $scope._plansVariant = 'default' + if $scope.user.signUpDate >= '2011-10-18' + $scope.shouldABTestPlans = true + sixpack.participate 'plans-1610', ['default', 'heron', 'ibis'], (chosenVariation, rawResponse)-> + $scope._plansVariant = chosenVariation + if chosenVariation in ['heron', 'ibis'] + $scope.startTrialPlanCode = "collaborator_#{chosenVariation}" + $scope.settings = window.userSettings $scope.anonymous = window.anonymous @@ -75,7 +87,7 @@ define [ # Only run the header AB test for newly registered users. _abTestStartDate = new Date(Date.UTC(2016, 8, 28)) _userSignUpDate = new Date(window.user.signUpDate) - + $scope.shouldABTestHeaderLabels = _userSignUpDate > _abTestStartDate $scope.headerLabelsABVariant = "" @@ -92,7 +104,7 @@ define [ # Tracking code. $scope.$watch "ui.view", (newView, oldView) -> if newView? and newView != "editor" and newView != "pdf" - event_tracking.sendMBOnce "ide-open-view-#{ newView }-once" + event_tracking.sendMBOnce "ide-open-view-#{ newView }-once" $scope.$watch "ui.chatOpen", (isOpen) -> event_tracking.sendMBOnce "ide-open-chat-once" if isOpen @@ -105,7 +117,7 @@ define [ # End of tracking code. window._ide = ide - + ide.validFileRegex = '^[^\*\/]*$' # Don't allow * and / ide.project_id = $scope.project_id = window.project_id diff --git a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee index 790f2384a1..c2559b1faf 100644 --- a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee +++ b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee @@ -29,12 +29,12 @@ define [ $scope.$watch "shouldShowLogs", (shouldShow) -> if shouldShow - $scope.$applyAsync () -> + $scope.$applyAsync () -> $scope.shouldDropUp = getFilesDropdownTopCoordAsRatio() > 0.65 # log hints tracking $scope.logHintsNegFeedbackValues = logHintsFeedback.feedbackOpts - + $scope.trackLogHintsLearnMore = () -> event_tracking.sendMB "logs-hints-learn-more" @@ -108,7 +108,7 @@ define [ _csrf: window.csrfToken }, {params: params} - parseCompileResponse = (response) -> + parseCompileResponse = (response) -> # keep last url last_pdf_url = $scope.pdf.url @@ -469,7 +469,7 @@ define [ event_tracking.sendMB "subscription-start-trial", { source } - window.open("/user/subscription/new?planCode=student_free_trial_7_days") + window.open("/user/subscription/new?planCode=#{$scope.startTrialPlanCode}") $scope.startedFreeTrial = true App.factory "synctex", ["ide", "$http", "$q", (ide, $http, $q) -> diff --git a/services/web/public/coffee/main/account-upgrade.coffee b/services/web/public/coffee/main/account-upgrade.coffee index be842b6907..f2767bfbb1 100644 --- a/services/web/public/coffee/main/account-upgrade.coffee +++ b/services/web/public/coffee/main/account-upgrade.coffee @@ -10,10 +10,9 @@ define [ w = window.open() sixpack.convert "track-changes-discount", -> - sixpack.participate 'in-editor-free-trial-plan', ['student', 'collaborator'], (planName, rawResponse)-> - ga?('send', 'event', 'subscription-funnel', 'upgraded-free-trial', source) - url = "/user/subscription/new?planCode=#{planName}_free_trial_7_days&ssp=#{planName == 'collaborator'}" - if couponCode? - url = "#{url}&cc=#{couponCode}" - $scope.startedFreeTrial = true - w.location = url + ga?('send', 'event', 'subscription-funnel', 'upgraded-free-trial', source) + url = "/user/subscription/new?planCode=#{$scope.startTrialPlanCode}&ssp=true" + if couponCode? + url = "#{url}&cc=#{couponCode}" + $scope.startedFreeTrial = true + w.location = url diff --git a/services/web/public/coffee/main/new-subscription.coffee b/services/web/public/coffee/main/new-subscription.coffee index d006c6173c..61961cfccb 100644 --- a/services/web/public/coffee/main/new-subscription.coffee +++ b/services/web/public/coffee/main/new-subscription.coffee @@ -5,12 +5,15 @@ define [ App.controller "NewSubscriptionController", ($scope, MultiCurrencyPricing, abTestManager, $http, sixpack, event_tracking, ccUtils)-> throw new Error("Recurly API Library Missing.") if typeof recurly is "undefined" - + $scope.currencyCode = MultiCurrencyPricing.currencyCode $scope.plans = MultiCurrencyPricing.plans $scope.switchToStudent = ()-> - window.location = "/user/subscription/new?planCode=student_free_trial_7_days¤cy=#{$scope.currencyCode}&cc=#{$scope.data.coupon}" + currentPlanCode = window.plan_code + planCode = currentPlanCode.replace('collaborator', 'student') + event_tracking.sendMB 'subscription-form-switch-to-student', { plan: window.plan_code } + window.location = "/user/subscription/new?planCode=#{planCode}¤cy=#{$scope.currencyCode}&cc=#{$scope.data.coupon}" event_tracking.sendMB "subscription-form", { plan : window.plan_code } diff --git a/services/web/public/coffee/main/plans.coffee b/services/web/public/coffee/main/plans.coffee index 4f21c4b5a8..6db59aa0e4 100644 --- a/services/web/public/coffee/main/plans.coffee +++ b/services/web/public/coffee/main/plans.coffee @@ -5,12 +5,171 @@ define [ App.factory "MultiCurrencyPricing", () -> - + currencyCode = window.recomendedCurrency return { currencyCode:currencyCode - plans: + + heron: + USD: + student: + monthly: "$6" + annual: "$60" + collaborator: + monthly: "$12" + annual: "$144" + EUR: + student: + monthly: "€5" + annual: "€50" + collaborator: + monthly: "€10" + annual: "€120" + GBP: + student: + monthly: "£5" + annual: "£50" + collaborator: + monthly: "£10" + annual: "£120" + SEK: + student: + monthly: "45 kr" + annual: "450 kr" + collaborator: + monthly: "90 kr" + annual: "1080 kr" + CAD: + student: + monthly: "$7" + annual: "$70" + collaborator: + monthly: "$14" + annual: "$168" + NOK: + student: + monthly: "45 kr" + annual: "450 kr" + collaborator: + monthly: "90 kr" + annual: "1080 kr" + DKK: + student: + monthly: "40 kr" + annual: "400 kr" + collaborator: + monthly: "80 kr" + annual: "960 kr" + AUD: + student: + monthly: "$8" + annual: "$80" + collaborator: + monthly: "$16" + annual: "$192" + NZD: + student: + monthly: "$8" + annual: "$80" + collaborator: + monthly: "$16" + annual: "$192" + CHF: + student: + monthly: "Fr 6" + annual: "Fr 60" + collaborator: + monthly: "Fr 12" + annual: "Fr 144" + SGD: + student: + monthly: "$8" + annual: "$80" + collaborator: + monthly: "$16" + annual: "$192" + + ibis: + USD: + student: + monthly: "$10" + annual: "$100" + collaborator: + monthly: "$18" + annual: "$216" + EUR: + student: + monthly: "€9" + annual: "€90" + collaborator: + monthly: "€16" + annual: "€192" + GBP: + student: + monthly: "£7" + annual: "£70" + collaborator: + monthly: "£13" + annual: "£156" + SEK: + student: + monthly: "75 kr" + annual: "750 kr" + collaborator: + monthly: "140 kr" + annual: "1680 kr" + CAD: + student: + monthly: "$12" + annual: "$120" + collaborator: + monthly: "$22" + annual: "$264" + NOK: + student: + monthly: "75 kr" + annual: "750 kr" + collaborator: + monthly: "140 kr" + annual: "1680 kr" + DKK: + student: + monthly: "68 kr" + annual: "680 kr" + collaborator: + monthly: "122 kr" + annual: "1464 kr" + AUD: + student: + monthly: "$13" + annual: "$130" + collaborator: + monthly: "$24" + annual: "$288" + NZD: + student: + monthly: "$14" + annual: "$140" + collaborator: + monthly: "$25" + annual: "$300" + CHF: + student: + monthly: "Fr 10" + annual: "Fr 100" + collaborator: + monthly: "Fr 18" + annual: "Fr 216" + SGD: + student: + monthly: "$14" + annual: "$140" + collaborator: + monthly: "$25" + annual: "$300" + + plans: USD: symbol: "$" student: @@ -23,7 +182,7 @@ define [ monthly: "$30" annual: "$360" - EUR: + EUR: symbol: "€" student: monthly: "€7" @@ -34,7 +193,7 @@ define [ professional: monthly: "€28" annual: "€336" - + GBP: symbol: "£" student: @@ -117,7 +276,7 @@ define [ professional: monthly: "$35" annual: "$420" - + CHF: symbol: "Fr" student: @@ -141,36 +300,51 @@ define [ professional: monthly: "$40" annual: "$480" + } - + App.controller "PlansController", ($scope, $modal, event_tracking, abTestManager, MultiCurrencyPricing, $http, sixpack) -> - App.controller "PlansController", ($scope, $modal, event_tracking, abTestManager, MultiCurrencyPricing, $http) -> + $scope.plansVariant = 'default' + $scope.shouldABTestPlans = window.shouldABTestPlans + + if $scope.shouldABTestPlans + sixpack.participate 'plans-1610', ['default', 'heron', 'ibis'], (chosenVariation, rawResponse)-> + $scope.plansVariant = chosenVariation + if chosenVariation in ['heron', 'ibis'] + # overwrite student plans with alternative + for currency, _v of $scope.plans + $scope.plans[currency]['student'] = MultiCurrencyPricing[chosenVariation][currency]['student'] + $scope.plans[currency]['collaborator'] = MultiCurrencyPricing[chosenVariation][currency]['collaborator'] $scope.plans = MultiCurrencyPricing.plans + $scope.currencyCode = MultiCurrencyPricing.currencyCode $scope.trial_len = 7 + $scope.planQueryString = '_free_trial_7_days' $scope.ui = view: "monthly" - $scope.changeCurreny = (newCurrency)-> $scope.currencyCode = newCurrency $scope.signUpNowClicked = (plan, annual)-> if $scope.ui.view == "annual" plan = "#{plan}_annual" - - event_tracking.send 'subscription-funnel', 'sign_up_now_button', plan + + event_tracking.send 'subscription-funnel', 'sign_up_now_button', plan + # TODO: double check this is correct + if $scope.shouldABTestPlans and plan in ['student', 'collaborator'] + sixpack.convert 'plans-1610', () -> $scope.switchToMonthly = -> $scope.ui.view = "monthly" event_tracking.send 'subscription-funnel', 'plans-page', 'monthly-prices' - + $scope.switchToStudent = -> $scope.ui.view = "student" event_tracking.send 'subscription-funnel', 'plans-page', 'student-prices' @@ -178,7 +352,7 @@ define [ $scope.switchToAnnual = -> $scope.ui.view = "annual" event_tracking.send 'subscription-funnel', 'plans-page', 'student-prices' - + $scope.openGroupPlanModal = () -> $modal.open { templateUrl: "groupPlanModalTemplate" diff --git a/services/web/public/coffee/main/subscription-dashboard.coffee b/services/web/public/coffee/main/subscription-dashboard.coffee index 7476d814e1..22d68baea5 100644 --- a/services/web/public/coffee/main/subscription-dashboard.coffee +++ b/services/web/public/coffee/main/subscription-dashboard.coffee @@ -9,7 +9,7 @@ define [ App.controller "CurrenyDropdownController", ($scope, MultiCurrencyPricing, $q)-> - $scope.plans = MultiCurrencyPricing.plans + # $scope.plans = MultiCurrencyPricing.plans $scope.currencyCode = MultiCurrencyPricing.currencyCode $scope.changeCurrency = (newCurrency)-> @@ -31,7 +31,7 @@ define [ $scope.currencyCode = MultiCurrencyPricing.currencyCode $scope.pricing = MultiCurrencyPricing - $scope.plans = MultiCurrencyPricing.plans + # $scope.plans = MultiCurrencyPricing.plans $scope.currencySymbol = MultiCurrencyPricing.plans[MultiCurrencyPricing.currencyCode].symbol $scope.currencyCode = MultiCurrencyPricing.currencyCode @@ -53,9 +53,9 @@ define [ price = "" App.controller "ConfirmChangePlanController", ($scope, $modalInstance, $http)-> - + $scope.confirmChangePlan = -> - body = + body = plan_code: $scope.plan.planCode _csrf : window.csrfToken @@ -74,7 +74,7 @@ define [ $scope.confirmLeaveGroup = -> $scope.inflight = true $http({ - url: "/subscription/group/user", + url: "/subscription/group/user", method: "DELETE", params: {admin_user_id: $scope.admin_id, _csrf: window.csrfToken} }).success -> @@ -87,6 +87,8 @@ define [ App.controller "UserSubscriptionController", ($scope, MultiCurrencyPricing, $http, sixpack, $modal) -> + $scope.plans = MultiCurrencyPricing.plans + freeTrialEndDate = new Date(subscription?.trial_ends_at) sevenDaysTime = new Date() @@ -96,6 +98,16 @@ define [ freeTrialExpiresUnderSevenDays = freeTrialEndDate < sevenDaysTime $scope.view = 'overview' + $scope.getSuffix = (planCode) -> + planCode?.match(/(.*?)_(.*)/)?[2] || null + $scope.subscriptionSuffix = $scope.getSuffix(window?.subscription?.planCode) + if $scope.subscriptionSuffix == 'free_trial_7_days' + $scope.subscriptionSuffix = '' + $scope.isNextGenPlan = $scope.subscriptionSuffix in ['heron', 'ibis'] + + $scope.shouldShowPlan = (planCode) -> + $scope.getSuffix(planCode) not in ['heron', 'ibis'] + isMonthlyCollab = subscription?.planCode?.indexOf("collaborator") != -1 and subscription?.planCode?.indexOf("ann") == -1 stillInFreeTrial = freeTrialInFuture and freeTrialExpiresUnderSevenDays @@ -118,7 +130,7 @@ define [ $scope.studentPrice = $scope.currencySymbol + (totalPriceExTax + taxAmmount) $scope.downgradeToStudent = -> - body = + body = plan_code: 'student' _csrf : window.csrfToken $scope.inflight = true @@ -129,7 +141,7 @@ define [ console.log "something went wrong changing plan" $scope.cancelSubscription = -> - body = + body = _csrf : window.csrfToken $scope.inflight = true @@ -158,7 +170,7 @@ define [ $scope.exendTrial = -> - body = + body = _csrf : window.csrfToken $scope.inflight = true $http.put("/user/subscription/extend", body) @@ -166,6 +178,3 @@ define [ location.reload() .error -> console.log "something went wrong changing plan" - - - diff --git a/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee b/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee index 1f935e420f..3a43c8988e 100644 --- a/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee @@ -20,7 +20,7 @@ mockSubscriptions = describe "SubscriptionController sanboxed", -> beforeEach -> - @user = {email:"tom@yahoo.com", _id: 'one'} + @user = {email:"tom@yahoo.com", _id: 'one', signUpDate: new Date('2000-10-01')} @activeRecurlySubscription = mockSubscriptions["subscription-123-active"] @AuthenticationController = @@ -63,6 +63,8 @@ describe "SubscriptionController sanboxed", -> getCurrencyCode:sinon.stub() @SubscriptionDomainHandler = getDomainLicencePage:sinon.stub() + @UserGetter = + getUser: sinon.stub().callsArgWith(2, null, @user) @SubscriptionController = SandboxedModule.require modulePath, requires: '../Authentication/AuthenticationController': @AuthenticationController './SubscriptionHandler': @SubscriptionHandler @@ -76,6 +78,7 @@ describe "SubscriptionController sanboxed", -> warn:-> "settings-sharelatex": @settings "./SubscriptionDomainHandler":@SubscriptionDomainHandler + "../User/UserGetter": @UserGetter @res = new MockResponse() @@ -92,12 +95,31 @@ describe "SubscriptionController sanboxed", -> @GeoIpLookup.getCurrencyCode.callsArgWith(1, null, @stubbedCurrencyCode) @res.callback = done @SubscriptionController.plansPage(@req, @res) + @UserGetter.getUser = sinon.stub().callsArgWith(2, null, @user) it "should set the recommended currency from the geoiplookup", (done)-> @res.renderedVariables.recomendedCurrency.should.equal(@stubbedCurrencyCode) @GeoIpLookup.getCurrencyCode.calledWith(@req.ip).should.equal true done() + it 'should fetch the current user', (done) -> + @UserGetter.getUser.callCount.should.equal 1 + done() + + it 'should decide not to AB test the plans', (done) -> + @res.renderedVariables.shouldABTestPlans.should.equal false + done() + + describe 'when user is not logged in', (done) -> + + beforeEach -> + @AuthenticationController.getLoggedInUserId.returns(null) + + it 'should not fetch the current user', (done) -> + @UserGetter.getUser.callCount.should.equal 0 + done() + + describe "editBillingDetailsPage", -> describe "with a user with a subscription", -> beforeEach (done) ->