@dhyasama/totem-models 8.46.0 → 8.47.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/lib/Investment.js CHANGED
@@ -25,40 +25,14 @@ module.exports = function(mongoose, config) {
25
25
  // Used by Round to selectively populate
26
26
  customer: { type: Schema.ObjectId, ref: 'Organization', required: true, index: true },
27
27
 
28
- investmentDate: { type: Date, required: true },
29
- cost: { type: Number, default: 0 },
30
- costPlusInterest: { type: Number, default: 0 },
31
- pricePerShare: { type: Number, default: 0 },
32
-
33
- debt: { type: Boolean, default: false },
34
- debtType: {
35
- type: String,
36
- enum: [ 'Convertible Note', 'Convertible Promissory Note', 'Demand Note', 'Demand Promissory Note', 'SAFE', 'SAFT', 'SAFTE', 'KISS', null ],
37
- default: null,
38
- required: false,
39
- validate: {
40
- validator: function(v) {
41
- var self = this;
42
- if (v && v.length && self.debt == false) return false;
43
- else return true;
44
- },
45
- message: 'There is a debt type ({VALUE}) but debt is set to false! Either set debt to true or remove the debt type.'
46
- }
47
- },
48
-
49
- converted: { type: Boolean, default: false },
50
- convertedInto: {
51
- type: String,
52
- trim: true,
53
- validate: {
54
- validator: function(v) {
55
- var self = this;
56
- if (self.converted && (!v || v.length == 0)) return false;
57
- else return true;
58
- },
59
- message: 'The investments is marked as converted but a converted into value was not provided! Either set converted to false or provide a value for converted into.'
60
- }
61
- },
28
+ date: { type: Date, required: true },
29
+ investment: { type: Number, default: 0 },
30
+ unrealized: { type: Number, default: 0 },
31
+ realized: { type: Number, default: 0 },
32
+ raised: { type: Number, required: false },
33
+ premoney: { type: Number, required: false },
34
+ postmoney: { type: Number, required: false },
35
+ pricePerShare: { type: Number, required: false },
62
36
 
63
37
  // Catch-all for customer specific key-value pairs from sheet that aren't supported by our schema
64
38
  details: [{
@@ -66,38 +40,15 @@ module.exports = function(mongoose, config) {
66
40
  value: { type: Schema.Types.Mixed, required: true },
67
41
  format: { type: String, enum: [null, 'number', 'decimal', 'money', 'percentage', 'date']},
68
42
  _id: false
69
- }],
70
-
71
- // note these fields are duplicative at the round level
72
- // this is private data and will override the round level numbers where appropriate
73
- preMoneyValuation: { type: Number, default: 0 },
74
- postMoneyValuation: { type: Number, default: 0 },
75
- dollarsRaised: { type: Number, default: 0 },
76
- closingDate: { type: Date, default: null }
43
+ }]
77
44
 
78
45
  });
79
46
 
80
-
81
-
82
47
  ///////////////////////////////////////////////////////////////////////////////////////
83
48
  // VIRTUALS
84
49
  // Properties that are not persisted to the database
85
50
  ///////////////////////////////////////////////////////////////////////////////////////
86
51
 
87
- Investment.virtual('month').get(function () {
88
- var self = this;
89
- var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
90
- if (!self.investmentDate) return 'Unknown';
91
- else return monthNames[self.investmentDate.getMonth()];
92
- });
93
-
94
- Investment.virtual('year').get(function () {
95
- var self = this;
96
- if (!self.investmentDate) return 'Unknown';
97
- else return self.investmentDate.getFullYear();
98
- });
99
-
100
-
101
52
 
102
53
  //////////////////////////////////////////////////////
103
54
  // STATICS
@@ -179,6 +130,4 @@ module.exports = function(mongoose, config) {
179
130
 
180
131
  mongoose.model('Investment', Investment);
181
132
 
182
- };
183
-
184
-
133
+ };
package/lib/Round.js CHANGED
@@ -29,16 +29,6 @@ module.exports = function(mongoose, config) {
29
29
 
30
30
  roundName: { type: String, trim: true, required: true },
31
31
 
32
- // used when cap table round names are changed and need to be matched to investment data
33
- oldRoundName: { type: String, trim: true, default: null },
34
-
35
- // these three values are public and will be used in the absence of overriding private data
36
- // if private data exists (in the form of investments), the most recent investment data will be used
37
- preMoneyValuation: { type: Number, default: 0 },
38
- postMoneyValuation: { type: Number, default: 0 },
39
- dollarsRaised: { type: Number, default: 0 },
40
- closingDate: { type: Date, default: null },
41
-
42
32
  // People that participated in this round
43
33
  // This is a public list of people that invested
44
34
  // Use the addPerson method and removePerson static
@@ -65,11 +55,7 @@ module.exports = function(mongoose, config) {
65
55
  investments: [{ type: Schema.ObjectId, ref: 'Investment', required: false }],
66
56
 
67
57
  // computed from investments
68
- cost: { type: Number, default: 0 },
69
-
70
- // set at the vehicle level during investment pull
71
- fairValue: { type: Number, default: 0 },
72
- valuationDate: { type: Date, default: null },
58
+ investment: { type: Number, default: 0 },
73
59
  unrealized: { type: Number, default: 0 },
74
60
  realized: { type: Number, default: 0 },
75
61
 
@@ -79,8 +65,6 @@ module.exports = function(mongoose, config) {
79
65
 
80
66
  });
81
67
 
82
-
83
-
84
68
  ///////////////////////////////////////////////////////////////////////////////////////
85
69
  // HELPERS
86
70
  ///////////////////////////////////////////////////////////////////////////////////////
@@ -93,15 +77,15 @@ module.exports = function(mongoose, config) {
93
77
 
94
78
  var calculateOrgPerformance = function calculateOrgPerformance(org, rounds) {
95
79
 
96
- // sum the cost of each vehicle
97
- org.cost = _.reduce(rounds, function(memo, round) {
98
- var sum = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.cost; }, 0);
80
+ // sum the investment of each vehicle
81
+ org.investment = _.reduce(rounds, function(memo, round) {
82
+ var sum = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.investment; }, 0);
99
83
  return memo + sum;
100
84
  }, 0);
101
85
 
102
- // sum the fair value of each vehicle, i.e., the unrealized value
86
+ // sum the unrealized of each vehicle
103
87
  org.unrealized = _.reduce(rounds, function(memo, round) {
104
- var sum = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.fairValue; }, 0);
88
+ var sum = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.unrealized; }, 0);
105
89
  return memo + sum;
106
90
  }, 0);
107
91
 
@@ -112,7 +96,7 @@ module.exports = function(mongoose, config) {
112
96
  }, 0);
113
97
 
114
98
  // finally, calc the multiple
115
- org.multiple = org.cost > 0 ? (org.unrealized + org.realized) / org.cost : 0;
99
+ org.multiple = org.investment > 0 ? (org.unrealized + org.realized) / org.investment : 0;
116
100
 
117
101
  return org;
118
102
 
@@ -158,8 +142,6 @@ module.exports = function(mongoose, config) {
158
142
  contact: rounds[0].organization.contact,
159
143
  filters: rounds[0].organization.filters,
160
144
  status: rounds[0].organization.status,
161
- preMoneyValuation: rounds[0].preMoneyValuation,
162
- postMoneyValuation: rounds[0].postMoneyValuation,
163
145
  chairs: rounds[0].organization.chairs,
164
146
  funds: funds
165
147
  };
@@ -220,43 +202,19 @@ module.exports = function(mongoose, config) {
220
202
 
221
203
  };
222
204
 
223
-
224
-
225
205
  ///////////////////////////////////////////////////////////////////////////////////////
226
206
  // VIRTUALS
227
207
  // Properties that are not persisted to the database
228
208
  ///////////////////////////////////////////////////////////////////////////////////////
229
209
 
230
- Round.virtual('cost').get(function () {
231
- // sums the cost of all vehicles in the round
232
- var self = this;
233
- return _.reduce(self.vehicles, function(memo, vehicle) { return memo + vehicle.cost; }, 0);
234
- });
235
-
236
- Round.virtual('month').get(function () {
237
- var self = this;
238
- var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
239
- if (!self.closingDate) return 'Unknown';
240
- else return monthNames[self.closingDate.getMonth()];
241
- });
242
-
243
210
  Round.virtual('value').get(function () {
244
- // sums the value (fair or realized) of all vehicles in the round
211
+ // sums the value (realized and unrealized) of all vehicles in the round
245
212
  var self = this;
246
213
  return _.reduce(self.vehicles, function(memo, vehicle) {
247
- if (self.roundName === 'Proceeds') return memo + vehicle.realized; // proceeds are realized and do not have a fair value
248
- else return memo + vehicle.fairValue;
214
+ return memo + vehicle.unrealized + vehicle.realized;
249
215
  }, 0);
250
216
  });
251
217
 
252
- Round.virtual('year').get(function () {
253
- var self = this;
254
- if (!self.closingDate) return 'Unknown';
255
- else return self.closingDate.getFullYear();
256
- });
257
-
258
-
259
-
260
218
  ///////////////////////////////////////////////////////////////////////////////////////
261
219
  // METHODS
262
220
  //
@@ -315,7 +273,6 @@ module.exports = function(mongoose, config) {
315
273
 
316
274
  // If not, add it
317
275
  if (!match) vehicle.investments.push(investment);
318
- // note there is no need to compute vehicle cost as it is done during upsert
319
276
 
320
277
  };
321
278
 
@@ -366,9 +323,8 @@ module.exports = function(mongoose, config) {
366
323
  }
367
324
 
368
325
  data = data || {};
369
- data.fairValue = data.fairValue || 0;
326
+ data.unrealized = data.unrealized || 0;
370
327
  data.realized = data.realized || 0;
371
- data.valuationDate = data.valuationDate || null;
372
328
 
373
329
  // Check if vehicle is already added
374
330
  let vehicle = _.find(self.vehicles, function(v) {
@@ -378,18 +334,16 @@ module.exports = function(mongoose, config) {
378
334
 
379
335
  // update data on existing vehicle
380
336
  if (vehicle) {
381
- vehicle.fairValue = data.fairValue;
337
+ vehicle.unrealized = data.unrealized;
382
338
  vehicle.realized = data.realized;
383
- vehicle.valuationDate = data.valuationDate;
384
339
  }
385
340
  // create vehicle
386
341
  else {
387
342
  vehicle = {
388
343
  fund: fund,
389
344
  investments: [],
390
- fairValue: data.fairValue,
391
- realized: data.realized,
392
- valuationDate: data.valuationDate
345
+ unrealized: data.unrealized,
346
+ realized: data.realized
393
347
  };
394
348
  self.vehicles.push(vehicle);
395
349
  }
@@ -398,8 +352,6 @@ module.exports = function(mongoose, config) {
398
352
 
399
353
  };
400
354
 
401
-
402
-
403
355
  //////////////////////////////////////////////////////
404
356
  // STATICS
405
357
  // Statics operate on the entire collection
@@ -453,14 +405,13 @@ module.exports = function(mongoose, config) {
453
405
  // reverse chronological
454
406
  rounds = _.sortBy(rounds, function(r) {
455
407
 
456
- let date = r.closingDate;
457
-
458
- // use investment date in absence of closing date
459
- if (!date && r.vehicles.length && r.vehicles[0].investments.length) {
460
- date = r.vehicles[0].investments[0].investmentDate;
408
+ if (r.vehicles.length && r.vehicles[0].investments.length) {
409
+ return r.vehicles[0].investments[0].date;
461
410
  }
462
411
 
463
- return date;
412
+ else {
413
+ return false;
414
+ }
464
415
 
465
416
  }).reverse();
466
417
 
@@ -515,14 +466,13 @@ module.exports = function(mongoose, config) {
515
466
  // reverse chronological
516
467
  rounds = _.sortBy(rounds, function(r) {
517
468
 
518
- let date = r.closingDate;
519
-
520
- // use investment date in absence of closing date
521
- if (!date && r.vehicles.length && r.vehicles[0].investments.length) {
522
- date = r.vehicles[0].investments[0].investmentDate;
469
+ if (r.vehicles.length && r.vehicles[0].investments.length) {
470
+ return r.vehicles[0].investments[0].date;
523
471
  }
524
472
 
525
- return date;
473
+ else {
474
+ return false;
475
+ }
526
476
 
527
477
  }).reverse();
528
478
 
@@ -607,27 +557,27 @@ module.exports = function(mongoose, config) {
607
557
 
608
558
  // we now have all the rounds the fund has participated in with other fund information removed from each round
609
559
 
610
- let totalFundCost = _.reduce(rounds, function(memo, round) {
611
- let roundCost = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.cost; }, 0);
560
+ let totalInvestment = _.reduce(rounds, function(memo, round) {
561
+ let roundInvestment = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.investment; }, 0);
612
562
  return memo + roundCost;
613
563
  }, 0);
614
564
 
615
565
  let totalUnrealized = _.reduce(rounds, function(memo, round) {
616
- let roundValue = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.fairValue; }, 0);
617
- return memo + roundValue;
566
+ let roundUnrealized = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.unrealized; }, 0);
567
+ return memo + roundUnrealized;
618
568
  }, 0);
619
569
 
620
570
  let totalRealized = _.reduce(rounds, function(memo, round) {
621
- let roundValue = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.realized; }, 0);
622
- return memo + roundValue;
571
+ let roundRealized = _.reduce(round.vehicles, function(memo, vehicle) { return memo + vehicle.realized; }, 0);
572
+ return memo + roundRealized;
623
573
  }, 0);
624
574
 
625
575
  return cb(null, {
626
- cost: totalFundCost,
576
+ investment: totalInvestment,
627
577
  unrealized: totalUnrealized,
628
578
  realized: totalRealized,
629
579
  value: totalUnrealized + totalRealized,
630
- multiple: totalFundCost > 0 ? (totalUnrealized + totalRealized) / totalFundCost : 0
580
+ multiple: totalInvestment > 0 ? (totalUnrealized + totalRealized) / totalInvestment : 0
631
581
  });
632
582
 
633
583
  });
@@ -652,7 +602,7 @@ module.exports = function(mongoose, config) {
652
602
 
653
603
  let query = self.find({ 'vehicles.fund': fundId });
654
604
 
655
- query.select('organization vehicles preMoneyValuation postMoneyValuation');
605
+ query.select('organization vehicles');
656
606
  query.populate('organization', 'name slug logoUrl description contact filters status ipo closed acquired operating website websiteAliases');
657
607
  query.populate('vehicles.fund');
658
608
 
@@ -706,7 +656,7 @@ module.exports = function(mongoose, config) {
706
656
 
707
657
  let query = self.find({ 'vehicles.fund': { $in: fundIds } });
708
658
 
709
- query.select('organization vehicles preMoneyValuation postMoneyValuation');
659
+ query.select('organization vehicles');
710
660
  query.populate('organization', 'name slug logoUrl description contact chairs filters status ipo closed acquired operating website websiteAliases');
711
661
  query.deepPopulate([
712
662
  'organization.chairs.first',
@@ -879,26 +829,10 @@ module.exports = function(mongoose, config) {
879
829
  var investments = vehicle.investments;
880
830
 
881
831
  if (investments.length >= 1) {
882
- // sum cost of each investment
883
- vehicle.cost = _.reduce(investments, function(memo, investment){ return memo + investment.cost; }, 0);
832
+ vehicle.investment = _.reduce(investments, function(memo, investment) { return memo + investment.investment; }, 0);
884
833
  }
885
834
  else {
886
- // no investments = no cost
887
- vehicle.cost = 0;
888
- }
889
-
890
- // proceeds are special in that the cost is actually a realized gain
891
- if (doc.roundName == 'Proceeds') {
892
- vehicle.realized = vehicle.cost;
893
- vehicle.cost = 0;
894
- vehicle.unrealized = 0;
895
- vehicle.fairValue = 0;
896
- }
897
-
898
- // escrow is also special, except the gains are unrealized
899
- else if (doc.roundName === 'Escrow') {
900
- vehicle.unrealized = vehicle.fairValue - vehicle.cost;
901
- vehicle.realized = 0;
835
+ vehicle.investment = 0;
902
836
  }
903
837
 
904
838
  });
@@ -911,7 +845,7 @@ module.exports = function(mongoose, config) {
911
845
 
912
846
  result.populate({
913
847
  path: 'vehicles.investments',
914
- select: 'cost'
848
+ select: 'investment'
915
849
  }, function(err, doc) {
916
850
 
917
851
  if (err) return cb(err, null);
@@ -940,13 +874,6 @@ module.exports = function(mongoose, config) {
940
874
 
941
875
  // note participating people are public as there is no investment, i.e., private, data attached to them
942
876
 
943
- // note that public versions of the following data exist at this level:
944
- // preMoneyValuation
945
- // postMoneyValuation
946
- // amountRaised
947
- // closingDate
948
- // this data will be overwritten if private data belonging to the current customer is present
949
-
950
877
  // participating vehicles are public
951
878
  // merge private data that was matched for customer
952
879
 
@@ -954,17 +881,6 @@ module.exports = function(mongoose, config) {
954
881
  return vehicle.investments.length > 0;
955
882
  });
956
883
 
957
- let allInvestments = _.flatten(_.pluck(doc.vehicles, 'investments'));
958
- let mostRecentInvestment = _.max(allInvestments, function(investment) { return investment.investmentDate; });
959
-
960
- // if we have private data, use it rather than the public data
961
- if (mostRecentInvestment) {
962
- if (mostRecentInvestment.preMoneyValuation) { doc.preMoneyValuation = mostRecentInvestment.preMoneyValuation; }
963
- if (mostRecentInvestment.postMoneyValuation) { doc.postMoneyValuation = mostRecentInvestment.postMoneyValuation; }
964
- if (mostRecentInvestment.dollarsRaised) { doc.dollarsRaised = mostRecentInvestment.dollarsRaised; }
965
- if (mostRecentInvestment.closingDate) { doc.closingDate = mostRecentInvestment.closingDate; }
966
- }
967
-
968
884
  next();
969
885
 
970
886
  });
@@ -985,6 +901,4 @@ module.exports = function(mongoose, config) {
985
901
 
986
902
  mongoose.model('Round', Round);
987
903
 
988
- };
989
-
990
-
904
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhyasama/totem-models",
3
- "version": "8.46.0",
3
+ "version": "8.47.1",
4
4
  "author": "Jason Reynolds",
5
5
  "license": "UNLICENSED",
6
6
  "description": "Models for Totem platform",