@dhyasama/totem-models 4.7.1 → 5.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/index.js CHANGED
@@ -19,6 +19,9 @@ var bootstrap = function(mongoose, config) {
19
19
 
20
20
  // todo - find a solution to load without worrying about order
21
21
 
22
+ // deal must be loaded before organization
23
+ require('./lib/Deal.js')(mongoose, config);
24
+
22
25
  // flag must be loaded before fund
23
26
  // flag must be loaded before limited partner
24
27
  // flag must be loaded before organization
package/lib/Deal.js ADDED
@@ -0,0 +1,240 @@
1
+ "use strict";
2
+
3
+ module.exports = function(mongoose, config) {
4
+
5
+ var
6
+
7
+ Schema = mongoose.Schema,
8
+ postFind = require('mongoose-post-find'),
9
+ _ = require('underscore');
10
+
11
+ var Deal = new Schema({
12
+
13
+ customer: { type: Schema.ObjectId, ref: 'Organization', required: true },
14
+
15
+ organization: { type: Schema.ObjectId, ref: 'Organization', required: true },
16
+
17
+ stage: { type: String, trim: true, required: true },
18
+
19
+ sources: [{
20
+ person: { type: Schema.ObjectId, ref: 'Person', required: true },
21
+ type: { type: String, enum: ['Inbound', 'Outbound', 'Event', 'Referral', 'Other'], required: true }
22
+ }],
23
+
24
+ referrers: [{
25
+ person: { type: Schema.ObjectId, ref: 'Person', required: true },
26
+ type: { type: String, enum: ['Founder', 'Investor', 'Service provider', 'Friends and family', 'Limited partner', 'Other'], required: true }
27
+ }],
28
+
29
+ documents: [ { type: Schema.ObjectId, ref: 'Document' } ],
30
+
31
+ messages: [ { type: Schema.ObjectId, ref: 'Message' } ],
32
+
33
+ fundraise: {
34
+ amount: { type: Number, default: 0 },
35
+ valuation: { type: Number, default: 0 },
36
+ details: [{
37
+ key: { type: String, trim: true, required: true },
38
+ value: { type: String, trim: true, required: true },
39
+ }]
40
+ },
41
+
42
+ resources: [{
43
+ title: { type: String, trim: true, required: true },
44
+ link: { type: String, trim: true, required: true },
45
+ }],
46
+
47
+ history: [{
48
+ timestamp: { type: String, required: true },
49
+ account: { type: Schema.ObjectId, ref: 'Account', required: true },
50
+ stage: { type: String, required: true },
51
+ description: { type: String, trim: true, required: true }
52
+ }]
53
+
54
+ });
55
+
56
+
57
+
58
+ ///////////////////////////////////////////////////////////////////////////////////////
59
+ // VIRTUALS
60
+ // Properties that are not persisted to the database
61
+ ///////////////////////////////////////////////////////////////////////////////////////
62
+
63
+
64
+
65
+ ///////////////////////////////////////////////////////////////////////////////////////
66
+ // METHODS
67
+ // Methods operate on a single document that has already been returned
68
+ // Note that running a method on a document does not save it
69
+ ///////////////////////////////////////////////////////////////////////////////////////
70
+
71
+
72
+
73
+ //////////////////////////////////////////////////////
74
+ // STATICS
75
+ // Statics operate on the entire collection
76
+ //////////////////////////////////////////////////////
77
+
78
+ Deal.statics.delete = function(id, cb) {
79
+
80
+ var self = this;
81
+
82
+ // Not strictly necessary but provides verification that the document being deleted belongs to the customer doing the deleting
83
+ self.findOne({
84
+ '_id': id,
85
+ 'customer': config.CUSTOMER_ID
86
+ }, function(err, deal) {
87
+
88
+ if (err) return cb(err, null);
89
+ else if (!deal) return cb(null, null);
90
+
91
+ deal.remove(cb);
92
+
93
+ });
94
+
95
+ };
96
+
97
+ Deal.statics.getAll = function (cb) {
98
+ this.find({}).exec(cb);
99
+ };
100
+
101
+ Deal.statics.getById = function (id, cb) {
102
+
103
+ var self = this;
104
+
105
+ self.findOne({
106
+ '_id': id,
107
+ 'customer': config.CUSTOMER_ID
108
+ })
109
+ .populate('organization', 'name logoUrl website websiteAliases')
110
+ .populate('messages')
111
+ .populate('sources.person', 'name avatarUrl title')
112
+ .populate({
113
+ path: 'documents',
114
+ match: { customer: config.CUSTOMER_ID }
115
+ })
116
+ .populate('history.account', 'person')
117
+ .exec(cb);
118
+
119
+ };
120
+
121
+ // Get all deals belonging to a customer
122
+ Deal.statics.getForCustomer = function (customerId, cb) {
123
+
124
+ var self = this;
125
+
126
+ self
127
+ .find({ 'customer': customerId })
128
+ .populate('organization', 'name logoUrl website websiteAliases')
129
+ .populate('messages')
130
+ .populate('sources.person', 'name avatarUrl')
131
+ .populate({
132
+ path: 'documents',
133
+ match: { customer: customerId }
134
+ })
135
+ .exec(cb);
136
+
137
+ };
138
+
139
+ // Get a deal for a org, belonging to current customer
140
+ Deal.statics.getForOrg = function (orgId, cb) {
141
+
142
+ var self = this;
143
+
144
+ self
145
+ .findOne({
146
+ 'organization': orgId,
147
+ 'customer': config.CUSTOMER_ID
148
+ })
149
+ .populate('organization', 'name logoUrl website websiteAliases')
150
+ .populate('messages')
151
+ .populate('sources.person', 'name avatarUrl title')
152
+ .populate({
153
+ path: 'documents',
154
+ match: { customer: config.CUSTOMER_ID }
155
+ })
156
+ .populate('history.account', 'person')
157
+ .exec(cb);
158
+ };
159
+
160
+ Deal.statics.upsert = function upsert(deal, user, cb) {
161
+
162
+ // Deal is dumb and doesn't validate customer stages or duplicate deals. That responsibility is with the org.
163
+
164
+ if (!deal) { return cb(new Error('deal is required'), null); }
165
+
166
+ var getLastStage = function() {
167
+
168
+ if (!deal.history || deal.history.length == 0) return null;
169
+
170
+ var history = _.sortBy(deal.history);
171
+ var last = history[history.length - 1];
172
+
173
+ return last.stage;
174
+
175
+ };
176
+
177
+ var description = '';
178
+ var lastStage = getLastStage();
179
+
180
+ if (lastStage == null) description = 'The deal was created';
181
+ else if (lastStage != deal.stage) description += 'The deal was updated from ' + lastStage + ' to ' + deal.stage;
182
+ else description = 'The deal was updated';
183
+
184
+ deal.history.push({
185
+ timestamp: new Date(),
186
+ account: user,
187
+ stage: deal.stage,
188
+ description: description
189
+ });
190
+
191
+ deal.save(cb);
192
+
193
+ };
194
+
195
+ Deal.plugin(postFind, {
196
+
197
+ find: function(results, done) {
198
+
199
+ var CUSTOMER_ID = config.CUSTOMER_ID;
200
+
201
+ if (CUSTOMER_ID == 'GLOBAL_PROCESS') return done(null, results);
202
+
203
+ // Reject any item that is for a different customer
204
+ results = _.reject(results, function(item) {
205
+ return item.customer.toString() != CUSTOMER_ID;
206
+ });
207
+
208
+ return done(null, results);
209
+
210
+ },
211
+
212
+ findOne: function(result, done) {
213
+
214
+ var CUSTOMER_ID = config.CUSTOMER_ID;
215
+
216
+ if (!result) return done(null, null);
217
+ else if (CUSTOMER_ID == 'GLOBAL_PROCESS') return done(null, result);
218
+ else if (result.customer.toString() == CUSTOMER_ID) return done(null, result);
219
+ else return done(null, null);
220
+
221
+ }
222
+
223
+ });
224
+
225
+
226
+
227
+ ///////////////////////////////////////////////////////////////////////////////////////
228
+ // CONFIG
229
+ ///////////////////////////////////////////////////////////////////////////////////////
230
+
231
+ Deal.set('toJSON', { virtuals: true });
232
+ Deal.set('autoIndex', false);
233
+ Deal.on('index', function(err) { console.log('error building deal indexes: ' + err); });
234
+
235
+ var deepPopulate = require('mongoose-deep-populate')(mongoose);
236
+ Deal.plugin(deepPopulate);
237
+
238
+ mongoose.model('Deal', Deal);
239
+
240
+ };
package/lib/Document.js CHANGED
@@ -30,9 +30,7 @@ module.exports = function(mongoose, config) {
30
30
  key: { type: String, required: true, trim: true }
31
31
  },
32
32
 
33
- type: { type: String, required: true, enum: ['deals', 'portfolio', 'other'] },
34
-
35
- subtype: { type: String, enum: [null, 'deck'] },
33
+ type: { type: String, enum: ['deck', 'other'], required: true },
36
34
 
37
35
  });
38
36
 
@@ -8,6 +8,7 @@ module.exports = function(mongoose, config) {
8
8
  async = require('async'),
9
9
  utils = require('@dhyasama/ffvc-utilities'),
10
10
  Schema = mongoose.Schema,
11
+ Deal = mongoose.model('Deal'),
11
12
  Flag = mongoose.model('Flag'),
12
13
  Note = mongoose.model('Note'),
13
14
  customerFunds = [],
@@ -33,16 +34,6 @@ module.exports = function(mongoose, config) {
33
34
  linkedin: { type: String, trim: true, unique: true, partialFilterExpression : { type :"string" } }
34
35
  },
35
36
 
36
- deals: [{
37
- customer: { type: Schema.ObjectId, ref: 'Organization' },
38
- status: { type: String, trim: true },
39
- history: [{
40
- timestamp: { type: String },
41
- account: { type: Schema.ObjectId, ref: 'Account' },
42
- status: { type: String }
43
- }]
44
- }],
45
-
46
37
  contact: {
47
38
 
48
39
  phone: [{
@@ -162,6 +153,9 @@ module.exports = function(mongoose, config) {
162
153
  // customer specific (customer id is stored on note)
163
154
  notes: [ { type: Schema.ObjectId, ref: 'Note' } ],
164
155
 
156
+ // customer specific (customer id is stored on deal)
157
+ deals: [ { type: Schema.ObjectId, ref: 'Deal' } ],
158
+
165
159
  // customer specific (customer id is stored on doc)
166
160
  documents: [ { type: Schema.ObjectId, ref: 'Document' } ],
167
161
 
@@ -183,6 +177,10 @@ module.exports = function(mongoose, config) {
183
177
 
184
178
  investmentsSheet: {
185
179
  sheet: { type: String, trim: true, unique: true, partialFilterExpression : { type :"string" } },
180
+ format: {
181
+ proceedsConsolidated: { type: Boolean },
182
+ unrealizedConsolidated: { type: Boolean }
183
+ },
186
184
  googleSheetCreds: {
187
185
  private_key_id: { type: String, trim: true, unique: true, partialFilterExpression : { type :"string" } },
188
186
  private_key: { type: String, trim: true, unique: true, partialFilterExpression : { type :"string" } },
@@ -679,6 +677,111 @@ module.exports = function(mongoose, config) {
679
677
  // Statics query the entire collection
680
678
  //////////////////////////////////////////////////////
681
679
 
680
+ Organization.statics.addDeal = function(deal, user, cb) {
681
+
682
+ var self = this;
683
+
684
+ var checkForDuplicates = function checkForDuplicates(previous, callback) {
685
+
686
+ // get org and make sure not already a deal for current customer
687
+
688
+ self.getById(utils.getIdAsString(previous.deal, 'organization'), {}, function(err, org) {
689
+
690
+ if (err) return callback(err, null);
691
+ else if (!org) return callback(new Error('Org not found'), null);
692
+ else if (org.deleted) return callback(new Error('Org deleted'), null);
693
+
694
+ var match = _.find(org.deals, function(d) {
695
+ return utils.getIdAsString(d, 'customer') == deal.customer._id.toString();
696
+ });
697
+
698
+ if (match) return callback(new Error('This org already has a deal for this customer'), null);
699
+
700
+ previous.org = org;
701
+
702
+ return callback(null, previous);
703
+
704
+ });
705
+
706
+ };
707
+
708
+ var validateStage = function validateStage(previous, callback) {
709
+
710
+ // check allowable deal stages against the new deal
711
+
712
+ self.findById(deal.customer, function(err, org) {
713
+
714
+ if (err) return callback(err, null);
715
+ else if (!org) return callback(new Error('Customer not found'), null);
716
+
717
+ var statuses = org.customer.deals.activeStatuses;
718
+
719
+ var match = _.find(statuses, function(status) {
720
+ return status == previous.deal.stage;
721
+ });
722
+
723
+ if (!match) return callback(new Error('This stage is not valid for this customer'), null);
724
+
725
+ return callback(null, previous);
726
+
727
+ });
728
+
729
+ };
730
+
731
+ var createDeal = function createDeal(previous, callback) {
732
+
733
+ Deal.upsert(previous.deal, previous.user, function(err, result) {
734
+
735
+ if (err) return callback(err, null);
736
+
737
+ previous.deal = result;
738
+
739
+ return callback(null, previous);
740
+
741
+ });
742
+
743
+ };
744
+
745
+ var addDealToOrg = function addDealToOrg(previous, callback) {
746
+
747
+ previous.org.deals.push(previous.deal);
748
+
749
+ self.upsert(previous.org, previous.user.username, function(err, result) {
750
+
751
+ if (err) return callback(err, null);
752
+
753
+ previous.org = result;
754
+
755
+ return callback(null, previous);
756
+
757
+ });
758
+
759
+ };
760
+
761
+ var previous = {
762
+ deal: deal,
763
+ user: user,
764
+ org: null
765
+ };
766
+
767
+ async.waterfall([
768
+ checkForDuplicates.bind(null, previous),
769
+ validateStage,
770
+ createDeal,
771
+ addDealToOrg
772
+ ], function(err, results) {
773
+
774
+ if (err) return cb(err, null);
775
+
776
+ return cb(null, {
777
+ org: results.org,
778
+ deal: results.deal
779
+ });
780
+
781
+ });
782
+
783
+ };
784
+
682
785
  Organization.statics.addFlag = function(organizationId, creatorPersonId, text, cb) {
683
786
 
684
787
  Flag.createForModel({
@@ -697,6 +800,27 @@ module.exports = function(mongoose, config) {
697
800
 
698
801
  };
699
802
 
803
+ Organization.statics.deleteDeal = function(dealId, cb) {
804
+
805
+ // Delete the deal itself along with any references
806
+
807
+ var self = this;
808
+
809
+ var removeReferences = function removeReferences(callback) {
810
+ self.update({}, {
811
+ $pull: { 'deals' : [dealId] }
812
+ }, callback);
813
+ };
814
+
815
+ async.series([
816
+ Deal.delete.bind(Deal, dealId),
817
+ removeReferences
818
+ ], function(err, results) {
819
+ return cb(err, null);
820
+ });
821
+
822
+ };
823
+
700
824
  Organization.statics.deleteFlag = function(flagId, cb) {
701
825
 
702
826
  // Delete the flag itself along with reference
@@ -977,6 +1101,7 @@ module.exports = function(mongoose, config) {
977
1101
  if (config.CUSTOMER_ID != 'GLOBAL_PROCESS') lpPopulateOptions.match = { customer: config.CUSTOMER_ID };
978
1102
 
979
1103
  var query = self.findById(id);
1104
+
980
1105
  query.populate('people.person', 'name avatarUrl title contact doNotDisplay');
981
1106
  query.populate('related', 'name logoUrl');
982
1107
  query.populate('chairs.first', 'name avatarUrl title');
@@ -985,9 +1110,17 @@ module.exports = function(mongoose, config) {
985
1110
  query.populate('operating.acquired.public.by', 'name logoUrl');
986
1111
  query.populate('operating.acquired.private.by', 'name logoUrl');
987
1112
 
1113
+ query.populate({
1114
+ path: 'deals',
1115
+ match: { customer: config.CUSTOMER_ID }
1116
+ });
1117
+
988
1118
  if (options.role != 'none') {
989
1119
  query.populate(lpPopulateOptions);
990
1120
  query.deepPopulate([
1121
+ 'deals.sources.person',
1122
+ 'documents',
1123
+ 'history.account',
991
1124
  'lps.fundsInvested.fund'
992
1125
  ], {
993
1126
  populate: {
@@ -995,6 +1128,13 @@ module.exports = function(mongoose, config) {
995
1128
  }
996
1129
  })
997
1130
  }
1131
+ else {
1132
+ query.deepPopulate([
1133
+ 'deals.sources.person',
1134
+ 'documents',
1135
+ 'history.account'
1136
+ ]);
1137
+ }
998
1138
 
999
1139
  query.exec(cb);
1000
1140
 
@@ -1045,33 +1185,6 @@ module.exports = function(mongoose, config) {
1045
1185
 
1046
1186
  };
1047
1187
 
1048
- Organization.statics.getDeals = function getDeals(customerId, cb) {
1049
-
1050
- var self = this;
1051
-
1052
- self
1053
- .find({ 'deals.customer': customerId, 'deleted': { $ne: true } })
1054
- .select('name website websiteAliases deals')
1055
- .exec(function(err, result) {
1056
-
1057
- if (err) return cb(err, null);
1058
-
1059
- result.deals = _.reject(result.deals, function(item) { return !item.customer || item.customer.toString() != customerId.toString(); });
1060
- result = _.map(result, function(item) {
1061
- return {
1062
- name: item.name,
1063
- website: item.website,
1064
- websiteAliases: item.websiteAliases,
1065
- deals: item.deals
1066
- }
1067
- });
1068
-
1069
- return cb(null, result);
1070
-
1071
- });
1072
-
1073
- };
1074
-
1075
1188
  Organization.statics.getFlags = function getFlags(orgid, cb) {
1076
1189
 
1077
1190
  var self = this;
@@ -1628,7 +1741,6 @@ module.exports = function(mongoose, config) {
1628
1741
  doc.chairs = _.reject(doc.chairs, function(item) { return !item.customer || item.customer.toString() != CUSTOMER_ID; });
1629
1742
  doc.operating.acquired.private = _.find(doc.operating.acquired.private, function(item) { return !item.customer || item.customer.toString() == CUSTOMER_ID; });
1630
1743
  doc.operating.closed.private = _.find(doc.operating.closed.private, function(item) { return !item.customer || item.customer.toString() == CUSTOMER_ID; });
1631
- doc.deals = _.reject(doc.deals, function(item) { return !item.customer || item.customer.toString() != CUSTOMER_ID; });
1632
1744
 
1633
1745
  // people
1634
1746
  _.each(doc.people, function(person) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhyasama/totem-models",
3
- "version": "4.7.1",
3
+ "version": "5.0.0",
4
4
  "author": "Jason Reynolds",
5
5
  "license": "UNLICENSED",
6
6
  "description": "Models for Totem platform",
package/test/Deal.js ADDED
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+
3
+ var
4
+
5
+ should = require("should"),
6
+ config = require('./config')['test'],
7
+ _ = require('underscore'),
8
+ mongoose = require('mongoose'),
9
+ clearDB = require('mocha-mongoose')(config.db.uri, {noClear: true}),
10
+ Account = mongoose.model('Account'),
11
+ Deal = mongoose.model('Deal'),
12
+ Organization = mongoose.model('Organization');
13
+
14
+ var org;
15
+ var customer;
16
+ var dealId;
17
+ var account;
18
+
19
+ describe('Deal', function() {
20
+
21
+ before(function(done) {
22
+ if (mongoose.connection.db) return done();
23
+ mongoose.connect(config.db.uri, done);
24
+ });
25
+
26
+ before(function(done) {
27
+ clearDB(done);
28
+ });
29
+
30
+ before(function(done) {
31
+
32
+ org = new Organization();
33
+ org.name = 'Big Org';
34
+ org.slug = 'big-org';
35
+
36
+ Organization.upsert(org, 'test', function(err, result) {
37
+
38
+ should.not.exist(err);
39
+ should.exist(result);
40
+
41
+ org = result;
42
+
43
+ return done();
44
+
45
+ });
46
+
47
+ });
48
+
49
+ before(function(done) {
50
+
51
+ customer = new Organization();
52
+ customer.name = 'HUGE VC';
53
+ customer.slug = 'huge-vc';
54
+
55
+ Organization.upsert(customer, 'test', function(err, result) {
56
+
57
+ should.not.exist(err);
58
+ should.exist(result);
59
+
60
+ customer = result;
61
+
62
+ config.CUSTOMER_ID = customer._id.toString();
63
+
64
+ return done();
65
+
66
+ });
67
+
68
+ });
69
+
70
+ before(function (done) {
71
+
72
+ account = new Account();
73
+ account.username = 'test-user';
74
+ account.email = 'test@totemvc.com';
75
+ account.person = new mongoose.Types.ObjectId();
76
+
77
+ Account.upsert(account, function (err, result) {
78
+
79
+ should.not.exist(err);
80
+ should.exist(result);
81
+
82
+ account = result;
83
+
84
+ return done();
85
+
86
+ });
87
+
88
+ });
89
+
90
+ it('creates a deal', function(done) {
91
+
92
+ var deal = new Deal({
93
+ customer: customer,
94
+ organization: org,
95
+ stage: 'New'
96
+ });
97
+
98
+ Deal.upsert(deal, account, function(err, result) {
99
+
100
+ should.not.exist(err);
101
+ should.exist(result);
102
+
103
+ dealId = result._id;
104
+
105
+ return done();
106
+
107
+ });
108
+
109
+ });
110
+
111
+ it('gets a deal by id', function(done) {
112
+ Deal.getById(dealId, function(err, result) {
113
+ should.not.exist(err);
114
+ should.exist(result);
115
+ result._id.toString().should.equal(dealId.toString());
116
+ return done();
117
+ });
118
+ });
119
+
120
+ it('adds a document to a deal', function(done) {
121
+
122
+ Deal.getById(dealId, function(err, deal) {
123
+
124
+ should.not.exist(err);
125
+ should.exist(deal);
126
+
127
+ deal.documents.push(new mongoose.Types.ObjectId());
128
+
129
+ Deal.upsert(deal, account, function(err, result) {
130
+
131
+ should.not.exist(err);
132
+ should.exist(result);
133
+ return done();
134
+
135
+ });
136
+
137
+ });
138
+
139
+ });
140
+
141
+ it('changes the deal stage', function(done) {
142
+
143
+ Deal.getById(dealId, function(err, deal) {
144
+
145
+ should.not.exist(err);
146
+ should.exist(deal);
147
+
148
+ deal.stage = 'Pass';
149
+
150
+ Deal.upsert(deal, account, function(err, result) {
151
+
152
+ should.not.exist(err);
153
+ should.exist(result);
154
+ return done();
155
+
156
+ });
157
+
158
+ });
159
+
160
+ });
161
+
162
+ it('gets all deals for a customer', function(done) {
163
+
164
+ var d = new Deal({
165
+ customer: customer,
166
+ organization: new mongoose.Types.ObjectId(),
167
+ stage: 'New'
168
+ });
169
+
170
+ Deal.upsert(d, account, function(err, result) {
171
+
172
+ should.not.exist(err);
173
+ should.exist(result);
174
+
175
+ var d = new Deal({
176
+ customer: new mongoose.Types.ObjectId(),
177
+ organization: new mongoose.Types.ObjectId(),
178
+ stage: 'New'
179
+ });
180
+
181
+ Deal.upsert(d, account, function(err, result) {
182
+
183
+ should.not.exist(err);
184
+ should.exist(result);
185
+
186
+ Deal.getForCustomer(config.CUSTOMER_ID, function(err, result) {
187
+ should.not.exist(err);
188
+ should.exist(result)
189
+ result.length.should.equal(2);
190
+ return done();
191
+ });
192
+
193
+ });
194
+
195
+ });
196
+
197
+ });
198
+
199
+ it('gets all deals', function(done) {
200
+
201
+ var temp = config.CUSTOMER_ID;
202
+ config.CUSTOMER_ID = 'GLOBAL_PROCESS';
203
+
204
+ Deal.getAll(function(err, result) {
205
+ should.not.exist(err);
206
+ should.exist(result)
207
+ result.length.should.equal(3);
208
+ config.CUSTOMER_ID = temp;
209
+ return done();
210
+ });
211
+
212
+ });
213
+
214
+ it('deletes a deal', function(done) {
215
+ Deal.delete(dealId, function(err, result) {
216
+ should.not.exist(err);
217
+ should.exist(result);
218
+ return done();
219
+ });
220
+ });
221
+
222
+ });
package/test/Document.js CHANGED
@@ -7,13 +7,15 @@ var
7
7
  _ = require('underscore'),
8
8
  mongoose = require('mongoose'),
9
9
  clearDB = require('mocha-mongoose')(config.db.uri, {noClear: true}),
10
+ Account = mongoose.model('Account'),
11
+ Deal = mongoose.model('Deal'),
10
12
  Document = mongoose.model('Document'),
11
13
  Interaction = mongoose.model('Interaction'),
12
14
  Message = mongoose.model('Message'),
13
15
  Organization = mongoose.model('Organization'),
14
16
  Person = mongoose.model('Person');
15
17
 
16
- var interaction, message, org, person, documentCreator, documentId;
18
+ var deal, account, interaction, message, org, person, documentCreator, documentId;
17
19
 
18
20
  describe('Document', function() {
19
21
 
@@ -96,6 +98,45 @@ describe('Document', function() {
96
98
 
97
99
  });
98
100
 
101
+ before(function (done) {
102
+
103
+ account = new Account();
104
+ account.username = 'test-user';
105
+ account.email = 'test@totemvc.com';
106
+ account.person = new mongoose.Types.ObjectId();
107
+
108
+ Account.upsert(account, function (err, result) {
109
+
110
+ should.not.exist(err);
111
+ should.exist(result);
112
+
113
+ account = result;
114
+
115
+ return done();
116
+
117
+ });
118
+
119
+ });
120
+
121
+ before(function(done) {
122
+
123
+ deal = new Deal();
124
+ deal.customer = new mongoose.Types.ObjectId();
125
+ deal.organization = new mongoose.Types.ObjectId();
126
+ deal.stage = 'New';
127
+
128
+ Deal.upsert(deal, account, function(err, result) {
129
+
130
+ should.not.exist(err);
131
+ should.exist(result);
132
+ deal = result;
133
+
134
+ return done();
135
+
136
+ });
137
+
138
+ });
139
+
99
140
  before(function(done) {
100
141
 
101
142
  person = new Person();
@@ -177,7 +218,7 @@ describe('Document', function() {
177
218
  bucket: 'totem',
178
219
  key: 'docs'
179
220
  },
180
- type: 'deals'
221
+ type: 'other'
181
222
  }, Message, message._id, function(err, result) {
182
223
 
183
224
  should.not.exist(err);
@@ -204,7 +245,7 @@ describe('Document', function() {
204
245
  bucket: 'totem',
205
246
  key: 'docs'
206
247
  },
207
- type: 'portfolio'
248
+ type: 'other'
208
249
  }, Organization, org._id, function(err, result) {
209
250
 
210
251
  should.not.exist(err);
@@ -248,6 +289,33 @@ describe('Document', function() {
248
289
 
249
290
  });
250
291
 
292
+ it('creates a document for a deal', function(done) {
293
+
294
+ Document.createForModel({
295
+ customer: config.CUSTOMER_ID,
296
+ createdBy: documentCreator,
297
+ name: 'test.pdf',
298
+ contentType: 'application/pdf',
299
+ contentLength: 54321,
300
+ s3: {
301
+ bucket: 'totem',
302
+ key: 'docs'
303
+ },
304
+ type: 'deck'
305
+ }, Deal, deal._id, function(err, result) {
306
+
307
+ should.not.exist(err);
308
+ should.exist(result);
309
+ should.exist(result.document);
310
+ should.exist(result.addedTo);
311
+ result.addedTo.documents.length.should.equal(1);
312
+
313
+ return done();
314
+
315
+ });
316
+
317
+ });
318
+
251
319
  it('gets a document by id', function(done) {
252
320
  Document.getById(documentId, function(err, result) {
253
321
  should.not.exist(err);
@@ -11,17 +11,17 @@ var
11
11
  Person = mongoose.model('Person'),
12
12
  LimitedPartner = mongoose.model('LimitedPartner'),
13
13
  Fund = mongoose.model('Fund'),
14
- Note = mongoose.model('Note'),
14
+ Deal = mongoose.model('Deal'),
15
15
  Account = mongoose.model('Account');
16
16
 
17
17
  var person, person1, person2;
18
18
  var noteId;
19
- var eventNote;
20
19
  var flagId;
21
20
  var someOtherFund;
22
21
  var someOtherLp;
23
22
  var account;
24
23
  var customer1, customer2;
24
+ var deal;
25
25
 
26
26
  describe('Organization', function() {
27
27
 
@@ -1131,8 +1131,6 @@ describe('Organization', function() {
1131
1131
 
1132
1132
  describe('Deals', function() {
1133
1133
 
1134
- var org;
1135
-
1136
1134
  it('gets deal statuses for a customer', function(done) {
1137
1135
 
1138
1136
  var statuses = customer1.customer.deals.activeStatuses;
@@ -1148,29 +1146,23 @@ describe('Organization', function() {
1148
1146
 
1149
1147
  it('adds a deal', function(done) {
1150
1148
 
1151
- org = new Organization();
1152
- org.name = 'New Co';
1153
- org.slug = 'new-co';
1154
- org.website = 'new.co';
1149
+ config.CUSTOMER_ID = customer1._id.toString();
1155
1150
 
1156
- Organization.upsert(org, 'test-user', function(err, result) {
1151
+ deal = new Deal({
1152
+ customer: customer1,
1153
+ organization: org3,
1154
+ stage: 'New'
1155
+ });
1156
+
1157
+ Organization.addDeal(deal, account, function(err, result) {
1157
1158
 
1158
1159
  should.not.exist(err);
1159
1160
  should.exist(result);
1161
+ result.org.deals.length.should.equal(1);
1160
1162
 
1161
- result.addDeal('New', customer1, account);
1162
-
1163
- Organization.upsert(result, 'test-user', function(err, result) {
1164
-
1165
- should.not.exist(err);
1166
- should.exist(result);
1167
- result.deals.length.should.equal(1);
1168
-
1169
- org = result;
1170
-
1171
- return done();
1163
+ deal = result.deal;
1172
1164
 
1173
- });
1165
+ return done();
1174
1166
 
1175
1167
  });
1176
1168
 
@@ -1178,60 +1170,65 @@ describe('Organization', function() {
1178
1170
 
1179
1171
  it('adds a deal again', function(done) {
1180
1172
 
1181
- var threwError = false;
1173
+ var d = new Deal({
1174
+ customer: customer1,
1175
+ organization: org3,
1176
+ stage: 'New'
1177
+ });
1178
+
1179
+ Organization.addDeal(d, account, function(err, result) {
1182
1180
 
1183
- try {
1184
- org.addDeal('Pass', customer1, account);
1185
- }
1186
- catch (err) {
1187
- threwError = true;
1188
- }
1181
+ should.exist(err);
1182
+ should.not.exist(result);
1189
1183
 
1190
- threwError.should.equal(false);
1191
- org.deals.length.should.equal(1);
1192
- org.deals[0].status.should.equal('Pass');
1184
+ return done();
1193
1185
 
1194
- return done();
1186
+ });
1195
1187
 
1196
1188
  });
1197
1189
 
1198
1190
  it('adds a deal with an inactive state', function(done) {
1199
1191
 
1200
- var threwError = false;
1192
+ var d = new Deal({
1193
+ customer: customer1,
1194
+ organization: org4,
1195
+ stage: 'Pending'
1196
+ });
1201
1197
 
1202
- try {
1203
- org.addDeal('Pending', customer1, account);
1204
- }
1205
- catch (err) {
1206
- threwError = true;
1207
- }
1198
+ Organization.addDeal(d, account, function(err, result) {
1208
1199
 
1209
- threwError.should.equal(true);
1200
+ should.exist(err);
1201
+ should.not.exist(result);
1210
1202
 
1211
- return done();
1203
+ return done();
1204
+
1205
+ });
1212
1206
 
1213
1207
  });
1214
1208
 
1215
1209
  it('adds a deal for another customer', function(done) {
1216
1210
 
1211
+ config.CUSTOMER_ID = customer2._id.toString();
1212
+
1217
1213
  var org2 = new Organization();
1218
1214
  org2.name = 'Newest Co';
1219
1215
  org2.slug = 'newest-co';
1220
1216
 
1221
- Organization.upsert(org2, 'test-user', function(err, result) {
1217
+ Organization.upsert(org2, 'test-user', function(err, result1) {
1222
1218
 
1223
1219
  should.not.exist(err);
1224
- should.exist(result);
1220
+ should.exist(result1);
1225
1221
 
1226
- result.addDeal('Pass', customer2, account);
1222
+ var d = new Deal({
1223
+ customer: customer2,
1224
+ organization: result1,
1225
+ stage: 'Pass'
1226
+ });
1227
1227
 
1228
- Organization.upsert(result, 'test-user', function(err, result) {
1228
+ Organization.addDeal(d, account, function(err, result2) {
1229
1229
 
1230
1230
  should.not.exist(err);
1231
- should.exist(result);
1232
- result.deals.length.should.equal(1);
1233
-
1234
- org = result;
1231
+ should.exist(result2);
1235
1232
 
1236
1233
  return done();
1237
1234
 
@@ -1241,45 +1238,11 @@ describe('Organization', function() {
1241
1238
 
1242
1239
  });
1243
1240
 
1244
- it('gets deals for non-customer process', function(done) {
1245
-
1246
- var temp = config.CUSTOMER_ID;
1247
- config.CUSTOMER_ID = 'GLOBAL_PROCESS';
1248
-
1249
- Organization.getDeals(customer1._id, function(err, result) {
1250
-
1251
- should.not.exist(err);
1252
- should.exist(result);
1253
- result.length.should.equal(1);
1254
- result[0].name.should.equal('New Co');
1255
- result[0].deals.length.should.equal(1);
1256
- result[0].deals[0].customer.toString().should.equal(customer1._id.toString());
1257
- result[0].deals[0].status.should.equal('New');
1258
-
1259
- config.CUSTOMER_ID = temp;
1260
-
1261
- return done();
1262
-
1263
- });
1264
-
1265
- });
1266
-
1267
- it('gets deals for a customer', function(done) {
1268
-
1269
- var temp = config.CUSTOMER_ID;
1270
- config.CUSTOMER_ID = customer1._id.toString();
1241
+ it('deletes a deal', function (done) {
1271
1242
 
1272
- Organization.getDeals(customer1._id, function(err, result) {
1243
+ Organization.deleteDeal(deal._id, function (err, result) {
1273
1244
 
1274
1245
  should.not.exist(err);
1275
- should.exist(result);
1276
- result.length.should.equal(1);
1277
- result[0].name.should.equal('New Co');
1278
- result[0].deals.length.should.equal(1);
1279
- result[0].deals[0].customer.toString().should.equal(customer1._id.toString());
1280
- result[0].deals[0].status.should.equal('New');
1281
-
1282
- config.CUSTOMER_ID = temp;
1283
1246
 
1284
1247
  return done();
1285
1248