diff --git a/scripts/mongodb/migrations/2015-11-20-add-course-headcount-old-trial-requests.js b/scripts/mongodb/migrations/2015-11-20-add-course-headcount-old-trial-requests.js new file mode 100644 index 000000000..08dc2b3d4 --- /dev/null +++ b/scripts/mongodb/migrations/2015-11-20-add-course-headcount-old-trial-requests.js @@ -0,0 +1,155 @@ +// Add 2 course headcount to older approved teacher surveys + +// Usage: +// mongo <address>:<port>/<database> <script file> -u <username> -p <password> + +// Who needs 2 course headcount added? +// Approved trial.requests but no prepaid with properties.trialRequestID set + +// Priority userID selection +// 1. UserID that redeemed approved prepaid +// 2. UserID that applied for trial request +// 3. User email that applied for trial request +// NOTE: May give course headcount to multiple accounts if they applied and redeemed with different users + +addHeadcount(); + +function addHeadcount() { + print("Finding approved trial requests.."); + + var approvedUserIDMap = {}; + var approvedUserEmails = []; + var codeRequestMap = {}; + var userIDRequestMap = {}; + var userEmailRequestMap = {}; + var cursor = db['trial.requests'].find({status: 'approved', type: 'subscription'}, {}); + while (cursor.hasNext()) { + var doc = cursor.next(); + if (doc.applicant) { + approvedUserIDMap[doc.applicant.valueOf()] = false; + userIDRequestMap[doc.applicant.valueOf()] = doc._id; + } + if (doc.prepaidCode) { + codeRequestMap[doc.prepaidCode] = doc._id; + } + approvedUserEmails.push(doc.properties.email.toLowerCase()); + userEmailRequestMap[doc.properties.email.toLowerCase()] = doc._id; + } + + print("Finding users via redeemed prepaids.."); + cursor = db.prepaids.find({code: {$in: Object.keys(codeRequestMap)}}); + while (cursor.hasNext()) { + var doc = cursor.next(); + if (doc.redeemers && doc.redeemers.length > 0) { + for (var i = 0; i < doc.redeemers.length; i++) { + approvedUserIDMap[doc.redeemers[i].userID.valueOf()] = false; + userIDRequestMap[doc.redeemers[i].userID.valueOf()] = codeRequestMap[doc.code]; + } + } + } + + print("Finding users via approved emails.."); + cursor = db.users.find({emailLower: {$in: approvedUserEmails}}); + while (cursor.hasNext()) { + var doc = cursor.next(); + approvedUserIDMap[doc._id.valueOf()] = false; + if (userEmailRequestMap[doc.emailLower]) { + // Trial request had a known email, but not an applicant field set + userIDRequestMap[doc._id.valueOf()] = userEmailRequestMap[doc.emailLower]; + } + } + + var approvedUserIDs = []; + for (var userID in approvedUserIDMap) { + approvedUserIDs.push(new ObjectId(userID)); + } + print("Approved user IDs:", approvedUserIDs.length); + + print("Finding approved users with trial request headcount.."); + cursor = db.prepaids.find({$and: [{creator: {$in: approvedUserIDs}}, {'properties.trialRequestID': {$exists: true}}]}); + while (cursor.hasNext()) { + var doc = cursor.next(); + approvedUserIDMap[doc.creator.valueOf()] = true; + } + + var needsHeadcount = []; + for (var userID in approvedUserIDMap) { + if (approvedUserIDMap[userID] === false) { + needsHeadcount.push(ObjectId(userID)); + } + } + print("Needs headcount:", needsHeadcount.length); + + var updateCount = 0; + function insertHeadCount(userID) { + if (!userIDRequestMap[userID.valueOf()]) { + print('ERROR: No trial request ID', userID); + print('Trial course headcount prepaids inserted:', updateCount); + return; + } + + generateNewCode(function(code) { + if (!code) { + print("ERROR: no code"); + return; + } + criteria = { + creator: userID, + type: 'course', + maxRedeemers: NumberInt(2), + properties: { + trialRequestID: userIDRequestMap[userID.valueOf()] + }, + exhausted: false, + __v: NumberInt(0) + }; + if (!db.prepaids.findOne(criteria)) { + // print('Adding trial request prepaid for', userID, code); + criteria.code = code; + var writeResult = db.prepaids.insert(criteria); + updateCount += writeResult.nInserted; + } + else { + print('ERROR: Already has trial request headcount', userID, criteria.properties.trialRequestID); + print('Trial course headcount prepaids inserted:', updateCount); + return; + } + + if (updateCount < 500 && needsHeadcount.length > 0) { + insertHeadCount(needsHeadcount.pop()); + } + else { + print('Trial course headcount prepaids inserted:', updateCount); + } + }); + } + + if (needsHeadcount.length > 0) { + insertHeadCount(needsHeadcount.pop()); + } +} + +function generateNewCode(done) +{ + function tryCode() { + code = createCode(8); + criteria = {code: code}; + if (db.prepaids.findOne(criteria)) { + return tryCode(); + } + return done(code); + } + tryCode(); +} + +function createCode(length) +{ + var text = ""; + var possible = "abcdefghijklmnopqrstuvwxyz0123456789"; + + for( var i=0; i < length; i++ ) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + + return text; +}