@dhyasama/totem-merge 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/cli.js +154 -0
- package/config.js +23 -0
- package/index.js +109 -0
- package/lib/changeBSON.js +22 -0
- package/lib/helpers.js +117 -0
- package/lib/organizations.js +408 -0
- package/lib/people.js +739 -0
- package/package.json +30 -0
- package/test/config.js +17 -0
- package/test/index.js +1159 -0
package/lib/people.js
ADDED
|
@@ -0,0 +1,739 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
let async = require('async');
|
|
4
|
+
let _ = require('underscore');
|
|
5
|
+
let helpers = require('./helpers');
|
|
6
|
+
let mongoose = require('mongoose');
|
|
7
|
+
let ObjectId = mongoose.Types.ObjectId;
|
|
8
|
+
|
|
9
|
+
var merge = function merge(context, target, source, mergedBy, customerId, cb) {
|
|
10
|
+
|
|
11
|
+
console.log('Merging people...');
|
|
12
|
+
|
|
13
|
+
// validate parameters
|
|
14
|
+
if (!context) return cb(new Error('context is required'), null);
|
|
15
|
+
if (!target) return cb(new Error('target is required'), null);
|
|
16
|
+
if (!source) return cb(new Error('source is required'), null);
|
|
17
|
+
if (!mergedBy) return cb(new Error('mergedBy is required'), null);
|
|
18
|
+
if (!cb) throw new Error('cb is required');
|
|
19
|
+
|
|
20
|
+
var savePerson = function(person, username, callback) {
|
|
21
|
+
|
|
22
|
+
console.log('Saving target person...');
|
|
23
|
+
console.log(' ID:', person._id.toString());
|
|
24
|
+
|
|
25
|
+
context.Person.upsert(person, username, function(err, result) {
|
|
26
|
+
return callback(err, result);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
if (context.flagOnly) {
|
|
32
|
+
|
|
33
|
+
var url = 'https://admin.totemvc.com/people/' + source.id;
|
|
34
|
+
var text = 'This person should be merged with ' + url;
|
|
35
|
+
|
|
36
|
+
context.Person.addFlag(target._id, target._id, text, customerId, function(err, result) {
|
|
37
|
+
if (err) return cb(err, null);
|
|
38
|
+
return cb(null, result);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
|
|
44
|
+
// mergedBy can be either an account or a username
|
|
45
|
+
var username = mergedBy.username ? mergedBy.username : mergedBy;
|
|
46
|
+
|
|
47
|
+
async.series([
|
|
48
|
+
|
|
49
|
+
// Create a snapshot of the target
|
|
50
|
+
helpers.createSnapshot.bind(null, context, 'Person', target, username),
|
|
51
|
+
|
|
52
|
+
// Create a snapshot of the source
|
|
53
|
+
helpers.createSnapshot.bind(null, context, 'Person', source, username),
|
|
54
|
+
|
|
55
|
+
// Merge the source into the target
|
|
56
|
+
mergeSourceIntoTarget.bind(null, target, source),
|
|
57
|
+
|
|
58
|
+
// Delete the source
|
|
59
|
+
// Do this prior to saving merged target in order to avoid unique key issues
|
|
60
|
+
helpers.removeEntity.bind(null, context, source),
|
|
61
|
+
|
|
62
|
+
// Save the updated target
|
|
63
|
+
savePerson.bind(null, target, username),
|
|
64
|
+
|
|
65
|
+
// Change source references to target
|
|
66
|
+
updateReferences.bind(null, context, target, source, mergedBy)
|
|
67
|
+
|
|
68
|
+
], function(err, results) {
|
|
69
|
+
|
|
70
|
+
if (err) return cb(err, null);
|
|
71
|
+
|
|
72
|
+
// result from savePerson
|
|
73
|
+
var updatedTarget = results[4];
|
|
74
|
+
|
|
75
|
+
// return updated target
|
|
76
|
+
return cb(null, updatedTarget);
|
|
77
|
+
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
var mergeSourceIntoTarget = function mergeEntities(target, source, cb) {
|
|
85
|
+
|
|
86
|
+
console.log('Merging source into target...');
|
|
87
|
+
|
|
88
|
+
var doNotMergeKeys = [
|
|
89
|
+
'merged',
|
|
90
|
+
'deleted',
|
|
91
|
+
'entered',
|
|
92
|
+
'__v',
|
|
93
|
+
'status',
|
|
94
|
+
'lps',
|
|
95
|
+
'subscriptions',
|
|
96
|
+
'account',
|
|
97
|
+
'sources'
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
var mergeSources = function mergeSources(target, source) {
|
|
101
|
+
|
|
102
|
+
// Note interaction counts are not combined here but will be updated on next calendar pull
|
|
103
|
+
|
|
104
|
+
var targetSources = target.sources || [];
|
|
105
|
+
var sourceSources = source.sources || [];
|
|
106
|
+
|
|
107
|
+
_.each(sourceSources, function(sourceSource) {
|
|
108
|
+
|
|
109
|
+
var match = _.find(targetSources, function(targetSource) {
|
|
110
|
+
return targetSource.customer.toString() === sourceSource.customer.toString() && targetSource.person.toString() === sourceSource.person.toString();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (!match) { targetSources.push(sourceSource); }
|
|
114
|
+
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
return targetSources;
|
|
118
|
+
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
helpers.mergeObjects(target, source, doNotMergeKeys);
|
|
122
|
+
|
|
123
|
+
target.sources = mergeSources(target, source);
|
|
124
|
+
|
|
125
|
+
// keep a list of copied people
|
|
126
|
+
target.addMerged(source.id);
|
|
127
|
+
|
|
128
|
+
// add copied person name as an alias if it's different from source name
|
|
129
|
+
if (target.name.full.toLowerCase() != source.name.full.toLowerCase()) {
|
|
130
|
+
target.aliases = target.aliases.concat([source.name.full]);
|
|
131
|
+
target.aliases = _.uniq(target.aliases);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// mark as entered by system
|
|
135
|
+
target.entered = {
|
|
136
|
+
by: 'ff-merge',
|
|
137
|
+
on: new Date()
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
return cb(null, target);
|
|
141
|
+
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// Flow control for updating references
|
|
145
|
+
// Takes us through updating each entity type
|
|
146
|
+
var updateReferences = function updateReferences(context, target, source, mergedBy, cb) {
|
|
147
|
+
|
|
148
|
+
console.log('Updating references...');
|
|
149
|
+
|
|
150
|
+
// validate parameters
|
|
151
|
+
if (!context) return cb(new Error('context is required'), null);
|
|
152
|
+
if (!target) return cb(new Error('target is required'), null);
|
|
153
|
+
if (!source) return cb(new Error('source is required'), null);
|
|
154
|
+
if (!cb) throw new Error('cb is required');
|
|
155
|
+
|
|
156
|
+
var oldPersonId = ObjectId(source.id);
|
|
157
|
+
var newPersonId = ObjectId(target.id);
|
|
158
|
+
|
|
159
|
+
console.log(' Target:', newPersonId.toString());
|
|
160
|
+
console.log(' Source:', oldPersonId.toString());
|
|
161
|
+
|
|
162
|
+
// mergedBy can be either an account or a username
|
|
163
|
+
var username = mergedBy.username ? mergedBy.username : mergedBy;
|
|
164
|
+
|
|
165
|
+
// Do not update cap tables or rounds as these are complicated
|
|
166
|
+
// and get cleaned and updated on each pull anyway
|
|
167
|
+
|
|
168
|
+
async.parallel([
|
|
169
|
+
|
|
170
|
+
updateDeals.bind(context, newPersonId, oldPersonId, mergedBy),
|
|
171
|
+
|
|
172
|
+
updateDocuments.bind(context, newPersonId, oldPersonId, null),
|
|
173
|
+
|
|
174
|
+
updateFlags.bind(context, newPersonId, oldPersonId, username),
|
|
175
|
+
|
|
176
|
+
updateInteractions.bind(context, newPersonId, oldPersonId, username),
|
|
177
|
+
|
|
178
|
+
updateLimitedPartners.bind(context, newPersonId, oldPersonId, mergedBy),
|
|
179
|
+
|
|
180
|
+
updateLists.bind(context, newPersonId, oldPersonId, null),
|
|
181
|
+
|
|
182
|
+
updateMessages.bind(context, newPersonId, oldPersonId, null),
|
|
183
|
+
|
|
184
|
+
updateNotes.bind(context, newPersonId, oldPersonId, username),
|
|
185
|
+
|
|
186
|
+
updateOrganizations.bind(context, newPersonId, oldPersonId, username),
|
|
187
|
+
|
|
188
|
+
updatePeople.bind(context, newPersonId, oldPersonId, username)
|
|
189
|
+
|
|
190
|
+
], cb);
|
|
191
|
+
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
var updateDeals = function updateDeals(newPersonId, oldPersonId, user, cb) {
|
|
195
|
+
|
|
196
|
+
console.log(' Updating deals...');
|
|
197
|
+
|
|
198
|
+
var self = this;
|
|
199
|
+
|
|
200
|
+
// Get all deals for this person
|
|
201
|
+
self.Deal.collection.find({ $or: [{ 'source.person': oldPersonId }, { 'referrer.person': oldPersonId }]}).toArray(function(err, items) {
|
|
202
|
+
|
|
203
|
+
if (err) return cb(err, null);
|
|
204
|
+
else if (!items || items.length === 0) return cb(null, []);
|
|
205
|
+
|
|
206
|
+
var tasks = [];
|
|
207
|
+
var updated = [];
|
|
208
|
+
|
|
209
|
+
_.each(items, function(item) {
|
|
210
|
+
|
|
211
|
+
var setObj = {};
|
|
212
|
+
|
|
213
|
+
if (item.source && item.source.person && item.source.person.toString() === oldPersonId.toString()) { setObj.source = { person: newPersonId }; }
|
|
214
|
+
if (item.referrer && item.referrer.person && item.referrer.person.toString() === oldPersonId.toString()) { setObj.referrer = { person: newPersonId }; }
|
|
215
|
+
|
|
216
|
+
tasks.push({
|
|
217
|
+
id: item._id,
|
|
218
|
+
update: { $set: setObj }
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
console.log(' Found ' + tasks.length + ' deal references to update');
|
|
224
|
+
|
|
225
|
+
var queue = async.queue(function(task, callback) {
|
|
226
|
+
self.Deal.modifyById(task.id, task.update, function(err, result) {
|
|
227
|
+
if (err) { return callback(err, null); }
|
|
228
|
+
else if (result) { updated.push(result); }
|
|
229
|
+
return callback(null, result);
|
|
230
|
+
});
|
|
231
|
+
}, 8);
|
|
232
|
+
|
|
233
|
+
queue.drain = function() { return cb(null, updated); };
|
|
234
|
+
|
|
235
|
+
queue.push(tasks);
|
|
236
|
+
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
var updateDocuments = function updateDocuments(newPersonId, oldPersonId, user, cb) {
|
|
242
|
+
|
|
243
|
+
console.log(' Updating docs...');
|
|
244
|
+
|
|
245
|
+
var self = this;
|
|
246
|
+
|
|
247
|
+
// Get all documents for this person
|
|
248
|
+
self.Document.collection.find({ $or: [{ 'source.person': oldPersonId }, { 'referrer.person': oldPersonId }]}).toArray(function(err, items) {
|
|
249
|
+
|
|
250
|
+
if (err) return cb(err, null);
|
|
251
|
+
else if (!items || items.length === 0) return cb(null, []);
|
|
252
|
+
|
|
253
|
+
var tasks = [];
|
|
254
|
+
var updated = [];
|
|
255
|
+
|
|
256
|
+
_.each(items, function(item) {
|
|
257
|
+
|
|
258
|
+
var setObj = {};
|
|
259
|
+
|
|
260
|
+
if (item.source && item.source.person && item.source.person.toString() === oldPersonId.toString()) { setObj.source = { person: newPersonId }; }
|
|
261
|
+
if (item.referrer && item.referrer.person && item.referrer.person.toString() === oldPersonId.toString()) { setObj.referrer = { person: newPersonId }; }
|
|
262
|
+
|
|
263
|
+
tasks.push({
|
|
264
|
+
id: item._id,
|
|
265
|
+
update: { $set: setObj }
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
console.log(' Found ' + tasks.length + ' doc references to update');
|
|
271
|
+
|
|
272
|
+
var queue = async.queue(function(task, callback) {
|
|
273
|
+
self.Document.modifyById(task.id, task.update, function(err, result) {
|
|
274
|
+
if (err) { return callback(err, null); }
|
|
275
|
+
else if (result) { updated.push(result); }
|
|
276
|
+
return callback(null, result);
|
|
277
|
+
});
|
|
278
|
+
}, 8);
|
|
279
|
+
|
|
280
|
+
queue.drain = function() { return cb(null, updated); };
|
|
281
|
+
|
|
282
|
+
queue.push(tasks);
|
|
283
|
+
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
var updateFlags = function updateFlags(newPersonId, oldPersonId, user, cb) {
|
|
289
|
+
|
|
290
|
+
console.log(' Updating flags...');
|
|
291
|
+
|
|
292
|
+
var self = this;
|
|
293
|
+
|
|
294
|
+
// Get all flags for this person
|
|
295
|
+
self.Flag.collection.find({ 'createdBy': oldPersonId }).toArray(function(err, items) {
|
|
296
|
+
|
|
297
|
+
if (err) return cb(err, null);
|
|
298
|
+
else if (!items || items.length === 0) return cb(null, []);
|
|
299
|
+
|
|
300
|
+
var tasks = [];
|
|
301
|
+
var updated = [];
|
|
302
|
+
|
|
303
|
+
_.each(items, function(item) {
|
|
304
|
+
|
|
305
|
+
var setObj = {};
|
|
306
|
+
|
|
307
|
+
if (item.createdBy.toString() === oldPersonId.toString()) { setObj.createdBy = newPersonId; }
|
|
308
|
+
|
|
309
|
+
tasks.push({
|
|
310
|
+
id: item._id,
|
|
311
|
+
update: { $set: setObj }
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
console.log(' Found ' + tasks.length + ' flag references to update');
|
|
317
|
+
|
|
318
|
+
var queue = async.queue(function(task, callback) {
|
|
319
|
+
self.Flag.modifyById(task.id, task.update, function(err, result) {
|
|
320
|
+
if (err) { return callback(err, null); }
|
|
321
|
+
else if (result) { updated.push(result); }
|
|
322
|
+
return callback(null, result);
|
|
323
|
+
});
|
|
324
|
+
}, 8);
|
|
325
|
+
|
|
326
|
+
queue.drain = function() { return cb(null, updated); };
|
|
327
|
+
|
|
328
|
+
queue.push(tasks);
|
|
329
|
+
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
var updateInteractions = function updateInteractions(newPersonId, oldPersonId, user, cb) {
|
|
335
|
+
|
|
336
|
+
console.log(' Updating interactions...');
|
|
337
|
+
|
|
338
|
+
var self = this;
|
|
339
|
+
|
|
340
|
+
// Get all interactions for this person
|
|
341
|
+
self.Interaction.collection.find({ $or: [{ 'attendees.external': oldPersonId }, { 'attendees.internal': oldPersonId }] }).toArray(function(err, items) {
|
|
342
|
+
|
|
343
|
+
if (err) return cb(err, null);
|
|
344
|
+
else if (!items || items.length === 0) return cb(null, []);
|
|
345
|
+
|
|
346
|
+
var tasks = [];
|
|
347
|
+
var updated = [];
|
|
348
|
+
|
|
349
|
+
_.each(items, function(item) {
|
|
350
|
+
|
|
351
|
+
item.attendees.internal = _.map(item.attendees.internal, function(attendee) {
|
|
352
|
+
if (attendee.toString() === oldPersonId.toString()) { attendee = newPersonId; }
|
|
353
|
+
return attendee;
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
item.attendees.external = _.map(item.attendees.external, function(attendee) {
|
|
357
|
+
if (attendee.toString() === oldPersonId.toString()) { attendee = newPersonId; }
|
|
358
|
+
return attendee;
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
tasks.push({
|
|
362
|
+
id: item._id,
|
|
363
|
+
update: { $set: {
|
|
364
|
+
'attendees.internal': item.attendees.internal,
|
|
365
|
+
'attendees.external': item.attendees.external
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
console.log(' Found ' + tasks.length + ' interaction references to update');
|
|
373
|
+
|
|
374
|
+
var queue = async.queue(function(task, callback) {
|
|
375
|
+
self.Interaction.modifyById(task.id, task.update, function(err, result) {
|
|
376
|
+
if (err) { return callback(err, null); }
|
|
377
|
+
else if (result) { updated.push(result); }
|
|
378
|
+
return callback(null, result);
|
|
379
|
+
});
|
|
380
|
+
}, 8);
|
|
381
|
+
|
|
382
|
+
queue.drain = function() { return cb(null, updated); };
|
|
383
|
+
|
|
384
|
+
queue.push(tasks);
|
|
385
|
+
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
var updateLimitedPartners = function updateLimitedPartners(newPersonId, oldPersonId, user, cb) {
|
|
391
|
+
|
|
392
|
+
console.log(' Updating lps...');
|
|
393
|
+
|
|
394
|
+
var self = this;
|
|
395
|
+
|
|
396
|
+
// Get all lps for this person
|
|
397
|
+
self.LimitedPartner.collection.find({ 'people': oldPersonId }).toArray(function(err, items) {
|
|
398
|
+
|
|
399
|
+
if (err) return cb(err, null);
|
|
400
|
+
else if (!items || items.length === 0) return cb(null, []);
|
|
401
|
+
|
|
402
|
+
var tasks = [];
|
|
403
|
+
var updated = [];
|
|
404
|
+
|
|
405
|
+
_.each(items, function(item) {
|
|
406
|
+
|
|
407
|
+
item.people = _.map(item.people, function(person) {
|
|
408
|
+
if (person.toString() === oldPersonId.toString()) { person = newPersonId; }
|
|
409
|
+
return person;
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
tasks.push({
|
|
413
|
+
id: item._id,
|
|
414
|
+
update: { $set: {
|
|
415
|
+
'people': item.people
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
console.log(' Found ' + tasks.length + ' lp references to update');
|
|
423
|
+
|
|
424
|
+
var queue = async.queue(function(task, callback) {
|
|
425
|
+
self.LimitedPartner.modifyById(task.id, task.update, function(err, result) {
|
|
426
|
+
if (err) { return callback(err, null); }
|
|
427
|
+
else if (result) { updated.push(result); }
|
|
428
|
+
return callback(null, result);
|
|
429
|
+
});
|
|
430
|
+
}, 8);
|
|
431
|
+
|
|
432
|
+
queue.drain = function() { return cb(null, updated); };
|
|
433
|
+
|
|
434
|
+
queue.push(tasks);
|
|
435
|
+
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
var updateLists = function updateLists(newPersonId, oldPersonId, user, cb) {
|
|
441
|
+
|
|
442
|
+
console.log(' Updating lists...');
|
|
443
|
+
|
|
444
|
+
var self = this;
|
|
445
|
+
|
|
446
|
+
// Get all lists for this person
|
|
447
|
+
self.List.collection.find({ $or: [{ 'people': oldPersonId }, { 'createdBy': oldPersonId }] }).toArray(function(err, items) {
|
|
448
|
+
|
|
449
|
+
if (err) return cb(err, null);
|
|
450
|
+
else if (!items || items.length === 0) return cb(null, []);
|
|
451
|
+
|
|
452
|
+
var tasks = [];
|
|
453
|
+
var updated = [];
|
|
454
|
+
|
|
455
|
+
_.each(items, function(item) {
|
|
456
|
+
|
|
457
|
+
var setObj = {};
|
|
458
|
+
|
|
459
|
+
if (item.createdBy.toString() === oldPersonId.toString()) { setObj.createdBy = newPersonId; }
|
|
460
|
+
|
|
461
|
+
setObj.people = _.map(item.people, function(person) {
|
|
462
|
+
if (person.toString() === oldPersonId.toString()) { person = newPersonId; }
|
|
463
|
+
return person;
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
tasks.push({
|
|
467
|
+
id: item._id,
|
|
468
|
+
update: { $set: setObj }
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
console.log(' Found ' + tasks.length + ' list references to update');
|
|
474
|
+
|
|
475
|
+
var queue = async.queue(function(task, callback) {
|
|
476
|
+
self.List.modifyById(task.id, task.update, function(err, result) {
|
|
477
|
+
if (err) { return callback(err, null); }
|
|
478
|
+
else if (result) { updated.push(result); }
|
|
479
|
+
return callback(null, result);
|
|
480
|
+
});
|
|
481
|
+
}, 8);
|
|
482
|
+
|
|
483
|
+
queue.drain = function() { return cb(null, updated); };
|
|
484
|
+
|
|
485
|
+
queue.push(tasks);
|
|
486
|
+
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
var updateMessages = function updateMessages(newPersonId, oldPersonId, user, cb) {
|
|
492
|
+
|
|
493
|
+
console.log(' Updating messages...');
|
|
494
|
+
|
|
495
|
+
var self = this;
|
|
496
|
+
|
|
497
|
+
// Get all messages for this person
|
|
498
|
+
self.Message.collection.find({ $or: [{ 'recipients.external': oldPersonId }, { 'recipients.internal': oldPersonId }] }).toArray(function(err, items) {
|
|
499
|
+
|
|
500
|
+
if (err) return cb(err, null);
|
|
501
|
+
else if (!items || items.length === 0) return cb(null, []);
|
|
502
|
+
|
|
503
|
+
var tasks = [];
|
|
504
|
+
var updated = [];
|
|
505
|
+
|
|
506
|
+
_.each(items, function(item) {
|
|
507
|
+
|
|
508
|
+
item.recipients.internal = _.map(item.recipients.internal, function(recipient) {
|
|
509
|
+
if (recipient.toString() === oldPersonId.toString()) { recipient = newPersonId; }
|
|
510
|
+
return recipient;
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
item.recipients.external = _.map(item.recipients.external, function(recipient) {
|
|
514
|
+
if (recipient.toString() === oldPersonId.toString()) { recipient = newPersonId; }
|
|
515
|
+
return recipient;
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
tasks.push({
|
|
519
|
+
id: item._id,
|
|
520
|
+
update: { $set: {
|
|
521
|
+
'recipients.internal': item.recipients.internal,
|
|
522
|
+
'recipients.external': item.recipients.external
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
console.log(' Found ' + tasks.length + ' message references to update');
|
|
530
|
+
|
|
531
|
+
var queue = async.queue(function(task, callback) {
|
|
532
|
+
self.Message.modifyById(task.id, task.update, function(err, result) {
|
|
533
|
+
if (err) { return callback(err, null); }
|
|
534
|
+
else if (result) { updated.push(result); }
|
|
535
|
+
return callback(null, result);
|
|
536
|
+
});
|
|
537
|
+
}, 8);
|
|
538
|
+
|
|
539
|
+
queue.drain = function() { return cb(null, updated); };
|
|
540
|
+
|
|
541
|
+
queue.push(tasks);
|
|
542
|
+
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
var updateNotes = function updateNotes(newPersonId, oldPersonId, user, cb) {
|
|
548
|
+
|
|
549
|
+
console.log(' Updating notes...');
|
|
550
|
+
|
|
551
|
+
var self = this;
|
|
552
|
+
|
|
553
|
+
// Get all notes for this person
|
|
554
|
+
self.Note.collection.find({ 'createdBy': oldPersonId }).toArray(function(err, items) {
|
|
555
|
+
|
|
556
|
+
if (err) return cb(err, null);
|
|
557
|
+
else if (!items || items.length === 0) return cb(null, []);
|
|
558
|
+
|
|
559
|
+
var tasks = [];
|
|
560
|
+
var updated = [];
|
|
561
|
+
|
|
562
|
+
_.each(items, function(item) {
|
|
563
|
+
|
|
564
|
+
var setObj = {};
|
|
565
|
+
|
|
566
|
+
if (item.createdBy.toString() === oldPersonId.toString()) { setObj.createdBy = newPersonId; }
|
|
567
|
+
|
|
568
|
+
tasks.push({
|
|
569
|
+
id: item._id,
|
|
570
|
+
update: { $set: setObj }
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
console.log(' Found ' + tasks.length + ' note references to update');
|
|
576
|
+
|
|
577
|
+
var queue = async.queue(function(task, callback) {
|
|
578
|
+
self.Note.modifyById(task.id, task.update, function(err, result) {
|
|
579
|
+
if (err) { return callback(err, null); }
|
|
580
|
+
else if (result) { updated.push(result); }
|
|
581
|
+
return callback(null, result);
|
|
582
|
+
});
|
|
583
|
+
}, 8);
|
|
584
|
+
|
|
585
|
+
queue.drain = function() { return cb(null, updated); };
|
|
586
|
+
|
|
587
|
+
queue.push(tasks);
|
|
588
|
+
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
var updateOrganizations = function updateOrganizations(newPersonId, oldPersonId, user, cb) {
|
|
594
|
+
|
|
595
|
+
console.log(' Updating orgs...');
|
|
596
|
+
|
|
597
|
+
var self = this;
|
|
598
|
+
|
|
599
|
+
// Get all orgs for this person
|
|
600
|
+
self.Organization.collection.find({ $or: [{ 'people.person': oldPersonId }, { 'chair.first': oldPersonId }, { 'chair.second': oldPersonId }] }).toArray(function(err, orgs) {
|
|
601
|
+
|
|
602
|
+
if (err) return cb(err, null);
|
|
603
|
+
else if (!orgs || orgs.length === 0) return cb(null, []);
|
|
604
|
+
|
|
605
|
+
var tasks = [];
|
|
606
|
+
var updated = [];
|
|
607
|
+
|
|
608
|
+
var checkIfBothPeopleAtOrg = function checkIfBothPeopleAtOrg(org) {
|
|
609
|
+
|
|
610
|
+
// if we blindly mapped the old person to the new person when they are both at the same org, then we'd end up
|
|
611
|
+
// with something like this:
|
|
612
|
+
//
|
|
613
|
+
// [ {
|
|
614
|
+
// person: 5cacc6238d38a6f68bf53c95,
|
|
615
|
+
// board: 'none',
|
|
616
|
+
// public: true,
|
|
617
|
+
// leader: false,
|
|
618
|
+
// current: true,
|
|
619
|
+
// title: 'CEO'
|
|
620
|
+
// },
|
|
621
|
+
// {
|
|
622
|
+
// person: 5cacc6238d38a6f68bf53c95,
|
|
623
|
+
// board: 'none',
|
|
624
|
+
// public: true,
|
|
625
|
+
// leader: false,
|
|
626
|
+
// current: true,
|
|
627
|
+
// title: 'CTO'
|
|
628
|
+
// }
|
|
629
|
+
// ]
|
|
630
|
+
//
|
|
631
|
+
// and be unable to determine which data to keep. We still can't know for sure, but let's default to keeping the
|
|
632
|
+
// target/new person's data. We do that by removing the source/old person here and then map the target/new person id.
|
|
633
|
+
|
|
634
|
+
var oldPerson = _.find(org.people, function(person) { return person.person.toString() === oldPersonId.toString(); });
|
|
635
|
+
var newPerson = _.find(org.people, function(person) { return person.person.toString() === newPersonId.toString(); });
|
|
636
|
+
|
|
637
|
+
// Both people are at this org
|
|
638
|
+
if (oldPerson && newPerson) {
|
|
639
|
+
org.people = _.reject(org.people, function(person) {
|
|
640
|
+
return person.person.toString() === oldPersonId.toString();
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
};
|
|
645
|
+
|
|
646
|
+
_.each(orgs, function(org) {
|
|
647
|
+
|
|
648
|
+
var setObj = {};
|
|
649
|
+
|
|
650
|
+
// keep the target info and remove the source if at the same org
|
|
651
|
+
// note this must be done before mapping the old id to the new id
|
|
652
|
+
checkIfBothPeopleAtOrg(org);
|
|
653
|
+
|
|
654
|
+
setObj.people = _.map(org.people, function(person) {
|
|
655
|
+
if (person.person.toString() === oldPersonId.toString()) { person.person = newPersonId; }
|
|
656
|
+
return person;
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
setObj.chairs = _.map(org.chairs, function(chair) {
|
|
660
|
+
if (chair.first && chair.first.toString() === oldPersonId.toString()) { chair.first = newPersonId; }
|
|
661
|
+
if (chair.second && chair.second.toString() === oldPersonId.toString()) { chair.second = newPersonId; }
|
|
662
|
+
return chair;
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
tasks.push({
|
|
666
|
+
id: org._id,
|
|
667
|
+
update: { $set: setObj }
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
console.log(' Found ' + tasks.length + ' org references to update');
|
|
673
|
+
|
|
674
|
+
var queue = async.queue(function(task, callback) {
|
|
675
|
+
self.Organization.modifyById(task.id, task.update, function(err, result) {
|
|
676
|
+
if (err) { return callback(err, null); }
|
|
677
|
+
else if (result) { updated.push(result); }
|
|
678
|
+
return callback(null, result);
|
|
679
|
+
});
|
|
680
|
+
}, 8);
|
|
681
|
+
|
|
682
|
+
queue.drain = function() { return cb(null, updated); };
|
|
683
|
+
|
|
684
|
+
queue.push(tasks);
|
|
685
|
+
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
var updatePeople = function updatePeople(newPersonId, oldPersonId, user, cb) {
|
|
691
|
+
|
|
692
|
+
console.log(' Updating people...');
|
|
693
|
+
|
|
694
|
+
var self = this;
|
|
695
|
+
|
|
696
|
+
// Get all orgs for this person
|
|
697
|
+
self.Organization.collection.find({ 'related': oldPersonId }).toArray(function(err, items) {
|
|
698
|
+
|
|
699
|
+
if (err) return cb(err, null);
|
|
700
|
+
else if (!items || items.length === 0) return cb(null, []);
|
|
701
|
+
|
|
702
|
+
var tasks = [];
|
|
703
|
+
var updated = [];
|
|
704
|
+
|
|
705
|
+
_.each(items, function(item) {
|
|
706
|
+
|
|
707
|
+
var setObj = {};
|
|
708
|
+
|
|
709
|
+
setObj.related = _.map(item.related, function(person) {
|
|
710
|
+
if (person.toString() === oldPersonId.toString()) { person = newPersonId; }
|
|
711
|
+
return person;
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
tasks.push({
|
|
715
|
+
id: item._id,
|
|
716
|
+
update: { $set: setObj }
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
console.log(' Found ' + tasks.length + ' person references to update');
|
|
722
|
+
|
|
723
|
+
var queue = async.queue(function(task, callback) {
|
|
724
|
+
self.Organization.modifyById(task.id, task.update, function(err, result) {
|
|
725
|
+
if (err) { return callback(err, null); }
|
|
726
|
+
else if (result) { updated.push(result); }
|
|
727
|
+
return callback(null, result);
|
|
728
|
+
});
|
|
729
|
+
}, 8);
|
|
730
|
+
|
|
731
|
+
queue.drain = function() { return cb(null, updated); };
|
|
732
|
+
|
|
733
|
+
queue.push(tasks);
|
|
734
|
+
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
};
|
|
738
|
+
|
|
739
|
+
module.exports.merge = merge;
|