@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 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
- query.exec(function (err, messages) {
238
+ // Optionally limit search space to message newer than some timestamp
239
+ if (options.timestamp) query.where({'messageDate': { $gte: options.timestamp }});
250
240
 
251
- if (err) {
252
- return cb(err, null);
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
- return cb(null, message);
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.52.0",
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",