UNPKG

@tiledesk/tiledesk-server

Version:
584 lines (429 loc) 16.5 kB
var express = require('express'); var router = express.Router(); var Lead = require("../models/lead"); var LeadConstants = require("../models/leadConstants"); var winston = require('../config/winston'); var leadService = require("../services/leadService"); csv = require('csv-express'); csv.separator = ';'; const leadEvent = require('../event/leadEvent'); var Segment = require("../models/segment"); var Segment2MongoConverter = require("../utils/segment2mongoConverter"); router.post('/', function (req, res) { winston.debug(req.body); winston.debug("req.user", req.user); leadService.createWitId(req.body.lead_id, req.body.fullname, req.body.email, req.projectid, req.user.id, req.body.attributes).then(function(savedLead) { res.json(savedLead); }) }); router.put('/:leadid', function (req, res) { winston.debug(req.body); var update = {}; if (req.body.fullname!=undefined) { update.fullname = req.body.fullname; } if (req.body.email!=undefined) { update.email = req.body.email; } if (req.body.attributes!=undefined) { update.attributes = req.body.attributes; } if (req.body.status!=undefined) { update.status = req.body.status; } if (req.body.phone!=undefined) { update.phone = req.body.phone; } if (req.body.company!=undefined) { update.company = req.body.company; } if (req.body.note!=undefined) { update.note = req.body.note; } if (req.body.streetAddress!=undefined) { update.streetAddress = req.body.streetAddress; } if (req.body.city!=undefined) { update.city = req.body.city; } if (req.body.region!=undefined) { update.region = req.body.region; } if (req.body.zipcode!=undefined) { update.zipcode = req.body.zipcode; } if (req.body.country!=undefined) { update.country = req.body.country; } if (req.body.tags) { update.tags = req.body.tags; } Lead.findByIdAndUpdate(req.params.leadid, update, { new: true, upsert: true }, function (err, updatedLead) { if (err) { winston.error('--- > ERROR ', err); return res.status(500).send({ success: false, msg: 'Error updating object.' }); } leadEvent.emit('lead.update', updatedLead); if (req.body.fullname!=undefined) { leadEvent.emit('lead.fullname.update', updatedLead); } if (req.body.email!=undefined) { leadEvent.emit('lead.email.update', updatedLead); } if (req.body.email!=undefined || req.body.fullname!=undefined) { leadEvent.emit('lead.fullname.email.update', updatedLead); } res.json(updatedLead); }); }); router.put('/:leadid/tag', async (req, res) => { let lead_id = req.params.leadid; let tags_list = req.body; winston.debug("(Lead) /tag tags_list: ", tags_list) if (tags_list.length == 0) { winston.warn("(Lead) /tag no tag specified") return res.status(400).send({ success: false, message: "No tag specified" }) } let lead = await Lead.findById(lead_id).catch((err) => { winston.error("(Lead) /tag error getting lead ", err); return res.status(500).send({ success: false, error: "Error getting lead with id " + lead_id}); }) if (!lead) { winston.warn("(Lead) /tag lead not found with lead_id " + lead_id); return res.status(404).send({ success: false, error: "Lead not found with id " + lead_id }); } let current_tags = lead.tags; tags_list.forEach(t => { // Check if tag already exists in the lead. If true, skip the adding. if (!current_tags.includes(t)) { current_tags.push(t) } }) let update = { tags: current_tags } Lead.findByIdAndUpdate(lead_id, update, { new: true }, (err, updatedLead) => { if (err) { winston.error("(Lead) /tag error finding and update lead ", err); return res.status(500).send({ success: false, error: "Error updating lead with id " + lead_id }) } if (!updatedLead) { winston.warn("(Lead) /tag The lead was deleted while adding tags for lead " + lead_id); return res.status(404).send({ success: false, error: "The lead was deleted while adding tags for lead " + lead_id }) } winston.debug("(Lead) /tag Lead updated successfully ", updatedLead); leadEvent.emit('lead.update', updatedLead); res.status(200).send(updatedLead) }) }) router.patch('/:leadid/attributes', function (req, res) { var data = req.body; // TODO use service method Lead.findById(req.params.leadid, function (err, lead) { if (err) { winston.error('--- > ERROR ', err); return res.status(500).send({ success: false, msg: 'Error updating object.' }); } if (!lead) { return res.status(404).send({ success: false, msg: 'Object not found.' }); } if (!lead.attributes) { winston.debug("empty attributes") lead.attributes = {}; } winston.debug(" lead attributes", lead.attributes) Object.keys(data).forEach(function(key) { var val = data[key]; winston.debug("data attributes "+key+" " +val) lead.attributes[key] = val; }); winston.debug(" lead attributes", lead.attributes) // https://stackoverflow.com/questions/24054552/mongoose-not-saving-nested-object lead.markModified('attributes'); //cacheinvalidation lead.save(function (err, savedLead) { if (err) { winston.error("error saving lead attributes",err) return res.status(500).send({ success: false, msg: 'Error getting object.' }); } winston.verbose(" saved lead attributes",savedLead.toObject()) leadEvent.emit('lead.update', savedLead); res.json(savedLead); }); }); }); //.post and .patch for /properties are equals router.post('/:leadid/properties', function (req, res) { var data = req.body; // TODO use service method Lead.findById(req.params.leadid, function (err, lead) { if (err) { winston.error('--- > ERROR ', err); return res.status(500).send({ success: false, msg: 'Error updating object.' }); } if (!lead) { return res.status(404).send({ success: false, msg: 'Object not found.' }); } if (!lead.properties) { winston.debug("empty properties") lead.properties = {}; } winston.debug(" lead properties", lead.properties) Object.keys(data).forEach(function(key) { var val = data[key]; winston.debug("data attributes "+key+" " +val) lead.properties[key] = val; }); winston.debug(" lead properties", lead.properties) // https://stackoverflow.com/questions/24054552/mongoose-not-saving-nested-object lead.markModified('properties'); //cacheinvalidation lead.save(function (err, savedLead) { if (err) { winston.error("error saving lead properties",err) return res.status(500).send({ success: false, msg: 'Error getting object.' }); } winston.verbose(" saved lead properties",savedLead.toObject()) leadEvent.emit('lead.update', savedLead); res.json(savedLead); }); }); }); router.patch('/:leadid/properties', function (req, res) { var data = req.body; // TODO use service method Lead.findById(req.params.leadid, function (err, lead) { if (err) { winston.error('--- > ERROR ', err); return res.status(500).send({ success: false, msg: 'Error updating object.' }); } if (!lead) { return res.status(404).send({ success: false, msg: 'Object not found.' }); } if (!lead.properties) { winston.debug("empty properties") lead.properties = {}; } winston.debug(" lead properties", lead.properties) Object.keys(data).forEach(function(key) { var val = data[key]; winston.debug("data attributes "+key+" " +val) lead.properties[key] = val; }); winston.debug(" lead properties", lead.properties) // https://stackoverflow.com/questions/24054552/mongoose-not-saving-nested-object lead.markModified('properties'); //cacheinvalidation lead.save(function (err, savedLead) { if (err) { winston.error("error saving lead properties",err) return res.status(500).send({ success: false, msg: 'Error getting object.' }); } winston.verbose(" saved lead properties",savedLead.toObject()) leadEvent.emit('lead.update', savedLead); res.json(savedLead); }); }); }); // router.put('/:leadid', function (req, res) { // winston.debug(req.body); // var update = {}; // // trasforma in patch altrimenti nn va // update.fullname = req.body.fullname; // update.email = req.body.email; // update.attributes = req.body.attributes; // update.status = req.body.status; // Lead.findByIdAndUpdate(req.params.leadid, update, { new: true, upsert: true }, function (err, updatedLead) { // if (err) { // winston.error('--- > ERROR ', err); // return res.status(500).send({ success: false, msg: 'Error updating object.' }); // } // leadEvent.emit('lead.update', updatedLead); // res.json(updatedLead); // }); // }); router.delete('/:leadid/tag/:tag', async (req, res) => { let lead_id = req.params.leadid; let tag = req.params.tag; Lead.findByIdAndUpdate(lead_id, { $pull: { tags: tag }}, { new: true}).then((updatedLead) => { if (!updatedLead) { winston.warn("(Lead) /removetag lead not found with id " + lead_id); return res.status(404).send({ success: false, error: "Lead not found with id " + lead_id }) } winston.debug("(Lead) /removetag updatedLead: ", updatedLead) res.status(200).send(updatedLead) }).catch((err) => { winston.error("(Lead) /removetag error updating lead: ", err); res.status(500).send({ success: false, error: err }); }) }) router.delete('/:leadid', function (req, res) { winston.debug(req.body); Lead.findByIdAndUpdate(req.params.leadid, {status: LeadConstants.DELETED}, { new: true, upsert: true }, function (err, updatedLead) { if (err) { winston.error('--- > ERROR ', err); return res.status(500).send({ success: false, msg: 'Error updating object.' }); } leadEvent.emit('lead.delete', updatedLead); res.json(updatedLead); }); }); router.delete('/:leadid/physical', function (req, res) { winston.debug(req.body); var projectuser = req.projectuser; if (projectuser.role != "owner" ) { return res.status(403).send({ success: false, msg: 'Unauthorized.' }); } // TODO use findByIdAndRemove otherwise lead don't contains label object Lead.remove({ _id: req.params.leadid }, function (err, lead) { if (err) { winston.error('--- > ERROR ', err); return res.status(500).send({ success: false, msg: 'Error deleting object.' }); } leadEvent.emit('lead.delete', lead); res.json(lead); }); }); // DOWNLOAD leads AS CSV router.get('/csv', function (req, res, next) { var limit = 100000; // Number of leads per page var page = 0; if (req.query.page) { page = req.query.page; } var skip = page * limit; winston.debug('LEAD ROUTE - SKIP PAGE ', skip); var query = { "id_project": req.projectid, "status": {$lt: LeadConstants.DELETED}}; if (req.query.full_text) { winston.debug('LEAD ROUTE req.query.fulltext', req.query.full_text); query.$text = { "$search": req.query.full_text }; } if (req.query.email) { winston.debug('LEAD ROUTE req.query.email', req.query.email); query.email = req.query.email; } var direction = -1; //-1 descending , 1 ascending if (req.query.direction) { direction = req.query.direction; } winston.debug("direction", direction); var sortField = "createdAt"; if (req.query.sort) { sortField = req.query.sort; } winston.debug("sortField", sortField); var sortQuery = {}; sortQuery[sortField] = direction; winston.debug("sort query", sortQuery); // TODO ORDER BY SCORE // return Faq.find(query, {score: { $meta: "textScore" } }) // .sort( { score: { $meta: "textScore" } } ) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score // Lead.find({ "id_project": req.projectid }, function (err, leads, next) { return Lead.find(query, '-attributes -__v'). skip(skip).limit(limit). sort(sortQuery).lean(). exec(function (err, leads) { if (err) { winston.error('LEAD ROUTE - EXPORT CONTACT TO CSV ERR ', err) return next(err); } winston.verbose('LEAD ROUTE - EXPORT CONTACT TO CSV LEADS', leads) return res.csv(leads, true); }); }); router.get('/:leadid', function (req, res) { winston.debug(req.body); Lead.findById(req.params.leadid, function (err, lead) { if (err) { return res.status(500).send({ success: false, msg: 'Error getting object.' }); } if (!lead) { return res.status(404).send({ success: false, msg: 'Object not found.' }); } res.json(lead); }); }); router.get('/', async(req, res) => { var limit = 40; // Number of request per page if (req.query.limit) { limit = parseInt(req.query.limit); winston.debug('LEAD ROUTE - limit: '+limit); } var page = 0; if (req.query.page) { page = req.query.page; } var skip = page * limit; winston.debug('LEAD ROUTE - SKIP PAGE ', skip); var query = {}; if (req.query.segment) { let segment = await Segment.findOne({id_project: req.projectid, _id: req.query.segment }).exec(); if (!segment) { return res.status(404).send({ success: false, msg: 'Error segment not found' }); } Segment2MongoConverter.convert(query, segment); } if (req.query.full_text) { winston.debug('LEAD ROUTE req.query.fulltext', req.query.full_text); query.$text = { "$search": req.query.full_text }; } if (req.query.email) { winston.debug('LEAD ROUTE req.query.email', req.query.email); query.email = req.query.email; } if (req.query.with_email) { //for internal request and zapier to retrieve only lead with an email winston.debug('LEAD ROUTE req.query.withemail', req.query.withemail); query.email = { "$exists": true }; } if (req.query.with_fullname) { //or internal request to retrieve only lead with an email winston.debug('LEAD ROUTE req.query.withfullname', req.query.with_fullname); query.fullname = { "$exists": true }; } // aggiungi filtro per data if (req.query.tags) { winston.debug('req.query.tags', req.query.tags); query["tags"] = req.query.tags; } // last query modifier query["id_project"] = req.projectid; query["status"] = LeadConstants.NORMAL; if (req.query.status) { query.status = req.query.status; } winston.debug("query", query); var direction = -1; //-1 descending , 1 ascending if (req.query.direction) { direction = req.query.direction; } var sortField = "createdAt"; if (req.query.sort) { sortField = req.query.sort; } var sortQuery = {}; sortQuery[sortField] = direction; winston.debug("sort query", sortQuery); // TODO ORDER BY SCORE // return Faq.find(query, {score: { $meta: "textScore" } }) // .sort( { score: { $meta: "textScore" } } ) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score // aggiungi filtro per data marco return Lead.find(query). skip(skip).limit(limit). sort(sortQuery). exec(function (err, leads) { if (err) { winston.error('LEAD ROUTE - REQUEST FIND ERR ', err) return (err); } // blocked to 1000 TODO increases it // collection.count is deprecated, and will be removed in a future version. Use Collection.countDocuments or Collection.estimatedDocumentCount instead return Lead.countDocuments(query, function (err, totalRowCount) { var objectToReturn = { perPage: limit, count: totalRowCount, leads: leads }; return res.json(objectToReturn); }); }); }); module.exports = router;