@dhyasama/totem-models 7.58.0 → 8.0.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/.npmignore +14 -0
- package/helpers.js +89 -0
- package/index.js +0 -1
- package/lib/Account.js +125 -79
- package/lib/Activity.js +0 -2
- package/lib/CalendarEvent.js +1 -7
- package/lib/CapTable.js +0 -1
- package/lib/Deal.js +215 -151
- package/lib/Document.js +57 -56
- package/lib/Financials.js +115 -176
- package/lib/Flag.js +37 -14
- package/lib/Fund.js +6 -33
- package/lib/Interaction.js +79 -32
- package/lib/Investment.js +4 -10
- package/lib/LimitedPartner.js +303 -634
- package/lib/List.js +105 -147
- package/lib/Message.js +100 -51
- package/lib/News.js +1 -53
- package/lib/Note.js +60 -66
- package/lib/Organization.js +470 -645
- package/lib/Person.js +342 -650
- package/lib/Round.js +191 -134
- package/lib/Snapshot.js +3 -5
- package/lib/Webhook.js +1 -4
- package/package-lock.json +1927 -0
- package/package.json +2 -3
- package/test/Account.js +53 -38
- package/test/Deal.js +14 -30
- package/test/Document.js +51 -50
- package/test/Financials.js +5 -3
- package/test/Flag.js +18 -14
- package/test/Interaction.js +1 -31
- package/test/Investment.js +2 -3
- package/test/LimitedPartner.js +399 -554
- package/test/List.js +24 -29
- package/test/Message.js +7 -46
- package/test/News.js +12 -29
- package/test/Note.js +23 -22
- package/test/Organization.js +33 -307
- package/test/Person.js +6 -253
- package/test/Round.js +11 -11
- package/lib/Sync.js +0 -48
package/lib/Deal.js
CHANGED
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
module.exports = function(mongoose, config) {
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
let
|
|
6
6
|
|
|
7
7
|
Schema = mongoose.Schema,
|
|
8
|
-
postFind = require('mongoose-post-find'),
|
|
9
8
|
async = require('async'),
|
|
10
9
|
_ = require('underscore'),
|
|
11
|
-
|
|
10
|
+
utilities = require('@dhyasama/ffvc-utilities');
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
let Deal = new Schema({
|
|
14
13
|
|
|
15
14
|
customer: { type: Schema.ObjectId, ref: 'Organization', required: true },
|
|
16
15
|
|
|
@@ -65,29 +64,23 @@ module.exports = function(mongoose, config) {
|
|
|
65
64
|
|
|
66
65
|
});
|
|
67
66
|
|
|
68
|
-
var customExample = {
|
|
69
|
-
revenue: 1000000,
|
|
70
|
-
note: 'love it',
|
|
71
|
-
international: false,
|
|
72
|
-
region: 'Northeast',
|
|
73
|
-
industries: ['AI', 'Logistics']
|
|
74
|
-
};
|
|
75
67
|
|
|
76
68
|
|
|
77
69
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
78
70
|
// VIRTUALS
|
|
79
71
|
// Properties that are not persisted to the database
|
|
80
72
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
73
|
+
|
|
81
74
|
Deal.virtual('deck').get(function () {
|
|
82
75
|
|
|
83
|
-
|
|
76
|
+
const self = this;
|
|
84
77
|
return _.find(self.documents, function(document) { return document.type == 'deck'; })
|
|
85
78
|
|
|
86
79
|
});
|
|
87
80
|
|
|
88
81
|
Deal.virtual('added').get(function () {
|
|
89
82
|
|
|
90
|
-
|
|
83
|
+
const self = this;
|
|
91
84
|
|
|
92
85
|
if(self.history && self.history.length > 0) return self.history[0].timestamp;
|
|
93
86
|
else return null;
|
|
@@ -96,7 +89,7 @@ module.exports = function(mongoose, config) {
|
|
|
96
89
|
|
|
97
90
|
Deal.virtual('updated').get(function () {
|
|
98
91
|
|
|
99
|
-
|
|
92
|
+
const self = this;
|
|
100
93
|
|
|
101
94
|
if(self.history && self.history.length > 0) return self.history[self.history.length - 1].timestamp;
|
|
102
95
|
else return null;
|
|
@@ -116,58 +109,104 @@ module.exports = function(mongoose, config) {
|
|
|
116
109
|
// Statics operate on the entire collection
|
|
117
110
|
//////////////////////////////////////////////////////
|
|
118
111
|
|
|
119
|
-
Deal.statics.delete = function(id, cb) {
|
|
112
|
+
Deal.statics.delete = function(id, options, cb) {
|
|
120
113
|
|
|
121
|
-
|
|
114
|
+
let self = this;
|
|
115
|
+
|
|
116
|
+
if (!cb) { throw new Error('cb is required'); }
|
|
117
|
+
if (!id) { return cb(new Error('id is required'), null); }
|
|
118
|
+
if (!mongoose.Types.ObjectId.isValid(id)) { return cb(new Error('id is not a valid ObjectId'), null); }
|
|
119
|
+
if (!options) { return cb(new Error('options is required'), null); }
|
|
120
|
+
if (!options.CUSTOMER_ID) { return cb(new Error('options.CUSTOMER_ID is required'), null); }
|
|
121
|
+
if (!mongoose.Types.ObjectId.isValid(options.CUSTOMER_ID)) { return cb(new Error('options.CUSTOMER_ID is not a valid ObjectId'), null); }
|
|
122
122
|
|
|
123
123
|
// Not strictly necessary but provides verification that the document being deleted belongs to the customer doing the deleting
|
|
124
|
-
self.findOne({
|
|
124
|
+
let query = self.findOne({
|
|
125
125
|
'_id': id,
|
|
126
|
-
'customer':
|
|
127
|
-
}
|
|
126
|
+
'customer': options.CUSTOMER_ID
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
query.exec(function(err, deal) {
|
|
128
130
|
|
|
129
131
|
if (err) return cb(err, null);
|
|
130
132
|
else if (!deal) return cb(null, null);
|
|
131
133
|
|
|
134
|
+
// No population so no need to scrub
|
|
135
|
+
|
|
132
136
|
deal.remove(cb);
|
|
133
137
|
|
|
134
138
|
});
|
|
135
139
|
|
|
136
140
|
};
|
|
137
141
|
|
|
138
|
-
Deal.statics.
|
|
139
|
-
this.find({}).exec(cb);
|
|
140
|
-
};
|
|
142
|
+
Deal.statics.getById = function (id, options, cb) {
|
|
141
143
|
|
|
142
|
-
|
|
144
|
+
let self = this;
|
|
143
145
|
|
|
144
|
-
|
|
146
|
+
if (!cb) { throw new Error('cb is required'); }
|
|
147
|
+
if (!id) { return cb(new Error('id is required'), null); }
|
|
148
|
+
if (!mongoose.Types.ObjectId.isValid(id)) { return cb(new Error('id is not a valid ObjectId'), null); }
|
|
149
|
+
if (!options) { return cb(new Error('options is required'), null); }
|
|
150
|
+
if (!options.CUSTOMER_ID) { return cb(new Error('options.CUSTOMER_ID is required'), null); }
|
|
151
|
+
if (!mongoose.Types.ObjectId.isValid(options.CUSTOMER_ID)) { return cb(new Error('options.CUSTOMER_ID is not a valid ObjectId'), null); }
|
|
152
|
+
|
|
153
|
+
let query = self.findOne({
|
|
154
|
+
'_id': id,
|
|
155
|
+
'customer': options.CUSTOMER_ID
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
query.populate({ path: 'documents', match: { customer: options.CUSTOMER_ID } });
|
|
159
|
+
query.populate({ path: 'messages', match: { customer: options.CUSTOMER_ID } });
|
|
160
|
+
query.populate('organization', 'name description logoUrl website websiteAliases chairs contact');
|
|
161
|
+
query.populate('history.account', 'person');
|
|
162
|
+
query.populate('referrer.person', 'name avatarUrl title');
|
|
163
|
+
query.populate('source.person', 'name avatarUrl title');
|
|
164
|
+
|
|
165
|
+
query.exec(cb);
|
|
145
166
|
|
|
146
|
-
self.findOne({
|
|
147
|
-
'_id': id,
|
|
148
|
-
'customer': config.CUSTOMER_ID
|
|
149
|
-
})
|
|
150
|
-
.populate('organization', 'name description logoUrl website websiteAliases chairs contact')
|
|
151
|
-
.populate('messages')
|
|
152
|
-
.populate('referrer.person', 'name avatarUrl title')
|
|
153
|
-
.populate({
|
|
154
|
-
path: 'documents',
|
|
155
|
-
match: { customer: config.CUSTOMER_ID }
|
|
156
|
-
})
|
|
157
|
-
.exec(cb);
|
|
158
167
|
};
|
|
159
168
|
|
|
160
|
-
Deal.statics.getByIds = function (ids, cb) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
Deal.statics.getByIds = function (ids, options, cb) {
|
|
170
|
+
|
|
171
|
+
let self = this;
|
|
172
|
+
|
|
173
|
+
if (!cb) { throw new Error('cb is required'); }
|
|
174
|
+
if (!ids) { return cb(new Error('ids is required'), null); }
|
|
175
|
+
if (!options) { return cb(new Error('options is required'), null); }
|
|
176
|
+
if (!options.CUSTOMER_ID) { return cb(new Error('options.CUSTOMER_ID is required'), null); }
|
|
177
|
+
if (!mongoose.Types.ObjectId.isValid(options.CUSTOMER_ID)) { return cb(new Error('options.CUSTOMER_ID is not a valid ObjectId'), null); }
|
|
178
|
+
|
|
179
|
+
let query = self.find({
|
|
180
|
+
customer: options.CUSTOMER_ID,
|
|
181
|
+
'_id': { $in : ids }
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
query.populate({ path: 'documents', match: { customer: options.CUSTOMER_ID } });
|
|
185
|
+
query.populate({ path: 'messages', match: { customer: options.CUSTOMER_ID } });
|
|
186
|
+
query.populate('organization', 'name description logoUrl website websiteAliases chairs contact');
|
|
187
|
+
query.populate('referrer.person', 'name avatarUrl title');
|
|
188
|
+
query.populate('source.person', 'name avatarUrl title');
|
|
189
|
+
|
|
190
|
+
query.exec(function(err, deals) {
|
|
191
|
+
|
|
192
|
+
if (err) return cb(err, null);
|
|
193
|
+
else if (!deals || deals.length === 0) return cb(null, []);
|
|
194
|
+
|
|
195
|
+
let calls = [];
|
|
196
|
+
|
|
197
|
+
_.each(deals, function(deal) {
|
|
198
|
+
let func = function(callback) {
|
|
199
|
+
deal.deepPopulate('organization.chairs.first', {
|
|
200
|
+
populate: { 'organization.chairs.first': { select: 'name avatarUrl title doNotDisplay' } }
|
|
201
|
+
}, callback);
|
|
202
|
+
};
|
|
203
|
+
calls.push(func);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
async.parallel(calls, cb);
|
|
207
|
+
|
|
208
|
+
});
|
|
209
|
+
|
|
171
210
|
};
|
|
172
211
|
|
|
173
212
|
// Get all deals belonging to a customer
|
|
@@ -177,132 +216,189 @@ module.exports = function(mongoose, config) {
|
|
|
177
216
|
// not sure why chained deepPopulate isn't working (it throws an error)
|
|
178
217
|
// it works to deepPopulate each result instance in parallel
|
|
179
218
|
|
|
180
|
-
|
|
219
|
+
let self = this;
|
|
220
|
+
|
|
221
|
+
if (!cb) { throw new Error('cb is required'); }
|
|
222
|
+
if (!customerId) { return cb(new Error('customerId is required'), null); }
|
|
223
|
+
if (!mongoose.Types.ObjectId.isValid(customerId)) { return cb(new Error('customerId is not a valid ObjectId'), null); }
|
|
181
224
|
|
|
182
225
|
options = options || {};
|
|
183
226
|
|
|
184
227
|
// { history: { $elemMatch: { timestamp: { $gte: ISODate("2019-01-03T20:45:14.406+0000") } } } }
|
|
185
228
|
|
|
186
|
-
|
|
229
|
+
let terms = { 'customer': customerId };
|
|
187
230
|
if (options.stage) { terms['stage'] = { $in: options.stage }; }
|
|
188
231
|
if (options.since) { terms['history'] = { $elemMatch: { timestamp: { $gte: options.since } } }; }
|
|
189
232
|
|
|
190
233
|
self
|
|
191
234
|
.find(terms)
|
|
235
|
+
.populate({ path: 'documents', match: { customer: customerId } })
|
|
236
|
+
.populate({ path: 'messages', match: { customer: customerId } })
|
|
192
237
|
.populate('organization', 'name description logoUrl website websiteAliases chairs contact')
|
|
193
|
-
.populate('messages')
|
|
194
238
|
.populate('referrer.person', 'name avatarUrl title')
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
239
|
+
|
|
240
|
+
.exec(function(err, deals) {
|
|
241
|
+
|
|
242
|
+
if (err) { return cb(err, null); }
|
|
243
|
+
else if (!deals || deals.length === 0) { return cb(null, []); }
|
|
244
|
+
|
|
245
|
+
let calls = [];
|
|
246
|
+
|
|
247
|
+
_.each(deals, function(deal) {
|
|
248
|
+
let func = function(callback) {
|
|
249
|
+
deal.deepPopulate('organization.chairs.first', {
|
|
250
|
+
populate: { 'organization.chairs.first': { select: 'name avatarUrl title doNotDisplay' } }
|
|
251
|
+
}, callback);
|
|
252
|
+
};
|
|
253
|
+
calls.push(func);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
async.parallel(calls, cb);
|
|
257
|
+
|
|
258
|
+
});
|
|
199
259
|
|
|
200
260
|
};
|
|
201
261
|
|
|
202
|
-
Deal.statics.getByReferrer = function (personId, cb) {
|
|
262
|
+
Deal.statics.getByReferrer = function (personId, options, cb) {
|
|
203
263
|
|
|
204
|
-
|
|
264
|
+
let self = this;
|
|
205
265
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
266
|
+
if (!cb) { throw new Error('cb is required'); }
|
|
267
|
+
if (!personId) { return cb(new Error('personId is required'), null); }
|
|
268
|
+
if (!mongoose.Types.ObjectId.isValid(personId)) { return cb(new Error('personId is not a valid ObjectId'), null); }
|
|
269
|
+
if (!options) { return cb(new Error('options is required'), null); }
|
|
270
|
+
if (!options.CUSTOMER_ID) { return cb(new Error('options.CUSTOMER_ID is required'), null); }
|
|
271
|
+
if (!mongoose.Types.ObjectId.isValid(options.CUSTOMER_ID)) { return cb(new Error('options.CUSTOMER_ID is not a valid ObjectId'), null); }
|
|
272
|
+
|
|
273
|
+
let query = self.find({
|
|
274
|
+
'referrer.person': personId,
|
|
275
|
+
'customer': options.CUSTOMER_ID
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
query.populate('organization', 'name description logoUrl website websiteAliases');
|
|
279
|
+
|
|
280
|
+
query.exec(cb);
|
|
213
281
|
|
|
214
282
|
};
|
|
215
283
|
|
|
216
284
|
// Get a deal for a org, belonging to current customer
|
|
217
|
-
Deal.statics.getForOrg = function (orgId, cb) {
|
|
285
|
+
Deal.statics.getForOrg = function (orgId, options, cb) {
|
|
218
286
|
|
|
219
|
-
|
|
287
|
+
const self = this;
|
|
288
|
+
|
|
289
|
+
if (!cb) { throw new Error('cb is required'); }
|
|
290
|
+
if (!orgId) { return cb(new Error('orgId is required'), null); }
|
|
291
|
+
if (!mongoose.Types.ObjectId.isValid(orgId)) { return cb(new Error('orgId is not a valid ObjectId'), null); }
|
|
292
|
+
if (!options) { return cb(new Error('options is required'), null); }
|
|
293
|
+
if (!options.CUSTOMER_ID) { return cb(new Error('options.CUSTOMER_ID is required'), null); }
|
|
294
|
+
if (!mongoose.Types.ObjectId.isValid(options.CUSTOMER_ID)) { return cb(new Error('options.CUSTOMER_ID is not a valid ObjectId'), null); }
|
|
295
|
+
|
|
296
|
+
let query = self.findOne({
|
|
297
|
+
'organization': orgId,
|
|
298
|
+
'customer': options.CUSTOMER_ID
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
query.populate({ path: 'documents', match: { customer: options.CUSTOMER_ID } });
|
|
302
|
+
query.populate({ path: 'messages', match: { customer: options.CUSTOMER_ID } });
|
|
303
|
+
query.populate('organization', 'name logoUrl website websiteAliases');
|
|
304
|
+
query.populate('referrer.person', 'name avatarUrl title');
|
|
305
|
+
query.populate('source.person', 'name avatarUrl title');
|
|
306
|
+
|
|
307
|
+
query.exec(function(err, deal) {
|
|
308
|
+
if (deal && deal.history) {
|
|
309
|
+
deal.deepPopulate('history.account.person', {
|
|
310
|
+
populate: { 'history.account.person': { select: 'name avatarUrl title doNotDisplay' } }
|
|
311
|
+
}, cb);
|
|
312
|
+
}
|
|
313
|
+
else cb(err, deal);
|
|
314
|
+
});
|
|
220
315
|
|
|
221
|
-
self
|
|
222
|
-
.findOne({
|
|
223
|
-
'organization': orgId,
|
|
224
|
-
'customer': config.CUSTOMER_ID
|
|
225
|
-
})
|
|
226
|
-
.populate('organization', 'name logoUrl website websiteAliases')
|
|
227
|
-
.populate('messages')
|
|
228
|
-
.populate('referrer.person', 'name avatarUrl title')
|
|
229
|
-
.populate({
|
|
230
|
-
path: 'documents',
|
|
231
|
-
match: { customer: config.CUSTOMER_ID }
|
|
232
|
-
})
|
|
233
|
-
.exec(cb);
|
|
234
316
|
};
|
|
235
317
|
|
|
236
|
-
Deal.statics.modifyById = function(id, update, cb) {
|
|
318
|
+
Deal.statics.modifyById = function(id, update, options, cb) {
|
|
237
319
|
|
|
238
320
|
// VERY IMPORTANT NOTE
|
|
239
321
|
// findByIdAndUpdate and findOneAndUpdate do not trigger pre-save hook so that code will not run here
|
|
240
322
|
|
|
241
|
-
|
|
323
|
+
let self = this;
|
|
324
|
+
|
|
325
|
+
if (!cb) { throw new Error('cb is required'); }
|
|
242
326
|
if (!id) { return cb(new Error('id is required'), null); }
|
|
327
|
+
if (!mongoose.Types.ObjectId.isValid(id)) { return cb(new Error('id is not a valid ObjectId'), null); }
|
|
243
328
|
if (!update) { return cb(new Error('update is required'), null); }
|
|
244
|
-
|
|
245
|
-
|
|
329
|
+
if (!options) { return cb(new Error('options is required'), null); }
|
|
330
|
+
if (!options.CUSTOMER_ID) { return cb(new Error('options.CUSTOMER_ID is required'), null); }
|
|
331
|
+
if (!mongoose.Types.ObjectId.isValid(options.CUSTOMER_ID)) { return cb(new Error('options.CUSTOMER_ID is not a valid ObjectId'), null); }
|
|
246
332
|
|
|
247
333
|
// https://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate
|
|
248
334
|
// options runValidators defaults false which is ok since we have upsert false
|
|
249
335
|
// new returns the updated document
|
|
250
336
|
|
|
251
|
-
self.
|
|
337
|
+
let query = self.findOneAndUpdate({ _id: id, customer: options.CUSTOMER_ID }, update, { upsert: false, new: true });
|
|
338
|
+
|
|
339
|
+
// No population so no need to scrub
|
|
340
|
+
|
|
341
|
+
query.exec(cb);
|
|
252
342
|
|
|
253
343
|
};
|
|
254
344
|
|
|
255
|
-
Deal.statics.upsert = function upsert(deal,
|
|
345
|
+
Deal.statics.upsert = function upsert(deal, options, cb) {
|
|
256
346
|
|
|
257
347
|
// Deal is dumb and doesn't validate customer stages or duplicate deals. That responsibility is with the org.
|
|
258
348
|
|
|
349
|
+
if (!cb) { throw new Error('cb is required'); }
|
|
259
350
|
if (!deal) { return cb(new Error('deal is required'), null); }
|
|
351
|
+
if (!options) { return cb(new Error('options is required'), null); }
|
|
352
|
+
if (!options.account) { return cb(new Error('options.account is required'), null); }
|
|
353
|
+
if (!options.CUSTOMER_ID) { return cb(new Error('options.CUSTOMER_ID is required'), null); }
|
|
354
|
+
if (!mongoose.Types.ObjectId.isValid(options.CUSTOMER_ID)) { return cb(new Error('options.CUSTOMER_ID is not a valid ObjectId'), null); }
|
|
260
355
|
|
|
261
|
-
|
|
356
|
+
let getLastStage = function() {
|
|
262
357
|
|
|
263
|
-
if (!deal.history || deal.history.length
|
|
358
|
+
if (!deal.history || deal.history.length === 0) return null;
|
|
264
359
|
|
|
265
|
-
|
|
266
|
-
|
|
360
|
+
let history = _.sortBy(deal.history);
|
|
361
|
+
let last = history[history.length - 1];
|
|
267
362
|
|
|
268
363
|
return last.stage;
|
|
269
364
|
|
|
270
365
|
};
|
|
271
366
|
|
|
272
|
-
|
|
367
|
+
let getLastFundraiseAmount = function() {
|
|
273
368
|
|
|
274
|
-
if (!deal.history || deal.history.length
|
|
369
|
+
if (!deal.history || deal.history.length === 0) return null;
|
|
275
370
|
|
|
276
|
-
|
|
277
|
-
|
|
371
|
+
let history = _.sortBy(deal.history);
|
|
372
|
+
let last = history[history.length - 1];
|
|
278
373
|
|
|
279
374
|
return last.fundraise.amount;
|
|
280
375
|
|
|
281
376
|
};
|
|
282
377
|
|
|
283
|
-
|
|
378
|
+
let getLastFundraiseValuation = function() {
|
|
284
379
|
|
|
285
|
-
if (!deal.history || deal.history.length
|
|
380
|
+
if (!deal.history || deal.history.length === 0) return null;
|
|
286
381
|
|
|
287
|
-
|
|
288
|
-
|
|
382
|
+
let history = _.sortBy(deal.history);
|
|
383
|
+
let last = history[history.length - 1];
|
|
289
384
|
|
|
290
385
|
return last.fundraise.valuation;
|
|
291
386
|
|
|
292
387
|
};
|
|
293
388
|
|
|
294
|
-
|
|
389
|
+
let getLastFundraiseDetails = function () {
|
|
295
390
|
|
|
296
|
-
if (!deal.history || deal.history.length
|
|
391
|
+
if (!deal.history || deal.history.length === 0 || !deal.fundraise.details) return null;
|
|
297
392
|
|
|
298
|
-
|
|
299
|
-
|
|
393
|
+
let history = _.sortBy(deal.history);
|
|
394
|
+
let last = history[history.length - 1];
|
|
300
395
|
|
|
301
396
|
return last.fundraise.details;
|
|
302
397
|
|
|
303
398
|
};
|
|
304
399
|
|
|
305
|
-
|
|
400
|
+
let formatMoney = function(n, c, d, t) {
|
|
401
|
+
|
|
306
402
|
var c = isNaN(c = Math.abs(c)) ? 2 : c,
|
|
307
403
|
d = d == undefined ? "." : d,
|
|
308
404
|
t = t == undefined ? "," : t,
|
|
@@ -311,31 +407,32 @@ module.exports = function(mongoose, config) {
|
|
|
311
407
|
j = (j = i.length) > 3 ? j % 3 : 0;
|
|
312
408
|
|
|
313
409
|
return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
|
|
410
|
+
|
|
314
411
|
};
|
|
315
412
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
413
|
+
let description = '';
|
|
414
|
+
let lastStage = getLastStage();
|
|
415
|
+
let lastFundraiseAmount = getLastFundraiseAmount();
|
|
416
|
+
let lastFundraiseValuation = getLastFundraiseValuation();
|
|
417
|
+
let lastFundraiseDetails = getLastFundraiseDetails();
|
|
321
418
|
|
|
322
|
-
if (lastStage
|
|
419
|
+
if (lastStage === null) { description = 'The deal was created'; }
|
|
323
420
|
else {
|
|
324
|
-
if (lastStage
|
|
325
|
-
if (lastFundraiseAmount
|
|
326
|
-
if (lastFundraiseValuation
|
|
327
|
-
if (lastFundraiseDetails && lastFundraiseDetails
|
|
328
|
-
if (!lastFundraiseDetails && deal.fundraise.details) description += 'Fundraise details were added: ' + deal.fundraise.details;
|
|
421
|
+
if (lastStage !== deal.stage) { description += 'The deal was updated from ' + lastStage + ' to ' + deal.stage; }
|
|
422
|
+
if (lastFundraiseAmount !== deal.fundraise.amount) { description += 'Fundraise amount was updated from $' + formatMoney(lastFundraiseAmount, 0) + ' to $' + formatMoney(deal.fundraise.amount, 0); }
|
|
423
|
+
if (lastFundraiseValuation !== deal.fundraise.valuation) { description += 'Fundraise valuation was updated from $' + formatMoney(lastFundraiseValuation, 0) + ' to $' + formatMoney(deal.fundraise.valuation, 0); }
|
|
424
|
+
if (lastFundraiseDetails && lastFundraiseDetails !== deal.fundraise.details) { description += 'Fundraise details were updated from ' + lastFundraiseDetails + ' to ' + deal.fundraise.details; }
|
|
425
|
+
if (!lastFundraiseDetails && deal.fundraise.details) { description += 'Fundraise details were added: ' + deal.fundraise.details; }
|
|
329
426
|
}
|
|
330
427
|
|
|
331
428
|
// only add history if the description is set from the above conditions
|
|
332
|
-
if(description
|
|
429
|
+
if (description !== '') {
|
|
333
430
|
|
|
334
431
|
deal.history = deal.history || [];
|
|
335
432
|
|
|
336
433
|
deal.history.push({
|
|
337
434
|
timestamp: new Date(),
|
|
338
|
-
account:
|
|
435
|
+
account: options.account,
|
|
339
436
|
stage: deal.stage,
|
|
340
437
|
fundraise: deal.fundraise,
|
|
341
438
|
description: description
|
|
@@ -345,54 +442,21 @@ module.exports = function(mongoose, config) {
|
|
|
345
442
|
|
|
346
443
|
// Required for mixed types
|
|
347
444
|
deal.markModified('customFields');
|
|
348
|
-
|
|
445
|
+
|
|
349
446
|
deal.save(cb);
|
|
350
447
|
|
|
351
448
|
};
|
|
352
|
-
|
|
353
|
-
Deal.plugin(postFind, {
|
|
354
|
-
|
|
355
|
-
find: function(results, done) {
|
|
356
|
-
|
|
357
|
-
var CUSTOMER_ID = config.CUSTOMER_ID;
|
|
358
|
-
|
|
359
|
-
if (CUSTOMER_ID == 'GLOBAL_PROCESS') return done(null, results);
|
|
360
|
-
|
|
361
|
-
// Reject any item that is for a different customer
|
|
362
|
-
results = _.reject(results, function(item) {
|
|
363
|
-
return item.customer.toString() != CUSTOMER_ID;
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
return done(null, results);
|
|
367
|
-
|
|
368
|
-
},
|
|
369
|
-
|
|
370
|
-
findOne: function(result, done) {
|
|
371
|
-
|
|
372
|
-
var CUSTOMER_ID = config.CUSTOMER_ID;
|
|
373
|
-
|
|
374
|
-
if (!result) return done(null, null);
|
|
375
|
-
else if (CUSTOMER_ID == 'GLOBAL_PROCESS') return done(null, result);
|
|
376
|
-
else if (result.customer.toString() == CUSTOMER_ID) return done(null, result);
|
|
377
|
-
else return done(null, null);
|
|
378
|
-
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
449
|
+
|
|
385
450
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
386
451
|
// CONFIG
|
|
387
452
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
388
453
|
|
|
389
|
-
Deal.set('usePushEach', true);
|
|
390
454
|
Deal.set('toJSON', { virtuals: true });
|
|
391
455
|
Deal.set('autoIndex', false);
|
|
392
|
-
|
|
456
|
+
|
|
393
457
|
Deal.on('index', function(err) { console.log('error building deal indexes: ' + err); });
|
|
394
458
|
|
|
395
|
-
|
|
459
|
+
const deepPopulate = require('mongoose-deep-populate')(mongoose);
|
|
396
460
|
Deal.plugin(deepPopulate);
|
|
397
461
|
|
|
398
462
|
mongoose.model('Deal', Deal);
|