@tiledesk/tiledesk-server 2.3.17 → 2.3.19

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,250 @@
1
+ var amqp = require('amqplib/callback_api');
2
+ var winston = require('../../config/winston');
3
+ const requestEvent = require('../../event/requestEvent');
4
+ const messageEvent = require('../../event/messageEvent');
5
+ const authEvent = require('../../event/authEvent');
6
+ // https://elements.heroku.com/addons/cloudamqp
7
+ // https://gist.github.com/carlhoerberg/006b01ac17a0a94859ba#file-reconnect-js
8
+ // http://www.rabbitmq.com/tutorials/tutorial-one-javascript.html
9
+
10
+ // if the connection is closed or fails to be established at all, we will reconnect
11
+ var amqpConn = null;
12
+ var url = process.env.CLOUDAMQP_URL + "?heartbeat=60" || "amqp://localhost";
13
+ // attento devi aggiornare configMap di PRE E PROD
14
+ // var url = process.env.AMQP_URL + "?heartbeat=60" || "amqp://localhost";
15
+
16
+ // MOD0
17
+ var exchange = 'ws';
18
+
19
+ function start() {
20
+ amqp.connect(url, function(err, conn) {
21
+ if (err) {
22
+ winston.error("[AMQP Fanout]", err.message);
23
+ return setTimeout(start, 1000);
24
+ }
25
+ conn.on("error", function(err) {
26
+ if (err.message !== "Connection closing") {
27
+ winston.error("[AMQP Fanout] conn error", err);
28
+ }
29
+ });
30
+ conn.on("close", function() {
31
+ winston.error("[AMQP Fanout] reconnecting");
32
+ return setTimeout(start, 1000);
33
+ });
34
+
35
+ winston.info("[AMQP Fanout] connected");
36
+ amqpConn = conn;
37
+
38
+ whenConnected();
39
+ });
40
+ }
41
+
42
+ function whenConnected() {
43
+ startPublisher();
44
+ startWorker();
45
+ }
46
+
47
+ var pubChannel = null;
48
+ var offlinePubQueue = [];
49
+ function startPublisher() {
50
+ amqpConn.createConfirmChannel(function(err, ch) {
51
+ if (closeOnErr(err)) return;
52
+ ch.on("error", function(err) {
53
+ winston.error("[AMQP Fanout] channel error", err);
54
+ });
55
+ ch.on("close", function() {
56
+ winston.info("[AMQP Fanout] channel closed");
57
+ });
58
+
59
+ pubChannel = ch;
60
+ while (true) {
61
+ var m = offlinePubQueue.shift();
62
+ if (!m) break;
63
+ publish(m[0], m[1], m[2]);
64
+ }
65
+ });
66
+ }
67
+
68
+ // method to publish a message, will queue messages internally if the connection is down and resend later
69
+ function publish(exchange, routingKey, content) {
70
+ try {
71
+
72
+ // MOD2
73
+ // pubChannel.publish('logs', '', Buffer.from('Hello World!'));
74
+ pubChannel.publish(exchange, routingKey, content, { },
75
+ // pubChannel.publish(exchange, routingKey, content, { persistent: true },
76
+ function(err, ok) {
77
+ if (err) {
78
+ winston.error("[AMQP Fanout] publish", err);
79
+ offlinePubQueue.push([exchange, routingKey, content]);
80
+ pubChannel.connection.close();
81
+ }
82
+ });
83
+ } catch (e) {
84
+ winston.error("[AMQP Fanout] publish", e);
85
+ offlinePubQueue.push([exchange, routingKey, content]);
86
+ }
87
+ }
88
+
89
+ // A worker that acks messages only if processed succesfully
90
+ // var channel;
91
+ function startWorker() {
92
+ amqpConn.createChannel(function(err, ch) {
93
+ if (closeOnErr(err)) return;
94
+ ch.on("error", function(err) {
95
+ winston.error("[AMQP Fanout] channel error", err);
96
+ });
97
+ ch.on("close", function() {
98
+ winston.info("[AMQP Fanout] channel closed");
99
+ });
100
+ ch.prefetch(10);//leggila da env
101
+
102
+ // ch.assertExchange(exchange, 'topic', {
103
+ // durable: true
104
+ // });
105
+
106
+ // MOD1
107
+ ch.assertExchange(exchange, 'fanout', {durable: false});
108
+
109
+ //MOD3
110
+ ch.assertQueue('', {exclusive: true}, function(err, _ok) {
111
+ // ch.assertQueue("jobs", { durable: true }, function(err, _ok) {
112
+
113
+ if (closeOnErr(err)) return;
114
+
115
+ //MOD4
116
+ ch.bindQueue(_ok.queue, exchange, '', {}, function(err3, oka) {
117
+ winston.info("Queue Fanout bind: "+_ok.queue+ " err: "+err3);
118
+ winston.info("Data Queue", oka)
119
+ });
120
+
121
+ // ch.bindQueue(_ok.queue, exchange, "request_create", {}, function(err3, oka) {
122
+ // console.log("queue bind: "+_ok.queue+ " err: "+err3+ " key: request_create");
123
+ // console.log("data queue", oka)
124
+ // });
125
+ // ch.bindQueue(_ok.queue, exchange, "request_update", {}, function(err3, oka) {
126
+ // console.log("queue bind: "+_ok.queue+ " err: "+err3+ " key: request_update");
127
+ // console.log("data queue", oka)
128
+ // });
129
+ // ch.bindQueue(_ok.queue, exchange, "message_create", {}, function(err3, oka) {
130
+ // console.log("queue bind: "+_ok.queue+ " err: "+err3+ " key: message_create");
131
+ // console.log("data queue", oka)
132
+ // });
133
+ // ch.bindQueue(_ok.queue, exchange, "project_user_update", {}, function(err3, oka) {
134
+ // console.log("queue bind: "+_ok.queue+ " err: "+err3+ " key: project_user_update");
135
+ // console.log("data queue", oka)
136
+ // });
137
+ ch.consume(_ok.queue, processMsg, { noAck: false });
138
+ winston.info("Worker Fanout is started");
139
+ });
140
+
141
+
142
+ function processMsg(msg) {
143
+ work(msg, function(ok) {
144
+ try {
145
+ if (ok)
146
+ ch.ack(msg);
147
+ else
148
+ ch.reject(msg, true);
149
+ } catch (e) {
150
+ closeOnErr(e);
151
+ }
152
+ });
153
+ }
154
+ });
155
+ }
156
+
157
+ function work(msg, cb) {
158
+ const message_string = msg.content.toString();
159
+ const topic = msg.fields.routingKey //.replace(/[.]/g, '/');
160
+
161
+ winston.debug("Got Fanout msg topic:" + topic);
162
+
163
+ winston.debug("Got Fanout msg:"+ message_string + " topic:" + topic);
164
+
165
+ if (topic === 'request_create') {
166
+ winston.debug("here topic:" + topic);
167
+ winston.info("reconnect request.update")
168
+ requestEvent.emit('request.create.queue.pubsub', JSON.parse(message_string));
169
+ }
170
+ if (topic === 'request_update') {
171
+ winston.debug("here topic:" + topic);
172
+ requestEvent.emit('request.update.queue.pubsub', JSON.parse(message_string));
173
+ }
174
+ if (topic === 'message_create') {
175
+ winston.debug("here topic:" + topic);
176
+ messageEvent.emit('message.create.queue.pubsub', JSON.parse(message_string));
177
+ }
178
+ if (topic === 'project_user_update') {
179
+ winston.debug("here topic:" + topic);
180
+ authEvent.emit('project_user.update.queue.pubsub', JSON.parse(message_string));
181
+ }
182
+ cb(true);
183
+ // WebSocket.cb(true);
184
+ // requestEvent.on(msg.KEYYYYYYY+'.ws', msg.content);
185
+ }
186
+
187
+
188
+ function closeOnErr(err) {
189
+ if (!err) return false;
190
+ winston.error("[AMQP Fanout] error", err);
191
+ amqpConn.close();
192
+ return true;
193
+ }
194
+
195
+ // setInterval(function() {
196
+ // var d = new Date();
197
+ // publish(exchange, "request_create", Buffer.from("work work work: "+d));
198
+ // }, 10000);
199
+
200
+
201
+
202
+ // http://www.squaremobius.net/amqp.node/channel_api.html
203
+ // https://docs.parseplatform.org/parse-server/guide/#scalability
204
+
205
+
206
+
207
+ function listen() {
208
+
209
+ requestEvent.on('request.create', function(request) {
210
+ setImmediate(() => {
211
+ publish(exchange, "request_create", Buffer.from(JSON.stringify(request)));
212
+ });
213
+ });
214
+
215
+ requestEvent.on('request.update', function(request) {
216
+ setImmediate(() => {
217
+ publish(exchange, "request_update", Buffer.from(JSON.stringify(request)));
218
+ });
219
+ });
220
+
221
+
222
+ messageEvent.on('message.create', function(message) {
223
+ setImmediate(() => {
224
+ publish(exchange, "message_create", Buffer.from(JSON.stringify(message)));
225
+ });
226
+ });
227
+
228
+ authEvent.on('project_user.update',function(data) {
229
+ setImmediate(() => {
230
+
231
+ let user = undefined;
232
+ if (data.req && data.req.user) { //i think is null from chat21webhook
233
+ user = data.req.user;
234
+ }
235
+ var dat = {updatedProject_userPopulated: data.updatedProject_userPopulated, req: {user: user}}; //remove request
236
+
237
+ publish(exchange, "project_user_update", Buffer.from(JSON.stringify(dat)));
238
+ });
239
+ });
240
+ }
241
+
242
+ if (process.env.QUEUE_ENABLED === "true") {
243
+ requestEvent.queueEnabled = true;
244
+ messageEvent.queueEnabled = true;
245
+ authEvent.queueEnabled = true;
246
+ listen();
247
+ start();
248
+ winston.info("Queue Fanout enabled. endpint: " + url );
249
+ }
250
+
@@ -0,0 +1,3 @@
1
+ const listener = require("./listener");
2
+
3
+ module.exports = {listener:listener };
@@ -0,0 +1,328 @@
1
+ const projectEvent = require('../../event/projectEvent');
2
+ const departmentEvent = require('../../event/departmentEvent');
3
+ const authEvent = require('../../event/authEvent');
4
+ const requestEvent = require('../../event/requestEvent');
5
+ var Request = require('../../models/request');
6
+ var Project = require('../../models/project');
7
+ var Project_user = require('../../models/project_user');
8
+ var winston = require('../../config/winston');
9
+
10
+ var ProjectUserUtil = require("../../utils/project_userUtil");
11
+
12
+ // var request = require('retry-request', {
13
+ // request: require('request')
14
+ // });
15
+
16
+ // TODO riabilitare questo
17
+
18
+ // const ROUTE_QUEUE_ENDPOINT = process.env.ROUTE_QUEUE_ENDPOINT;
19
+ // winston.debug("ROUTE_QUEUE_ENDPOINT: " + ROUTE_QUEUE_ENDPOINT);
20
+
21
+ // if (ROUTE_QUEUE_ENDPOINT) {
22
+ // winston.info("Route queue endpoint: " + ROUTE_QUEUE_ENDPOINT);
23
+ // } else {
24
+ // winston.info("Route queue endpoint not configured");
25
+ // }
26
+
27
+
28
+ class Listener {
29
+
30
+
31
+ constructor() {
32
+ this.enabled = true;
33
+ if (process.env.ROUTE_QUEUE_ENABLED=="false" || process.env.ROUTE_QUEUE_ENABLED==false) {
34
+ this.enabled = false;
35
+ }
36
+ winston.debug("Listener this.enabled: "+ this.enabled);
37
+ }
38
+
39
+ nextOperator(array, index) {
40
+ // console.log('array: ', array);
41
+ // console.log('index: ' + index);
42
+
43
+ index = index || 0;
44
+
45
+ if (array === undefined || array === null)
46
+ array = [];
47
+ else if (!Array.isArray(array))
48
+ throw new Error('Expecting argument to RoundRound to be an Array');
49
+
50
+ // return function () {
51
+ index++;
52
+ if (index >= array.length) index = 0;
53
+ // console.log('index: ' + index);
54
+ return array[index];
55
+ // };
56
+ }
57
+
58
+ // db.getCollection('project_users').find({"number_assigned_requests" : {"$lt":0}}).count()
59
+
60
+
61
+ updateProjectUser(id_user, id_project, operation) {
62
+ winston.debug("updateProjectUser start");
63
+ return Project_user
64
+ .findOneAndUpdate({id_user: id_user, id_project: id_project}, {$inc : {'number_assigned_requests' : operation}}, {new: true, upsert:false}, function(err, updatedPU) {
65
+ if (err) {
66
+ return winston.error(err);
67
+ }
68
+ winston.debug("number_assigned_requests +1 :" + updatedPU.id);
69
+
70
+ updatedPU.populate({path:'id_user', select:{'firstname':1, 'lastname':1}},function (err, updatedProject_userPopulated){
71
+
72
+ var pu = updatedProject_userPopulated.toJSON();
73
+
74
+ return Project.findById(id_project).exec(function(err, project) {
75
+ pu.isBusy = ProjectUserUtil.isBusy(updatedProject_userPopulated, project.settings && project.settings.max_agent_assigned_chat);
76
+ winston.debug("pu.isBusy: "+ pu.isBusy);
77
+ authEvent.emit('project_user.update', {updatedProject_userPopulated:pu, req: undefined, skipArchive: true});
78
+ })
79
+
80
+ });
81
+
82
+ });
83
+ }
84
+
85
+ updateParticipatingProjectUsers(request, operation) {
86
+ winston.debug("request.participatingAgents", request.participatingAgents);
87
+ if (request.participatingAgents.length>0) {
88
+ request.participatingAgents.forEach(user => {
89
+ winston.debug("request.participatingAgents user",user); //it is a user and not a project_user
90
+ this.updateProjectUser(user.id, request.id_project, operation);
91
+ });
92
+ }
93
+ }
94
+
95
+ listen() {
96
+
97
+ if (this.enabled==true) {
98
+ winston.info("Route queue Listener listen");
99
+ } else {
100
+ return winston.info("Route queue Listener disabled");
101
+ }
102
+
103
+ var that = this;
104
+
105
+ // TODO fai versione che passa anche project
106
+ requestEvent.on('request.create', async (request) => {
107
+ setImmediate(() => {
108
+ this.updateParticipatingProjectUsers(request, +1);
109
+ });
110
+ });
111
+
112
+ // TODO usa versione complete con project per evitare query??
113
+ requestEvent.on('request.close', async (request) => {
114
+ setImmediate(() => {
115
+ this.updateParticipatingProjectUsers(request, -1);
116
+ });
117
+ });
118
+
119
+
120
+ requestEvent.on('request.participants.join', async (data) => {
121
+ var request = data.request;
122
+ var member = data.member;
123
+ setImmediate(() => {
124
+ this.updateProjectUser(member, request.id_project, 1);
125
+ });
126
+ });
127
+
128
+ requestEvent.on('request.participants.leave', async (data) => {
129
+ var request = data.request;
130
+ var member = data.member;
131
+ setImmediate(() => {
132
+ this.updateProjectUser(member, request.id_project, -1);
133
+ });
134
+ });
135
+
136
+ requestEvent.on('request.participants.update', async (data) => {
137
+ var request = data.request;
138
+ var removedParticipants = data.removedParticipants;
139
+ var addedParticipants = data.addedParticipants;
140
+
141
+ setImmediate(() => {
142
+
143
+ addedParticipants.forEach(participant => {
144
+ winston.debug('addedParticipants participant', participant);
145
+ this.updateProjectUser(participant, request.id_project, 1);
146
+ });
147
+
148
+ removedParticipants.forEach(participant => {
149
+ winston.debug('removedParticipants participant', participant);
150
+ this.updateProjectUser(participant, request.id_project, -1);
151
+ });
152
+
153
+ });
154
+ });
155
+
156
+ departmentEvent.on('operator.select.base2', async (res) => {
157
+ // departmentEvent.prependListener('operator.select', async (data) => {
158
+
159
+ var operatorsResult = res.result;
160
+ winston.info('operator.select.base2 res', res);
161
+
162
+
163
+ var disableWebHookCall = res.disableWebHookCall;
164
+ winston.debug("operator.select.base2 disableWebHookCall: "+ disableWebHookCall);
165
+
166
+ if (disableWebHookCall===true) {
167
+ winston.debug("operator.select.base2 disableWebHookCall enabled: "+ disableWebHookCall);
168
+ // return callNextEvent('operator.select', res);
169
+ return res.resolve(operatorsResult);
170
+
171
+ }
172
+
173
+
174
+
175
+
176
+
177
+
178
+
179
+
180
+ var project = operatorsResult.project;
181
+ var max_agent_assigned_chat = undefined;
182
+
183
+
184
+ // console.log("project: ", project);
185
+
186
+ if (project && project.settings && project.settings.chat_limit_on && project.settings.max_agent_assigned_chat) {
187
+ max_agent_assigned_chat = project.settings.max_agent_assigned_chat;
188
+ winston.debug('operator.select max_agent_assigned_chat: '+max_agent_assigned_chat);
189
+
190
+ } else {
191
+ winston.debug("chat_limit_on not defined calling next ");
192
+ return departmentEvent.callNextEvent('operator.select', res);
193
+ }
194
+
195
+
196
+
197
+
198
+ // winston.info('qui', operatorsResult.available_agents.length);
199
+ operatorsResult.available_agents_request = [];
200
+
201
+ if (operatorsResult && operatorsResult.available_agents && operatorsResult.available_agents.length > 0) {
202
+
203
+ // winston.info('qui1');
204
+ // qui1000
205
+ var query = {id_project: operatorsResult.id_project, status: {$lt:1000}};
206
+ // asyncForEach(operatorsResult.available_agents, async (aa) => {
207
+ for (const aa of operatorsResult.available_agents) {
208
+ query.participants = aa.id_user._id.toString();// attento qui
209
+ winston.debug("department operators query:" , query);
210
+
211
+
212
+ // questa cosa nn va bene. nn puoi usare ? number_assigned_requests??
213
+ var count = await Request.countDocuments(query);
214
+ winston.debug("department operators count: "+ count);
215
+ operatorsResult.available_agents_request.push({project_user: aa, openRequetsCount : count});
216
+
217
+ }
218
+
219
+ }
220
+
221
+
222
+
223
+
224
+
225
+
226
+ var available_agents_request = operatorsResult.available_agents_request;
227
+ var available_agents_not_busy = [];
228
+ if (available_agents_request && available_agents_request.length>0) {
229
+ for (const aa of available_agents_request) {
230
+ // console.log("aa.openRequetsCount ", aa.openRequetsCount, " for:", aa.project_user.id_user);
231
+
232
+ var maxAssignedchatForUser = max_agent_assigned_chat;
233
+
234
+ var max_agent_assigned_chat_specific_user = aa.project_user.max_assigned_chat;
235
+ // console.log("max_agent_assigned_chat_specific_user: ", max_agent_assigned_chat_specific_user);
236
+
237
+ if (max_agent_assigned_chat_specific_user && max_agent_assigned_chat_specific_user!=-1 ) {
238
+ maxAssignedchatForUser = max_agent_assigned_chat_specific_user;
239
+ }
240
+
241
+ winston.debug("maxAssignedchatForUser: "+ maxAssignedchatForUser);
242
+
243
+ if (aa.openRequetsCount < maxAssignedchatForUser) {
244
+ winston.debug("adding "+ aa.project_user.id_user+ " with openRequetsCount: "+ aa.openRequetsCount +" and with maxAssignedchatForUser " + maxAssignedchatForUser +" to available_agents_not_busy" );
245
+ available_agents_not_busy.push(aa.project_user);
246
+ }
247
+ }
248
+ } else {
249
+ winston.debug("available_agents_request not defined");
250
+ }
251
+
252
+ winston.debug("available_agents_not_busy", available_agents_not_busy);
253
+
254
+
255
+
256
+ // TODO non riassegnare allo stesso utente usa history oppure lastabandonedby in attributes
257
+ // in project_user sengni il numero di abandoni se uguale a psettng lo metto offline
258
+ winston.debug("res.context",res.context);
259
+
260
+ winston.debug("res.context.request.attributes",res.context.request.attributes);
261
+
262
+ if (res.context && res.context.request && res.context.request &&
263
+ res.context.request.attributes && res.context.request.attributes.abandoned_by_project_users ) { //&& res.context.request.attributes.queue_important==false (vip sla continuo reassign)
264
+
265
+ // var abandoned_by_project_users= {"5ecd44cfa3f5670034109b44":true,"5ecd56a10e7d2d00343203cc":true}
266
+
267
+ winston.debug("res.context.request.attributes.abandoned_by_project_users: ", res.context.request.attributes.abandoned_by_project_users );
268
+
269
+ var abandoned_by_project_usersAsArray = Object.keys(res.context.request.attributes.abandoned_by_project_users);
270
+
271
+ if (abandoned_by_project_usersAsArray.length>0 ) {
272
+ winston.debug("abandoned_by_project_usersAsArray", abandoned_by_project_usersAsArray);
273
+
274
+ var available_agents_not_busy = available_agents_not_busy.filter(projectUser=> !abandoned_by_project_usersAsArray.includes(projectUser._id.toString()))
275
+
276
+ winston.debug("available_agents_not_busy after: ", available_agents_not_busy );
277
+ }
278
+ }
279
+
280
+ // if (res.context && res.context.request && res.context.request &&
281
+ // res.context.request.attributes && res.context.request.attributes.last_abandoned_by ) {
282
+ // winston.debug("res.context.request.attributes.last_abandoned_by: "+res.context.request.attributes.last_abandoned_by );
283
+ // let last_abandoned_by_index = available_agents_not_busy.findIndex(projectUser => projectUser._id.toString() === res.context.request.attributes.last_abandoned_by);
284
+ // winston.debug("last_abandoned_by_index: "+last_abandoned_by_index );
285
+ // if (last_abandoned_by_index>-1) {
286
+ // available_agents_not_busy.splice(last_abandoned_by_index, 1);
287
+ // winston.debug("available_agents_not_busy after", available_agents_not_busy );
288
+ // }
289
+
290
+ // }
291
+
292
+
293
+ var lastOperatorId = operatorsResult.lastOperatorId;
294
+
295
+ let lastOperatorIndex = available_agents_not_busy.findIndex(projectUser => projectUser.id_user.toString() === lastOperatorId);
296
+ winston.debug("lastOperatorIndex: "+ lastOperatorIndex);
297
+ var nextOper = that.nextOperator(available_agents_not_busy, lastOperatorIndex);
298
+ // console.log("nextOper: ", nextOper);
299
+ var nextOperatorId = undefined;
300
+ if (nextOper && nextOper.id_user) {
301
+ nextOperatorId = nextOper.id_user;
302
+ winston.verbose("nextOperatorId: "+ nextOperatorId);
303
+
304
+ operatorsResult.operators = [{id_user: nextOperatorId}];
305
+
306
+ // return resolve(result);
307
+ } else {
308
+ winston.debug("nextOper is not defined");
309
+ operatorsResult.operators = [];
310
+ // return resolve(result);
311
+ }
312
+
313
+
314
+ return departmentEvent.callNextEvent('operator.select', res);
315
+
316
+
317
+
318
+ });
319
+
320
+
321
+ }
322
+
323
+ }
324
+
325
+ var listener = new Listener();
326
+
327
+
328
+ module.exports = listener;
@@ -102,9 +102,13 @@ projectEvent.on('project.create', async (project) => {
102
102
  */
103
103
 
104
104
 
105
- winston.info("triggers created for new project");
105
+ winston.debug("triggers created for new project");
106
106
 
107
107
 
108
+
109
+
110
+ // cc
111
+
108
112
  });
109
113
  });
110
114
 
package/routes/auth.js CHANGED
@@ -112,13 +112,18 @@ function (req, res) {
112
112
  winston.error("SigninAnonymously validation error", {errors: errors, reqBody: req.body, reqUrl: req.url });
113
113
  return res.status(422).json({ errors: errors.array() });
114
114
  }
115
- var firstname = req.body.firstname || "Guest";
115
+
116
+ let uid = uuidv4();
117
+ let shortuid = uid.substring(0,4);
118
+ var firstname = req.body.firstname || "guest#"+shortuid; // guest_here
119
+ // var firstname = req.body.firstname || "Guest"; // guest_here
120
+
116
121
 
117
122
 
118
123
  //TODO togli trattini da uuidv4()
119
124
 
120
125
  // TODO remove email.sec?
121
- let userAnonym = {_id: uuidv4(), firstname:firstname, lastname: req.body.lastname, email: req.body.email, attributes: req.body.attributes};
126
+ let userAnonym = {_id: uid, firstname:firstname, lastname: req.body.lastname, email: req.body.email, attributes: req.body.attributes};
122
127
 
123
128
  req.user = UserUtil.decorateUser(userAnonym);
124
129
 
@@ -220,6 +220,10 @@ router.put('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
220
220
  if (req.body.user_available!=undefined) {
221
221
  update.user_available = req.body.user_available;
222
222
  }
223
+
224
+ if (req.body.profileStatus!=undefined) {
225
+ update.profileStatus = req.body.profileStatus;
226
+ }
223
227
 
224
228
  if (req.body.max_assigned_chat!=undefined) {
225
229
  update.max_assigned_chat = req.body.max_assigned_chat;
@@ -241,6 +245,7 @@ router.put('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
241
245
 
242
246
 
243
247
 
248
+
244
249
  Project_user.findByIdAndUpdate(req.projectuser.id, update, { new: true, upsert: true }, function (err, updatedProject_user) {
245
250
  if (err) {
246
251
  winston.error("Error gettting project_user for update", err);
@@ -274,6 +279,10 @@ router.put('/:project_userid', [passport.authenticate(['basic', 'jwt'], { sessio
274
279
  update.user_available = req.body.user_available;
275
280
  }
276
281
 
282
+ if (req.body.profileStatus!=undefined) {
283
+ update.profileStatus = req.body.profileStatus;
284
+ }
285
+
277
286
  if (req.body.max_assigned_chat!=undefined) {
278
287
  update.max_assigned_chat = req.body.max_assigned_chat;
279
288
  }
package/routes/request.js CHANGED
@@ -162,6 +162,20 @@ router.patch('/:requestid', function (req, res) {
162
162
  update.priority = req.body.priority;
163
163
  }
164
164
 
165
+ if (req.body.smartAssignment!=undefined) {
166
+ update.smartAssignment = req.body.smartAssignment;
167
+ }
168
+
169
+ if (req.body.workingStatus!=undefined) {
170
+ update.workingStatus = req.body.workingStatus;
171
+ }
172
+
173
+
174
+ if (req.body.channelName) {
175
+ update["channel.name"] = req.body.channelName;
176
+ }
177
+
178
+
165
179
 
166
180
  winston.verbose("Request patch update",update);
167
181
 
@@ -710,6 +724,10 @@ router.get('/', function (req, res, next) {
710
724
  winston.debug('REQUEST ROUTE - QUERY DEPT ID', query.department);
711
725
  }
712
726
 
727
+ if (req.query.requester_email) {
728
+ query["snapshot.lead.email"] = req.query.requester_email;
729
+ }
730
+
713
731
  if (req.query.full_text) {
714
732
  winston.debug('req.query.fulltext', req.query.full_text);
715
733
  query.$text = { "$search": req.query.full_text };