@dhyasama/totem-models 9.52.0 → 9.53.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 +1 -0
- package/lib/Deal.js +15 -1
- package/lib/Financials.js +4 -3
- package/lib/Message.js +18 -30
- package/lib/MessageRecipient.js +90 -0
- package/package.json +2 -1
package/index.js
CHANGED
|
@@ -57,6 +57,7 @@ var bootstrap = function(mongoose, config) {
|
|
|
57
57
|
require('./lib/Investment.js')(mongoose, config);
|
|
58
58
|
require('./lib/List.js')(mongoose, config);
|
|
59
59
|
require('./lib/Message.js')(mongoose, config);
|
|
60
|
+
require('./lib/MessageRecipient.js')(mongoose, config);
|
|
60
61
|
require('./lib/News.js')(mongoose, config);
|
|
61
62
|
require('./lib/Snapshot.js')(mongoose, config);
|
|
62
63
|
require('./lib/Sync.js')(mongoose, config);
|
package/lib/Deal.js
CHANGED
|
@@ -59,7 +59,11 @@ module.exports = function(mongoose, config) {
|
|
|
59
59
|
description: { type: String, trim: true, required: true }
|
|
60
60
|
}],
|
|
61
61
|
|
|
62
|
-
customFields: { type: Schema.Types.Mixed }
|
|
62
|
+
customFields: { type: Schema.Types.Mixed },
|
|
63
|
+
|
|
64
|
+
latestInteraction: { type: Schema.ObjectId, ref: 'Interaction', required: false },
|
|
65
|
+
|
|
66
|
+
latestMessage: { type: Schema.ObjectId, ref: 'Message', required: false }
|
|
63
67
|
|
|
64
68
|
});
|
|
65
69
|
|
|
@@ -210,6 +214,16 @@ module.exports = function(mongoose, config) {
|
|
|
210
214
|
};
|
|
211
215
|
|
|
212
216
|
let query = self.find(terms);
|
|
217
|
+
|
|
218
|
+
if (options.populate) {
|
|
219
|
+
query.populate({ path: 'documents', match: { customer: options.CUSTOMER_ID } });
|
|
220
|
+
query.populate({ path: 'messages', match: { customer: options.CUSTOMER_ID }, select: '-raw' });
|
|
221
|
+
query.populate('organization', 'name aliases description logoUrl website websiteAliases chairs contact people');
|
|
222
|
+
query.populate('referrer.person', 'name avatarUrl title');
|
|
223
|
+
query.populate('latestInteraction');
|
|
224
|
+
query.populate('latestMessage');
|
|
225
|
+
}
|
|
226
|
+
|
|
213
227
|
query.exec(cb);
|
|
214
228
|
|
|
215
229
|
};
|
package/lib/Financials.js
CHANGED
|
@@ -84,6 +84,7 @@ module.exports = function(mongoose, config) {
|
|
|
84
84
|
type: { type: String, enum: [null, 'header', 'block', 'document', 'metric', 'question']}
|
|
85
85
|
}],
|
|
86
86
|
|
|
87
|
+
// health block
|
|
87
88
|
cash: {
|
|
88
89
|
amount: { type: Number, default: 0 },
|
|
89
90
|
},
|
|
@@ -99,7 +100,7 @@ module.exports = function(mongoose, config) {
|
|
|
99
100
|
period: { type: String, enum: [null, 'monthly', 'quarterly', 'yearly']},
|
|
100
101
|
},
|
|
101
102
|
|
|
102
|
-
// income statement
|
|
103
|
+
// income statement block
|
|
103
104
|
revenue: {
|
|
104
105
|
amount: { type: Number, default: 0 },
|
|
105
106
|
projected: { type: Number, default: 0 },
|
|
@@ -121,7 +122,7 @@ module.exports = function(mongoose, config) {
|
|
|
121
122
|
breakdown: { type: Schema.Types.Mixed }
|
|
122
123
|
},
|
|
123
124
|
|
|
124
|
-
// balance sheet
|
|
125
|
+
// balance sheet block
|
|
125
126
|
assets: {
|
|
126
127
|
amount: { type: Number, default: 0 },
|
|
127
128
|
breakdown: { type: Schema.Types.Mixed }
|
|
@@ -135,7 +136,7 @@ module.exports = function(mongoose, config) {
|
|
|
135
136
|
breakdown: { type: Schema.Types.Mixed }
|
|
136
137
|
},
|
|
137
138
|
|
|
138
|
-
// cash flow
|
|
139
|
+
// cash flow block
|
|
139
140
|
operatingActivities: {
|
|
140
141
|
amount: { type: Number, default: 0 },
|
|
141
142
|
breakdown: { type: Schema.Types.Mixed }
|
package/lib/Message.js
CHANGED
|
@@ -30,21 +30,8 @@ module.exports = function(mongoose, config) {
|
|
|
30
30
|
},
|
|
31
31
|
notes: [ { type: Schema.ObjectId, ref: 'Note' } ],
|
|
32
32
|
documents: [ { type: Schema.ObjectId, ref: 'Document' } ],
|
|
33
|
-
raw: { type: Schema.Types.Mixed, required: true }
|
|
34
|
-
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
///////////////////////////////////////
|
|
38
|
-
|
|
39
|
-
Message.virtual('messageDate').get(function () {
|
|
40
|
-
|
|
41
|
-
// A little helper to get the message date since
|
|
42
|
-
// the original message date isn't always contained
|
|
43
|
-
// in the email. In its absence, use created on.
|
|
44
|
-
|
|
45
|
-
const self = this;
|
|
46
|
-
|
|
47
|
-
return self.originalMessageDate || self.createdOn;
|
|
33
|
+
raw: { type: Schema.Types.Mixed, required: true },
|
|
34
|
+
messageDate: { type: Date, required: true },
|
|
48
35
|
|
|
49
36
|
});
|
|
50
37
|
|
|
@@ -242,28 +229,23 @@ module.exports = function(mongoose, config) {
|
|
|
242
229
|
|
|
243
230
|
const self = this;
|
|
244
231
|
|
|
232
|
+
// Must match customer
|
|
245
233
|
let query = self.find({ customer: options.CUSTOMER_ID });
|
|
246
234
|
|
|
235
|
+
// Match either the org or a list of people
|
|
247
236
|
query.where({ $or: [{organization: orgId}, {'recipients.external': { $in : personIds }}] });
|
|
248
237
|
|
|
249
|
-
|
|
238
|
+
// Optionally limit search space to message newer than some timestamp
|
|
239
|
+
if (options.timestamp) query.where({'messageDate': { $gte: options.timestamp }});
|
|
250
240
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
else if (!messages) {
|
|
255
|
-
return cb(null, null);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
messages = _.sortBy(messages, function(message) {
|
|
259
|
-
return message.originalMessageDate || message.createdOn;
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
var message = _.last(messages);
|
|
241
|
+
// Don't need the full raw message
|
|
242
|
+
query.select({ 'raw': -1 });
|
|
263
243
|
|
|
264
|
-
|
|
244
|
+
// Only need one
|
|
245
|
+
query.sort({ 'messageDate': -1 });
|
|
246
|
+
query.limit(1);
|
|
265
247
|
|
|
266
|
-
|
|
248
|
+
query.exec(cb);
|
|
267
249
|
|
|
268
250
|
};
|
|
269
251
|
|
|
@@ -409,9 +391,15 @@ module.exports = function(mongoose, config) {
|
|
|
409
391
|
|
|
410
392
|
const timestamp = new Date();
|
|
411
393
|
|
|
394
|
+
// Use now if created on is empty
|
|
412
395
|
message.createdOn = message.createdOn || timestamp;
|
|
396
|
+
|
|
397
|
+
// Updated on is always now
|
|
413
398
|
message.updatedOn = timestamp;
|
|
414
399
|
|
|
400
|
+
// The original message date isn't always contained in the email. In its absence, use created on.
|
|
401
|
+
message.messageDate = message.messageDate || message.originalMessageDate || message.createdOn;
|
|
402
|
+
|
|
415
403
|
message.save(cb);
|
|
416
404
|
|
|
417
405
|
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
module.exports = function(mongoose, config) {
|
|
4
|
+
|
|
5
|
+
let Schema = mongoose.Schema;
|
|
6
|
+
|
|
7
|
+
let MessageRecipient = new Schema({
|
|
8
|
+
|
|
9
|
+
message: { type: Schema.ObjectId, ref: 'Message', required: true },
|
|
10
|
+
customer: { type: Schema.ObjectId, ref: 'Organization', required: true },
|
|
11
|
+
organization: { type: Schema.ObjectId, ref: 'Organization', required: true },
|
|
12
|
+
recipient: { type: Schema.ObjectId, ref: 'Person', required: true },
|
|
13
|
+
messageDate: { type: Date, required: true },
|
|
14
|
+
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
///////////////////////////////////////
|
|
18
|
+
|
|
19
|
+
MessageRecipient.statics.getMostRecent = function getMostRecent(orgId, customerId, personId, options, cb) {
|
|
20
|
+
|
|
21
|
+
if (!cb) { throw new Error('cb is required'); }
|
|
22
|
+
if (!orgId) { return cb(new Error('orgId is required'), null); }
|
|
23
|
+
if (!mongoose.Types.ObjectId.isValid(orgId)) { return cb(new Error('orgId is not a valid ObjectId'), null); }
|
|
24
|
+
if (!customerId) { return cb(new Error('customerId is required'), null); }
|
|
25
|
+
if (!mongoose.Types.ObjectId.isValid(customerId)) { return cb(new Error('customerId is not a valid ObjectId'), null); }
|
|
26
|
+
if (!personId) { return cb(new Error('personId is required'), null); }
|
|
27
|
+
if (!mongoose.Types.ObjectId.isValid(personId)) { return cb(new Error('personId is not a valid ObjectId'), null); }
|
|
28
|
+
|
|
29
|
+
const self = this;
|
|
30
|
+
|
|
31
|
+
options = options || {};
|
|
32
|
+
|
|
33
|
+
let query = self.find({
|
|
34
|
+
customer: options.CUSTOMER_ID,
|
|
35
|
+
organization: orgId,
|
|
36
|
+
recipient: personId
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Optionally limit search space to message newer than some timestamp
|
|
40
|
+
if (options.timestamp) query.where({'messageDate': { $gte: options.timestamp }});
|
|
41
|
+
|
|
42
|
+
// Only need one
|
|
43
|
+
query.sort({ 'messageDate': -1 });
|
|
44
|
+
query.limit(1);
|
|
45
|
+
|
|
46
|
+
query.exec(cb);
|
|
47
|
+
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
MessageRecipient.statics.getMostRecentBatch = function getMostRecentBatch(orgId, customerId, personIds, options, cb) {
|
|
51
|
+
|
|
52
|
+
if (!cb) { throw new Error('cb is required'); }
|
|
53
|
+
if (!orgId) { return cb(new Error('orgId is required'), null); }
|
|
54
|
+
if (!mongoose.Types.ObjectId.isValid(orgId)) { return cb(new Error('orgId is not a valid ObjectId'), null); }
|
|
55
|
+
if (!customerId) { return cb(new Error('customerId is required'), null); }
|
|
56
|
+
if (!mongoose.Types.ObjectId.isValid(customerId)) { return cb(new Error('customerId is not a valid ObjectId'), null); }
|
|
57
|
+
if (!personIds) { return cb(new Error('personIds is required'), null); }
|
|
58
|
+
if (!Array.isArray(personIds)) { return cb(new Error('personIds must be an array'), null); }
|
|
59
|
+
|
|
60
|
+
const self = this;
|
|
61
|
+
|
|
62
|
+
options = options || {};
|
|
63
|
+
|
|
64
|
+
let query = self.find({
|
|
65
|
+
customer: options.CUSTOMER_ID,
|
|
66
|
+
organization: orgId
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
query.where({ 'recipient': { $in : personIds }});
|
|
70
|
+
|
|
71
|
+
// Optionally limit search space to message newer than some timestamp
|
|
72
|
+
if (options.timestamp) query.where({'messageDate': { $gte: options.timestamp }});
|
|
73
|
+
|
|
74
|
+
// Only need one
|
|
75
|
+
query.sort({ 'messageDate': -1 });
|
|
76
|
+
query.limit(1);
|
|
77
|
+
|
|
78
|
+
query.exec(cb);
|
|
79
|
+
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
MessageRecipient.statics.upsert = function(message, cb) {
|
|
83
|
+
message.save(cb);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
///////////////////////////////////////
|
|
87
|
+
|
|
88
|
+
mongoose.model('MessageRecipient', MessageRecipient);
|
|
89
|
+
|
|
90
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dhyasama/totem-models",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.53.0",
|
|
4
4
|
"author": "Jason Reynolds",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"description": "Models for Totem platform",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@dhyasama/totem-utilities": "^3.0.0",
|
|
19
|
+
"algoliasearch": "^4.13.0",
|
|
19
20
|
"async": "^2.6.3",
|
|
20
21
|
"awesome-phonenumber": "^1.0.14",
|
|
21
22
|
"bluebird": "^3.7.2",
|