SubscriptionViewModelBuilder.coffee 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. PublishersGetter = require("../Publishers/PublishersGetter")
  10. sanitizeHtml = require 'sanitize-html'
  11. logger = require('logger-sharelatex')
  12. _ = require("underscore")
  13. async = require('async')
  14. buildBillingDetails = (recurlySubscription) ->
  15. hostedLoginToken = recurlySubscription?.account?.hosted_login_token
  16. recurlySubdomain = Settings?.apis?.recurly?.subdomain
  17. if hostedLoginToken? && recurlySubdomain?
  18. return [
  19. "https://",
  20. recurlySubdomain,
  21. ".recurly.com/account/billing_info/edit?ht=",
  22. hostedLoginToken
  23. ].join("")
  24. module.exports =
  25. buildUsersSubscriptionViewModel: (user, callback = (error, data) ->) ->
  26. async.auto {
  27. personalSubscription: (cb) ->
  28. SubscriptionLocator.getUsersSubscription user, cb
  29. recurlySubscription: ['personalSubscription', (cb, {personalSubscription}) ->
  30. if !personalSubscription?.recurlySubscription_id? or personalSubscription?.recurlySubscription_id == ''
  31. return cb(null, null)
  32. RecurlyWrapper.getSubscription personalSubscription.recurlySubscription_id, includeAccount: true, cb
  33. ]
  34. recurlyCoupons: ['recurlySubscription', (cb, {recurlySubscription}) ->
  35. return cb(null, null) if !recurlySubscription
  36. accountId = recurlySubscription.account.account_code
  37. RecurlyWrapper.getAccountActiveCoupons accountId, cb
  38. ]
  39. plan: ['personalSubscription', (cb, {personalSubscription}) ->
  40. return cb() if !personalSubscription?
  41. plan = PlansLocator.findLocalPlanInSettings(personalSubscription.planCode)
  42. return cb(new Error("No plan found for planCode '#{personalSubscription.planCode}'")) if !plan?
  43. cb(null, plan)
  44. ]
  45. memberGroupSubscriptions: (cb) ->
  46. SubscriptionLocator.getMemberSubscriptions user, cb
  47. managedGroupSubscriptions: (cb) ->
  48. SubscriptionLocator.getManagedGroupSubscriptions user, cb
  49. confirmedMemberInstitutions: (cb) ->
  50. InstitutionsGetter.getConfirmedInstitutions user._id, cb
  51. managedInstitutions: (cb) ->
  52. InstitutionsGetter.getManagedInstitutions user._id, cb
  53. managedPublishers: (cb) ->
  54. PublishersGetter.getManagedPublishers user._id, cb
  55. v1SubscriptionStatus: (cb) ->
  56. V1SubscriptionManager.getSubscriptionStatusFromV1 user._id, (error, status, v1Id) ->
  57. return cb(error) if error?
  58. cb(null, status)
  59. }, (err, results) ->
  60. return callback(err) if err?
  61. {
  62. personalSubscription,
  63. memberGroupSubscriptions,
  64. managedGroupSubscriptions,
  65. confirmedMemberInstitutions,
  66. managedInstitutions,
  67. managedPublishers,
  68. v1SubscriptionStatus,
  69. recurlySubscription,
  70. recurlyCoupons,
  71. plan
  72. } = results
  73. memberGroupSubscriptions ?= []
  74. managedGroupSubscriptions ?= []
  75. confirmedMemberInstitutions ?= []
  76. managedInstitutions ?= []
  77. v1SubscriptionStatus ?= {}
  78. recurlyCoupons ?= []
  79. if personalSubscription?.toObject?
  80. # Downgrade from Mongoose object, so we can add a recurly and plan attribute
  81. personalSubscription = personalSubscription.toObject()
  82. if plan?
  83. personalSubscription.plan = plan
  84. if personalSubscription? and recurlySubscription?
  85. tax = recurlySubscription?.tax_in_cents || 0
  86. personalSubscription.recurly = {
  87. tax: tax
  88. taxRate: parseFloat(recurlySubscription?.tax_rate?._)
  89. billingDetailsLink: buildBillingDetails(recurlySubscription)
  90. price: SubscriptionFormatters.formatPrice (recurlySubscription?.unit_amount_in_cents + tax), recurlySubscription?.currency
  91. nextPaymentDueAt: SubscriptionFormatters.formatDate(recurlySubscription?.current_period_ends_at)
  92. currency: recurlySubscription.currency
  93. state: recurlySubscription.state
  94. trialEndsAtFormatted: SubscriptionFormatters.formatDate(recurlySubscription?.trial_ends_at)
  95. trial_ends_at: recurlySubscription.trial_ends_at
  96. activeCoupons: recurlyCoupons
  97. }
  98. for memberGroupSubscription in memberGroupSubscriptions
  99. if memberGroupSubscription.teamNotice
  100. memberGroupSubscription.teamNotice = sanitizeHtml(memberGroupSubscription.teamNotice)
  101. callback null, {
  102. personalSubscription,
  103. managedGroupSubscriptions,
  104. memberGroupSubscriptions,
  105. confirmedMemberInstitutions,
  106. managedInstitutions,
  107. managedPublishers,
  108. v1SubscriptionStatus
  109. }
  110. buildViewModel : ->
  111. plans = Settings.plans
  112. allPlans = {}
  113. plans.forEach (plan)->
  114. allPlans[plan.planCode] = plan
  115. result =
  116. allPlans: allPlans
  117. result.personalAccount = _.find plans, (plan)->
  118. plan.planCode == "personal"
  119. result.studentAccounts = _.filter plans, (plan)->
  120. plan.planCode.indexOf("student") != -1
  121. result.groupMonthlyPlans = _.filter plans, (plan)->
  122. plan.groupPlan and !plan.annual
  123. result.groupAnnualPlans = _.filter plans, (plan)->
  124. plan.groupPlan and plan.annual
  125. result.individualMonthlyPlans = _.filter plans, (plan)->
  126. !plan.groupPlan and !plan.annual and plan.planCode != "personal" and plan.planCode.indexOf("student") == -1
  127. result.individualAnnualPlans = _.filter plans, (plan)->
  128. !plan.groupPlan and plan.annual and plan.planCode.indexOf("student") == -1
  129. return result