2018-07-10 17:53:06 -04:00
|
|
|
logger = require 'logger-sharelatex'
|
|
|
|
async = require 'async'
|
|
|
|
db = require("../../infrastructure/mongojs").db
|
2019-02-25 05:22:47 -05:00
|
|
|
_ = require("underscore")
|
2018-07-10 17:53:06 -04:00
|
|
|
ObjectId = require("../../infrastructure/mongojs").ObjectId
|
|
|
|
{ getInstitutionAffiliations } = require('./InstitutionsAPI')
|
|
|
|
FeaturesUpdater = require('../Subscription/FeaturesUpdater')
|
2019-01-28 09:18:01 -05:00
|
|
|
UserGetter = require('../User/UserGetter')
|
2019-02-25 05:22:47 -05:00
|
|
|
NotificationsBuilder = require("../Notifications/NotificationsBuilder")
|
|
|
|
SubscriptionLocator = require("../Subscription/SubscriptionLocator")
|
|
|
|
Institution = require("../../models/Institution").Institution
|
2019-05-20 08:08:30 -04:00
|
|
|
Subscription = require("../../models/Subscription").Subscription
|
2018-07-10 17:53:06 -04:00
|
|
|
|
|
|
|
ASYNC_LIMIT = 10
|
|
|
|
module.exports = InstitutionsManager =
|
|
|
|
upgradeInstitutionUsers: (institutionId, callback = (error) ->) ->
|
2019-02-25 05:22:47 -05:00
|
|
|
async.waterfall [
|
|
|
|
(cb) ->
|
|
|
|
fetchInstitutionAndAffiliations institutionId, cb
|
|
|
|
(institution, affiliations, cb) ->
|
|
|
|
affiliations = _.map affiliations, (affiliation) ->
|
|
|
|
affiliation.institutionName = institution.name
|
|
|
|
affiliation.institutionId = institutionId
|
|
|
|
return affiliation
|
|
|
|
async.eachLimit affiliations, ASYNC_LIMIT, refreshFeatures, (err) -> cb(err)
|
|
|
|
], callback
|
|
|
|
|
2019-01-28 09:18:01 -05:00
|
|
|
checkInstitutionUsers: (institutionId, callback = (error) ->) ->
|
|
|
|
getInstitutionAffiliations institutionId, (error, affiliations) ->
|
|
|
|
UserGetter.getUsersByAnyConfirmedEmail(
|
|
|
|
affiliations.map((affiliation) -> affiliation.email),
|
|
|
|
{ features: 1 },
|
|
|
|
(error, users) ->
|
|
|
|
callback(error, checkFeatures(users))
|
|
|
|
)
|
2018-07-10 17:53:06 -04:00
|
|
|
|
2019-05-20 08:08:30 -04:00
|
|
|
getInstitutionUsersSubscriptions: (institutionId, callback = (error, subscriptions) ->) ->
|
|
|
|
getInstitutionAffiliations institutionId, (error, affiliations) ->
|
|
|
|
return callback(error) if error?
|
|
|
|
userIds = affiliations.map (affiliation) -> ObjectId(affiliation.user_id)
|
|
|
|
Subscription
|
|
|
|
.find admin_id: userIds
|
|
|
|
.populate 'admin_id', 'email'
|
|
|
|
.exec callback
|
|
|
|
|
2019-02-25 05:22:47 -05:00
|
|
|
fetchInstitutionAndAffiliations = (institutionId, callback) ->
|
|
|
|
async.waterfall [
|
|
|
|
(cb) ->
|
|
|
|
Institution.findOne {v1Id: institutionId}, (err, institution) -> cb(err, institution)
|
|
|
|
(institution, cb) ->
|
|
|
|
institution.fetchV1Data (err, institution) -> cb(err, institution)
|
|
|
|
(institution, cb) ->
|
|
|
|
getInstitutionAffiliations institutionId, (err, affiliations) -> cb(err, institution, affiliations)
|
|
|
|
], callback
|
|
|
|
|
2018-07-10 17:53:06 -04:00
|
|
|
refreshFeatures = (affiliation, callback) ->
|
|
|
|
userId = ObjectId(affiliation.user_id)
|
2019-02-25 05:22:47 -05:00
|
|
|
async.waterfall [
|
|
|
|
(cb) ->
|
|
|
|
FeaturesUpdater.refreshFeatures userId, true, (err, features, featuresChanged) -> cb(err, featuresChanged)
|
|
|
|
(featuresChanged, cb) ->
|
|
|
|
getUserInfo userId, (error, user, subscription) -> cb(error, user, subscription, featuresChanged)
|
|
|
|
(user, subscription, featuresChanged, cb) ->
|
|
|
|
notifyUser user, affiliation, subscription, featuresChanged, cb
|
|
|
|
], callback
|
|
|
|
|
|
|
|
getUserInfo = (userId, callback) ->
|
|
|
|
async.waterfall [
|
|
|
|
(cb) ->
|
|
|
|
UserGetter.getUser userId, cb
|
|
|
|
(user, cb) ->
|
|
|
|
SubscriptionLocator.getUsersSubscription user, (err, subscription) -> cb(err, user, subscription)
|
|
|
|
], callback
|
|
|
|
|
|
|
|
notifyUser = (user, affiliation, subscription, featuresChanged, callback) ->
|
|
|
|
async.parallel [
|
|
|
|
(cb) ->
|
|
|
|
if featuresChanged
|
|
|
|
NotificationsBuilder.featuresUpgradedByAffiliation(affiliation, user).create cb
|
|
|
|
else
|
|
|
|
cb()
|
|
|
|
(cb) ->
|
|
|
|
if subscription? and !subscription.planCode.match(/(free|trial)/)? and !subscription.groupPlan
|
|
|
|
NotificationsBuilder.redundantPersonalSubscription(affiliation, user).create cb
|
|
|
|
else
|
|
|
|
cb()
|
|
|
|
], callback
|
2019-01-28 09:18:01 -05:00
|
|
|
|
|
|
|
checkFeatures = (users) ->
|
|
|
|
usersSummary = {
|
|
|
|
totalConfirmedUsers: users.length
|
|
|
|
totalConfirmedProUsers: 0
|
|
|
|
totalConfirmedNonProUsers: 0
|
|
|
|
confirmedNonProUsers: []
|
|
|
|
}
|
|
|
|
users.forEach((user) ->
|
|
|
|
if user.features.collaborators == -1 and user.features.trackChanges
|
|
|
|
usersSummary.totalConfirmedProUsers += 1
|
|
|
|
else
|
|
|
|
usersSummary.totalConfirmedNonProUsers += 1
|
|
|
|
usersSummary.confirmedNonProUsers.push user._id
|
|
|
|
)
|
2019-02-25 05:22:47 -05:00
|
|
|
return usersSummary
|