Built motion from commit 4143fce.|0.0.15
[motion.git] / server / api / contact_manager / contact_manager.controller.js
1 'use strict';
2
3 var _ = require('lodash');
4 var Contact = require('../../models').Contact;
5 var ContactPhone = require('../../models').ContactPhone;
6 var ContactEmail = require('../../models').ContactEmail;
7 var CustomField = require('../../models').CustomField;
8 var ReportCall = require('../../models').ReportCall;
9 var ReportCallHistory = require('../../models').history.ReportCallHistory;
10 var ReportMailSession = require('../../models').ReportMailSession;
11 var ReportMailSessionHistory = require('../../models').history.ReportMailSessionHistory;
12 var Tag = require('../../models').Tag;
13 var stream = require('stream');
14 var sequelize = require('../../models').sequelize;
15 var util = require('util');
16
17 // Get list of contacts
18 exports.index = function(req, res) {
19
20   var attributes = ['name', 'surname', 'description'];
21   var per_page = req.query.per_page ? parseInt(req.query.per_page, 10) : 100;
22   var page = req.query.page ? parseInt(req.query.page, 10) : 0;
23
24   var query = {
25     where: {},
26     limit: per_page,
27     offset: page * per_page
28   };
29
30   _.forIn(req.query, function(value, key) {
31     switch (key) {
32       case 'per_page':
33       case 'page':
34         break;
35       case 'sort_by':
36         query.order = util.format('%s %s', req.query.sort_by, req.query.sort_order || 'ASC') || null;
37         break;
38       case 'sort_order':
39         break;
40       case '$':
41         query.where.$or = [];
42         attributes.forEach(function(attribute) {
43           var tmp = {};
44           tmp[attribute] = {
45             $like: '%' + value + '%'
46           };
47
48           query.where.$or.push(tmp);
49         });
50         break;
51       default:
52         query.where[key] = {
53           $like: {}
54         };
55         query.where[key].$like = '%' + value + '%';
56     }
57   });
58
59
60   Contact
61     .findAndCountAll(query)
62     .then(function(result) {
63
64       var total_pages = Math.ceil(result.count / per_page);
65       var next_page = total_pages > (query.offset + 1) ? util.format('%s://%s%s?page=%d', req.protocol, req.headers.host, req.baseUrl, page + 1) : null;
66       var previous_page = page > 0 ? util.format('%s://%s%s?page=%d', req.protocol, req.headers.host, req.baseUrl, page - 1) : null;
67
68       res.status(200).send({
69         count: result.count,
70         rows: result.rows,
71         next_page: next_page,
72         previous_page: previous_page,
73         total_pages: total_pages
74       });
75
76     })
77     .catch(function(err) {
78       res.status(500).send({
79         error: 'Something blew up!'
80       });
81     });
82 };
83
84 // Get a single managed_contact
85 exports.show = function(req, res) {
86   Contact
87     .findById(req.params.id, {
88       include: [{
89         model: ContactPhone,
90         as: 'Phones',
91         include: [{
92           model: ReportCall,
93           as: 'Inbounds',
94           include: [{
95             all: true
96           }]
97         }, {
98           model: ReportCall,
99           as: 'Outbounds',
100           include: [{
101             all: true
102           }]
103         }, {
104           model: ReportCallHistory,
105           as: 'HistoryInbounds',
106           include: [{
107             all: true
108           }]
109         }, {
110           model: ReportCallHistory,
111           as: 'HistoryOutbounds',
112           include: [{
113             all: true
114           }]
115         }]
116       }, {
117         model: ContactEmail,
118         as: 'Emails',
119         include: [{
120           model: ReportMailSession,
121           as: 'InboundMessages',
122           include: [{
123             all: true
124           }]
125         }, {
126           model: ReportMailSession,
127           as: 'OutboundMessages',
128           include: [{
129             all: true
130           }]
131         }, {
132           model: ReportMailSessionHistory,
133           as: 'HistoryInboundMessages',
134           include: [{
135             all: true
136           }]
137         }, {
138           model: ReportMailSessionHistory,
139           as: 'HistoryOutboundMessages',
140           include: [{
141             all: true
142           }]
143         }]
144       }, {
145         model: CustomField,
146         as: 'CustomFields'
147       }]
148     })
149     .then(function(managed_contact) {
150       if (!managed_contact) {
151         return res.sendStatus(404);
152       }
153       return res.send(managed_contact);
154     })
155     .catch(function(err) {
156       console.log(err);
157       return handleError(res, err);
158     });
159 };
160
161 exports.getHistory = function(req, res) {
162
163 };
164
165 // validate contact uniqueness
166 exports.contactValidation = function(req, res) {
167   Contact.findAll({
168       where: {
169         $or: {
170           '$Phones.phone$': req.body.phones,
171           '$Emails.email$': req.body.emails
172         }
173       },
174       include: [{
175         all: true
176       }]
177     })
178     .then(function(contacts) {
179       console.log(contacts);
180       return res.status(200).send(contacts);
181     })
182     .catch(function(err) {
183       console.log(err);
184       return handleError(res, err);
185     });
186 };
187
188 // Creates a new managed_contact in the DB.
189 exports.create = function(req, res, next) {
190   var newPhones = [],
191     newEmails = [],
192     newCustomFields = {};
193   Tag.findAll()
194     .then(function(tags) {
195       var newTags = [];
196       var tagList = _.pluck(_.pluck(tags, 'dataValues'), 'name');
197       if (req.body.tags) {
198         var contactTags = req.body.tags.split(',');
199         contactTags.forEach(function(elem) {
200           if (!_.includes(tags, elem)) {
201             newTags.push({
202               name: elem
203             });
204           }
205         });
206         if (newTags.length) {
207           Tag.bulkCreate(newTags, {
208             individualHooks: true
209           });
210         }
211       }
212       req.body.UserId = req.user.id;
213       var phones = _.uniq(_.pluck(req.body.Phones, 'phone'));
214       var contactPhones = [];
215       phones.forEach(function(elem) {
216         contactPhones.push(ContactPhone.findOrCreate({
217           where: {
218             phone: elem
219           },
220           defaults: {
221             phone: elem
222           }
223         }));
224       });
225       return contactPhones;
226     })
227     .all()
228     .then(function(res) {
229       newPhones = _.map(res, function(elem) {
230         return elem[0];
231       });
232
233       var contactEmails = [];
234       var emails = _.uniq(_.pluck(req.body.Emails, 'email'));
235       emails.forEach(function(elem) {
236         contactEmails.push(ContactEmail.findOrCreate({
237           where: {
238             email: elem
239           },
240           defaults: {
241             email: elem
242           }
243         }));
244       });
245       return contactEmails;
246     })
247     .all()
248     .then(function(res) {
249       newEmails = _.map(res, function(elem) {
250         return elem[0];
251       });
252       delete req.body.Phones;
253       delete req.body.Emails;
254       newCustomFields = _.clone(req.body.customFields);
255       delete req.body.customFields;
256
257       return Contact.create(req.body);
258     })
259     .then(function(contact) {
260       return [contact, contact.setPhones(newPhones)];
261     })
262     .spread(function(contact) {
263       return [contact, contact.setEmails(newEmails)];
264     })
265     .spread(function(contact) {
266       var customFieldsIds = _.keys(newCustomFields);
267       return [contact, CustomField.findAll({
268         where: {
269           id: customFieldsIds
270         }
271       })];
272     })
273     .spread(function(contact, customFields) {
274       customFields.forEach(function(elem) {
275         elem.ContactHasCustomField = {
276           value: newCustomFields[String(elem.id)]
277         }
278       });
279       return [contact, contact.setCustomFields(customFields)];
280     })
281     .spread(function(contact) {
282       return res.status(201).send(contact);
283     })
284     .catch(function(err) {
285       console.log(err);
286       return next(err);
287     });
288 };
289
290 // Updates an existing managed_contact in the DB.
291 exports.update = function(req, res, next) {
292   var newPhones = [],
293     newEmails = [],
294     newCustomFields = {};
295   Tag.findAll()
296     .then(function(tags) {
297       var newTags = [];
298       var tagList = _.pluck(_.pluck(tags, 'dataValues'), 'name');
299       if (req.body.tags) {
300         var contactTags = req.body.tags.split(',');
301         contactTags.forEach(function(elem) {
302           if (!_.includes(tags, elem)) {
303             newTags.push({
304               name: elem
305             });
306           }
307         });
308         if (newTags.length) {
309           Tag.bulkCreate(newTags, {
310             individualHooks: true
311           });
312         }
313       }
314       var contactPhones = [];
315       var phones = _.uniq(_.pluck(req.body.Phones, 'phone'));
316       phones.forEach(function(elem) {
317         contactPhones.push(ContactPhone.findOrCreate({
318           where: {
319             phone: elem
320           },
321           defaults: {
322             phone: elem
323           }
324         }));
325       });
326       return contactPhones;
327     })
328     .all()
329     .then(function(res) {
330       newPhones = _.map(res, function(elem) {
331         return elem[0];
332       });
333
334       var contactEmails = [];
335       var emails = _.uniq(_.pluck(req.body.Emails, 'email'));
336       emails.forEach(function(elem) {
337         contactEmails.push(ContactEmail.findOrCreate({
338           where: {
339             email: elem
340           },
341           defaults: {
342             email: elem
343           }
344         }));
345       });
346       return contactEmails;
347     })
348     .all()
349     .then(function(res) {
350       newEmails = _.map(res, function(elem) {
351         return elem[0];
352       });
353       delete req.body.Phones;
354       delete req.body.Emails;
355       newCustomFields = _.clone(req.body.customFields);
356       delete req.body.customFields;
357       delete req.body.CustomFields;
358       var updateId = req.body.id;
359       delete req.body.id;
360
361       return Contact.findById(updateId);
362     })
363     .then(function(contact) {
364       return [contact, contact.setPhones(newPhones)];
365     })
366     .spread(function(contact) {
367       return [contact, contact.setEmails(newEmails)];
368     })
369     .spread(function(contact) {
370       var customFieldsIds = _.keys(newCustomFields);
371       return [contact, CustomField.findAll({
372         where: {
373           id: customFieldsIds
374         }
375       })];
376     })
377     .spread(function(contact, customFields) {
378       customFields.forEach(function(elem) {
379         elem.ContactHasCustomField = {
380           value: newCustomFields[String(elem.id)]
381         }
382       });
383       return [contact, contact.setCustomFields(customFields)];
384     })
385     .spread(function(contact) {
386       return contact.updateAttributes(req.body)
387     })
388     .then(function(contact) {
389       return res.status(200).send(contact);
390     })
391     .catch(function(err) {
392       console.log(err);
393       return handleError(res, err);
394     });
395 };
396
397 // // Join contacts info in the DB.
398 // exports.joinContacts = function(req, res, next) {
399 //   if (req.body.tags) {
400 //     Tag.findAll()
401 //       .then(function(tags) {
402 //         var newTags = [];
403 //         var tagList = _.pluck(_.pluck(tags, 'dataValues'), 'name');
404 //         var contactTags = req.body.tags.split(',');
405 //         contactTags.forEach(function(elem) {
406 //           if (!_.includes(tags, elem)) {
407 //             newTags.push({
408 //               name: elem
409 //             });
410 //           }
411 //         });
412 //         if (newTags.length) {
413 //           Tag.bulkCreate(newTags, {
414 //             individualHooks: true
415 //           });
416 //         }
417 //       })
418 //       .catch(function(err) {
419 //         return handleError(res, err);
420 //       });
421 //   }
422 //   var updateId = req.body.id;
423 //   delete req.body.id;
424 //   var phones = _.map(req.body.Phones, function(elem) {
425 //     return {
426 //       phone: elem.phone,
427 //       ContactId: updateId
428 //     };
429 //   });
430 //   var emails = _.map(req.body.Emails, function(elem) {
431 //     return {
432 //       email: elem.email,
433 //       ContactId: updateId
434 //     };
435 //   });
436 //   delete req.body.Phones;
437 //   delete req.body.Emails;
438 //   return sequelize.transaction(function(t) {
439 //       return Contact.update(req.body, {
440 //           where: {
441 //             id: updateId
442 //           }
443 //         }, {
444 //           transaction: t,
445 //           include: [{
446 //             all: true
447 //           }]
448 //         })
449 //         .then(function(contact) {
450 //           return ContactPhone
451 //             .bulkCreate(phones, {
452 //               transaction: t
453 //             })
454 //             .then(function() {
455 //               return ContactEmail
456 //                 .bulkCreate(emails, {
457 //                   transaction: t
458 //                 })
459 //                 .then(function() {
460 //                   return Contact.findById(updateId, {
461 //                       transaction: t
462 //                     })
463 //                     .then(function(contact) {
464 //                       return res.status(201).send(contact);
465 //                     })
466 //                 })
467 //             })
468 //         })
469 //     })
470 //     .catch(function(err) {
471 //       console.log(err);
472 //       return next(err);
473 //     });
474 // };
475
476 // Deletes a managed_contact from the DB.
477 exports.destroy = function(req, res) {
478   Contact
479     .findById(req.params.id)
480     .then(function(managed_contact) {
481       if (!managed_contact) {
482         return res.sendStatus(404);
483       }
484       managed_contact.destroy()
485         .then(function() {
486           return res.sendStatus(204);
487         })
488         .catch(function(err) {
489           return handleError(res, err);
490         });
491     })
492     .catch(function(err) {
493       return handleError(res, err);
494     });
495 };
496
497 // Deletes a managed_contact from the DB.
498 exports.bulkDestroy = function(req, res) {
499   Contact
500     .destroy({
501       where: {
502         id: req.query.id
503       },
504       individualHooks: true
505     })
506     .then(function() {
507       return res.sendStatus(204);
508     })
509     .catch(function(err) {
510       return handleError(res, err);
511     });
512 };
513
514 function handleError(res, err) {
515   return res.status(500).send(err);
516 }