@dhyasama/totem-models 11.86.0 → 11.88.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/Financials.js +3 -0
- package/lib/Round.js +239 -11
- package/package.json +1 -1
package/lib/Financials.js
CHANGED
|
@@ -19,6 +19,9 @@ module.exports = function(mongoose, config) {
|
|
|
19
19
|
|
|
20
20
|
customer: { type: Schema.ObjectId, ref: 'Organization', required: true, index: true },
|
|
21
21
|
|
|
22
|
+
// the date the financial is as of (not the date added to our system)
|
|
23
|
+
asOfDate: { type: Date },
|
|
24
|
+
|
|
22
25
|
fiscal: {
|
|
23
26
|
month: { type: Number, default: 1 },
|
|
24
27
|
day: { type: Number, default: 1 },
|
package/lib/Round.js
CHANGED
|
@@ -258,16 +258,6 @@ module.exports = function(mongoose, config) {
|
|
|
258
258
|
// Statics operate on the entire collection
|
|
259
259
|
//////////////////////////////////////////////////////\
|
|
260
260
|
|
|
261
|
-
Round.statics.getAllOrgs = function getAllOrgs(cb) {
|
|
262
|
-
|
|
263
|
-
const self = this;
|
|
264
|
-
|
|
265
|
-
if (!cb) { throw new Error('cb is required'); }
|
|
266
|
-
|
|
267
|
-
self.distinct('organization', cb);
|
|
268
|
-
|
|
269
|
-
};
|
|
270
|
-
|
|
271
261
|
Round.statics.getByOrg = function getByOrg(orgId, options, cb) {
|
|
272
262
|
|
|
273
263
|
// Gets all the rounds an org has raised
|
|
@@ -351,7 +341,7 @@ module.exports = function(mongoose, config) {
|
|
|
351
341
|
'organization': { $in: orgIds }
|
|
352
342
|
});
|
|
353
343
|
|
|
354
|
-
query.populate('organization', 'name logoUrl website websiteAliases');
|
|
344
|
+
query.populate('organization', 'name logoUrl website websiteAliases operating');
|
|
355
345
|
query.populate('vehicles.fund');
|
|
356
346
|
|
|
357
347
|
if (options.isWorkerProcess) {
|
|
@@ -487,6 +477,74 @@ module.exports = function(mongoose, config) {
|
|
|
487
477
|
});
|
|
488
478
|
|
|
489
479
|
};
|
|
480
|
+
|
|
481
|
+
Round.statics.getPortfolioInvestments = function getPortfolioInvestments(options, cb) {
|
|
482
|
+
|
|
483
|
+
const self = this;
|
|
484
|
+
|
|
485
|
+
if (!cb) { throw new Error('cb is required'); }
|
|
486
|
+
if (!options) { return cb(new Error('options is required'), null); }
|
|
487
|
+
|
|
488
|
+
options = helpers.getDefaultOptions(options);
|
|
489
|
+
|
|
490
|
+
if (!options.isWorkerProcess) {
|
|
491
|
+
if (!options.CUSTOMER_ID) { return cb(new Error('options.CUSTOMER_ID is required'), null); }
|
|
492
|
+
if (!mongoose.Types.ObjectId.isValid(options.CUSTOMER_ID)) { return cb(new Error('options.CUSTOMER_ID is not a valid ObjectId'), null); }
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// First get the customer's fund IDs
|
|
496
|
+
Organization.getById(options.CUSTOMER_ID, { CUSTOMER_ID: options.CUSTOMER_ID }, function(err, customer) {
|
|
497
|
+
|
|
498
|
+
if (err) return cb(err, null);
|
|
499
|
+
if (!customer) return cb(new Error('Customer not found'), null);
|
|
500
|
+
if (!customer.funds || customer.funds.length === 0) return cb(null, []);
|
|
501
|
+
|
|
502
|
+
const fundIds = _.pluck(customer.funds, '_id');
|
|
503
|
+
|
|
504
|
+
let query = self.find({ 'vehicles.fund': { $in: fundIds } });
|
|
505
|
+
query.select('organization roundName vehicles');
|
|
506
|
+
query.populate('organization', 'name description logoUrl website websiteAliases filters status ipo closed acquired operating');
|
|
507
|
+
|
|
508
|
+
if (options.isWorkerProcess) {
|
|
509
|
+
query.populate('vehicles.investments');
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
query.populate({
|
|
513
|
+
path: 'vehicles.investments',
|
|
514
|
+
match: { customer: options.CUSTOMER_ID }
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
query.exec(function(err, rounds) {
|
|
519
|
+
|
|
520
|
+
if (err) return cb(err, null);
|
|
521
|
+
if (!rounds) return cb(null, []);
|
|
522
|
+
|
|
523
|
+
if (!options.isWorkerProcess) {
|
|
524
|
+
_.each(rounds, function(round) {
|
|
525
|
+
round = helpers.cleanRound(round, fundIds, options.CUSTOMER_ID);
|
|
526
|
+
round.organization = helpers.cleanOrg(round.organization, options.CUSTOMER_ID);
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
let portfolioInvestments = [];
|
|
531
|
+
_.each(rounds, function(round) {
|
|
532
|
+
_.each(round.vehicles, function(vehicle) {
|
|
533
|
+
_.each(vehicle.investments, function(investment) {
|
|
534
|
+
investment.organization = round.organization;
|
|
535
|
+
investment.roundName = round.roundName;
|
|
536
|
+
portfolioInvestments.push(investment);
|
|
537
|
+
});
|
|
538
|
+
});
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
return cb(null, portfolioInvestments);
|
|
542
|
+
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
};
|
|
490
548
|
|
|
491
549
|
Round.statics.getFundPerformance = function getFundPerformance(fundId, options, cb) {
|
|
492
550
|
|
|
@@ -696,6 +754,7 @@ module.exports = function(mongoose, config) {
|
|
|
696
754
|
website: rounds[0].organization.website,
|
|
697
755
|
status: rounds[0].organization.status,
|
|
698
756
|
people: rounds[0].organization.people,
|
|
757
|
+
operating: rounds[0].organization.operating,
|
|
699
758
|
funds: fundList
|
|
700
759
|
});
|
|
701
760
|
|
|
@@ -757,6 +816,175 @@ module.exports = function(mongoose, config) {
|
|
|
757
816
|
|
|
758
817
|
};
|
|
759
818
|
|
|
819
|
+
Round.statics.getRelated = function getRelated(orgid, options, cb) {
|
|
820
|
+
|
|
821
|
+
const self = this;
|
|
822
|
+
const async = require('async');
|
|
823
|
+
const Organization = mongoose.model('Organization');
|
|
824
|
+
|
|
825
|
+
if (!cb) { throw new Error('cb is required'); }
|
|
826
|
+
if (!orgid) { return cb(new Error('orgid is required'), null); }
|
|
827
|
+
if (!mongoose.Types.ObjectId.isValid(orgid)) { return cb(new Error('orgid is not a valid ObjectId'), null); }
|
|
828
|
+
if (!options) { return cb(new Error('options is required'), null); }
|
|
829
|
+
if (!options.CUSTOMER_ID) { return cb(new Error('options.CUSTOMER_ID is required'), null); }
|
|
830
|
+
if (!mongoose.Types.ObjectId.isValid(options.CUSTOMER_ID)) { return cb(new Error('options.CUSTOMER_ID is not a valid ObjectId'), null); }
|
|
831
|
+
|
|
832
|
+
// We need customerFunds to filter rounds - extract from options or get all customer funds
|
|
833
|
+
var customerFunds = options.customerFunds;
|
|
834
|
+
if (!customerFunds) {
|
|
835
|
+
const Fund = mongoose.model('Fund');
|
|
836
|
+
return Fund.findByCustomer(options.CUSTOMER_ID, function(err, funds) {
|
|
837
|
+
if (err) return cb(err);
|
|
838
|
+
options.customerFunds = funds;
|
|
839
|
+
return self.getRelated(orgid, options, cb);
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
async.parallel([
|
|
844
|
+
|
|
845
|
+
// Find organizations acquired by this org (acquirees)
|
|
846
|
+
function(callback) {
|
|
847
|
+
Organization
|
|
848
|
+
.find({
|
|
849
|
+
$or: [
|
|
850
|
+
{ 'operating.acquired.private.by': orgid, 'operating.acquired.private.customer': options.CUSTOMER_ID, 'deleted': { $ne: true } },
|
|
851
|
+
{ 'operating.acquired.public.by': orgid, 'deleted': { $ne: true } }
|
|
852
|
+
]
|
|
853
|
+
})
|
|
854
|
+
.select('name logoUrl')
|
|
855
|
+
.exec(callback);
|
|
856
|
+
},
|
|
857
|
+
|
|
858
|
+
// Find organizations merged with this org
|
|
859
|
+
function(callback) {
|
|
860
|
+
Organization
|
|
861
|
+
.find({
|
|
862
|
+
$or: [
|
|
863
|
+
{ 'operating.merged.private.with': orgid, 'operating.merged.private.customer': options.CUSTOMER_ID, 'deleted': { $ne: true } },
|
|
864
|
+
{ 'operating.merged.public.with': orgid, 'deleted': { $ne: true } }
|
|
865
|
+
]
|
|
866
|
+
})
|
|
867
|
+
.select('name logoUrl')
|
|
868
|
+
.exec(callback);
|
|
869
|
+
},
|
|
870
|
+
|
|
871
|
+
// Find organizations that acquired this org (acquirers) or merged with this org
|
|
872
|
+
function(callback) {
|
|
873
|
+
Organization
|
|
874
|
+
.findById(orgid)
|
|
875
|
+
.select('operating')
|
|
876
|
+
.exec(function(err, mainOrg) {
|
|
877
|
+
if (err) return callback(err);
|
|
878
|
+
if (!mainOrg) return callback(null, []);
|
|
879
|
+
|
|
880
|
+
var relatedIds = [];
|
|
881
|
+
|
|
882
|
+
// Check for acquirer
|
|
883
|
+
if (mainOrg.operating && mainOrg.operating.acquired) {
|
|
884
|
+
// acquired.private is an array, iterate through it
|
|
885
|
+
if (mainOrg.operating.acquired.private && Array.isArray(mainOrg.operating.acquired.private)) {
|
|
886
|
+
mainOrg.operating.acquired.private.forEach(function(acquiredEntry) {
|
|
887
|
+
if (acquiredEntry && acquiredEntry.by) {
|
|
888
|
+
relatedIds.push(acquiredEntry.by);
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
if (mainOrg.operating.acquired.public && mainOrg.operating.acquired.public.by) {
|
|
894
|
+
relatedIds.push(mainOrg.operating.acquired.public.by);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
// Check for merger partner
|
|
899
|
+
if (mainOrg.operating && mainOrg.operating.merged) {
|
|
900
|
+
// merged.private is an array, iterate through it
|
|
901
|
+
if (mainOrg.operating.merged.private && Array.isArray(mainOrg.operating.merged.private)) {
|
|
902
|
+
mainOrg.operating.merged.private.forEach(function(mergedEntry) {
|
|
903
|
+
if (mergedEntry && mergedEntry.with) {
|
|
904
|
+
relatedIds.push(mergedEntry.with);
|
|
905
|
+
}
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
if (mainOrg.operating.merged.public && mainOrg.operating.merged.public.with) {
|
|
910
|
+
relatedIds.push(mainOrg.operating.merged.public.with);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
if (relatedIds.length === 0) return callback(null, []);
|
|
915
|
+
|
|
916
|
+
Organization
|
|
917
|
+
.find({
|
|
918
|
+
'_id': { $in: relatedIds },
|
|
919
|
+
'deleted': { $ne: true }
|
|
920
|
+
})
|
|
921
|
+
.select('name logoUrl')
|
|
922
|
+
.exec(callback);
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
], function(err, results) {
|
|
927
|
+
if (err) return cb(err);
|
|
928
|
+
|
|
929
|
+
// Flatten and combine all results
|
|
930
|
+
var allResults = [];
|
|
931
|
+
results.forEach(function(resultSet) {
|
|
932
|
+
if (Array.isArray(resultSet)) {
|
|
933
|
+
allResults = allResults.concat(resultSet);
|
|
934
|
+
}
|
|
935
|
+
});
|
|
936
|
+
|
|
937
|
+
// Remove duplicates and the org itself
|
|
938
|
+
var uniqueResults = [];
|
|
939
|
+
var seenIds = new Set();
|
|
940
|
+
|
|
941
|
+
allResults.forEach(function(org) {
|
|
942
|
+
if (!seenIds.has(org._id.toString()) && org._id.toString() !== orgid.toString()) {
|
|
943
|
+
seenIds.add(org._id.toString());
|
|
944
|
+
uniqueResults.push(org);
|
|
945
|
+
}
|
|
946
|
+
});
|
|
947
|
+
|
|
948
|
+
// Now get rounds for each related organization
|
|
949
|
+
async.map(uniqueResults, function(org, mapCallback) {
|
|
950
|
+
|
|
951
|
+
var fundIds = customerFunds.map(function(fund) { return fund._id; });
|
|
952
|
+
|
|
953
|
+
self
|
|
954
|
+
.find({
|
|
955
|
+
'organization': org._id,
|
|
956
|
+
'vehicles.fund': { $in: fundIds },
|
|
957
|
+
'deleted': { $ne: true }
|
|
958
|
+
})
|
|
959
|
+
.populate('vehicles.fund', 'name shortName hexColorCode abbreviation closeDate')
|
|
960
|
+
.populate('organization', 'name logoUrl')
|
|
961
|
+
.populate({
|
|
962
|
+
path: 'vehicles.investments',
|
|
963
|
+
match: { customer: options.CUSTOMER_ID }
|
|
964
|
+
})
|
|
965
|
+
.exec(function(err, rounds) {
|
|
966
|
+
if (err) return mapCallback(err);
|
|
967
|
+
|
|
968
|
+
// Clean rounds to only show vehicles for customer funds
|
|
969
|
+
if (rounds && !options.isWorkerProcess) {
|
|
970
|
+
rounds = rounds.map(function(round) {
|
|
971
|
+
return helpers.cleanRound(round, fundIds, options.CUSTOMER_ID);
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
mapCallback(null, {
|
|
976
|
+
org: org,
|
|
977
|
+
rounds: rounds || []
|
|
978
|
+
});
|
|
979
|
+
});
|
|
980
|
+
|
|
981
|
+
}, function(err, relatedWithRounds) {
|
|
982
|
+
if (err) return cb(err);
|
|
983
|
+
cb(null, relatedWithRounds);
|
|
984
|
+
});
|
|
985
|
+
});
|
|
986
|
+
};
|
|
987
|
+
|
|
760
988
|
Round.statics.upsert = function(round, cb) {
|
|
761
989
|
|
|
762
990
|
if (!round) { return cb(new Error('round is required'), null); }
|