tango-app-api-infra 3.0.38-dev → 3.0.40-dev
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/package.json +4 -3
- package/src/controllers/infra.controllers.js +104 -6
- package/src/controllers/internalInfra.controller.js +469 -5
- package/src/hbs/closeTicekt.hbs +289 -0
- package/src/hbs/createTicket.hbs +288 -0
- package/src/hbs/dailyInfraReport.hbs +315 -0
- package/src/hbs/refreshTicket.hbs +292 -0
- package/src/routes/internalInfra.routes.js +3 -1
- package/src/validations/infra.validation.js +7 -1
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
|
|
2
|
-
import { logger } from 'tango-app-api-middleware';
|
|
2
|
+
import { logger, getOpenSearchData, appConfig } from 'tango-app-api-middleware';
|
|
3
3
|
import dayjs from 'dayjs';
|
|
4
4
|
import utc from 'dayjs/plugin/utc.js';
|
|
5
5
|
import timezone from 'dayjs/plugin/timezone.js';
|
|
6
6
|
import 'dayjs/locale/en.js';
|
|
7
|
+
import { readFileSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import handlebars from 'handlebars';
|
|
7
10
|
dayjs.extend( utc );
|
|
8
11
|
dayjs.extend( timezone );
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
|
|
12
|
+
import { sendEmailWithSES } from 'tango-app-api-middleware';
|
|
13
|
+
import { createClient, findClient, aggregateClient } from '../services/client.service.js';
|
|
14
|
+
import { createStore, findStore, updateOneStore, findOneStore } from '../services/store.service.js';
|
|
15
|
+
import { findTangoTicket, findOneTangoTicket, countDocumentsTangoTicket, aggregateTangoTicket, updateOneTangoTicket } from '../services/tangoTicket.service.js';
|
|
16
|
+
import { findOneGroup } from '../services/group.service.js';
|
|
17
|
+
import { findinfraReason } from '../services/infraReason.service.js';
|
|
18
|
+
import { findOneUser } from '../services/user.service.js';
|
|
19
|
+
import xl from 'excel4node';
|
|
13
20
|
|
|
14
21
|
export async function migrateClient() {
|
|
15
22
|
try {
|
|
@@ -143,8 +150,61 @@ export async function assigntoUser( req, res ) {
|
|
|
143
150
|
export async function updateRefreshTicket( req, res ) {
|
|
144
151
|
try {
|
|
145
152
|
for ( let ticket of req.body.TicketList ) {
|
|
153
|
+
let getTicket = await findOneTangoTicket( { ticketId: ticket.ticketId } );
|
|
146
154
|
await updateOneTangoTicket( { ticketId: ticket.ticketId }, { 'ticketDetails.ticketType': 'refreshticket' } );
|
|
155
|
+
let downTimeQuery = {
|
|
156
|
+
'size': 1,
|
|
157
|
+
'query': {
|
|
158
|
+
'bool': {
|
|
159
|
+
'must': [
|
|
160
|
+
{
|
|
161
|
+
'term': {
|
|
162
|
+
'doc.date.keyword': dayjs( getTicket.issueDate ).format( 'DD-MM-YYYY' ),
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
'term': {
|
|
167
|
+
'doc.store_id.keyword': getTicket.basicDetails.storeId,
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
],
|
|
172
|
+
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
let downtimetotal;
|
|
177
|
+
const downtime = await getOpenSearchData( 'live_downtime_hourly', downTimeQuery );
|
|
178
|
+
let streamwiseDowntime = downtime.body.hits.hits.length > 0 ? downtime.body.hits.hits[0]._source.doc.streamwise_downtime : [];
|
|
179
|
+
if ( streamwiseDowntime.length > 0 ) {
|
|
180
|
+
const sum = streamwiseDowntime.reduce( ( accumulator, currentValue ) => {
|
|
181
|
+
return accumulator + currentValue.down_time;
|
|
182
|
+
}, 0 );
|
|
183
|
+
const average = sum / streamwiseDowntime.length;
|
|
184
|
+
downtimetotal = Math.round( average );
|
|
185
|
+
} else {
|
|
186
|
+
downtimetotal = 0;
|
|
187
|
+
}
|
|
188
|
+
let Timestamp = dayjs().format( 'YYYY-MM-DD HH:mm' );
|
|
189
|
+
const attachments = null;
|
|
190
|
+
const subject = `Tango Eye - Infra Ticket Closed for ${getTicket.basicDetails.storeName} `;
|
|
191
|
+
const fileContent = readFileSync( join() + '/src/hbs/refreshTicket.hbs', 'utf8' );
|
|
192
|
+
const htmlContent = handlebars.compile( fileContent );
|
|
193
|
+
let store = await findOneStore( { storeId: getTicket.basicDetails.storeId } );
|
|
194
|
+
if ( store.spocDetails && store.spocDetails.length > 0 ) {
|
|
195
|
+
let spocEmail = store.spocDetails[0].email;
|
|
196
|
+
let spocName = store.spocDetails[0].name;
|
|
197
|
+
let Issue = getTicket.ticketActivity.filter( ( a ) => a.actionType == 'issueUpdate' );
|
|
198
|
+
let primaryIssue = 'Not Identified';
|
|
199
|
+
if ( Issue.length > 0 && Issue[0].reasons.length > 0 ) {
|
|
200
|
+
primaryIssue = Issue[0].reasons[0].primaryIssue;
|
|
201
|
+
}
|
|
202
|
+
let Uidomain = `${appConfig.url.domain}/manage/stores/infra-ticket?storeId=${getTicket.basicDetails.storeId}`;
|
|
203
|
+
const html = htmlContent( { ...getTicket, Uidomain: Uidomain, primary: primaryIssue, storeName: getTicket.basicDetails.storeName, hibernation: '', spocName: spocName, date: dayjs( getTicket.issueDate ).format( 'YYYY-MM-DD' ), downtimetotal: downtimetotal, Timestamp: Timestamp, domain: appConfig.url.apiDomain } );
|
|
204
|
+
await sendEmailWithSES( spocEmail, subject, html, attachments, appConfig.cloud.aws.ses.adminEmail );
|
|
205
|
+
}
|
|
147
206
|
}
|
|
207
|
+
|
|
148
208
|
res.sendSuccess( 'updated Successfully' );
|
|
149
209
|
} catch ( error ) {
|
|
150
210
|
logger.error( { error: error, function: 'updateRefreshTicket' } );
|
|
@@ -168,10 +228,414 @@ export async function closeTicket( req, res ) {
|
|
|
168
228
|
issueClosedDate: new Date(),
|
|
169
229
|
},
|
|
170
230
|
);
|
|
231
|
+
let downTimeQuery = {
|
|
232
|
+
'size': 1,
|
|
233
|
+
'query': {
|
|
234
|
+
'bool': {
|
|
235
|
+
'must': [
|
|
236
|
+
{
|
|
237
|
+
'term': {
|
|
238
|
+
'doc.date.keyword': dayjs( getTicket.issueDate ).format( 'DD-MM-YYYY' ),
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
'term': {
|
|
243
|
+
'doc.store_id.keyword': getTicket.basicDetails.storeId,
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
|
|
247
|
+
],
|
|
248
|
+
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
let downtimetotal;
|
|
253
|
+
const downtime = await getOpenSearchData( 'live_downtime_hourly', downTimeQuery );
|
|
254
|
+
let streamwiseDowntime = downtime.body.hits.hits.length > 0 ? downtime.body.hits.hits[0]._source.doc.streamwise_downtime : [];
|
|
255
|
+
if ( streamwiseDowntime.length > 0 ) {
|
|
256
|
+
const sum = streamwiseDowntime.reduce( ( accumulator, currentValue ) => {
|
|
257
|
+
return accumulator + currentValue.down_time;
|
|
258
|
+
}, 0 );
|
|
259
|
+
const average = sum / streamwiseDowntime.length;
|
|
260
|
+
downtimetotal = Math.round( average );
|
|
261
|
+
} else {
|
|
262
|
+
downtimetotal = 0;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
let Issue = getTicket.ticketActivity.filter( ( a ) => a.actionType == 'issueUpdate' );
|
|
266
|
+
let primaryIssue = '';
|
|
267
|
+
|
|
268
|
+
if ( Issue.length > 0 && Issue[0].reasons.length > 0 ) {
|
|
269
|
+
primaryIssue = Issue[0].reasons[0].primaryIssue;
|
|
270
|
+
}
|
|
271
|
+
let Timestamp = dayjs().format( 'YYYY-MM-DD HH:mm' );
|
|
272
|
+
const attachments = null;
|
|
273
|
+
const subject = `Tango Eye - Infra Ticket Closed for ${getTicket.basicDetails.storeName} `;
|
|
274
|
+
const fileContent = readFileSync( join() + '/src/hbs/closeTicekt.hbs', 'utf8' );
|
|
275
|
+
const htmlContent = handlebars.compile( fileContent );
|
|
276
|
+
let store = await findOneStore( { storeId: getTicket.basicDetails.storeId } );
|
|
277
|
+
if ( store.spocDetails && store.spocDetails.length > 0 ) {
|
|
278
|
+
let spocEmail = store.spocDetails[0].email;
|
|
279
|
+
let spocName = store.spocDetails[0].name;
|
|
280
|
+
let Uidomain = `${appConfig.url.domain}/manage/stores/infra-ticket?storeId=${getTicket.basicDetails.storeId}`;
|
|
281
|
+
const html = htmlContent( { ...getTicket, Uidomain: Uidomain, primaryIssue: primaryIssue, storeName: getTicket.basicDetails.storeName, spocName: spocName, date: dayjs( getTicket.issueDate ).format( 'YYYY-MM-DD HH:mm' ), downtimetotal: downtimetotal, Timestamp: Timestamp, domain: appConfig.url.apiDomain } );
|
|
282
|
+
await sendEmailWithSES( spocEmail, subject, html, attachments, appConfig.cloud.aws.ses.adminEmail );
|
|
283
|
+
}
|
|
171
284
|
}
|
|
285
|
+
|
|
172
286
|
res.sendSuccess( 'updated Successfully' );
|
|
173
287
|
} catch ( error ) {
|
|
174
288
|
logger.error( { error: error, function: 'closeTicket' } );
|
|
175
289
|
res.sendError( error, 500 );
|
|
176
290
|
}
|
|
177
291
|
}
|
|
292
|
+
export async function emailUserList( req, res ) {
|
|
293
|
+
try {
|
|
294
|
+
let clientList = await aggregateClient( [
|
|
295
|
+
{
|
|
296
|
+
$match: {
|
|
297
|
+
status: 'active',
|
|
298
|
+
// clientId:{ req.body.clientId},
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
$project: {
|
|
303
|
+
'clientId': 1,
|
|
304
|
+
'ticketConfigs.infraReport': 1,
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
'$lookup': {
|
|
309
|
+
'from': 'users',
|
|
310
|
+
'let': { 'clientId': '$clientId' },
|
|
311
|
+
'pipeline': [
|
|
312
|
+
{
|
|
313
|
+
'$match': {
|
|
314
|
+
'$expr': {
|
|
315
|
+
$and: [
|
|
316
|
+
{ '$eq': [ '$clientId', '$$clientId' ] },
|
|
317
|
+
{ '$eq': [ '$userType', 'client' ] },
|
|
318
|
+
|
|
319
|
+
],
|
|
320
|
+
},
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
$project: {
|
|
325
|
+
userName: 1,
|
|
326
|
+
email: 1,
|
|
327
|
+
role: 1,
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
'as': 'user',
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
$unwind: {
|
|
336
|
+
path: '$user',
|
|
337
|
+
preserveNullAndEmptyArrays: true,
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
'$lookup': {
|
|
342
|
+
'from': 'userAssignedStore',
|
|
343
|
+
'let': { 'email': '$user.email' },
|
|
344
|
+
'pipeline': [
|
|
345
|
+
{
|
|
346
|
+
'$match': {
|
|
347
|
+
'$expr': {
|
|
348
|
+
$and: [
|
|
349
|
+
{ '$eq': [ '$userEmail', '$$email' ] },
|
|
350
|
+
|
|
351
|
+
],
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
$project: {
|
|
357
|
+
assignedValue: 1,
|
|
358
|
+
assignedType: 1,
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
],
|
|
362
|
+
'as': 'assignedstore',
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
$unwind: {
|
|
367
|
+
path: '$assignedstore',
|
|
368
|
+
preserveNullAndEmptyArrays: true,
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
$project: {
|
|
373
|
+
'clientId': 1,
|
|
374
|
+
'ticketConfigs': 1,
|
|
375
|
+
'email': '$user.email',
|
|
376
|
+
'userName': '$user.userName',
|
|
377
|
+
'role': '$user.role',
|
|
378
|
+
'assignedValue': '$assignedstore.assignedValue',
|
|
379
|
+
'assignedType': '$assignedstore.assignedType',
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
$group: {
|
|
384
|
+
'_id': '$email',
|
|
385
|
+
'clientId': { $first: '$clientId' },
|
|
386
|
+
'ticketConfigs': { $first: '$ticketConfigs' },
|
|
387
|
+
'email': { $first: '$email' },
|
|
388
|
+
'userName': { $first: '$userName' },
|
|
389
|
+
'role': { $first: '$role' },
|
|
390
|
+
'assignedValue': { $push: '$assignedValue' },
|
|
391
|
+
'assignedType': { $first: '$assignedType' },
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
] );
|
|
395
|
+
let response = [];
|
|
396
|
+
for ( let user of clientList ) {
|
|
397
|
+
if ( user.role == 'superadmin' ) {
|
|
398
|
+
let storelist = await findStore( { clientId: user.clientId, status: 'active' }, { 'storeId': 1, 'storeProfile.timeZone': 1 } );
|
|
399
|
+
user.storeList = storelist;
|
|
400
|
+
} else if ( user.role != 'superadmin' ) {
|
|
401
|
+
if ( user.assignedType == 'store' ) {
|
|
402
|
+
let storelist = await findStore( { storeId: { $in: user.assignedValue } }, { 'storeId': 1, 'storeProfile.timeZone': 1 } );
|
|
403
|
+
user.storeList = storelist;
|
|
404
|
+
}
|
|
405
|
+
if ( user.assignedType == 'group' ) {
|
|
406
|
+
user.storeList = [];
|
|
407
|
+
for ( let group of user.assignedValue ) {
|
|
408
|
+
let groupdata = await findOneGroup( { groupName: group } );
|
|
409
|
+
let storelist = await findStore( { storeId: { $in: groupdata.storeList } }, { 'storeId': 1, 'storeProfile.timeZone': 1 } );
|
|
410
|
+
user.storeList = [ ...user.storeList, ...storelist ];
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if ( user.storeList && user.storeList.length > 0 && user.ticketConfigs && user.ticketConfigs.infraReport ) {
|
|
416
|
+
response.push( {
|
|
417
|
+
email: user.email,
|
|
418
|
+
userName: user.userName,
|
|
419
|
+
clientId: user.clientId,
|
|
420
|
+
role: user.role,
|
|
421
|
+
storeList: user.storeList,
|
|
422
|
+
ticketConfigs: user.ticketConfigs.infraReport,
|
|
423
|
+
} );
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
res.sendSuccess( { count: response.length, response: response } );
|
|
427
|
+
} catch ( error ) {
|
|
428
|
+
logger.error( { error: error, function: 'emailUserList' } );
|
|
429
|
+
res.sendError( error, 500 );
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
export async function infraReportSent( req, res ) {
|
|
433
|
+
try {
|
|
434
|
+
let date;
|
|
435
|
+
if ( req.body.type == 'start' ) {
|
|
436
|
+
date = dayjs().subtract( 1, 'day' ).format( 'YYYY-MM-DD' );
|
|
437
|
+
} else if ( req.body.storeList == 'start' ) {
|
|
438
|
+
date = dayjs().format( 'YYYY-MM-DD' );
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
let query = [ {
|
|
442
|
+
$match: {
|
|
443
|
+
$and: [
|
|
444
|
+
{ issueDate: new Date( date ) },
|
|
445
|
+
{ 'basicDetails.storeId': { $in: req.body.storeList } },
|
|
446
|
+
{ issueType: 'infra' },
|
|
447
|
+
{ 'ticketDetails.issueStatus': 'identified' },
|
|
448
|
+
],
|
|
449
|
+
},
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
$project: {
|
|
453
|
+
ticketId: 1,
|
|
454
|
+
basicDetails: 1,
|
|
455
|
+
createdAt: 1,
|
|
456
|
+
status: 1,
|
|
457
|
+
ticketDetails: 1,
|
|
458
|
+
issueClosedDate: 1,
|
|
459
|
+
primaryIssue: {
|
|
460
|
+
$filter: {
|
|
461
|
+
input: '$ticketActivity',
|
|
462
|
+
as: 'item',
|
|
463
|
+
cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
|
|
464
|
+
},
|
|
465
|
+
},
|
|
466
|
+
},
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
$unwind: {
|
|
470
|
+
path: '$primaryIssue', preserveNullAndEmptyArrays: true,
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
$unwind: {
|
|
475
|
+
path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
|
|
476
|
+
},
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
$unwind: {
|
|
480
|
+
path: '$primaryIssue.reasons.secondaryIssue', preserveNullAndEmptyArrays: true,
|
|
481
|
+
},
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
$project: {
|
|
485
|
+
ticketId: 1,
|
|
486
|
+
basicDetails: 1,
|
|
487
|
+
createdAt: 1,
|
|
488
|
+
status: 1,
|
|
489
|
+
ticketDetails: 1,
|
|
490
|
+
issueClosedDate: 1,
|
|
491
|
+
primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '-' ] },
|
|
492
|
+
secondaryIssue: { $ifNull: [ '$primaryIssue.reasons.secondaryIssue.name', '-' ] },
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
$group: {
|
|
497
|
+
_id: '$ticketId',
|
|
498
|
+
ticketDetails: { $first: '$ticketDetails' },
|
|
499
|
+
issueClosedDate: { $first: '$issueClosedDate' },
|
|
500
|
+
basicDetails: { $first: '$basicDetails' },
|
|
501
|
+
primaryIssue: { $last: '$primaryIssue' },
|
|
502
|
+
secondaryIssue: { $last: '$secondaryIssue' },
|
|
503
|
+
createdAt: { $first: '$createdAt' },
|
|
504
|
+
status: { $last: '$status' },
|
|
505
|
+
|
|
506
|
+
},
|
|
507
|
+
},
|
|
508
|
+
];
|
|
509
|
+
|
|
510
|
+
let ticketList = await aggregateTangoTicket( query );
|
|
511
|
+
const exportdata = [];
|
|
512
|
+
for ( let element of ticketList ) {
|
|
513
|
+
let clientuser = await findOneUser( { _id: element.ticketDetails.addressingClient } );
|
|
514
|
+
let tangouser = await findOneUser( { _id: element.ticketDetails.addressingUser } );
|
|
515
|
+
exportdata.push( {
|
|
516
|
+
'Client ID': element.basicDetails.clientId,
|
|
517
|
+
'Client Name': element.basicDetails.clientName,
|
|
518
|
+
'Created Date & Time': dayjs( element.createdAt ).format( 'YYYY-MM-DD HH:mm A' ),
|
|
519
|
+
'Store ID': element.basicDetails.clientName,
|
|
520
|
+
'Store Name': element.basicDetails.clientName,
|
|
521
|
+
'Issue ': element.primaryIssue,
|
|
522
|
+
'Secondary Issue': element.secondaryIssue,
|
|
523
|
+
'Issue Date & Time': dayjs( element.date ).format( 'YYYY-MM-DD' ),
|
|
524
|
+
'Status ': element.status,
|
|
525
|
+
'Responded By': clientuser && clientuser.userName ? clientuser.userName : '-',
|
|
526
|
+
'Resolved By': tangouser && tangouser.userName ? tangouser.userName : '-',
|
|
527
|
+
'Closed Date & Time': element.issueClosedDate?dayjs( element.issueClosedDate ).format( 'YYYY-MM-DD HH:mm A' ):'-',
|
|
528
|
+
'Latest Comment': '',
|
|
529
|
+
'Activity Log': '',
|
|
530
|
+
} );
|
|
531
|
+
}
|
|
532
|
+
let issueCount = await countDocumentsTangoTicket( {
|
|
533
|
+
|
|
534
|
+
$and: [
|
|
535
|
+
{ issueDate: new Date( date ) },
|
|
536
|
+
{ 'basicDetails.storeId': { $in: req.body.storeList } },
|
|
537
|
+
{ issueType: 'infra' },
|
|
538
|
+
{ 'ticketDetails.issueStatus': 'identified' },
|
|
539
|
+
],
|
|
540
|
+
|
|
541
|
+
} );
|
|
542
|
+
let finalcount = 0;
|
|
543
|
+
for ( let storedata of req.body.storeList ) {
|
|
544
|
+
let downTimeQuery = {
|
|
545
|
+
'size': 1,
|
|
546
|
+
'query': {
|
|
547
|
+
'bool': {
|
|
548
|
+
'must': [
|
|
549
|
+
{
|
|
550
|
+
'term': {
|
|
551
|
+
'doc.date.keyword': dayjs( date ).format( 'DD-MM-YYYY' ),
|
|
552
|
+
},
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
'term': {
|
|
556
|
+
'doc.store_id.keyword': storedata,
|
|
557
|
+
},
|
|
558
|
+
},
|
|
559
|
+
|
|
560
|
+
],
|
|
561
|
+
|
|
562
|
+
},
|
|
563
|
+
},
|
|
564
|
+
};
|
|
565
|
+
let downtimetotal;
|
|
566
|
+
const downtime = await getOpenSearchData( 'live_downtime_hourly', downTimeQuery );
|
|
567
|
+
let streamwiseDowntime = downtime.body.hits.hits.length > 0 ? downtime.body.hits.hits[0]._source.doc.streamwise_downtime : [];
|
|
568
|
+
if ( streamwiseDowntime.length > 0 ) {
|
|
569
|
+
const sum = streamwiseDowntime.reduce( ( accumulator, currentValue ) => {
|
|
570
|
+
return accumulator + currentValue.down_time;
|
|
571
|
+
}, 0 );
|
|
572
|
+
const average = sum / streamwiseDowntime.length;
|
|
573
|
+
downtimetotal = Math.round( average );
|
|
574
|
+
} else {
|
|
575
|
+
downtimetotal = 0;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
finalcount = finalcount + downtimetotal;
|
|
579
|
+
}
|
|
580
|
+
let avgDownTime = Math.round( finalcount / req.body.storeList.length );
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
let issueList = await findinfraReason( { parentId: { '$exists': false } } );
|
|
584
|
+
const categoryCounts = {};
|
|
585
|
+
let response;
|
|
586
|
+
if ( ticketList.length > 0 ) {
|
|
587
|
+
ticketList.forEach( ( item ) => {
|
|
588
|
+
const categoryName = item.primaryIssue;
|
|
589
|
+
if ( categoryCounts[categoryName] ) {
|
|
590
|
+
categoryCounts[categoryName]++;
|
|
591
|
+
} else {
|
|
592
|
+
categoryCounts[categoryName] = 1;
|
|
593
|
+
}
|
|
594
|
+
} );
|
|
595
|
+
response = issueList.map( ( category ) => ( {
|
|
596
|
+
name: category.name,
|
|
597
|
+
count: categoryCounts[category.name] || 0,
|
|
598
|
+
} ) );
|
|
599
|
+
} else {
|
|
600
|
+
response = issueList.map( ( category ) => ( {
|
|
601
|
+
name: category.name,
|
|
602
|
+
count: 0,
|
|
603
|
+
} ) );
|
|
604
|
+
}
|
|
605
|
+
let reportdate = dayjs().format( 'YYYY-MM-DD' );
|
|
606
|
+
const wb = new xl.Workbook();
|
|
607
|
+
const ws = wb.addWorksheet( 'Daily report' );
|
|
608
|
+
const headers = Object.keys( exportdata[0] );
|
|
609
|
+
|
|
610
|
+
for ( let i = 0; i < headers.length; i++ ) {
|
|
611
|
+
ws.cell( 1, i + 1 ).string( headers[i] );
|
|
612
|
+
};
|
|
613
|
+
for ( let i = 0; i < exportdata.length; i++ ) {
|
|
614
|
+
const dataRow = exportdata[i];
|
|
615
|
+
for ( let j = 0; j < headers.length; j++ ) {
|
|
616
|
+
const header = headers[j];
|
|
617
|
+
const value = dataRow[header];
|
|
618
|
+
ws.cell( i + 2, j + 1 ).string( value?.toString() );
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
let buffer = await wb.writeToBuffer();
|
|
622
|
+
|
|
623
|
+
const attachments = {
|
|
624
|
+
filename: `dailyInfraReport- ${reportdate}.xlsx`,
|
|
625
|
+
content: buffer,
|
|
626
|
+
contentType: 'application/xlsx', // e.g., 'application/pdf'
|
|
627
|
+
};
|
|
628
|
+
const subject = `Daily Digest - Infra Downtime Report - ${reportdate}`;
|
|
629
|
+
const fileContent = readFileSync( join() + '/src/hbs/dailyInfraReport.hbs', 'utf8' );
|
|
630
|
+
const htmlContent = handlebars.compile( fileContent );
|
|
631
|
+
let Uidomain = `${appConfig.url.domain}`;
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
const html = htmlContent( { ...req.body, Uidomain: Uidomain, issueCount: issueCount, avgDownTime: avgDownTime, reportdate: reportdate, content: response, date: date, domain: appConfig.url.apiDomain } );
|
|
635
|
+
const result = await sendEmailWithSES( req.body.email, subject, html, attachments, appConfig.cloud.aws.ses.adminEmail );
|
|
636
|
+
res.sendSuccess( result );
|
|
637
|
+
} catch ( error ) {
|
|
638
|
+
logger.error( { error: error, function: 'infraReportSent' } );
|
|
639
|
+
res.sendError( error, 500 );
|
|
640
|
+
}
|
|
641
|
+
}
|