@dhyasama/totem-models 4.8.0 → 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
 
@@ -683,6 +677,111 @@ module.exports = function(mongoose, config) {
683
677
  // Statics query the entire collection
684
678
  //////////////////////////////////////////////////////
685
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
+
686
785
  Organization.statics.addFlag = function(organizationId, creatorPersonId, text, cb) {
687
786
 
688
787
  Flag.createForModel({
@@ -701,6 +800,27 @@ module.exports = function(mongoose, config) {
701
800
 
702
801
  };
703
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
+
704
824
  Organization.statics.deleteFlag = function(flagId, cb) {
705
825
 
706
826
  // Delete the flag itself along with reference
@@ -981,6 +1101,7 @@ module.exports = function(mongoose, config) {
981
1101
  if (config.CUSTOMER_ID != 'GLOBAL_PROCESS') lpPopulateOptions.match = { customer: config.CUSTOMER_ID };
982
1102
 
983
1103
  var query = self.findById(id);
1104
+
984
1105
  query.populate('people.person', 'name avatarUrl title contact doNotDisplay');
985
1106
  query.populate('related', 'name logoUrl');
986
1107
  query.populate('chairs.first', 'name avatarUrl title');
@@ -989,9 +1110,17 @@ module.exports = function(mongoose, config) {
989
1110
  query.populate('operating.acquired.public.by', 'name logoUrl');
990
1111
  query.populate('operating.acquired.private.by', 'name logoUrl');
991
1112
 
1113
+ query.populate({
1114
+ path: 'deals',
1115
+ match: { customer: config.CUSTOMER_ID }
1116
+ });
1117
+
992
1118
  if (options.role != 'none') {
993
1119
  query.populate(lpPopulateOptions);
994
1120
  query.deepPopulate([
1121
+ 'deals.sources.person',
1122
+ 'documents',
1123
+ 'history.account',
995
1124
  'lps.fundsInvested.fund'
996
1125
  ], {
997
1126
  populate: {
@@ -999,6 +1128,13 @@ module.exports = function(mongoose, config) {
999
1128
  }
1000
1129
  })
1001
1130
  }
1131
+ else {
1132
+ query.deepPopulate([
1133
+ 'deals.sources.person',
1134
+ 'documents',
1135
+ 'history.account'
1136
+ ]);
1137
+ }
1002
1138
 
1003
1139
  query.exec(cb);
1004
1140
 
@@ -1049,33 +1185,6 @@ module.exports = function(mongoose, config) {
1049
1185
 
1050
1186
  };
1051
1187
 
1052
- Organization.statics.getDeals = function getDeals(customerId, cb) {
1053
-
1054
- var self = this;
1055
-
1056
- self
1057
- .find({ 'deals.customer': customerId, 'deleted': { $ne: true } })
1058
- .select('name website websiteAliases deals')
1059
- .exec(function(err, result) {
1060
-
1061
- if (err) return cb(err, null);
1062
-
1063
- result.deals = _.reject(result.deals, function(item) { return !item.customer || item.customer.toString() != customerId.toString(); });
1064
- result = _.map(result, function(item) {
1065
- return {
1066
- name: item.name,
1067
- website: item.website,
1068
- websiteAliases: item.websiteAliases,
1069
- deals: item.deals
1070
- }
1071
- });
1072
-
1073
- return cb(null, result);
1074
-
1075
- });
1076
-
1077
- };
1078
-
1079
1188
  Organization.statics.getFlags = function getFlags(orgid, cb) {
1080
1189
 
1081
1190
  var self = this;
@@ -1632,7 +1741,6 @@ module.exports = function(mongoose, config) {
1632
1741
  doc.chairs = _.reject(doc.chairs, function(item) { return !item.customer || item.customer.toString() != CUSTOMER_ID; });
1633
1742
  doc.operating.acquired.private = _.find(doc.operating.acquired.private, function(item) { return !item.customer || item.customer.toString() == CUSTOMER_ID; });
1634
1743
  doc.operating.closed.private = _.find(doc.operating.closed.private, function(item) { return !item.customer || item.customer.toString() == CUSTOMER_ID; });
1635
- doc.deals = _.reject(doc.deals, function(item) { return !item.customer || item.customer.toString() != CUSTOMER_ID; });
1636
1744
 
1637
1745
  // people
1638
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.8.0",
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