tango-app-api-infra 3.1.16 → 3.1.18
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 +1 -1
- package/src/controllers/clientInfra.controller.js +426 -293
- package/src/controllers/dataMismatch.controller.js +13 -1
- package/src/controllers/infra.controllers.js +14 -3
- package/src/controllers/internalInfra.controller.js +4 -4
- package/src/controllers/storeInfra.controlller.js +351 -478
- package/src/controllers/userInfra.controller.js +29 -21
- package/src/validations/infra.validation.js +20 -21
|
@@ -302,7 +302,7 @@ export async function installationCard( req, res ) {
|
|
|
302
302
|
onboardedStoresCount: onboardedCount,
|
|
303
303
|
inactiveStoresCount: deactiveCount,
|
|
304
304
|
installedStoresCount: installedCount-yettoInstallCount.length,
|
|
305
|
-
yettoInstallCount: yettoInstallCount.length,
|
|
305
|
+
yettoInstallCount: yettoInstallCount.length-installFailedCount.length,
|
|
306
306
|
installFailedCount: installFailedCount.length,
|
|
307
307
|
infraIssues: response,
|
|
308
308
|
} );
|
|
@@ -314,21 +314,20 @@ export async function installationCard( req, res ) {
|
|
|
314
314
|
export async function infraIssuesTable( req, res ) {
|
|
315
315
|
try {
|
|
316
316
|
let date = await getUTC( new Date( req.body.fromDate ), new Date( req.body.toDate ) );
|
|
317
|
-
let issueStatus = [ 'identified' ];
|
|
317
|
+
let issueStatus = [ 'notidentified', 'identified' ];
|
|
318
|
+
|
|
318
319
|
if ( req.body.infrafilterIssue == 'Issues Not Identified' ) {
|
|
319
320
|
issueStatus = [ 'notidentified' ];
|
|
320
321
|
};
|
|
321
|
-
if ( req.body.infrafilterIssue == '
|
|
322
|
-
issueStatus = [ '
|
|
323
|
-
};
|
|
324
|
-
if ( req.body.infrafilterIssue == 'Live Stores' ) {
|
|
325
|
-
issueStatus = [ 'notidentified', 'identified' ];
|
|
322
|
+
if ( req.body.infrafilterIssue == 'Identified Issues' ) {
|
|
323
|
+
issueStatus = [ 'identified' ];
|
|
326
324
|
};
|
|
325
|
+
|
|
326
|
+
|
|
327
327
|
let totalstores = await aggregateStore( [ {
|
|
328
328
|
$match: {
|
|
329
329
|
'$and': [
|
|
330
330
|
{ 'clientId': { $in: req.body.clientId } },
|
|
331
|
-
{ 'edge.firstFile': true },
|
|
332
331
|
{ 'status': 'active' },
|
|
333
332
|
{ 'createdAt': { $lte: date.end } },
|
|
334
333
|
],
|
|
@@ -338,96 +337,115 @@ export async function infraIssuesTable( req, res ) {
|
|
|
338
337
|
for ( let store of totalstores ) {
|
|
339
338
|
totalnumberstores.push( store.storeId );
|
|
340
339
|
}
|
|
341
|
-
let
|
|
340
|
+
let pendingquery = [];
|
|
341
|
+
pendingquery.push( {
|
|
342
342
|
$match: {
|
|
343
343
|
$and: [
|
|
344
|
-
{ issueType: '
|
|
345
|
-
{ status: { $ne: 'closed' } },
|
|
344
|
+
{ issueType: 'installation' },
|
|
345
|
+
{ 'status': { $ne: 'closed' } },
|
|
346
346
|
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
347
|
-
{ 'basicDetails.storeId': { $in: totalnumberstores } },
|
|
348
|
-
{ 'ticketDetails.issueStatus': { $in: issueStatus } },
|
|
349
|
-
// { createdAt: { $gte: date.start } },
|
|
350
347
|
{ createdAt: { $lte: date.end } },
|
|
351
348
|
],
|
|
352
349
|
},
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
350
|
+
} );
|
|
351
|
+
let pendingstorecount = await aggregateTangoTicket( pendingquery );
|
|
352
|
+
let installpendingticket = pendingstorecount.map( ( store ) => store.basicDetails.storeId );
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
let query = [
|
|
356
|
+
{
|
|
357
|
+
$match: {
|
|
358
|
+
$and: [
|
|
359
|
+
{ issueType: 'infra' },
|
|
360
|
+
{ status: { $ne: 'closed' } },
|
|
361
|
+
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
362
|
+
{ 'basicDetails.storeId': { $in: totalnumberstores } },
|
|
363
|
+
{ 'ticketDetails.issueStatus': { $in: issueStatus } },
|
|
364
|
+
{ createdAt: { $lte: date.end } },
|
|
365
|
+
],
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
$project: {
|
|
370
|
+
storeId: '$basicDetails.storeId',
|
|
371
|
+
clientId: '$basicDetails.clientId',
|
|
372
|
+
ticketId: 1,
|
|
373
|
+
storeName: '$basicDetails.storeName',
|
|
374
|
+
clientName: '$basicDetails.clientName',
|
|
375
|
+
status: 1,
|
|
376
|
+
createdAt: 1,
|
|
377
|
+
issueIdentifiedDate: '$ticketDetails.issueIdentifiedDate',
|
|
378
|
+
issueClosedDate: '$issueClosedDate',
|
|
379
|
+
primaryIssue: {
|
|
380
|
+
$filter: {
|
|
381
|
+
input: '$ticketActivity',
|
|
382
|
+
as: 'item',
|
|
383
|
+
cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
|
|
384
|
+
},
|
|
370
385
|
},
|
|
371
386
|
},
|
|
372
387
|
},
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
388
|
+
{
|
|
389
|
+
$unwind: {
|
|
390
|
+
path: '$primaryIssue',
|
|
391
|
+
preserveNullAndEmptyArrays: true,
|
|
392
|
+
},
|
|
377
393
|
},
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
394
|
+
{
|
|
395
|
+
$unwind: {
|
|
396
|
+
path: '$primaryIssue.reasons',
|
|
397
|
+
preserveNullAndEmptyArrays: true,
|
|
398
|
+
},
|
|
382
399
|
},
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
400
|
+
{
|
|
401
|
+
$unwind: {
|
|
402
|
+
path: '$primaryIssue.reasons.secondaryIssue',
|
|
403
|
+
preserveNullAndEmptyArrays: true,
|
|
404
|
+
},
|
|
387
405
|
},
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
406
|
+
{
|
|
407
|
+
$project: {
|
|
408
|
+
storeId: 1,
|
|
409
|
+
clientId: 1,
|
|
410
|
+
storeName: 1,
|
|
411
|
+
createdAt: 1,
|
|
412
|
+
ticketId: 1,
|
|
413
|
+
clientName: 1,
|
|
414
|
+
actionBy: '$primaryIssue.actionBy',
|
|
415
|
+
issueIdentifiedDate: { $ifNull: [ '$issueIdentifiedDate', '' ] },
|
|
416
|
+
issueClosedDate: { $ifNull: [ '$issueClosedDate', '' ] },
|
|
417
|
+
status: 1,
|
|
418
|
+
primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '-' ] },
|
|
419
|
+
secondaryIssue: { $ifNull: [ '$primaryIssue.reasons.secondaryIssue.name', '-' ] },
|
|
420
|
+
},
|
|
403
421
|
},
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
422
|
+
{
|
|
423
|
+
$group: {
|
|
424
|
+
_id: '$ticketId',
|
|
425
|
+
storeId: { $first: '$storeId' },
|
|
426
|
+
clientId: { $first: '$clientId' },
|
|
427
|
+
ticketId: { $first: '$ticketId' },
|
|
428
|
+
actionBy: { $first: '$actionBy' },
|
|
429
|
+
storeName: { $first: '$storeName' },
|
|
430
|
+
clientName: { $first: '$clientName' },
|
|
431
|
+
createdAt: { $first: '$createdAt' },
|
|
432
|
+
issueIdentifiedDate: { $last: '$issueIdentifiedDate' },
|
|
433
|
+
issueClosedDate: { $last: '$issueClosedDate' },
|
|
434
|
+
status: { $last: '$status' },
|
|
435
|
+
primaryIssue: { $last: '$primaryIssue' },
|
|
436
|
+
secondaryIssue: { $last: '$secondaryIssue' },
|
|
437
|
+
},
|
|
420
438
|
},
|
|
421
|
-
},
|
|
422
439
|
];
|
|
440
|
+
|
|
423
441
|
let storesQuery = [];
|
|
424
442
|
if ( req.body.infrafilterIssue == 'Total Stores' ) {
|
|
425
443
|
storesQuery.push( {
|
|
426
444
|
$match: {
|
|
427
445
|
'$and': [
|
|
428
446
|
{ 'clientId': { $in: req.body.clientId } },
|
|
429
|
-
{ 'edge.firstFile': true },
|
|
430
447
|
{ 'status': 'active' },
|
|
448
|
+
{ 'storeId': { $nin: installpendingticket } },
|
|
431
449
|
{ 'createdAt': { $lte: date.end } },
|
|
432
450
|
],
|
|
433
451
|
},
|
|
@@ -436,16 +454,14 @@ export async function infraIssuesTable( req, res ) {
|
|
|
436
454
|
}
|
|
437
455
|
if ( req.body.infrafilterIssue == 'Live Stores' ) {
|
|
438
456
|
let infrastores = await aggregateTangoTicket( query );
|
|
439
|
-
let infraissueStore =
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
}
|
|
448
|
-
}
|
|
457
|
+
let infraissueStore = infrastores.map( ( store ) => store.storeId );
|
|
458
|
+
|
|
459
|
+
let result = totalnumberstores.filter( ( data ) =>
|
|
460
|
+
infraissueStore.length > 0 &&
|
|
461
|
+
!infraissueStore.includes( data ) &&
|
|
462
|
+
!installpendingticket.includes( data ),
|
|
463
|
+
);
|
|
464
|
+
|
|
449
465
|
storesQuery.push(
|
|
450
466
|
{
|
|
451
467
|
$match: {
|
|
@@ -456,34 +472,29 @@ export async function infraIssuesTable( req, res ) {
|
|
|
456
472
|
},
|
|
457
473
|
);
|
|
458
474
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
req.body.infrafilterIssue != 'Issues Not Identified' &&
|
|
462
|
-
req.body.infrafilterIssue != 'All Issues' ) {
|
|
475
|
+
const excludedIssues = [ 'Identified Issues', 'Issues Not Identified', 'All Issues' ];
|
|
476
|
+
if ( req.body.infrafilterIssue && !excludedIssues.includes( req.body.infrafilterIssue ) ) {
|
|
463
477
|
query.push( {
|
|
464
478
|
$match: {
|
|
465
479
|
primaryIssue: req.body.infrafilterIssue,
|
|
466
480
|
},
|
|
467
481
|
} );
|
|
468
482
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
$or: [
|
|
473
|
-
{ storeId: { $regex: req.body.searchValue, $options: 'i' } },
|
|
474
|
-
{ storeName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
475
|
-
],
|
|
476
|
-
},
|
|
477
|
-
} );
|
|
478
|
-
storesQuery.push( {
|
|
483
|
+
|
|
484
|
+
if ( req.body.searchValue && req.body.searchValue !== '' ) {
|
|
485
|
+
const searchCondition = {
|
|
479
486
|
$match: {
|
|
480
487
|
$or: [
|
|
481
488
|
{ storeId: { $regex: req.body.searchValue, $options: 'i' } },
|
|
482
489
|
{ storeName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
483
490
|
],
|
|
484
491
|
},
|
|
485
|
-
}
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
query.push( searchCondition );
|
|
495
|
+
storesQuery.push( searchCondition );
|
|
486
496
|
}
|
|
497
|
+
|
|
487
498
|
if ( req.body.filter && req.body.filter.length > 0 ) {
|
|
488
499
|
query.push(
|
|
489
500
|
{
|
|
@@ -494,12 +505,13 @@ export async function infraIssuesTable( req, res ) {
|
|
|
494
505
|
);
|
|
495
506
|
}
|
|
496
507
|
if ( req.body.sortColumName && req.body.sortColumName !== '' && req.body.sortBy ) {
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
508
|
+
const sortOption = { $sort: { [req.body.sortColumName]: req.body.sortBy } };
|
|
509
|
+
query.push( sortOption );
|
|
510
|
+
storesQuery.push( sortOption );
|
|
511
|
+
} else {
|
|
512
|
+
const sortOption = { $sort: { 'storeId': -1 } };
|
|
513
|
+
query.push( sortOption );
|
|
514
|
+
storesQuery.push( sortOption );
|
|
503
515
|
}
|
|
504
516
|
let count;
|
|
505
517
|
if ( req.body.infrafilterIssue == 'Live Stores' || req.body.infrafilterIssue == 'Total Stores' ) {
|
|
@@ -508,15 +520,56 @@ export async function infraIssuesTable( req, res ) {
|
|
|
508
520
|
count = await aggregateTangoTicket( query );
|
|
509
521
|
}
|
|
510
522
|
if ( req.body.limit && req.body.offset && !req.body.export ) {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
523
|
+
const skipValue = ( req.body.offset - 1 ) * req.body.limit;
|
|
524
|
+
const limitValue = Number( req.body.limit );
|
|
525
|
+
|
|
526
|
+
const pagination = [
|
|
527
|
+
{ $skip: skipValue },
|
|
528
|
+
{ $limit: limitValue },
|
|
529
|
+
];
|
|
530
|
+
|
|
531
|
+
query.push( ...pagination );
|
|
515
532
|
storesQuery.push(
|
|
516
|
-
|
|
517
|
-
{
|
|
533
|
+
...pagination,
|
|
534
|
+
{
|
|
535
|
+
$lookup: {
|
|
536
|
+
from: 'clients',
|
|
537
|
+
let: { clientId: '$clientId' },
|
|
538
|
+
pipeline: [
|
|
539
|
+
{
|
|
540
|
+
$match: {
|
|
541
|
+
$expr: {
|
|
542
|
+
$and: [
|
|
543
|
+
{ $eq: [ '$clientId', '$$clientId' ] },
|
|
544
|
+
],
|
|
545
|
+
},
|
|
546
|
+
},
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
$project: {
|
|
550
|
+
clientName: 1,
|
|
551
|
+
},
|
|
552
|
+
},
|
|
553
|
+
],
|
|
554
|
+
as: 'client',
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
$unwind: { path: '$client', preserveNullAndEmptyArrays: true },
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
$project: {
|
|
562
|
+
clientName: '$client.clientName',
|
|
563
|
+
storeId: 1,
|
|
564
|
+
clientId: 1,
|
|
565
|
+
storeName: 1,
|
|
566
|
+
status: 1,
|
|
567
|
+
createdAt: 1,
|
|
568
|
+
},
|
|
569
|
+
},
|
|
518
570
|
);
|
|
519
571
|
}
|
|
572
|
+
|
|
520
573
|
let result;
|
|
521
574
|
if ( req.body.infrafilterIssue == 'Live Stores' || req.body.infrafilterIssue == 'Total Stores' ) {
|
|
522
575
|
result = await aggregateStore( storesQuery );
|
|
@@ -524,21 +577,30 @@ export async function infraIssuesTable( req, res ) {
|
|
|
524
577
|
result = await aggregateTangoTicket( query );
|
|
525
578
|
}
|
|
526
579
|
if ( req.body.export && result.length > 0 ) {
|
|
527
|
-
const exportdata =
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
580
|
+
const exportdata = result.map( ( element ) => {
|
|
581
|
+
if ( req.body.infrafilterIssue === 'Live Stores' || req.body.infrafilterIssue === 'Total Stores' ) {
|
|
582
|
+
return {
|
|
583
|
+
'Created On': element.createdAt,
|
|
584
|
+
'StoreID': element.storeId,
|
|
585
|
+
'StoreName': element.storeName,
|
|
586
|
+
'Status': element.status,
|
|
587
|
+
};
|
|
588
|
+
} else {
|
|
589
|
+
return {
|
|
590
|
+
'Created On': element.createdAt,
|
|
591
|
+
'StoreID': element.storeId,
|
|
592
|
+
'StoreName': element.storeName,
|
|
593
|
+
'Primary Issue': element.primaryIssue,
|
|
594
|
+
'Sub Issue': element.secondaryIssue,
|
|
595
|
+
'Issue Identified on': element.issueIdentifiedDate ? dayjs( element.issueIdentifiedDate ).tz( 'Asia/Kolkata' ).format( 'YYYY-MM-DD HH:mm A' ) : '',
|
|
596
|
+
'Status': element.status,
|
|
597
|
+
};
|
|
598
|
+
}
|
|
538
599
|
} );
|
|
539
600
|
await download( exportdata, res );
|
|
540
601
|
return;
|
|
541
602
|
}
|
|
603
|
+
|
|
542
604
|
if ( result.length > 0 ) {
|
|
543
605
|
res.sendSuccess( {
|
|
544
606
|
count: count.length,
|
|
@@ -944,111 +1006,155 @@ function generateTimeSlots( startHour, endHour, interval, time ) {
|
|
|
944
1006
|
};
|
|
945
1007
|
export async function hourWiseDownstores( req, res ) {
|
|
946
1008
|
try {
|
|
947
|
-
let
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
if ( req.body.
|
|
1009
|
+
let date = await getUTC( new Date( req.body.fromDate ), new Date( req.body.toDate ) );
|
|
1010
|
+
let issueStatus = [ 'notidentified', 'identified' ];
|
|
1011
|
+
|
|
1012
|
+
if ( req.body.infrafilterIssue == 'Issues Not Identified' ) {
|
|
951
1013
|
issueStatus = [ 'notidentified' ];
|
|
952
1014
|
};
|
|
953
|
-
if ( req.body.
|
|
954
|
-
issueStatus = [ '
|
|
955
|
-
};
|
|
956
|
-
if ( req.body.filterIssue == 'Live Stores' ) {
|
|
957
|
-
issueStatus = [ 'notidentified', 'identified' ];
|
|
1015
|
+
if ( req.body.infrafilterIssue == 'Identified Issues' ) {
|
|
1016
|
+
issueStatus = [ 'identified' ];
|
|
958
1017
|
};
|
|
959
1018
|
|
|
1019
|
+
|
|
960
1020
|
let totalstores = await aggregateStore( [ {
|
|
961
1021
|
$match: {
|
|
962
1022
|
'$and': [
|
|
963
|
-
{ 'clientId': req.body.clientId },
|
|
964
|
-
{ 'edge.firstFile': true },
|
|
1023
|
+
{ 'clientId': { $in: req.body.clientId } },
|
|
965
1024
|
{ 'status': 'active' },
|
|
966
|
-
{ 'createdAt': { $lte:
|
|
1025
|
+
{ 'createdAt': { $lte: date.end } },
|
|
967
1026
|
],
|
|
968
1027
|
},
|
|
969
1028
|
} ] );
|
|
970
|
-
|
|
971
1029
|
let totalnumberstores = [];
|
|
972
1030
|
for ( let store of totalstores ) {
|
|
973
1031
|
totalnumberstores.push( store.storeId );
|
|
974
1032
|
}
|
|
975
|
-
let
|
|
1033
|
+
let pendingquery = [];
|
|
1034
|
+
pendingquery.push( {
|
|
976
1035
|
$match: {
|
|
977
1036
|
$and: [
|
|
978
|
-
{ '
|
|
979
|
-
{ 'basicDetails.storeId': { $in: totalnumberstores } },
|
|
1037
|
+
{ issueType: 'installation' },
|
|
980
1038
|
{ 'status': { $ne: 'closed' } },
|
|
981
|
-
{
|
|
982
|
-
{
|
|
983
|
-
{ 'issueDate': { $lte: new Date( req.body.toDate ) } },
|
|
1039
|
+
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
1040
|
+
{ createdAt: { $lte: date.end } },
|
|
984
1041
|
],
|
|
985
1042
|
},
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1043
|
+
} );
|
|
1044
|
+
let pendingstorecount = await aggregateTangoTicket( pendingquery );
|
|
1045
|
+
let installpendingticket = pendingstorecount.map( ( store ) => store.basicDetails.storeId );
|
|
1046
|
+
|
|
1047
|
+
|
|
1048
|
+
let query = [
|
|
1049
|
+
{
|
|
1050
|
+
$match: {
|
|
1051
|
+
$and: [
|
|
1052
|
+
{ issueType: 'infra' },
|
|
1053
|
+
{ status: { $ne: 'closed' } },
|
|
1054
|
+
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
1055
|
+
{ 'basicDetails.storeId': { $in: totalnumberstores } },
|
|
1056
|
+
{ 'ticketDetails.issueStatus': { $in: issueStatus } },
|
|
1057
|
+
{ createdAt: { $lte: date.end } },
|
|
1058
|
+
],
|
|
1059
|
+
},
|
|
1060
|
+
},
|
|
1061
|
+
{
|
|
1062
|
+
$project: {
|
|
1063
|
+
storeId: '$basicDetails.storeId',
|
|
1064
|
+
clientId: '$basicDetails.clientId',
|
|
1065
|
+
ticketId: 1,
|
|
1066
|
+
storeName: '$basicDetails.storeName',
|
|
1067
|
+
clientName: '$basicDetails.clientName',
|
|
1068
|
+
status: 1,
|
|
1069
|
+
createdAt: 1,
|
|
1070
|
+
issueIdentifiedDate: '$ticketDetails.issueIdentifiedDate',
|
|
1071
|
+
issueClosedDate: '$issueClosedDate',
|
|
1072
|
+
primaryIssue: {
|
|
1073
|
+
$filter: {
|
|
1074
|
+
input: '$ticketActivity',
|
|
1075
|
+
as: 'item',
|
|
1076
|
+
cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
|
|
1077
|
+
},
|
|
996
1078
|
},
|
|
997
1079
|
},
|
|
998
1080
|
},
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1081
|
+
{
|
|
1082
|
+
$unwind: {
|
|
1083
|
+
path: '$primaryIssue',
|
|
1084
|
+
preserveNullAndEmptyArrays: true,
|
|
1085
|
+
},
|
|
1003
1086
|
},
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1087
|
+
{
|
|
1088
|
+
$unwind: {
|
|
1089
|
+
path: '$primaryIssue.reasons',
|
|
1090
|
+
preserveNullAndEmptyArrays: true,
|
|
1091
|
+
},
|
|
1008
1092
|
},
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', 'NotIdentified' ] },
|
|
1093
|
+
{
|
|
1094
|
+
$unwind: {
|
|
1095
|
+
path: '$primaryIssue.reasons.secondaryIssue',
|
|
1096
|
+
preserveNullAndEmptyArrays: true,
|
|
1097
|
+
},
|
|
1015
1098
|
},
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1099
|
+
{
|
|
1100
|
+
$project: {
|
|
1101
|
+
storeId: 1,
|
|
1102
|
+
clientId: 1,
|
|
1103
|
+
storeName: 1,
|
|
1104
|
+
createdAt: 1,
|
|
1105
|
+
ticketId: 1,
|
|
1106
|
+
clientName: 1,
|
|
1107
|
+
actionBy: '$primaryIssue.actionBy',
|
|
1108
|
+
issueIdentifiedDate: { $ifNull: [ '$issueIdentifiedDate', '' ] },
|
|
1109
|
+
issueClosedDate: { $ifNull: [ '$issueClosedDate', '' ] },
|
|
1110
|
+
status: 1,
|
|
1111
|
+
primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '-' ] },
|
|
1112
|
+
secondaryIssue: { $ifNull: [ '$primaryIssue.reasons.secondaryIssue.name', '-' ] },
|
|
1113
|
+
},
|
|
1114
|
+
},
|
|
1115
|
+
{
|
|
1116
|
+
$group: {
|
|
1117
|
+
_id: '$ticketId',
|
|
1118
|
+
storeId: { $first: '$storeId' },
|
|
1119
|
+
clientId: { $first: '$clientId' },
|
|
1120
|
+
ticketId: { $first: '$ticketId' },
|
|
1121
|
+
actionBy: { $first: '$actionBy' },
|
|
1122
|
+
storeName: { $first: '$storeName' },
|
|
1123
|
+
clientName: { $first: '$clientName' },
|
|
1124
|
+
createdAt: { $first: '$createdAt' },
|
|
1125
|
+
issueIdentifiedDate: { $last: '$issueIdentifiedDate' },
|
|
1126
|
+
issueClosedDate: { $last: '$issueClosedDate' },
|
|
1127
|
+
status: { $last: '$status' },
|
|
1128
|
+
primaryIssue: { $last: '$primaryIssue' },
|
|
1129
|
+
secondaryIssue: { $last: '$secondaryIssue' },
|
|
1130
|
+
},
|
|
1023
1131
|
},
|
|
1024
|
-
},
|
|
1025
1132
|
];
|
|
1133
|
+
|
|
1026
1134
|
let storesQuery = [];
|
|
1027
|
-
if ( req.body.
|
|
1135
|
+
if ( req.body.infrafilterIssue == 'Total Stores' ) {
|
|
1028
1136
|
storesQuery.push( {
|
|
1029
1137
|
$match: {
|
|
1030
1138
|
'$and': [
|
|
1031
|
-
{ 'clientId': req.body.clientId },
|
|
1032
|
-
{ 'edge.firstFile': true },
|
|
1139
|
+
{ 'clientId': { $in: req.body.clientId } },
|
|
1033
1140
|
{ 'status': 'active' },
|
|
1034
|
-
{ '
|
|
1141
|
+
{ 'storeId': { $nin: installpendingticket } },
|
|
1142
|
+
{ 'createdAt': { $lte: date.end } },
|
|
1035
1143
|
],
|
|
1036
1144
|
},
|
|
1037
1145
|
},
|
|
1038
1146
|
);
|
|
1039
1147
|
}
|
|
1040
|
-
if ( req.body.
|
|
1148
|
+
if ( req.body.infrafilterIssue == 'Live Stores' ) {
|
|
1041
1149
|
let infrastores = await aggregateTangoTicket( query );
|
|
1042
|
-
let infraissueStore =
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1150
|
+
let infraissueStore = infrastores.map( ( store ) => store.storeId );
|
|
1151
|
+
|
|
1152
|
+
let result = totalnumberstores.filter( ( data ) =>
|
|
1153
|
+
infraissueStore.length > 0 &&
|
|
1154
|
+
!infraissueStore.includes( data ) &&
|
|
1155
|
+
!installpendingticket.includes( data ),
|
|
1156
|
+
);
|
|
1157
|
+
|
|
1052
1158
|
storesQuery.push(
|
|
1053
1159
|
{
|
|
1054
1160
|
$match: {
|
|
@@ -1059,71 +1165,116 @@ export async function hourWiseDownstores( req, res ) {
|
|
|
1059
1165
|
},
|
|
1060
1166
|
);
|
|
1061
1167
|
}
|
|
1062
|
-
|
|
1168
|
+
const excludedIssues = [ 'Identified Issues', 'Issues Not Identified', 'All Issues' ];
|
|
1169
|
+
if ( req.body.infrafilterIssue && !excludedIssues.includes( req.body.infrafilterIssue ) ) {
|
|
1063
1170
|
query.push( {
|
|
1064
1171
|
$match: {
|
|
1065
|
-
|
|
1066
|
-
{ storeName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
1067
|
-
{ storeId: { $regex: req.body.searchValue, $options: 'i' } },
|
|
1068
|
-
],
|
|
1172
|
+
primaryIssue: req.body.infrafilterIssue,
|
|
1069
1173
|
},
|
|
1070
1174
|
} );
|
|
1071
|
-
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
if ( req.body.searchValue && req.body.searchValue !== '' ) {
|
|
1178
|
+
const searchCondition = {
|
|
1072
1179
|
$match: {
|
|
1073
1180
|
$or: [
|
|
1074
|
-
{ storeName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
1075
1181
|
{ storeId: { $regex: req.body.searchValue, $options: 'i' } },
|
|
1182
|
+
{ storeName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
1076
1183
|
],
|
|
1077
1184
|
},
|
|
1078
|
-
}
|
|
1185
|
+
};
|
|
1186
|
+
|
|
1187
|
+
query.push( searchCondition );
|
|
1188
|
+
storesQuery.push( searchCondition );
|
|
1079
1189
|
}
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1190
|
+
|
|
1191
|
+
if ( req.body.filter && req.body.filter.length > 0 ) {
|
|
1192
|
+
query.push(
|
|
1193
|
+
{
|
|
1194
|
+
$match: {
|
|
1195
|
+
actionBy: { $in: req.body.filter },
|
|
1196
|
+
},
|
|
1197
|
+
},
|
|
1198
|
+
);
|
|
1087
1199
|
}
|
|
1088
|
-
if ( req.body.
|
|
1089
|
-
req.body.
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
} );
|
|
1200
|
+
if ( req.body.sortColumName && req.body.sortColumName !== '' && req.body.sortBy ) {
|
|
1201
|
+
const sortOption = { $sort: { [req.body.sortColumName]: req.body.sortBy } };
|
|
1202
|
+
query.push( sortOption );
|
|
1203
|
+
storesQuery.push( sortOption );
|
|
1204
|
+
} else {
|
|
1205
|
+
const sortOption = { $sort: { 'storeId': -1 } };
|
|
1206
|
+
query.push( sortOption );
|
|
1207
|
+
storesQuery.push( sortOption );
|
|
1097
1208
|
}
|
|
1098
|
-
|
|
1099
1209
|
let count;
|
|
1100
|
-
if ( req.body.
|
|
1210
|
+
if ( req.body.infrafilterIssue == 'Live Stores' || req.body.infrafilterIssue == 'Total Stores' ) {
|
|
1101
1211
|
count = await aggregateStore( storesQuery );
|
|
1102
1212
|
} else {
|
|
1103
1213
|
count = await aggregateTangoTicket( query );
|
|
1104
1214
|
}
|
|
1105
1215
|
if ( req.body.limit && req.body.offset && !req.body.export ) {
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1216
|
+
const skipValue = ( req.body.offset - 1 ) * req.body.limit;
|
|
1217
|
+
const limitValue = Number( req.body.limit );
|
|
1218
|
+
|
|
1219
|
+
const pagination = [
|
|
1220
|
+
{ $skip: skipValue },
|
|
1221
|
+
{ $limit: limitValue },
|
|
1222
|
+
];
|
|
1223
|
+
|
|
1224
|
+
query.push( ...pagination );
|
|
1110
1225
|
storesQuery.push(
|
|
1111
|
-
|
|
1112
|
-
{
|
|
1226
|
+
...pagination,
|
|
1227
|
+
{
|
|
1228
|
+
$lookup: {
|
|
1229
|
+
from: 'clients',
|
|
1230
|
+
let: { clientId: '$clientId' },
|
|
1231
|
+
pipeline: [
|
|
1232
|
+
{
|
|
1233
|
+
$match: {
|
|
1234
|
+
$expr: {
|
|
1235
|
+
$and: [
|
|
1236
|
+
{ $eq: [ '$clientId', '$$clientId' ] },
|
|
1237
|
+
],
|
|
1238
|
+
},
|
|
1239
|
+
},
|
|
1240
|
+
},
|
|
1241
|
+
{
|
|
1242
|
+
$project: {
|
|
1243
|
+
clientName: 1,
|
|
1244
|
+
},
|
|
1245
|
+
},
|
|
1246
|
+
],
|
|
1247
|
+
as: 'client',
|
|
1248
|
+
},
|
|
1249
|
+
},
|
|
1250
|
+
{
|
|
1251
|
+
$unwind: { path: '$client', preserveNullAndEmptyArrays: true },
|
|
1252
|
+
},
|
|
1253
|
+
{
|
|
1254
|
+
$project: {
|
|
1255
|
+
clientName: '$client.clientName',
|
|
1256
|
+
storeId: 1,
|
|
1257
|
+
clientId: 1,
|
|
1258
|
+
storeName: 1,
|
|
1259
|
+
status: 1,
|
|
1260
|
+
createdAt: 1,
|
|
1261
|
+
},
|
|
1262
|
+
},
|
|
1113
1263
|
);
|
|
1114
1264
|
}
|
|
1265
|
+
|
|
1115
1266
|
let storesList;
|
|
1116
|
-
if ( req.body.
|
|
1267
|
+
if ( req.body.infrafilterIssue == 'Live Stores' || req.body.infrafilterIssue == 'Total Stores' ) {
|
|
1117
1268
|
storesList = await aggregateStore( storesQuery );
|
|
1118
1269
|
} else {
|
|
1119
1270
|
storesList = await aggregateTangoTicket( query );
|
|
1120
1271
|
}
|
|
1121
|
-
|
|
1122
1272
|
if ( storesList.length == 0 ) {
|
|
1123
1273
|
return res.sendError( 'no data', 204 );
|
|
1124
1274
|
}
|
|
1125
1275
|
let data = {};
|
|
1126
1276
|
let result = [];
|
|
1277
|
+
let inputData = req.body;
|
|
1127
1278
|
for ( const store of storesList ) {
|
|
1128
1279
|
data.storeId = store.storeId;
|
|
1129
1280
|
data.storeName = store.storeName;
|
|
@@ -1142,82 +1293,64 @@ export async function hourWiseDownstores( req, res ) {
|
|
|
1142
1293
|
}
|
|
1143
1294
|
}
|
|
1144
1295
|
|
|
1296
|
+
async function downStoresCheck( data, inputData ) {
|
|
1297
|
+
try {
|
|
1298
|
+
const TimeSlots = generateTimeSlots( 8, 22, 60, inputData.Date );
|
|
1299
|
+
const formattedTimeSlots = TimeSlots.map( ( slot ) => ( {
|
|
1300
|
+
...slot,
|
|
1301
|
+
startTime: dayjs( slot.from ).format( 'hh:mm A' ),
|
|
1302
|
+
endTime: dayjs( slot.to ).format( 'hh:mm A' ),
|
|
1303
|
+
} ) );
|
|
1145
1304
|
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
'bool': {
|
|
1159
|
-
'must': [
|
|
1160
|
-
{
|
|
1161
|
-
'term': {
|
|
1162
|
-
'doc.date.keyword': dayjs( inputData.Date ).format( 'DD-MM-YYYY' ),
|
|
1163
|
-
},
|
|
1164
|
-
},
|
|
1165
|
-
{
|
|
1166
|
-
'term': {
|
|
1167
|
-
'doc.store_id.keyword': data.storeId,
|
|
1168
|
-
},
|
|
1169
|
-
},
|
|
1170
|
-
{
|
|
1171
|
-
'terms': {
|
|
1172
|
-
'doc.hour.keyword': [ obj.hour ],
|
|
1173
|
-
},
|
|
1174
|
-
},
|
|
1175
|
-
],
|
|
1176
|
-
|
|
1177
|
-
},
|
|
1305
|
+
const downTimePromises = formattedTimeSlots.map( async ( obj ) => {
|
|
1306
|
+
const downTime = await getOpenSearchData(
|
|
1307
|
+
JSON.parse( process.env.OPENSEARCH ).downTimeHourly,
|
|
1308
|
+
{
|
|
1309
|
+
size: 1,
|
|
1310
|
+
query: {
|
|
1311
|
+
bool: {
|
|
1312
|
+
must: [
|
|
1313
|
+
{ term: { 'doc.date.keyword': dayjs( inputData.Date ).format( 'DD-MM-YYYY' ) } },
|
|
1314
|
+
{ term: { 'doc.store_id.keyword': data.storeId } },
|
|
1315
|
+
{ terms: { 'doc.hour.keyword': [ obj.hour ] } },
|
|
1316
|
+
],
|
|
1178
1317
|
},
|
|
1318
|
+
},
|
|
1319
|
+
},
|
|
1320
|
+
);
|
|
1179
1321
|
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
const sum = streamwiseDowntime.reduce( ( accumulator, currentValue ) => {
|
|
1184
|
-
return accumulator + currentValue.down_time;
|
|
1185
|
-
}, 0 );
|
|
1186
|
-
|
|
1187
|
-
// Calculate the average
|
|
1188
|
-
const average = sum / streamwiseDowntime.length;
|
|
1189
|
-
obj[obj.startTime + '-' + obj.endTime] = Math.round( average );
|
|
1190
|
-
} else {
|
|
1191
|
-
obj[obj.startTime + '-' + obj.endTime] = '';
|
|
1192
|
-
}
|
|
1322
|
+
const streamwiseDowntime = downTime.body.hits.hits.length > 0 ?
|
|
1323
|
+
downTime.body.hits.hits[0]._source.doc.streamwise_downtime :
|
|
1324
|
+
[];
|
|
1193
1325
|
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
mergedData[key] = obj[key];
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1326
|
+
const average = streamwiseDowntime.length ?
|
|
1327
|
+
Math.round( streamwiseDowntime.reduce( ( acc, curr ) => acc + curr.down_time, 0 ) / streamwiseDowntime.length ) :
|
|
1328
|
+
'';
|
|
1329
|
+
|
|
1330
|
+
return { ...obj, [`${obj.startTime}-${obj.endTime}`]: average };
|
|
1331
|
+
} );
|
|
1332
|
+
|
|
1333
|
+
const timewise = await Promise.all( downTimePromises );
|
|
1334
|
+
|
|
1335
|
+
const mergedData = timewise.reduce( ( acc, obj ) => {
|
|
1336
|
+
for ( const [ key, value ] of Object.entries( obj ) ) {
|
|
1337
|
+
if ( ![ 'hour', 'from', 'to', 'startTime', 'endTime', 'clientId' ].includes( key ) ) {
|
|
1338
|
+
acc[key] = ( acc[key] || 0 ) + value;
|
|
1210
1339
|
}
|
|
1211
|
-
}
|
|
1340
|
+
}
|
|
1341
|
+
return acc;
|
|
1342
|
+
}, {
|
|
1343
|
+
storeName: data.storeName,
|
|
1344
|
+
storeId: data.storeId,
|
|
1345
|
+
PrimaryIssue: data.primaryIssue,
|
|
1346
|
+
} );
|
|
1212
1347
|
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
Reject( err );
|
|
1218
|
-
}
|
|
1219
|
-
} );
|
|
1348
|
+
return [ mergedData ];
|
|
1349
|
+
} catch ( err ) {
|
|
1350
|
+
throw err;
|
|
1351
|
+
}
|
|
1220
1352
|
}
|
|
1353
|
+
|
|
1221
1354
|
export async function ticketCountSplit( req, res ) {
|
|
1222
1355
|
try {
|
|
1223
1356
|
const inputData = req.body;
|