@dhyasama/totem-merge 7.0.3 → 7.1.0
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/index.js +0 -6
- package/lib/helpers.js +16 -2
- package/lib/organizations.js +34 -50
- package/lib/people.js +24 -39
- package/package.json +1 -1
- package/test/index.js +0 -50
package/index.js
CHANGED
|
@@ -23,12 +23,6 @@ var Merge = function(mongoose, config) {
|
|
|
23
23
|
this.Round = mongoose.model('Round');
|
|
24
24
|
this.Snapshot = mongoose.model('Snapshot');
|
|
25
25
|
|
|
26
|
-
// can choose to flag an entity as needing to be merged rather than actually merging it
|
|
27
|
-
// particularly useful for automated processes, e.g., a batch import that detects dupes
|
|
28
|
-
// but you don't want to auto-merge 1000 records
|
|
29
|
-
// defaults to false
|
|
30
|
-
this.flagOnly = config.flag == true ? true : false;
|
|
31
|
-
|
|
32
26
|
// turn on debug if in development and not explicitly turned off
|
|
33
27
|
mongoose.set('debug', (!config.suppressDebugLog && this.env == 'development'));
|
|
34
28
|
|
package/lib/helpers.js
CHANGED
|
@@ -70,12 +70,26 @@ var mergeObjects = function mergeObjects(target, source, doNotMergeKeys) {
|
|
|
70
70
|
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
-
var removeEntity = module.exports.removeEntity = function removeEntity(context, entity, cb) {
|
|
73
|
+
var removeEntity = module.exports.removeEntity = function removeEntity(context, modelName, entity, cb) {
|
|
74
74
|
|
|
75
75
|
context.logger.writeToInfoLog('Removing entity - ' + entity._id.toString());
|
|
76
76
|
|
|
77
|
-
entity
|
|
77
|
+
// entity may be a Mongoose document or a lean POJO (e.g. from Person.getById which uses .lean())
|
|
78
|
+
if (typeof entity.deleteOne === 'function') {
|
|
79
|
+
entity.deleteOne().then(function() { cb(null, entity); }).catch(cb);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
context[modelName].deleteOne({ _id: entity._id }).then(function() { cb(null, entity); }).catch(cb);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
};
|
|
78
86
|
|
|
87
|
+
// Add source id to target.merged, deduped. Works on POJOs and Mongoose docs alike.
|
|
88
|
+
var addMerged = module.exports.addMerged = function addMerged(target, sourceId) {
|
|
89
|
+
target.merged = target.merged || [];
|
|
90
|
+
var sourceIdStr = sourceId.toString();
|
|
91
|
+
var alreadyMerged = _.some(target.merged, function(m) { return m && m.toString() === sourceIdStr; });
|
|
92
|
+
if (!alreadyMerged) { target.merged = target.merged.concat([sourceId]); }
|
|
79
93
|
};
|
|
80
94
|
|
|
81
95
|
// Used for determining if need to dive in recursively
|
package/lib/organizations.js
CHANGED
|
@@ -32,70 +32,54 @@ var merge = function merge(context, target, source, mergedBy, customerId, cb) {
|
|
|
32
32
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
var text = 'This org should be merged with ' + url;
|
|
39
|
-
|
|
40
|
-
context.Organization.addFlag(target._id, target._id, text, customerId, function(err, result) {
|
|
41
|
-
if (err) return cb(err, null);
|
|
42
|
-
return cb(null, result);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
else {
|
|
48
|
-
|
|
49
|
-
// mergedBy can be either an account or a username
|
|
50
|
-
var username = mergedBy.username ? mergedBy.username : mergedBy;
|
|
51
|
-
logger.writeToInfoLog('Username: ' + username);
|
|
52
|
-
|
|
53
|
-
async.series([
|
|
35
|
+
// mergedBy can be either an account or a username
|
|
36
|
+
var username = mergedBy.username ? mergedBy.username : mergedBy;
|
|
37
|
+
logger.writeToInfoLog('Username: ' + username);
|
|
54
38
|
|
|
55
|
-
|
|
39
|
+
async.series([
|
|
56
40
|
|
|
57
|
-
|
|
58
|
-
helpers.createSnapshot.bind(null, context, 'Organization', target, username),
|
|
41
|
+
verifyOkToMerge.bind(null, target, source),
|
|
59
42
|
|
|
60
|
-
|
|
61
|
-
|
|
43
|
+
// Create a snapshot of the target
|
|
44
|
+
helpers.createSnapshot.bind(null, context, 'Organization', target, username),
|
|
62
45
|
|
|
63
|
-
|
|
64
|
-
|
|
46
|
+
// Create a snapshot of the source
|
|
47
|
+
helpers.createSnapshot.bind(null, context, 'Organization', source, username),
|
|
65
48
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
helpers.removeEntity.bind(null, context, source),
|
|
49
|
+
// Merge the source into the target
|
|
50
|
+
mergeSourceIntoTarget.bind(null, target, source),
|
|
69
51
|
|
|
70
|
-
|
|
71
|
-
|
|
52
|
+
// Delete the source
|
|
53
|
+
// Do this prior to saving merged target in order to avoid unique key issues
|
|
54
|
+
helpers.removeEntity.bind(null, context, 'Organization', source),
|
|
72
55
|
|
|
73
|
-
|
|
74
|
-
|
|
56
|
+
// Save the updated target
|
|
57
|
+
saveOrganization.bind(null, target, username),
|
|
75
58
|
|
|
76
|
-
|
|
59
|
+
// Change source references to target
|
|
60
|
+
updateReferences.bind(null, context, target, source, mergedBy, customerId)
|
|
77
61
|
|
|
78
|
-
|
|
62
|
+
], function(err, results) {
|
|
79
63
|
|
|
80
|
-
|
|
81
|
-
var updatedTarget = results[5];
|
|
64
|
+
if (err) { return cb(err, null); }
|
|
82
65
|
|
|
83
|
-
|
|
84
|
-
|
|
66
|
+
// result from saveOrganization
|
|
67
|
+
var updatedTarget = results[5];
|
|
85
68
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
var targetMatch = targetIdStr && _.find(updatedReferencesOrgs, function(o) {
|
|
89
|
-
return o && o.id && o.id.toString() === targetIdStr;
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// Return up to date target
|
|
93
|
-
if (targetMatch) { return cb(null, targetMatch); }
|
|
94
|
-
else { return cb(null, updatedTarget); }
|
|
69
|
+
// result from updateOrganizations within updateReferences
|
|
70
|
+
var updatedReferencesOrgs = results[6][5];
|
|
95
71
|
|
|
72
|
+
// Check if target had reference(s) updated
|
|
73
|
+
var targetIdStr = target.id && target.id.toString();
|
|
74
|
+
var targetMatch = targetIdStr && _.find(updatedReferencesOrgs, function(o) {
|
|
75
|
+
return o && o.id && o.id.toString() === targetIdStr;
|
|
96
76
|
});
|
|
97
77
|
|
|
98
|
-
|
|
78
|
+
// Return up to date target
|
|
79
|
+
if (targetMatch) { return cb(null, targetMatch); }
|
|
80
|
+
else { return cb(null, updatedTarget); }
|
|
81
|
+
|
|
82
|
+
});
|
|
99
83
|
|
|
100
84
|
};
|
|
101
85
|
|
|
@@ -113,7 +97,7 @@ var mergeSourceIntoTarget = function mergeEntities(target, source, cb) {
|
|
|
113
97
|
helpers.mergeObjects(target, source, doNotMergeKeys);
|
|
114
98
|
|
|
115
99
|
// keep a list of copied orgs
|
|
116
|
-
|
|
100
|
+
helpers.addMerged(target, source.id);
|
|
117
101
|
|
|
118
102
|
// add copied org name as an alias if it's different from source name
|
|
119
103
|
if (target.name.toLowerCase() != source.name.toLowerCase()) {
|
package/lib/people.js
CHANGED
|
@@ -28,56 +28,41 @@ var merge = function merge(context, target, source, mergedBy, customerId, cb) {
|
|
|
28
28
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
|
|
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;
|
|
31
|
+
// mergedBy can be either an account or a username
|
|
32
|
+
var username = mergedBy.username ? mergedBy.username : mergedBy;
|
|
46
33
|
|
|
47
|
-
|
|
34
|
+
async.series([
|
|
48
35
|
|
|
49
|
-
|
|
50
|
-
|
|
36
|
+
// Create a snapshot of the target
|
|
37
|
+
helpers.createSnapshot.bind(null, context, 'Person', target, username),
|
|
51
38
|
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
// Create a snapshot of the source
|
|
40
|
+
helpers.createSnapshot.bind(null, context, 'Person', source, username),
|
|
54
41
|
|
|
55
|
-
|
|
56
|
-
|
|
42
|
+
// Merge the source into the target
|
|
43
|
+
mergeSourceIntoTarget.bind(null, target, source),
|
|
57
44
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
45
|
+
// Delete the source
|
|
46
|
+
// Do this prior to saving merged target in order to avoid unique key issues
|
|
47
|
+
helpers.removeEntity.bind(null, context, 'Person', source),
|
|
61
48
|
|
|
62
|
-
|
|
63
|
-
|
|
49
|
+
// Save the updated target
|
|
50
|
+
savePerson.bind(null, target, username),
|
|
64
51
|
|
|
65
|
-
|
|
66
|
-
|
|
52
|
+
// Change source references to target
|
|
53
|
+
updateReferences.bind(null, context, target, source, mergedBy)
|
|
67
54
|
|
|
68
|
-
|
|
55
|
+
], function(err, results) {
|
|
69
56
|
|
|
70
|
-
|
|
57
|
+
if (err) return cb(err, null);
|
|
71
58
|
|
|
72
|
-
|
|
73
|
-
|
|
59
|
+
// result from savePerson
|
|
60
|
+
var updatedTarget = results[4];
|
|
74
61
|
|
|
75
|
-
|
|
76
|
-
|
|
62
|
+
// return updated target
|
|
63
|
+
return cb(null, updatedTarget);
|
|
77
64
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
65
|
+
});
|
|
81
66
|
|
|
82
67
|
};
|
|
83
68
|
|
|
@@ -121,7 +106,7 @@ var mergeSourceIntoTarget = function mergeEntities(target, source, cb) {
|
|
|
121
106
|
target.sources = mergeSources(target, source);
|
|
122
107
|
|
|
123
108
|
// keep a list of copied people
|
|
124
|
-
|
|
109
|
+
helpers.addMerged(target, source.id);
|
|
125
110
|
|
|
126
111
|
// add copied person name as an alias if it's different from source name
|
|
127
112
|
if (target.name.full.toLowerCase() != source.name.full.toLowerCase()) {
|
package/package.json
CHANGED
package/test/index.js
CHANGED
|
@@ -308,24 +308,8 @@ describe('Merge', function() {
|
|
|
308
308
|
|
|
309
309
|
describe('Orgs', function() {
|
|
310
310
|
|
|
311
|
-
it('Flags organization to be merged', function (done) {
|
|
312
|
-
|
|
313
|
-
config.flag = true;
|
|
314
|
-
merge = new Merge(mongoose, config);
|
|
315
|
-
|
|
316
|
-
merge.organizations(org2, org1, 'testy', customer._id, function(err, result) {
|
|
317
|
-
should.not.exist(err);
|
|
318
|
-
should.exist(result);
|
|
319
|
-
result.addedTo.flags.length.should.equal(1);
|
|
320
|
-
return done();
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
});
|
|
324
|
-
|
|
325
311
|
it('Merges organizations', function (done) {
|
|
326
312
|
|
|
327
|
-
// reset to not flag
|
|
328
|
-
config.flag = false;
|
|
329
313
|
merge = new Merge(mongoose, config);
|
|
330
314
|
|
|
331
315
|
Organization.upsert(org2, 'testy', function(err, result) {
|
|
@@ -362,8 +346,6 @@ describe('Merge', function() {
|
|
|
362
346
|
|
|
363
347
|
it('Merges organizations with different people', function (done) {
|
|
364
348
|
|
|
365
|
-
// reset to not flag
|
|
366
|
-
config.flag = false;
|
|
367
349
|
merge = new Merge(mongoose, config);
|
|
368
350
|
|
|
369
351
|
org4.people = [];
|
|
@@ -408,7 +390,6 @@ describe('Merge', function() {
|
|
|
408
390
|
|
|
409
391
|
it('Merges organizations with the same people', function (done) {
|
|
410
392
|
|
|
411
|
-
config.flag = false;
|
|
412
393
|
merge = new Merge(mongoose, config);
|
|
413
394
|
|
|
414
395
|
org2.people = [];
|
|
@@ -456,7 +437,6 @@ describe('Merge', function() {
|
|
|
456
437
|
|
|
457
438
|
it('Merges organizations when source has a deal', function (done) {
|
|
458
439
|
|
|
459
|
-
config.flag = false;
|
|
460
440
|
merge = new Merge(mongoose, config);
|
|
461
441
|
|
|
462
442
|
var deal = new Deal({
|
|
@@ -497,7 +477,6 @@ describe('Merge', function() {
|
|
|
497
477
|
|
|
498
478
|
it('Merges organizations when target has a list', function (done) {
|
|
499
479
|
|
|
500
|
-
config.flag = false;
|
|
501
480
|
merge = new Merge(mongoose, config);
|
|
502
481
|
|
|
503
482
|
var list = new List({
|
|
@@ -542,7 +521,6 @@ describe('Merge', function() {
|
|
|
542
521
|
|
|
543
522
|
it('Merges organizations when target has a message', function (done) {
|
|
544
523
|
|
|
545
|
-
config.flag = false;
|
|
546
524
|
merge = new Merge(mongoose, config);
|
|
547
525
|
|
|
548
526
|
var newOrg = new Organization();
|
|
@@ -599,7 +577,6 @@ describe('Merge', function() {
|
|
|
599
577
|
|
|
600
578
|
it('Merges organizations when target has news', function (done) {
|
|
601
579
|
|
|
602
|
-
config.flag = false;
|
|
603
580
|
merge = new Merge(mongoose, config);
|
|
604
581
|
|
|
605
582
|
var newOrg = new Organization();
|
|
@@ -650,7 +627,6 @@ describe('Merge', function() {
|
|
|
650
627
|
|
|
651
628
|
it('Will not merge customer', function (done) {
|
|
652
629
|
|
|
653
|
-
config.flag = false;
|
|
654
630
|
merge = new Merge(mongoose, config);
|
|
655
631
|
|
|
656
632
|
var newOrg = new Organization();
|
|
@@ -685,24 +661,8 @@ describe('Merge', function() {
|
|
|
685
661
|
|
|
686
662
|
describe('People', function() {
|
|
687
663
|
|
|
688
|
-
it('Flags person to be merged', function (done) {
|
|
689
|
-
|
|
690
|
-
config.flag = true;
|
|
691
|
-
merge = new Merge(mongoose, config);
|
|
692
|
-
|
|
693
|
-
merge.people(person2, person1, 'testy', customer._id, function(err, result) {
|
|
694
|
-
should.not.exist(err);
|
|
695
|
-
should.exist(result);
|
|
696
|
-
result.addedTo.flags.length.should.equal(1);
|
|
697
|
-
return done();
|
|
698
|
-
});
|
|
699
|
-
|
|
700
|
-
});
|
|
701
|
-
|
|
702
664
|
it('Merges people', function (done) {
|
|
703
665
|
|
|
704
|
-
// reset to not flag
|
|
705
|
-
config.flag = false;
|
|
706
666
|
merge = new Merge(mongoose, config);
|
|
707
667
|
|
|
708
668
|
merge.peopleById(person2.id, person1.id, 'testy', customer._id, function(err, result) {
|
|
@@ -723,8 +683,6 @@ describe('Merge', function() {
|
|
|
723
683
|
|
|
724
684
|
it('Merges people with different phone numbers', function (done) {
|
|
725
685
|
|
|
726
|
-
// reset to not flag
|
|
727
|
-
config.flag = false;
|
|
728
686
|
merge = new Merge(mongoose, config);
|
|
729
687
|
|
|
730
688
|
Person.getById(person2._id, { CUSTOMER_ID: customer._id }, function(err, result) {
|
|
@@ -831,8 +789,6 @@ describe('Merge', function() {
|
|
|
831
789
|
|
|
832
790
|
it('Merges two people that are referenced by same org', function (done) {
|
|
833
791
|
|
|
834
|
-
// reset to not flag
|
|
835
|
-
config.flag = false;
|
|
836
792
|
merge = new Merge(mongoose, config);
|
|
837
793
|
|
|
838
794
|
var myNewPerson1 = new Person();
|
|
@@ -955,8 +911,6 @@ describe('Merge', function() {
|
|
|
955
911
|
|
|
956
912
|
it('Merges two sources for same customer', function(done) {
|
|
957
913
|
|
|
958
|
-
// reset to not flag
|
|
959
|
-
config.flag = false;
|
|
960
914
|
merge = new Merge(mongoose, config);
|
|
961
915
|
|
|
962
916
|
var newPerson1 = new Person();
|
|
@@ -1013,8 +967,6 @@ describe('Merge', function() {
|
|
|
1013
967
|
|
|
1014
968
|
it('Merges same source for different customers', function(done) {
|
|
1015
969
|
|
|
1016
|
-
// reset to not flag
|
|
1017
|
-
config.flag = false;
|
|
1018
970
|
merge = new Merge(mongoose, config);
|
|
1019
971
|
|
|
1020
972
|
var newPerson1 = new Person();
|
|
@@ -1071,8 +1023,6 @@ describe('Merge', function() {
|
|
|
1071
1023
|
|
|
1072
1024
|
it('Merges two sources for two customers', function(done) {
|
|
1073
1025
|
|
|
1074
|
-
// reset to not flag
|
|
1075
|
-
config.flag = false;
|
|
1076
1026
|
merge = new Merge(mongoose, config);
|
|
1077
1027
|
|
|
1078
1028
|
var newPerson1 = new Person();
|