@dhyasama/totem-models 8.47.1 → 8.49.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/lib/Investment.js +1 -6
- package/lib/Round.js +54 -158
- package/package.json +1 -1
package/lib/Investment.js
CHANGED
|
@@ -88,9 +88,8 @@ module.exports = function(mongoose, config) {
|
|
|
88
88
|
|
|
89
89
|
if (!investment) { return cb(new Error('investment is required'), null); }
|
|
90
90
|
investment.save(cb);
|
|
91
|
-
};
|
|
92
|
-
|
|
93
91
|
|
|
92
|
+
};
|
|
94
93
|
|
|
95
94
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
96
95
|
// HOOKS
|
|
@@ -103,8 +102,6 @@ module.exports = function(mongoose, config) {
|
|
|
103
102
|
|
|
104
103
|
var self = this;
|
|
105
104
|
|
|
106
|
-
if (self.debtType) self.debt = true;
|
|
107
|
-
|
|
108
105
|
return next();
|
|
109
106
|
|
|
110
107
|
});
|
|
@@ -116,8 +113,6 @@ module.exports = function(mongoose, config) {
|
|
|
116
113
|
});
|
|
117
114
|
});
|
|
118
115
|
|
|
119
|
-
|
|
120
|
-
|
|
121
116
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
122
117
|
// CONFIG
|
|
123
118
|
///////////////////////////////////////////////////////////////////////////////////////
|
package/lib/Round.js
CHANGED
|
@@ -54,14 +54,9 @@ module.exports = function(mongoose, config) {
|
|
|
54
54
|
// These references are removed by the Investment post-remove hook calling Round.removeInvestment
|
|
55
55
|
investments: [{ type: Schema.ObjectId, ref: 'Investment', required: false }],
|
|
56
56
|
|
|
57
|
-
// computed from investments
|
|
58
|
-
investment: { type: Number, default: 0 },
|
|
59
|
-
unrealized: { type: Number, default: 0 },
|
|
60
|
-
realized: { type: Number, default: 0 },
|
|
61
|
-
|
|
62
57
|
_id: false
|
|
63
58
|
|
|
64
|
-
}]
|
|
59
|
+
}],
|
|
65
60
|
|
|
66
61
|
});
|
|
67
62
|
|
|
@@ -69,38 +64,37 @@ module.exports = function(mongoose, config) {
|
|
|
69
64
|
// HELPERS
|
|
70
65
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
71
66
|
|
|
72
|
-
var
|
|
73
|
-
|
|
74
|
-
// Given a collection of rounds and funds, construct a portfolio of organizations
|
|
75
|
-
|
|
76
|
-
var portfolio = [];
|
|
67
|
+
var calculatePerformance = function calculatePerformance(rounds) {
|
|
77
68
|
|
|
78
|
-
var
|
|
69
|
+
var totalInvestment = 0;
|
|
70
|
+
var totalUnrealized = 0;
|
|
71
|
+
var totalRealized = 0;
|
|
79
72
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
73
|
+
_.each(rounds, function(round) {
|
|
74
|
+
_.each(round.vehicles, function(vehicle) {
|
|
75
|
+
_.each(vehicle.investments, function(investment) {
|
|
76
|
+
totalInvestment += investment.investment || 0;
|
|
77
|
+
totalUnrealized += investment.unrealized || 0;
|
|
78
|
+
totalRealized += investment.realized || 0;
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
85
82
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
83
|
+
// finally, calc the multiple
|
|
84
|
+
return {
|
|
85
|
+
investment: totalInvestment,
|
|
86
|
+
unrealized: totalUnrealized,
|
|
87
|
+
realized: totalRealized,
|
|
88
|
+
multiple: totalInvestment > 0 ? (totalUnrealized + totalRealized) / totalInvestment : 0
|
|
89
|
+
};
|
|
91
90
|
|
|
92
|
-
|
|
93
|
-
org.realized = _.reduce(rounds, function(memo, round) {
|
|
94
|
-
var sum = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.realized; }, 0);
|
|
95
|
-
return memo + sum;
|
|
96
|
-
}, 0);
|
|
91
|
+
};
|
|
97
92
|
|
|
98
|
-
|
|
99
|
-
org.multiple = org.investment > 0 ? (org.unrealized + org.realized) / org.investment : 0;
|
|
93
|
+
var buildPortfolio = function buildPortfolio(rounds, fundIds) {
|
|
100
94
|
|
|
101
|
-
|
|
95
|
+
// Given a collection of rounds and funds, construct a portfolio of organizations
|
|
102
96
|
|
|
103
|
-
|
|
97
|
+
var portfolio = [];
|
|
104
98
|
|
|
105
99
|
rounds = filterVehicles(rounds, fundIds);
|
|
106
100
|
|
|
@@ -146,7 +140,11 @@ module.exports = function(mongoose, config) {
|
|
|
146
140
|
funds: funds
|
|
147
141
|
};
|
|
148
142
|
|
|
149
|
-
|
|
143
|
+
var performance = calculatePerformance(rounds);
|
|
144
|
+
org.investment = performance.investment;
|
|
145
|
+
org.unrealized = performance.unrealized;
|
|
146
|
+
org.realized = performance.realized;
|
|
147
|
+
org.multiple = performance.multiple;
|
|
150
148
|
|
|
151
149
|
portfolio.push(org);
|
|
152
150
|
|
|
@@ -202,19 +200,6 @@ module.exports = function(mongoose, config) {
|
|
|
202
200
|
|
|
203
201
|
};
|
|
204
202
|
|
|
205
|
-
///////////////////////////////////////////////////////////////////////////////////////
|
|
206
|
-
// VIRTUALS
|
|
207
|
-
// Properties that are not persisted to the database
|
|
208
|
-
///////////////////////////////////////////////////////////////////////////////////////
|
|
209
|
-
|
|
210
|
-
Round.virtual('value').get(function () {
|
|
211
|
-
// sums the value (realized and unrealized) of all vehicles in the round
|
|
212
|
-
var self = this;
|
|
213
|
-
return _.reduce(self.vehicles, function(memo, vehicle) {
|
|
214
|
-
return memo + vehicle.unrealized + vehicle.realized;
|
|
215
|
-
}, 0);
|
|
216
|
-
});
|
|
217
|
-
|
|
218
203
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
219
204
|
// METHODS
|
|
220
205
|
//
|
|
@@ -227,7 +212,7 @@ module.exports = function(mongoose, config) {
|
|
|
227
212
|
// will add a bunch of things and then just get saved once.
|
|
228
213
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
229
214
|
|
|
230
|
-
Round.methods.addInvestment = function addInvestment(investment, fund
|
|
215
|
+
Round.methods.addInvestment = function addInvestment(investment, fund) {
|
|
231
216
|
|
|
232
217
|
// Add an investment reference
|
|
233
218
|
// Investment data is private
|
|
@@ -252,7 +237,7 @@ module.exports = function(mongoose, config) {
|
|
|
252
237
|
}
|
|
253
238
|
|
|
254
239
|
// Create or update
|
|
255
|
-
var vehicle = self.addVehicle(fund
|
|
240
|
+
var vehicle = self.addVehicle(fund);
|
|
256
241
|
var fid = mongoose.Types.ObjectId.isValid(vehicle.fund) ? vehicle.fund : vehicle.fund._id;
|
|
257
242
|
|
|
258
243
|
// The vehicle returned by addVehicle, appears to be a copy not a reference which is odd to me.
|
|
@@ -304,7 +289,7 @@ module.exports = function(mongoose, config) {
|
|
|
304
289
|
|
|
305
290
|
};
|
|
306
291
|
|
|
307
|
-
Round.methods.addVehicle = function addVehicle(fund
|
|
292
|
+
Round.methods.addVehicle = function addVehicle(fund) {
|
|
308
293
|
|
|
309
294
|
// Add a vehicle, which is a fund
|
|
310
295
|
// This data is public
|
|
@@ -322,10 +307,6 @@ module.exports = function(mongoose, config) {
|
|
|
322
307
|
if (!mongoose.Types.ObjectId.isValid(fund)) throw new Error('Need a valid fund objectid!');
|
|
323
308
|
}
|
|
324
309
|
|
|
325
|
-
data = data || {};
|
|
326
|
-
data.unrealized = data.unrealized || 0;
|
|
327
|
-
data.realized = data.realized || 0;
|
|
328
|
-
|
|
329
310
|
// Check if vehicle is already added
|
|
330
311
|
let vehicle = _.find(self.vehicles, function(v) {
|
|
331
312
|
let fundid = mongoose.Types.ObjectId.isValid(v.fund) ? v.fund : v.fund._id;
|
|
@@ -333,17 +314,10 @@ module.exports = function(mongoose, config) {
|
|
|
333
314
|
});
|
|
334
315
|
|
|
335
316
|
// update data on existing vehicle
|
|
336
|
-
if (vehicle) {
|
|
337
|
-
vehicle.unrealized = data.unrealized;
|
|
338
|
-
vehicle.realized = data.realized;
|
|
339
|
-
}
|
|
340
|
-
// create vehicle
|
|
341
|
-
else {
|
|
317
|
+
if (!vehicle) {
|
|
342
318
|
vehicle = {
|
|
343
319
|
fund: fund,
|
|
344
|
-
investments: []
|
|
345
|
-
unrealized: data.unrealized,
|
|
346
|
-
realized: data.realized
|
|
320
|
+
investments: []
|
|
347
321
|
};
|
|
348
322
|
self.vehicles.push(vehicle);
|
|
349
323
|
}
|
|
@@ -537,7 +511,7 @@ module.exports = function(mongoose, config) {
|
|
|
537
511
|
|
|
538
512
|
};
|
|
539
513
|
|
|
540
|
-
Round.statics.getFundPerformance = function getFundPerformance(fundId, cb) {
|
|
514
|
+
Round.statics.getFundPerformance = function getFundPerformance(fundId, options, cb) {
|
|
541
515
|
|
|
542
516
|
if (!cb) { throw new Error('cb is required'); }
|
|
543
517
|
if (!fundId) { throw new Error('fundId is required'); }
|
|
@@ -547,38 +521,28 @@ module.exports = function(mongoose, config) {
|
|
|
547
521
|
|
|
548
522
|
let query = self.find({ 'vehicles.fund': fundId });
|
|
549
523
|
|
|
524
|
+
query.select('organization vehicles');
|
|
525
|
+
query.populate('organization', 'name slug logoUrl description ');
|
|
526
|
+
query.populate('vehicles.fund');
|
|
527
|
+
|
|
528
|
+
if (options.isWorkerProcess) {
|
|
529
|
+
query.populate('vehicles.investments');
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
query.populate({
|
|
533
|
+
path: 'vehicles.investments',
|
|
534
|
+
match: { customer: options.CUSTOMER_ID }
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
|
|
550
538
|
query.exec(function(err, rounds) {
|
|
551
539
|
|
|
552
540
|
if (err) return cb(err, null);
|
|
553
541
|
else if (!rounds) return cb(null, null);
|
|
554
|
-
else if(rounds.length === 0) return cb(null, []);
|
|
542
|
+
else if (rounds.length === 0) return cb(null, []);
|
|
555
543
|
|
|
556
544
|
rounds = filterVehicles(rounds, [fundId]);
|
|
557
|
-
|
|
558
|
-
// we now have all the rounds the fund has participated in with other fund information removed from each round
|
|
559
|
-
|
|
560
|
-
let totalInvestment = _.reduce(rounds, function(memo, round) {
|
|
561
|
-
let roundInvestment = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.investment; }, 0);
|
|
562
|
-
return memo + roundCost;
|
|
563
|
-
}, 0);
|
|
564
|
-
|
|
565
|
-
let totalUnrealized = _.reduce(rounds, function(memo, round) {
|
|
566
|
-
let roundUnrealized = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.unrealized; }, 0);
|
|
567
|
-
return memo + roundUnrealized;
|
|
568
|
-
}, 0);
|
|
569
|
-
|
|
570
|
-
let totalRealized = _.reduce(rounds, function(memo, round) {
|
|
571
|
-
let roundRealized = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.realized; }, 0);
|
|
572
|
-
return memo + roundRealized;
|
|
573
|
-
}, 0);
|
|
574
|
-
|
|
575
|
-
return cb(null, {
|
|
576
|
-
investment: totalInvestment,
|
|
577
|
-
unrealized: totalUnrealized,
|
|
578
|
-
realized: totalRealized,
|
|
579
|
-
value: totalUnrealized + totalRealized,
|
|
580
|
-
multiple: totalInvestment > 0 ? (totalUnrealized + totalRealized) / totalInvestment : 0
|
|
581
|
-
});
|
|
545
|
+
return cb(null, calculatePerformance(rounds));
|
|
582
546
|
|
|
583
547
|
});
|
|
584
548
|
|
|
@@ -739,11 +703,6 @@ module.exports = function(mongoose, config) {
|
|
|
739
703
|
// The preferred way to delete an investment is to delete it directly and this
|
|
740
704
|
// reference will be cleaned up by the investment post-remove hook.
|
|
741
705
|
|
|
742
|
-
// Note that hooks don't work on updates so that makes this more complicated because our pre-save hook to compute
|
|
743
|
-
// cost won't work on a straight update. The workaround is to pull a list of round ids that will have the investment
|
|
744
|
-
// removed, call update to remove the investments from rounds, retrieve the updated rounds and save them which will
|
|
745
|
-
// trigger the pre-save hook and update the cost.
|
|
746
|
-
|
|
747
706
|
if (!cb) { throw new Error('cb is required'); }
|
|
748
707
|
if (!investmentId) { throw new Error('investmentId is required'); }
|
|
749
708
|
if (!mongoose.Types.ObjectId.isValid(investmentId)) { return cb(new Error('investmentId is not a valid ObjectId'), null); }
|
|
@@ -765,25 +724,9 @@ module.exports = function(mongoose, config) {
|
|
|
765
724
|
query.exec(callback);
|
|
766
725
|
};
|
|
767
726
|
|
|
768
|
-
let updateCost = function updateCost(previous, callback) {
|
|
769
|
-
|
|
770
|
-
let ids = _.pluck(previous, '_id');
|
|
771
|
-
let query = self.find({_id: { $in: ids }});
|
|
772
|
-
|
|
773
|
-
query.exec(function (err, docs) {
|
|
774
|
-
async.map(docs, function (doc, saveCallback) {
|
|
775
|
-
doc.save(function (err) {
|
|
776
|
-
saveCallback(err, doc);
|
|
777
|
-
});
|
|
778
|
-
}, callback);
|
|
779
|
-
});
|
|
780
|
-
|
|
781
|
-
};
|
|
782
|
-
|
|
783
727
|
async.waterfall([
|
|
784
728
|
getRounds,
|
|
785
|
-
updateRounds
|
|
786
|
-
updateCost
|
|
729
|
+
updateRounds
|
|
787
730
|
], cb);
|
|
788
731
|
|
|
789
732
|
};
|
|
@@ -819,45 +762,7 @@ module.exports = function(mongoose, config) {
|
|
|
819
762
|
Round.statics.upsert = function(round, cb) {
|
|
820
763
|
|
|
821
764
|
if (!round) { return cb(new Error('round is required'), null); }
|
|
822
|
-
|
|
823
|
-
const compute = function compute(doc) {
|
|
824
|
-
|
|
825
|
-
// compute for each vehicle
|
|
826
|
-
|
|
827
|
-
_.each(doc.vehicles, function(vehicle) {
|
|
828
|
-
|
|
829
|
-
var investments = vehicle.investments;
|
|
830
|
-
|
|
831
|
-
if (investments.length >= 1) {
|
|
832
|
-
vehicle.investment = _.reduce(investments, function(memo, investment) { return memo + investment.investment; }, 0);
|
|
833
|
-
}
|
|
834
|
-
else {
|
|
835
|
-
vehicle.investment = 0;
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
});
|
|
839
|
-
|
|
840
|
-
};
|
|
841
|
-
|
|
842
|
-
round.save(function(err, result) {
|
|
843
|
-
|
|
844
|
-
if (err) return cb(err, null);
|
|
845
|
-
|
|
846
|
-
result.populate({
|
|
847
|
-
path: 'vehicles.investments',
|
|
848
|
-
select: 'investment'
|
|
849
|
-
}, function(err, doc) {
|
|
850
|
-
|
|
851
|
-
if (err) return cb(err, null);
|
|
852
|
-
else if (!doc) return cb(null, null);
|
|
853
|
-
|
|
854
|
-
compute(doc);
|
|
855
|
-
|
|
856
|
-
round.save(cb);
|
|
857
|
-
|
|
858
|
-
});
|
|
859
|
-
|
|
860
|
-
});
|
|
765
|
+
round.save(cb);
|
|
861
766
|
|
|
862
767
|
};
|
|
863
768
|
|
|
@@ -872,15 +777,6 @@ module.exports = function(mongoose, config) {
|
|
|
872
777
|
|
|
873
778
|
if (!doc || !doc.vehicles) { return next(); }
|
|
874
779
|
|
|
875
|
-
// note participating people are public as there is no investment, i.e., private, data attached to them
|
|
876
|
-
|
|
877
|
-
// participating vehicles are public
|
|
878
|
-
// merge private data that was matched for customer
|
|
879
|
-
|
|
880
|
-
doc.vehicles = _.filter(doc.vehicles, function(vehicle) {
|
|
881
|
-
return vehicle.investments.length > 0;
|
|
882
|
-
});
|
|
883
|
-
|
|
884
780
|
next();
|
|
885
781
|
|
|
886
782
|
});
|