tango-app-api-infra 3.0.9 → 3.0.11
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 +3 -2
- package/package.json +1 -1
- package/src/controllers/clientInfra.controller.js +393 -0
- package/src/controllers/infra.controllers.js +6 -13
- package/src/controllers/storeInfra.controlller.js +82 -5
- package/src/controllers/userInfra.controller.js +75 -4
- package/src/routes/clientInfra.routes.js +15 -0
- package/src/routes/storeInfra.routes.js +2 -1
- package/src/routes/userInfra.routes.js +3 -1
- package/src/services/client.service.js +3 -0
- package/src/services/store.service.js +7 -0
package/index.js
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import { infraRouter } from './src/routes/infra.routes.js';
|
|
4
4
|
import { internalInfraRouter } from './src/routes/internalInfra.routes.js';
|
|
5
|
-
import { userInfraRouter } from './src/routes/
|
|
5
|
+
import { userInfraRouter } from './src/routes/userInfra.routes.js';
|
|
6
6
|
import { storeInfraRouter } from './src/routes/storeInfra.routes.js';
|
|
7
|
-
|
|
7
|
+
import { clientInfraRouter } from './src/routes/clientInfra.routes.js';
|
|
8
|
+
export { infraRouter, internalInfraRouter, userInfraRouter, storeInfraRouter, clientInfraRouter };
|
|
8
9
|
|
|
9
10
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
|
|
2
|
+
import { countDocumentsStore, findStorewithpagination } from '../services/store.service.js';
|
|
3
|
+
import { logger } from 'tango-app-api-middleware';
|
|
4
|
+
import { aggregateTangoTicket } from '../services/tangoTicket.service.js';
|
|
5
|
+
import { findinfraReason } from '../services/infraReason.service.js';
|
|
6
|
+
import { findClientwithpagination } from '../services/client.service.js';
|
|
7
|
+
import dayjs from 'dayjs';
|
|
8
|
+
import { getOpenSearchData } from 'tango-app-api-middleware';
|
|
9
|
+
|
|
10
|
+
export async function infraCard( req, res ) {
|
|
11
|
+
try {
|
|
12
|
+
let storeCount = await countDocumentsStore( { clientId: { $in: req.body.clientId }, status: 'active' } );
|
|
13
|
+
let infraStoreCount = await aggregateTangoTicket( [
|
|
14
|
+
{
|
|
15
|
+
$match: {
|
|
16
|
+
'status': { $ne: 'closed' },
|
|
17
|
+
'basicDetails.clientId': { $in: req.body.clientId },
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
$project: {
|
|
22
|
+
storeId: '$basicDetails.storeId',
|
|
23
|
+
identifiedcount: {
|
|
24
|
+
$cond: [ { $eq: [ '$infraTicketDetails.issueStatus', 'identified' ] }, 1, 0 ],
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
$group: {
|
|
30
|
+
_id: '$storeId',
|
|
31
|
+
infraCount: { $sum: 1 },
|
|
32
|
+
identifiedcount: { $sum: '$identifiedcount' },
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
$group: {
|
|
37
|
+
_id: null,
|
|
38
|
+
infraCount: { $sum: '$infraCount' },
|
|
39
|
+
identifiedcount: { $sum: '$identifiedcount' },
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
] );
|
|
43
|
+
let query = [ {
|
|
44
|
+
$match: {
|
|
45
|
+
'basicDetails.clientId': { $in: req.body.clientId },
|
|
46
|
+
'infraTicketDetails.issueStatus': 'identified',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
$project: {
|
|
51
|
+
ticketId: 1,
|
|
52
|
+
issueStatus: '$infraTicketDetails.issueStatus',
|
|
53
|
+
primaryIssue: {
|
|
54
|
+
$filter: {
|
|
55
|
+
input: '$infraActivity',
|
|
56
|
+
as: 'item',
|
|
57
|
+
cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
$unwind: {
|
|
64
|
+
path: '$primaryIssue', preserveNullAndEmptyArrays: true,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
$unwind: {
|
|
69
|
+
path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
$project: {
|
|
74
|
+
ticketId: 1,
|
|
75
|
+
issueStatus: 1,
|
|
76
|
+
ticketType: 1,
|
|
77
|
+
primaryIssue: '$primaryIssue.reasons.primaryIssue',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
];
|
|
81
|
+
let ticketList = await aggregateTangoTicket( query );
|
|
82
|
+
let issueList = await findinfraReason( { parentId: { '$exists': false } } );
|
|
83
|
+
const categoryCounts = {};
|
|
84
|
+
let response;
|
|
85
|
+
if ( ticketList.length > 0 ) {
|
|
86
|
+
ticketList.forEach( ( item ) => {
|
|
87
|
+
const categoryName = item.primaryIssue;
|
|
88
|
+
if ( categoryCounts[categoryName] ) {
|
|
89
|
+
categoryCounts[categoryName]++;
|
|
90
|
+
} else {
|
|
91
|
+
categoryCounts[categoryName] = 1;
|
|
92
|
+
}
|
|
93
|
+
} );
|
|
94
|
+
response = issueList.map( ( category ) => ( {
|
|
95
|
+
name: category.name,
|
|
96
|
+
count: categoryCounts[category.name] || 0,
|
|
97
|
+
} ) );
|
|
98
|
+
} else {
|
|
99
|
+
response = issueList.map( ( category ) => ( {
|
|
100
|
+
name: category.name,
|
|
101
|
+
count: 0,
|
|
102
|
+
} ) );
|
|
103
|
+
}
|
|
104
|
+
res.sendSuccess( {
|
|
105
|
+
total: storeCount,
|
|
106
|
+
liveStoreCount: infraStoreCount.length > 0 ? storeCount - infraStoreCount[0].infraCount : 0,
|
|
107
|
+
infraStoreCount: infraStoreCount.length > 0 ? infraStoreCount[0].infraCount : 0,
|
|
108
|
+
identifiedcount: infraStoreCount.length > 0 ? infraStoreCount[0].identifiedcount : 0,
|
|
109
|
+
notidentifiedcount: infraStoreCount.length > 0 ? infraStoreCount[0].infraCount - infraStoreCount[0].identifiedcount : 0,
|
|
110
|
+
infraIssues: response,
|
|
111
|
+
} );
|
|
112
|
+
} catch ( error ) {
|
|
113
|
+
logger.error( { error: error, function: 'infraCard' } );
|
|
114
|
+
return res.sendError( error, 500 );
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
export async function infraIssuesTable( req, res ) {
|
|
120
|
+
try {
|
|
121
|
+
let query = [ {
|
|
122
|
+
$match: {
|
|
123
|
+
'basicDetails.clientId': { $in: req.body.clientId },
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
$project: {
|
|
128
|
+
storeId: '$basicDetails.storeId',
|
|
129
|
+
storeName: '$basicDetails.storeName',
|
|
130
|
+
status: 1,
|
|
131
|
+
createdAt: { $dateToString: { format: '%d-%m-%Y', date: '$createdAt' } },
|
|
132
|
+
issueIdentifiedDate: { $dateToString: { format: '%d-%m-%Y', date: '$infraTicketDetails.issueIdentifiedDate' } },
|
|
133
|
+
issueClosedDate: { $dateToString: { format: '%d-%m-%Y', date: '$issueClosedDate' } },
|
|
134
|
+
primaryIssue: {
|
|
135
|
+
$filter: {
|
|
136
|
+
input: '$infraActivity',
|
|
137
|
+
as: 'item',
|
|
138
|
+
cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
$unwind: {
|
|
145
|
+
path: '$primaryIssue', preserveNullAndEmptyArrays: true,
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
$unwind: {
|
|
150
|
+
path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
|
|
151
|
+
},
|
|
152
|
+
}, {
|
|
153
|
+
$project: {
|
|
154
|
+
storeId: 1,
|
|
155
|
+
storeName: 1,
|
|
156
|
+
createdAt: 1,
|
|
157
|
+
issueIdentifiedDate: { $ifNull: [ '$issueIdentifiedDate', '-' ] },
|
|
158
|
+
issueClosedDate: { $ifNull: [ '$issueClosedDate', '-' ] },
|
|
159
|
+
status: 1,
|
|
160
|
+
infraIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '-' ] },
|
|
161
|
+
},
|
|
162
|
+
} ];
|
|
163
|
+
let count = await aggregateTangoTicket( query );
|
|
164
|
+
if ( req.body.limit && req.body.offset && !req.body.export ) {
|
|
165
|
+
query.push(
|
|
166
|
+
{ $skip: ( req.body.offset - 1 ) * req.body.limit },
|
|
167
|
+
{ $limit: Number( req.body.limit ) },
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
let result = await aggregateTangoTicket( query );
|
|
171
|
+
res.sendSuccess( {
|
|
172
|
+
count: count.length,
|
|
173
|
+
result: result,
|
|
174
|
+
} );
|
|
175
|
+
} catch ( error ) {
|
|
176
|
+
logger.error( { error: error, function: 'infraIssuesTable' } );
|
|
177
|
+
return res.sendError( error, 500 );
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
export async function hourWiseDownClients( req, res ) {
|
|
183
|
+
try {
|
|
184
|
+
let inputData = req.body;
|
|
185
|
+
let skip = 0;
|
|
186
|
+
let limit = 10;
|
|
187
|
+
if ( req.body.limit && req.body.offset && !req.body.export ) {
|
|
188
|
+
skip = ( req.body.offset - 1 ) * req.body.limit,
|
|
189
|
+
limit = Number( req.body.limit );
|
|
190
|
+
}
|
|
191
|
+
let clientlist = await findClientwithpagination( { clientId: { $in: req.body.clientId } }, { clientId: 1, clientName: 1 }, skip, limit );
|
|
192
|
+
let data = {};
|
|
193
|
+
let result = [];
|
|
194
|
+
for ( const client of clientlist ) {
|
|
195
|
+
data.clientId = client.clientId;
|
|
196
|
+
data.clientName = client.clientName;
|
|
197
|
+
let clientdata = await livecountCheck( data, inputData );
|
|
198
|
+
result.push( clientdata[0] );
|
|
199
|
+
}
|
|
200
|
+
res.sendSuccess( { result: result } );
|
|
201
|
+
} catch ( error ) {
|
|
202
|
+
logger.error( { error: error, function: 'hourWiseDownClients' } );
|
|
203
|
+
return res.sendError( error, 500 );
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
export async function livecountCheck( data, inputData ) {
|
|
207
|
+
return new Promise( async ( Resolve, Reject ) => {
|
|
208
|
+
try {
|
|
209
|
+
let TimeSlots = generateTimeSlots( 8, 22, 60, inputData.Date );
|
|
210
|
+
let timewise = [];
|
|
211
|
+
for ( const obj of TimeSlots ) {
|
|
212
|
+
obj.startTime = dayjs( obj.from ).format( 'hh:mm A' );
|
|
213
|
+
obj.endTime = dayjs( obj.to ).format( 'hh:mm A' );
|
|
214
|
+
const liveCount = await getOpenSearchData( 'data_not_received_hour',
|
|
215
|
+
{
|
|
216
|
+
'size': 1,
|
|
217
|
+
'query': {
|
|
218
|
+
'bool': {
|
|
219
|
+
'must': [
|
|
220
|
+
{
|
|
221
|
+
'term': {
|
|
222
|
+
'doc.client_id.keyword': data.clientId,
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
'term': {
|
|
227
|
+
'doc.hour': obj.hour,
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
'term': {
|
|
232
|
+
'doc.date.keyword': dayjs( obj.from ).format( 'DD-MM-YYYY' ),
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
} );
|
|
239
|
+
if ( liveCount.body.hits.hits.length > 0 ) {
|
|
240
|
+
obj[obj.startTime + '-' + obj.endTime] = liveCount.body.hits.hits[0]._source.doc.zero_file_received_store_count;
|
|
241
|
+
} else {
|
|
242
|
+
obj[obj.startTime + '-' + obj.endTime] = 0;
|
|
243
|
+
}
|
|
244
|
+
obj.clientId = data.clientId;
|
|
245
|
+
timewise.push( obj );
|
|
246
|
+
}
|
|
247
|
+
const mergedData = {
|
|
248
|
+
brandName: data.brandName,
|
|
249
|
+
};
|
|
250
|
+
timewise.forEach( ( obj ) => {
|
|
251
|
+
for ( const key in obj ) {
|
|
252
|
+
if ( key !== 'hour' && key !== 'from' && key !== 'to' && key !== 'startTime' && key !== 'endTime' && key !== 'clientId' ) {
|
|
253
|
+
if ( mergedData[key] ) {
|
|
254
|
+
mergedData[key] += obj[key];
|
|
255
|
+
} else {
|
|
256
|
+
mergedData[key] = obj[key];
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
} );
|
|
261
|
+
|
|
262
|
+
// Create an array with the merged data.
|
|
263
|
+
const mergedArray = [ mergedData ];
|
|
264
|
+
Resolve( mergedArray );
|
|
265
|
+
} catch ( err ) {
|
|
266
|
+
Reject( err );
|
|
267
|
+
}
|
|
268
|
+
} );
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
function generateTimeSlots( startHour, endHour, interval, time ) {
|
|
273
|
+
const timeSlots = [];
|
|
274
|
+
for ( let hour = startHour; hour <= endHour; hour++ ) {
|
|
275
|
+
for ( let minute = 0; minute < 60; minute += interval ) {
|
|
276
|
+
let isoDate = new Date();
|
|
277
|
+
|
|
278
|
+
const inputDate = dayjs( time ).format( 'YYYY-MM-DD' );
|
|
279
|
+
isoDate = new Date( inputDate );
|
|
280
|
+
|
|
281
|
+
isoDate.setHours( hour, minute, 0, 0 );
|
|
282
|
+
const timeSlotObj = {
|
|
283
|
+
hour: hour,
|
|
284
|
+
from: isoDate.toISOString(),
|
|
285
|
+
to: new Date( isoDate.getTime() + interval * 60000 ).toISOString(),
|
|
286
|
+
};
|
|
287
|
+
timeSlots.push( timeSlotObj );
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return timeSlots;
|
|
291
|
+
};
|
|
292
|
+
export async function hourWiseDownstores( req, res ) {
|
|
293
|
+
try {
|
|
294
|
+
let inputData = req.body;
|
|
295
|
+
inputData.Date = dayjs().format( 'YYYY-MM-DD' );
|
|
296
|
+
let skip = 0;
|
|
297
|
+
let limit = 10;
|
|
298
|
+
if ( req.body.limit && req.body.offset && !req.body.export ) {
|
|
299
|
+
skip = ( req.body.offset - 1 ) * req.body.limit,
|
|
300
|
+
limit = Number( req.body.limit );
|
|
301
|
+
}
|
|
302
|
+
let storeslist = await findStorewithpagination( { clientId: req.body.clientId }, { storeId: 1, storeName: 1, storeProfile: 1 }, skip, limit );
|
|
303
|
+
let data = {};
|
|
304
|
+
let result = [];
|
|
305
|
+
for ( const store of storeslist ) {
|
|
306
|
+
data.storeId = store.storeId;
|
|
307
|
+
data.storeName = store.storeName;
|
|
308
|
+
let storedata = await downStoresCheck( data, inputData );
|
|
309
|
+
result.push( storedata[0] );
|
|
310
|
+
}
|
|
311
|
+
res.sendSuccess( { result: result } );
|
|
312
|
+
} catch ( error ) {
|
|
313
|
+
logger.error( { error: error, function: 'hourWiseDownstores' } );
|
|
314
|
+
return res.sendError( error, 500 );
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
function downStoresCheck( data, inputData ) {
|
|
320
|
+
return new Promise( async ( Resolve, Reject ) => {
|
|
321
|
+
try {
|
|
322
|
+
let TimeSlots = generateTimeSlots( 8, 22, 60, inputData.Date );
|
|
323
|
+
let timewise = [];
|
|
324
|
+
for ( const obj of TimeSlots ) {
|
|
325
|
+
obj.startTime = dayjs( obj.from ).format( 'hh:mm A' );
|
|
326
|
+
obj.endTime = dayjs( obj.to ).format( 'hh:mm A' );
|
|
327
|
+
const downTime = await getOpenSearchData( 'live_downtime_hourly',
|
|
328
|
+
{
|
|
329
|
+
'size': 1,
|
|
330
|
+
'query': {
|
|
331
|
+
'bool': {
|
|
332
|
+
'must': [
|
|
333
|
+
{
|
|
334
|
+
'term': {
|
|
335
|
+
'doc.date.keyword': dayjs( inputData.Date ).format( 'DD-MM-YYYY' ),
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
'term': {
|
|
340
|
+
'doc.store_id.keyword': data.storeId,
|
|
341
|
+
},
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
'terms': {
|
|
345
|
+
'doc.hour.keyword': [ obj.hour ],
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
],
|
|
349
|
+
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
|
|
353
|
+
} );
|
|
354
|
+
let streamwiseDowntime = downTime.body.hits.hits.length > 0 ? downTime.body.hits.hits[0]._source.doc.streamwise_downtime : [];
|
|
355
|
+
if ( streamwiseDowntime.length > 0 ) {
|
|
356
|
+
const sum = streamwiseDowntime.reduce( ( accumulator, currentValue ) => {
|
|
357
|
+
return accumulator + currentValue.down_time;
|
|
358
|
+
}, 0 );
|
|
359
|
+
|
|
360
|
+
// Calculate the average
|
|
361
|
+
const average = sum / streamwiseDowntime.length;
|
|
362
|
+
obj[obj.startTime + '-' + obj.endTime] = Math.round( average );
|
|
363
|
+
} else {
|
|
364
|
+
obj[obj.startTime + '-' + obj.endTime] = 0;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
timewise.push( obj );
|
|
368
|
+
}
|
|
369
|
+
const mergedData = {
|
|
370
|
+
storeName: data.storeName,
|
|
371
|
+
storeId: data.storeId,
|
|
372
|
+
|
|
373
|
+
};
|
|
374
|
+
timewise.forEach( ( obj ) => {
|
|
375
|
+
for ( const key in obj ) {
|
|
376
|
+
if ( key !== 'hour' && key !== 'from' && key !== 'to' && key !== 'startTime' && key !== 'endTime' && key !== 'clientId' ) {
|
|
377
|
+
if ( mergedData[key] ) {
|
|
378
|
+
mergedData[key] += obj[key];
|
|
379
|
+
} else {
|
|
380
|
+
mergedData[key] = obj[key];
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
} );
|
|
385
|
+
|
|
386
|
+
// Create an array with the merged data.
|
|
387
|
+
const mergedArray = [ mergedData ];
|
|
388
|
+
Resolve( mergedArray );
|
|
389
|
+
} catch ( err ) {
|
|
390
|
+
Reject( err );
|
|
391
|
+
}
|
|
392
|
+
} );
|
|
393
|
+
}
|
|
@@ -27,8 +27,7 @@ export async function createTicket( req, res ) {
|
|
|
27
27
|
|
|
28
28
|
export async function updateStatus( req, res ) {
|
|
29
29
|
try {
|
|
30
|
-
|
|
31
|
-
if ( req.body.status == 'close' ) {
|
|
30
|
+
if ( req.body.status == 'closed' ) {
|
|
32
31
|
req.body.issueClosedDate = new Date();
|
|
33
32
|
req.body.infraActivity.push( {
|
|
34
33
|
actionType: 'dataRecived',
|
|
@@ -41,13 +40,7 @@ export async function updateStatus( req, res ) {
|
|
|
41
40
|
actionBy: 'User',
|
|
42
41
|
} );
|
|
43
42
|
}
|
|
44
|
-
let updateTicket = await updateOneTangoTicket( { ticketId: req.body.ticketId },
|
|
45
|
-
{
|
|
46
|
-
status: req.body.status,
|
|
47
|
-
infraTicketDetails: infraTicketDetails,
|
|
48
|
-
infraActivity: req.body.infraActivity,
|
|
49
|
-
},
|
|
50
|
-
);
|
|
43
|
+
let updateTicket = await updateOneTangoTicket( { ticketId: req.body.ticketId }, req.body );
|
|
51
44
|
if ( updateTicket ) {
|
|
52
45
|
res.sendSuccess( 'Ticket Updated Successfully' );
|
|
53
46
|
}
|
|
@@ -90,9 +83,9 @@ export async function PrimaryReasons( req, res ) {
|
|
|
90
83
|
|
|
91
84
|
export async function secondaryReason( req, res ) {
|
|
92
85
|
try {
|
|
93
|
-
let list = await findinfraReason( { parentName: req.body.primaryIssue }, { name: 1, order: 1 } );
|
|
86
|
+
let list = await findinfraReason( { parentName: req.body.primaryIssue }, { name: 1, order: 1, toolTips: 1 } );
|
|
94
87
|
if ( list.length > 0 ) {
|
|
95
|
-
res.
|
|
88
|
+
res.sendSuccess( {
|
|
96
89
|
count: list.length,
|
|
97
90
|
result: list,
|
|
98
91
|
} );
|
|
@@ -106,7 +99,7 @@ export async function secondaryReason( req, res ) {
|
|
|
106
99
|
|
|
107
100
|
export async function updateTicketIssue( req, res ) {
|
|
108
101
|
try {
|
|
109
|
-
let updateTicket = await updateOneTangoTicket( { ticketId: req.body.ticketId }, { 'infraActivity': req.body.infraActivity, 'infraTicketDetails.issueStatus': 'identified' } );
|
|
102
|
+
let updateTicket = await updateOneTangoTicket( { ticketId: req.body.ticketId }, { 'infraActivity': req.body.infraActivity, 'infraTicketDetails.issueIdentifiedDate': new Date(), 'infraTicketDetails.issueIdentifiedBy': req.body.issueIdentifiedBy, 'infraTicketDetails.issueStatus': 'identified' } );
|
|
110
103
|
if ( updateTicket ) {
|
|
111
104
|
res.sendSuccess( 'Ticket Updated Successfully' );
|
|
112
105
|
}
|
|
@@ -123,7 +116,7 @@ export async function viewTicket( req, res ) {
|
|
|
123
116
|
res.sendSuccess( ticket );
|
|
124
117
|
}
|
|
125
118
|
} catch ( error ) {
|
|
126
|
-
logger.error( { error: error, function: '
|
|
119
|
+
logger.error( { error: error, function: 'viewTicket' } );
|
|
127
120
|
return res.sendError( error, 500 );
|
|
128
121
|
}
|
|
129
122
|
}
|
|
@@ -3,6 +3,7 @@ import { logger, getOpenSearchData } from 'tango-app-api-middleware';
|
|
|
3
3
|
import { aggregateTangoTicket } from '../services/tangoTicket.service.js';
|
|
4
4
|
import { findOneStore } from '../services/store.service.js';
|
|
5
5
|
import dayjs from 'dayjs';
|
|
6
|
+
import { findinfraReason } from '../services/infraReason.service.js';
|
|
6
7
|
export async function storeTicketList( req, res ) {
|
|
7
8
|
try {
|
|
8
9
|
let query = [ {
|
|
@@ -66,6 +67,80 @@ export async function storeTicketList( req, res ) {
|
|
|
66
67
|
return res.sendError( error, 500 );
|
|
67
68
|
}
|
|
68
69
|
}
|
|
70
|
+
|
|
71
|
+
export async function storeTicketcard( req, res ) {
|
|
72
|
+
try {
|
|
73
|
+
let query = [ {
|
|
74
|
+
$match: {
|
|
75
|
+
'basicDetails.storeId': req.body.storeId,
|
|
76
|
+
'infraTicketDetails.issueStatus': 'identified',
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
$project: {
|
|
81
|
+
ticketId: 1,
|
|
82
|
+
issueStatus: '$infraTicketDetails.issueStatus',
|
|
83
|
+
primaryIssue: {
|
|
84
|
+
$filter: {
|
|
85
|
+
input: '$infraActivity',
|
|
86
|
+
as: 'item',
|
|
87
|
+
cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
$unwind: {
|
|
94
|
+
path: '$primaryIssue', preserveNullAndEmptyArrays: true,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
$unwind: {
|
|
99
|
+
path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
$project: {
|
|
104
|
+
ticketId: 1,
|
|
105
|
+
issueStatus: 1,
|
|
106
|
+
ticketType: 1,
|
|
107
|
+
primaryIssue: '$primaryIssue.reasons.primaryIssue',
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
let ticketList = await aggregateTangoTicket( query );
|
|
112
|
+
let issueList = await findinfraReason( { parentId: { '$exists': false } } );
|
|
113
|
+
const categoryCounts = {};
|
|
114
|
+
let response;
|
|
115
|
+
if ( ticketList.length > 0 ) {
|
|
116
|
+
ticketList.forEach( ( item ) => {
|
|
117
|
+
const categoryName = item.primaryIssue;
|
|
118
|
+
if ( categoryCounts[categoryName] ) {
|
|
119
|
+
categoryCounts[categoryName]++;
|
|
120
|
+
} else {
|
|
121
|
+
categoryCounts[categoryName] = 1;
|
|
122
|
+
}
|
|
123
|
+
} );
|
|
124
|
+
response = issueList.map( ( category ) => ( {
|
|
125
|
+
name: category.name,
|
|
126
|
+
count: categoryCounts[category.name] || 0,
|
|
127
|
+
} ) );
|
|
128
|
+
} else {
|
|
129
|
+
response = issueList.map( ( category ) => ( {
|
|
130
|
+
name: category.name,
|
|
131
|
+
count: 0,
|
|
132
|
+
} ) );
|
|
133
|
+
}
|
|
134
|
+
res.sendSuccess( {
|
|
135
|
+
count: ticketList.length,
|
|
136
|
+
data: response,
|
|
137
|
+
} );
|
|
138
|
+
} catch ( error ) {
|
|
139
|
+
logger.error( { error: error, function: 'storeTicketList' } );
|
|
140
|
+
return res.sendError( error, 500 );
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
69
144
|
export async function edgeAppLogTable( req, res ) {
|
|
70
145
|
try {
|
|
71
146
|
const store = await findOneStore( { storeId: req.body.storeId } );
|
|
@@ -77,6 +152,9 @@ export async function edgeAppLogTable( req, res ) {
|
|
|
77
152
|
const interval = 60; // 1 hour in minutes
|
|
78
153
|
const timeSlots = generateTimeSlots( startHour, endHour, interval, req );
|
|
79
154
|
for ( const obj of timeSlots ) {
|
|
155
|
+
obj.startTime = dayjs( obj.from ).format( 'hh:mm A' );
|
|
156
|
+
obj.endTime = dayjs( obj.to ).format( 'hh:mm A' );
|
|
157
|
+
|
|
80
158
|
let internetSpeedQuery = {
|
|
81
159
|
'size': 1,
|
|
82
160
|
'query': {
|
|
@@ -192,7 +270,7 @@ export async function edgeAppLogTable( req, res ) {
|
|
|
192
270
|
} else {
|
|
193
271
|
obj.downtime = 0;
|
|
194
272
|
}
|
|
195
|
-
let
|
|
273
|
+
let appStatusQuery = {
|
|
196
274
|
'size': 1,
|
|
197
275
|
'query': {
|
|
198
276
|
'bool': {
|
|
@@ -228,8 +306,8 @@ export async function edgeAppLogTable( req, res ) {
|
|
|
228
306
|
{ 'timestamp': { 'order': 'desc' } },
|
|
229
307
|
],
|
|
230
308
|
};
|
|
231
|
-
const
|
|
232
|
-
obj.
|
|
309
|
+
const appStatus = await getOpenSearchData( 'edgeapp_systemlogs', appStatusQuery );
|
|
310
|
+
obj.appStatus = appStatus.body.hits.hits.length > 0 ? appStatus.body.hits.hits[0]._source.data.message : '';
|
|
233
311
|
}
|
|
234
312
|
res.sendSuccess( timeSlots );
|
|
235
313
|
} catch ( error ) {
|
|
@@ -465,7 +543,7 @@ export async function viewedgeAppLog( req, res ) {
|
|
|
465
543
|
|
|
466
544
|
const newFilesCount = await getOpenSearchData( 'edgeapp_filelogs',
|
|
467
545
|
{
|
|
468
|
-
|
|
546
|
+
// 'size': 1,
|
|
469
547
|
'query': {
|
|
470
548
|
'bool': {
|
|
471
549
|
'must': [
|
|
@@ -612,7 +690,6 @@ export async function viewedgeAppLog( req, res ) {
|
|
|
612
690
|
} else {
|
|
613
691
|
response.Internetspeed = '';
|
|
614
692
|
}
|
|
615
|
-
|
|
616
693
|
response.antiVirus = antiVirus.body.hits.hits.length > 0 && antiVirus.body.hits.hits[0]._source.data.message == 'st-launch-1.0.exe is deleted' ? antiVirus.body.hits.hits[0]._source.data.occuringTime : '';
|
|
617
694
|
response.appStartTime = appStartTime.body.hits.hits.length > 0 ? appStartTime.body.hits.hits[0]._source.data.occuringTime : '';
|
|
618
695
|
response.appQuitTime = appQuitTime.body.hits.hits.length > 0 ? appQuitTime.body.hits.hits[0]._source.data.occuringTime : '';
|
|
@@ -6,7 +6,7 @@ import mongoose from 'mongoose';
|
|
|
6
6
|
|
|
7
7
|
export async function userTakeTicket( req, res ) {
|
|
8
8
|
try {
|
|
9
|
-
let userTicket = await findOneTangoTicket( { 'status': { $ne: 'closed' }, 'infraTicketDetails.assigntoUser': true } );
|
|
9
|
+
let userTicket = await findOneTangoTicket( { 'status': { $ne: 'closed' }, 'infraTicketDetails.assigntoUser': true, 'infraTicketDetails.addressingUser': { $exists: false } } );
|
|
10
10
|
if ( userTicket ) {
|
|
11
11
|
let assignTicket = await updateOneTangoTicket( { ticketId: userTicket.ticketId }, { 'infraTicketDetails.addressingUser': req.body.userId } );
|
|
12
12
|
if ( assignTicket ) {
|
|
@@ -46,11 +46,13 @@ export async function userTicketList( req, res ) {
|
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
$unwind: {
|
|
49
|
-
path: '$primaryIssue', preserveNullAndEmptyArrays: true
|
|
49
|
+
path: '$primaryIssue', preserveNullAndEmptyArrays: true,
|
|
50
|
+
},
|
|
50
51
|
},
|
|
51
52
|
{
|
|
52
53
|
$unwind: {
|
|
53
|
-
path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true
|
|
54
|
+
path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
|
|
55
|
+
},
|
|
54
56
|
}, {
|
|
55
57
|
$project: {
|
|
56
58
|
storeId: 1,
|
|
@@ -87,7 +89,7 @@ export async function basicDetails( req, res ) {
|
|
|
87
89
|
res.sendSuccess( {
|
|
88
90
|
userName: user.userName,
|
|
89
91
|
userType: user.userType,
|
|
90
|
-
total: infraCount+installationCount,
|
|
92
|
+
total: infraCount + installationCount,
|
|
91
93
|
infraCount: infraCount,
|
|
92
94
|
installationCount: installationCount,
|
|
93
95
|
dataMismatchCount: 0,
|
|
@@ -100,3 +102,72 @@ export async function basicDetails( req, res ) {
|
|
|
100
102
|
}
|
|
101
103
|
}
|
|
102
104
|
|
|
105
|
+
export async function workHistory( req, res ) {
|
|
106
|
+
try {
|
|
107
|
+
let query = [ {
|
|
108
|
+
$match: {
|
|
109
|
+
'status': 'closed',
|
|
110
|
+
'infraTicketDetails.addressingUser': new mongoose.Types.ObjectId( req.body.userId ),
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
$project: {
|
|
115
|
+
storeId: '$basicDetails.storeId',
|
|
116
|
+
storeName: '$basicDetails.storeName',
|
|
117
|
+
clientId: '$basicDetails.clientId',
|
|
118
|
+
clientName: '$basicDetails.clientName',
|
|
119
|
+
issueDate: { $dateToString: { format: '%d-%m-%Y', date: '$issueDate' } },
|
|
120
|
+
issueClosedDate: { $dateToString: { format: '%d-%m-%Y', date: '$issueClosedDate' } },
|
|
121
|
+
ticketId: 1,
|
|
122
|
+
issueStatus: '$infraTicketDetails.issueStatus',
|
|
123
|
+
ticketType: '$infraTicketDetails.ticketType',
|
|
124
|
+
primaryIssue: {
|
|
125
|
+
$filter: {
|
|
126
|
+
input: '$infraActivity',
|
|
127
|
+
as: 'item',
|
|
128
|
+
cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
$unwind: {
|
|
135
|
+
path: '$primaryIssue', preserveNullAndEmptyArrays: true,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
$unwind: {
|
|
140
|
+
path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
|
|
141
|
+
},
|
|
142
|
+
}, {
|
|
143
|
+
$project: {
|
|
144
|
+
storeId: 1,
|
|
145
|
+
storeName: 1,
|
|
146
|
+
clientId: 1,
|
|
147
|
+
clientName: 1,
|
|
148
|
+
issueDate: 1,
|
|
149
|
+
issueClosedDate: 1,
|
|
150
|
+
ticketId: 1,
|
|
151
|
+
issueStatus: 1,
|
|
152
|
+
ticketType: 1,
|
|
153
|
+
infraIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '' ] },
|
|
154
|
+
},
|
|
155
|
+
} ];
|
|
156
|
+
let count = await aggregateTangoTicket( query );
|
|
157
|
+
if ( req.body.limit && req.body.offset && !req.body.export ) {
|
|
158
|
+
query.push(
|
|
159
|
+
{ $skip: ( req.body.offset - 1 ) * req.body.limit },
|
|
160
|
+
{ $limit: Number( req.body.limit ) },
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
let result = await aggregateTangoTicket( query );
|
|
164
|
+
res.sendSuccess( {
|
|
165
|
+
count: count.length,
|
|
166
|
+
result: result,
|
|
167
|
+
} );
|
|
168
|
+
} catch ( error ) {
|
|
169
|
+
logger.error( { error: error, function: 'workHistory' } );
|
|
170
|
+
return res.sendError( error, 500 );
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
import express from 'express';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
import { infraCard, infraIssuesTable, hourWiseDownClients, hourWiseDownstores } from '../controllers/clientInfra.controller.js';
|
|
6
|
+
|
|
7
|
+
export const clientInfraRouter = express.Router();
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
clientInfraRouter.post( '/infraCard', infraCard );
|
|
11
|
+
clientInfraRouter.post( '/infraIssuesTable', infraIssuesTable );
|
|
12
|
+
clientInfraRouter.post( '/hourWiseDownClients', hourWiseDownClients );
|
|
13
|
+
clientInfraRouter.post( '/hourWiseDownstores', hourWiseDownstores );
|
|
14
|
+
|
|
15
|
+
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
|
|
2
2
|
import express from 'express';
|
|
3
|
-
import { storeTicketList, edgeAppLogTable, viewedgeAppLog } from '../controllers/storeInfra.controlller.js';
|
|
3
|
+
import { storeTicketList, storeTicketcard, edgeAppLogTable, viewedgeAppLog } from '../controllers/storeInfra.controlller.js';
|
|
4
4
|
export const storeInfraRouter = express.Router();
|
|
5
5
|
|
|
6
6
|
storeInfraRouter.post( '/storeTicketList', storeTicketList );
|
|
7
|
+
storeInfraRouter.post( '/storeTicketcard', storeTicketcard );
|
|
7
8
|
storeInfraRouter.post( '/edgeAppLogTable', edgeAppLogTable );
|
|
8
9
|
storeInfraRouter.post( '/viewedgeAppLog', viewedgeAppLog );
|
|
9
10
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
|
-
import { userTakeTicket, userTicketList, basicDetails } from '../controllers/userInfra.controller.js';
|
|
2
|
+
import { userTakeTicket, userTicketList, basicDetails, workHistory } from '../controllers/userInfra.controller.js';
|
|
3
3
|
|
|
4
4
|
export const userInfraRouter = express.Router();
|
|
5
5
|
|
|
@@ -7,4 +7,6 @@ export const userInfraRouter = express.Router();
|
|
|
7
7
|
userInfraRouter.post( '/userTakeTicket', userTakeTicket );
|
|
8
8
|
userInfraRouter.post( '/userTicketList', userTicketList );
|
|
9
9
|
userInfraRouter.post( '/basicDetails', basicDetails );
|
|
10
|
+
userInfraRouter.post( '/workHistory', workHistory );
|
|
11
|
+
|
|
10
12
|
|
|
@@ -10,3 +10,6 @@ export async function findClient( query, project ) {
|
|
|
10
10
|
export async function findOneClient( query, project ) {
|
|
11
11
|
return await dataModel.clientModel.findOne( query, project );
|
|
12
12
|
}
|
|
13
|
+
export async function findClientwithpagination( query, project ) {
|
|
14
|
+
return await dataModel.clientModel.find( query, project );
|
|
15
|
+
}
|
|
@@ -7,9 +7,16 @@ export async function createStore( inputData ) {
|
|
|
7
7
|
export async function findStore( query, project ) {
|
|
8
8
|
return await dataModel.storeModel.find( query, project );
|
|
9
9
|
}
|
|
10
|
+
export async function findStorewithpagination( query, project, skip, limit ) {
|
|
11
|
+
return await dataModel.storeModel.find( query, project ).skip( skip ).limit( limit );
|
|
12
|
+
}
|
|
13
|
+
|
|
10
14
|
export async function findOneStore( query, project ) {
|
|
11
15
|
return await dataModel.storeModel.findOne( query, project );
|
|
12
16
|
}
|
|
13
17
|
export async function updateOneStore( query, data ) {
|
|
14
18
|
return await dataModel.storeModel.updateOne( query, { $set: data } );
|
|
15
19
|
}
|
|
20
|
+
export async function countDocumentsStore( query ) {
|
|
21
|
+
return await dataModel.storeModel.countDocuments( query );
|
|
22
|
+
}
|