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