SubscriptionViewModelBuilder.coffee 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. Settings = require('settings-sharelatex')
  2. RecurlyWrapper = require("./RecurlyWrapper")
  3. PlansLocator = require("./PlansLocator")
  4. SubscriptionFormatters = require("./SubscriptionFormatters")
  5. LimitationsManager = require("./LimitationsManager")
  6. SubscriptionLocator = require("./SubscriptionLocator")
  7. V1SubscriptionManager = require("./V1SubscriptionManager")
  8. InstitutionsGetter = require("../Institutions/InstitutionsGetter")
  9. logger = require('logger-sharelatex')
  10. _ = require("underscore")
  11. async = require('async')
  12. buildBillingDetails = (recurlySubscription) ->
  13. hostedLoginToken = recurlySubscription?.account?.hosted_login_token
  14. recurlySubdomain = Settings?.apis?.recurly?.subdomain
  15. if hostedLoginToken? && recurlySubdomain?
  16. return [
  17. "https://",
  18. recurlySubdomain,
  19. ".recurly.com/account/billing_info/edit?ht=",
  20. hostedLoginToken
  21. ].join("")
  22. module.exports =
  23. buildUsersSubscriptionViewModel: (user, callback = (error, data) ->) ->
  24. async.auto {
  25. personalSubscription: (cb) ->
  26. SubscriptionLocator.getUsersSubscription user, cb
  27. recurlySubscription: ['personalSubscription', (cb, {personalSubscription}) ->
  28. if !personalSubscription?.recurlySubscription_id? or personalSubscription?.recurlySubscription_id == ''
  29. return cb(null, null)
  30. RecurlyWrapper.getSubscription personalSubscription.recurlySubscription_id, includeAccount: true, cb
  31. ]
  32. plan: ['personalSubscription', (cb, {personalSubscription}) ->
  33. return cb() if !personalSubscription?
  34. plan = PlansLocator.findLocalPlanInSettings(personalSubscription.planCode)
  35. return cb(new Error("No plan found for planCode '#{personalSubscription.planCode}'")) if !plan?
  36. cb(null, plan)
  37. ]
  38. memberGroupSubscriptions: (cb) ->
  39. SubscriptionLocator.getMemberSubscriptions user, cb
  40. managedGroupSubscriptions: (cb) ->
  41. SubscriptionLocator.getManagedGroupSubscriptions user, cb
  42. confirmedMemberInstitutions: (cb) ->
  43. InstitutionsGetter.getConfirmedInstitutions user._id, cb
  44. managedInstitutions: (cb) ->
  45. InstitutionsGetter.getManagedInstitutions user._id, cb
  46. v1Subscriptions: (cb) ->
  47. V1SubscriptionManager.getSubscriptionsFromV1 user._id, (error, subscriptions, v1Id) ->
  48. return cb(error) if error?
  49. # Only return one argument to async.auto, otherwise it returns an array
  50. cb(null, subscriptions)
  51. }, (err, results) ->
  52. return callback(err) if err?
  53. {
  54. personalSubscription,
  55. memberGroupSubscriptions,
  56. managedGroupSubscriptions,
  57. confirmedMemberInstitutions,
  58. managedInstitutions,
  59. v1Subscriptions,
  60. recurlySubscription,
  61. plan
  62. } = results
  63. memberGroupSubscriptions ?= []
  64. managedGroupSubscriptions ?= []
  65. confirmedMemberInstitutions ?= []
  66. managedInstitutions ?= []
  67. v1Subscriptions ?= {}
  68. if personalSubscription?.toObject?
  69. # Downgrade from Mongoose object, so we can add a recurly and plan attribute
  70. personalSubscription = personalSubscription.toObject()
  71. if plan?
  72. personalSubscription.plan = plan
  73. if personalSubscription? and recurlySubscription?
  74. tax = recurlySubscription?.tax_in_cents || 0
  75. personalSubscription.recurly = {
  76. tax: tax
  77. taxRate: parseFloat(recurlySubscription?.tax_rate?._)
  78. billingDetailsLink: buildBillingDetails(recurlySubscription)
  79. price: SubscriptionFormatters.formatPrice (recurlySubscription?.unit_amount_in_cents + tax), recurlySubscription?.currency
  80. nextPaymentDueAt: SubscriptionFormatters.formatDate(recurlySubscription?.current_period_ends_at)
  81. currency: recurlySubscription.currency
  82. state: recurlySubscription.state
  83. trialEndsAtFormatted: SubscriptionFormatters.formatDate(recurlySubscription?.trial_ends_at)
  84. trial_ends_at: recurlySubscription.trial_ends_at
  85. }
  86. callback null, {
  87. personalSubscription,
  88. managedGroupSubscriptions,
  89. memberGroupSubscriptions,
  90. confirmedMemberInstitutions,
  91. managedInstitutions,
  92. v1Subscriptions
  93. }
  94. buildViewModel : ->
  95. plans = Settings.plans
  96. allPlans = {}
  97. plans.forEach (plan)->
  98. allPlans[plan.planCode] = plan
  99. result =
  100. allPlans: allPlans
  101. result.personalAccount = _.find plans, (plan)->
  102. plan.planCode == "personal"
  103. result.studentAccounts = _.filter plans, (plan)->
  104. plan.planCode.indexOf("student") != -1
  105. result.groupMonthlyPlans = _.filter plans, (plan)->
  106. plan.groupPlan and !plan.annual
  107. result.groupAnnualPlans = _.filter plans, (plan)->
  108. plan.groupPlan and plan.annual
  109. result.individualMonthlyPlans = _.filter plans, (plan)->
  110. !plan.groupPlan and !plan.annual and plan.planCode != "personal" and plan.planCode.indexOf("student") == -1
  111. result.individualAnnualPlans = _.filter plans, (plan)->
  112. !plan.groupPlan and plan.annual and plan.planCode.indexOf("student") == -1
  113. return result