SubscriptionViewModelBuilder.coffee 4.8 KB

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