@dhyasama/totem-models 2.2.2 → 2.3.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 CHANGED
@@ -53,6 +53,7 @@ var bootstrap = function(mongoose, config) {
53
53
  require('./lib/Activity.js')(mongoose, config);
54
54
  require('./lib/CalendarEvent.js')(mongoose, config);
55
55
  require('./lib/CapTable.js')(mongoose, config);
56
+ require('./lib/Financials.js')(mongoose, config);
56
57
  require('./lib/Interaction.js')(mongoose, config);
57
58
  require('./lib/Investment.js')(mongoose, config);
58
59
  require('./lib/List.js')(mongoose, config);
@@ -111,6 +111,17 @@ module.exports = function(mongoose, config) {
111
111
  .exec(cb);
112
112
  };
113
113
 
114
+ CalendarEvent.statics.markAsProcessed = function markAsProcessed(id, cb) {
115
+
116
+ var self = this;
117
+ var filter = { '_id': id };
118
+ var update = { $set: { processed: true } };
119
+ var options = { 'upsert': false, 'new': true };
120
+
121
+ self.findOneAndUpdate(filter, update, options, cb);
122
+
123
+ };
124
+
114
125
  CalendarEvent.statics.upsert = function(calendarEvent, cb) {
115
126
 
116
127
  var self = this;
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+
3
+ ///////////////////////////////////////////////////////////////////////////////////////
4
+ // NOTES
5
+ //
6
+ // This is private data
7
+ //
8
+ ///////////////////////////////////////////////////////////////////////////////////////
9
+
10
+ module.exports = function(mongoose, config) {
11
+
12
+ var Schema = mongoose.Schema;
13
+ var Round = mongoose.model('Round');
14
+ var async = require('async');
15
+ var _ = require('underscore');
16
+
17
+ var Financials = new Schema({
18
+
19
+ organization: { type: Schema.ObjectId, ref: 'Organization', required: true, index: true },
20
+
21
+ customer: { type: Schema.ObjectId, ref: 'Organization', required: true, index: true },
22
+
23
+ asOfDate: { type: Date, required: true },
24
+ burn: { type: Number, default: 0 },
25
+ runway: { type: Number, default: 0 },
26
+ cashBalance: { type: Number, default: 0 },
27
+
28
+ revenue: {
29
+ ytd: { type: Number, default: 0 },
30
+ projected: { type: Number, default: 0 },
31
+ past: [{
32
+ year: { type: Number, default: 0 },
33
+ amount: { type: Number, default: 0 }
34
+ }]
35
+ },
36
+
37
+ expenses: {
38
+ ytd: { type: Number, default: 0 },
39
+ projected: { type: Number, default: 0 },
40
+ past: [{
41
+ year: { type: Number, default: 0 },
42
+ amount: { type: Number, default: 0 }
43
+ }]
44
+ },
45
+
46
+ grossProfit: {
47
+ ytd: { type: Number, default: 0 },
48
+ projected: { type: Number, default: 0 },
49
+ past: [{
50
+ year: { type: Number, default: 0 },
51
+ amount: { type: Number, default: 0 }
52
+ }]
53
+ },
54
+
55
+ operatingIncome: {
56
+ ytd: { type: Number, default: 0 },
57
+ projected: { type: Number, default: 0 },
58
+ past: [{
59
+ year: { type: Number, default: 0 },
60
+ amount: { type: Number, default: 0 }
61
+ }]
62
+ },
63
+
64
+ // Catch-all for customer specific key-value pairs from sheet that aren't supported by our schema
65
+ details: [{
66
+ key: { type: String, trim: true, required: true },
67
+ value: { type: String, trim: true, required: true },
68
+ _id: false
69
+ }],
70
+
71
+ });
72
+
73
+
74
+
75
+ ///////////////////////////////////////////////////////////////////////////////////////
76
+ // VIRTUALS
77
+ // Properties that are not persisted to the database
78
+ ///////////////////////////////////////////////////////////////////////////////////////
79
+
80
+
81
+
82
+ //////////////////////////////////////////////////////
83
+ // STATICS
84
+ // Statics operate on the entire collection
85
+ //////////////////////////////////////////////////////
86
+
87
+ Financials.statics.getByOrg = function getByOrg(orgId, cb) {
88
+
89
+ var self = this;
90
+
91
+ var query = self.find({
92
+ 'organization': orgId,
93
+ 'customer': config.CUSTOMER_ID
94
+ });
95
+
96
+ query.exec(function(err, rounds) {
97
+
98
+ if (err) return cb(err, null);
99
+ if (!rounds || rounds.length == 0) return cb(null, []);
100
+
101
+ var error = checkForUnpopulatedData(rounds, 'Round.getByOrg');
102
+ if (error) return cb(error, null);
103
+
104
+ // reverse chronological
105
+ rounds = _.sortBy(rounds, function(r) {
106
+
107
+ var date = r.closingDate;
108
+
109
+ // use investment date in absence of closing date
110
+ if (!date && r.vehicles.length && r.vehicles[0].investments.length) {
111
+ date = r.vehicles[0].investments[0].investmentDate;
112
+ }
113
+
114
+ return date;
115
+
116
+ }).reverse();
117
+
118
+ return cb(null, rounds);
119
+
120
+ });
121
+
122
+ };
123
+
124
+ Financials.statics.removeCustomerFinancials = function removeCustomerFinancials(customerId, cb) {
125
+
126
+ var self = this;
127
+
128
+ self
129
+ .remove({customer: customerId})
130
+ .exec(cb);
131
+
132
+ };
133
+
134
+ Financials.statics.upsert = function upsert(financials, cb) {
135
+ if (!financials) { return cb(new Error('financials is required'), null); }
136
+ financials.save(cb);
137
+ };
138
+
139
+
140
+
141
+ ///////////////////////////////////////////////////////////////////////////////////////
142
+ // HOOKS
143
+ // Pre-save: fired on every document before it is saved
144
+ // Post-init: fired on every document when it's returned from a query
145
+ // Post-remove: fired on every document after it's deleted
146
+ ///////////////////////////////////////////////////////////////////////////////////////
147
+
148
+ Financials.pre('save', function(next) {
149
+
150
+ var self = this;
151
+
152
+ // todo
153
+
154
+ return next();
155
+
156
+ });
157
+
158
+ Financials.post('init', function(doc, next) {
159
+
160
+ doc.revenue.past = _.sortBy(doc.revenue.past, '-year');
161
+ doc.expenses.past = _.sortBy(doc.expenses.past, '-year');
162
+ doc.grossProfit.past = _.sortBy(doc.grossProfit.past, '-year');
163
+ doc.operatingIncome.past = _.sortBy(doc.operatingIncome.past, '-year');
164
+
165
+ return next();
166
+
167
+ });
168
+
169
+ Financials.post('remove', function(doc) {
170
+ // todo
171
+ });
172
+
173
+
174
+
175
+ ///////////////////////////////////////////////////////////////////////////////////////
176
+ // CONFIG
177
+ ///////////////////////////////////////////////////////////////////////////////////////
178
+
179
+ Financials.set('toJSON', { virtuals: true });
180
+ Financials.set('autoIndex', false);
181
+
182
+ Financials.on('index', function(err) { console.log('error building financials indexes: ' + err); });
183
+
184
+ mongoose.model('Financials', Financials);
185
+
186
+ };
187
+
188
+
@@ -302,7 +302,7 @@ module.exports = function(mongoose, config) {
302
302
 
303
303
  _.each(self.people, function(p) {
304
304
  var boardRole = p.board;
305
- if (boardRole && boardRole != 'none') members.push(p.person);
305
+ if (p.person && boardRole && boardRole != 'none') members.push(p.person);
306
306
  });
307
307
 
308
308
  members = _.sortBy(members, function(member) {
@@ -321,7 +321,7 @@ module.exports = function(mongoose, config) {
321
321
 
322
322
  _.each(self.people, function(p) {
323
323
  var boardRole = p.board;
324
- if (p.current && boardRole && boardRole != 'none') members.push(p.person);
324
+ if (p.person && p.current && boardRole && boardRole != 'none') members.push(p.person);
325
325
  });
326
326
 
327
327
  members = _.sortBy(members, function(member) {
@@ -340,7 +340,7 @@ module.exports = function(mongoose, config) {
340
340
 
341
341
  _.each(self.people, function(p) {
342
342
  var boardRole = p.board;
343
- if (!p.current && boardRole && boardRole != 'none') members.push(p.person);
343
+ if (p.person && !p.current && boardRole && boardRole != 'none') members.push(p.person);
344
344
  });
345
345
 
346
346
  members = _.sortBy(members, function(member) {
@@ -358,7 +358,7 @@ module.exports = function(mongoose, config) {
358
358
  var result = [];
359
359
 
360
360
  _.each(self.people, function(p) {
361
- if (!p.leader && (!p.board || p.board == 'none')) result.push(p);
361
+ if (p.person && !p.leader && (!p.board || p.board == 'none')) result.push(p);
362
362
  });
363
363
 
364
364
  result = _.sortBy(result, function(item) {
@@ -376,7 +376,7 @@ module.exports = function(mongoose, config) {
376
376
  var result = [];
377
377
 
378
378
  _.each(self.people, function(p) {
379
- if (p.current && !p.leader && (!p.board || p.board == 'none')) result.push(p);
379
+ if (p.person && p.current && !p.leader && (!p.board || p.board == 'none')) result.push(p);
380
380
  });
381
381
 
382
382
  result = _.sortBy(result, function(item) {
@@ -394,7 +394,7 @@ module.exports = function(mongoose, config) {
394
394
  var result = [];
395
395
 
396
396
  _.each(self.people, function(p) {
397
- if (!p.current && !p.leader && (!p.board || p.board == 'none')) result.push(p);
397
+ if (p.person && !p.current && !p.leader && (!p.board || p.board == 'none')) result.push(p);
398
398
  });
399
399
 
400
400
  result = _.sortBy(result, function(item) {
@@ -778,7 +778,8 @@ module.exports = function(mongoose, config) {
778
778
  'people': {
779
779
  $elemMatch: {
780
780
  'person': personId,
781
- 'board': { $in: ['chairman', 'director', 'observer'] }
781
+ 'board': { $in: ['chairman', 'director', 'observer'] },
782
+ 'current': true
782
783
  }
783
784
  }
784
785
  })
package/package-lock.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhyasama/totem-models",
3
- "version": "2.1.6",
3
+ "version": "2.2.3",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhyasama/totem-models",
3
- "version": "2.2.2",
3
+ "version": "2.3.0",
4
4
  "author": "Jason Reynolds",
5
5
  "license": "UNLICENSED",
6
6
  "description": "Models for Totem platform",