tango-app-api-infra 3.1.17 → 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 +422 -326
- package/src/controllers/dataMismatch.controller.js +13 -1
- package/src/controllers/infra.controllers.js +14 -3
- package/src/controllers/internalInfra.controller.js +1 -1
- package/src/controllers/storeInfra.controlller.js +351 -479
- package/src/controllers/userInfra.controller.js +29 -21
- package/src/validations/infra.validation.js +20 -21
|
@@ -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,52 +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
|
-
{
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
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
|
+
},
|
|
530
547
|
},
|
|
531
|
-
|
|
532
|
-
|
|
548
|
+
{
|
|
549
|
+
$project: {
|
|
550
|
+
clientName: 1,
|
|
551
|
+
},
|
|
552
|
+
},
|
|
553
|
+
],
|
|
554
|
+
as: 'client',
|
|
533
555
|
},
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
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,
|
|
538
568
|
},
|
|
539
|
-
|
|
540
|
-
},
|
|
541
|
-
},
|
|
542
|
-
{
|
|
543
|
-
$unwind: { path: '$client', preserveNullAndEmptyArrays: true },
|
|
544
|
-
},
|
|
545
|
-
{
|
|
546
|
-
$project: {
|
|
547
|
-
clientName: '$client.clientName',
|
|
548
|
-
storeId: 1,
|
|
549
|
-
clientId: 1,
|
|
550
|
-
storeName: 1,
|
|
551
|
-
status: 1,
|
|
552
|
-
createdAt: 1,
|
|
553
|
-
},
|
|
554
|
-
},
|
|
569
|
+
},
|
|
555
570
|
);
|
|
556
571
|
}
|
|
572
|
+
|
|
557
573
|
let result;
|
|
558
574
|
if ( req.body.infrafilterIssue == 'Live Stores' || req.body.infrafilterIssue == 'Total Stores' ) {
|
|
559
575
|
result = await aggregateStore( storesQuery );
|
|
@@ -561,21 +577,30 @@ export async function infraIssuesTable( req, res ) {
|
|
|
561
577
|
result = await aggregateTangoTicket( query );
|
|
562
578
|
}
|
|
563
579
|
if ( req.body.export && result.length > 0 ) {
|
|
564
|
-
const exportdata =
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
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
|
+
}
|
|
575
599
|
} );
|
|
576
600
|
await download( exportdata, res );
|
|
577
601
|
return;
|
|
578
602
|
}
|
|
603
|
+
|
|
579
604
|
if ( result.length > 0 ) {
|
|
580
605
|
res.sendSuccess( {
|
|
581
606
|
count: count.length,
|
|
@@ -981,111 +1006,155 @@ function generateTimeSlots( startHour, endHour, interval, time ) {
|
|
|
981
1006
|
};
|
|
982
1007
|
export async function hourWiseDownstores( req, res ) {
|
|
983
1008
|
try {
|
|
984
|
-
let
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
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' ) {
|
|
988
1013
|
issueStatus = [ 'notidentified' ];
|
|
989
1014
|
};
|
|
990
|
-
if ( req.body.
|
|
991
|
-
issueStatus = [ '
|
|
992
|
-
};
|
|
993
|
-
if ( req.body.filterIssue == 'Live Stores' ) {
|
|
994
|
-
issueStatus = [ 'notidentified', 'identified' ];
|
|
1015
|
+
if ( req.body.infrafilterIssue == 'Identified Issues' ) {
|
|
1016
|
+
issueStatus = [ 'identified' ];
|
|
995
1017
|
};
|
|
996
1018
|
|
|
1019
|
+
|
|
997
1020
|
let totalstores = await aggregateStore( [ {
|
|
998
1021
|
$match: {
|
|
999
1022
|
'$and': [
|
|
1000
|
-
{ 'clientId': req.body.clientId },
|
|
1001
|
-
{ 'edge.firstFile': true },
|
|
1023
|
+
{ 'clientId': { $in: req.body.clientId } },
|
|
1002
1024
|
{ 'status': 'active' },
|
|
1003
|
-
{ 'createdAt': { $lte:
|
|
1025
|
+
{ 'createdAt': { $lte: date.end } },
|
|
1004
1026
|
],
|
|
1005
1027
|
},
|
|
1006
1028
|
} ] );
|
|
1007
|
-
|
|
1008
1029
|
let totalnumberstores = [];
|
|
1009
1030
|
for ( let store of totalstores ) {
|
|
1010
1031
|
totalnumberstores.push( store.storeId );
|
|
1011
1032
|
}
|
|
1012
|
-
let
|
|
1033
|
+
let pendingquery = [];
|
|
1034
|
+
pendingquery.push( {
|
|
1013
1035
|
$match: {
|
|
1014
1036
|
$and: [
|
|
1015
|
-
{ '
|
|
1016
|
-
{ 'basicDetails.storeId': { $in: totalnumberstores } },
|
|
1037
|
+
{ issueType: 'installation' },
|
|
1017
1038
|
{ 'status': { $ne: 'closed' } },
|
|
1018
|
-
{
|
|
1019
|
-
{
|
|
1020
|
-
{ 'issueDate': { $lte: new Date( req.body.toDate ) } },
|
|
1039
|
+
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
1040
|
+
{ createdAt: { $lte: date.end } },
|
|
1021
1041
|
],
|
|
1022
1042
|
},
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
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
|
+
},
|
|
1033
1078
|
},
|
|
1034
1079
|
},
|
|
1035
1080
|
},
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1081
|
+
{
|
|
1082
|
+
$unwind: {
|
|
1083
|
+
path: '$primaryIssue',
|
|
1084
|
+
preserveNullAndEmptyArrays: true,
|
|
1085
|
+
},
|
|
1040
1086
|
},
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1087
|
+
{
|
|
1088
|
+
$unwind: {
|
|
1089
|
+
path: '$primaryIssue.reasons',
|
|
1090
|
+
preserveNullAndEmptyArrays: true,
|
|
1091
|
+
},
|
|
1045
1092
|
},
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', 'NotIdentified' ] },
|
|
1093
|
+
{
|
|
1094
|
+
$unwind: {
|
|
1095
|
+
path: '$primaryIssue.reasons.secondaryIssue',
|
|
1096
|
+
preserveNullAndEmptyArrays: true,
|
|
1097
|
+
},
|
|
1052
1098
|
},
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
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
|
+
},
|
|
1060
1131
|
},
|
|
1061
|
-
},
|
|
1062
1132
|
];
|
|
1133
|
+
|
|
1063
1134
|
let storesQuery = [];
|
|
1064
|
-
if ( req.body.
|
|
1135
|
+
if ( req.body.infrafilterIssue == 'Total Stores' ) {
|
|
1065
1136
|
storesQuery.push( {
|
|
1066
1137
|
$match: {
|
|
1067
1138
|
'$and': [
|
|
1068
|
-
{ 'clientId': req.body.clientId },
|
|
1069
|
-
{ 'edge.firstFile': true },
|
|
1139
|
+
{ 'clientId': { $in: req.body.clientId } },
|
|
1070
1140
|
{ 'status': 'active' },
|
|
1071
|
-
{ '
|
|
1141
|
+
{ 'storeId': { $nin: installpendingticket } },
|
|
1142
|
+
{ 'createdAt': { $lte: date.end } },
|
|
1072
1143
|
],
|
|
1073
1144
|
},
|
|
1074
1145
|
},
|
|
1075
1146
|
);
|
|
1076
1147
|
}
|
|
1077
|
-
if ( req.body.
|
|
1148
|
+
if ( req.body.infrafilterIssue == 'Live Stores' ) {
|
|
1078
1149
|
let infrastores = await aggregateTangoTicket( query );
|
|
1079
|
-
let infraissueStore =
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
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
|
+
|
|
1089
1158
|
storesQuery.push(
|
|
1090
1159
|
{
|
|
1091
1160
|
$match: {
|
|
@@ -1096,71 +1165,116 @@ export async function hourWiseDownstores( req, res ) {
|
|
|
1096
1165
|
},
|
|
1097
1166
|
);
|
|
1098
1167
|
}
|
|
1099
|
-
|
|
1168
|
+
const excludedIssues = [ 'Identified Issues', 'Issues Not Identified', 'All Issues' ];
|
|
1169
|
+
if ( req.body.infrafilterIssue && !excludedIssues.includes( req.body.infrafilterIssue ) ) {
|
|
1100
1170
|
query.push( {
|
|
1101
1171
|
$match: {
|
|
1102
|
-
|
|
1103
|
-
{ storeName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
1104
|
-
{ storeId: { $regex: req.body.searchValue, $options: 'i' } },
|
|
1105
|
-
],
|
|
1172
|
+
primaryIssue: req.body.infrafilterIssue,
|
|
1106
1173
|
},
|
|
1107
1174
|
} );
|
|
1108
|
-
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
if ( req.body.searchValue && req.body.searchValue !== '' ) {
|
|
1178
|
+
const searchCondition = {
|
|
1109
1179
|
$match: {
|
|
1110
1180
|
$or: [
|
|
1111
|
-
{ storeName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
1112
1181
|
{ storeId: { $regex: req.body.searchValue, $options: 'i' } },
|
|
1182
|
+
{ storeName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
1113
1183
|
],
|
|
1114
1184
|
},
|
|
1115
|
-
}
|
|
1185
|
+
};
|
|
1186
|
+
|
|
1187
|
+
query.push( searchCondition );
|
|
1188
|
+
storesQuery.push( searchCondition );
|
|
1116
1189
|
}
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
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
|
+
);
|
|
1124
1199
|
}
|
|
1125
|
-
if ( req.body.
|
|
1126
|
-
req.body.
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
} );
|
|
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 );
|
|
1134
1208
|
}
|
|
1135
|
-
|
|
1136
1209
|
let count;
|
|
1137
|
-
if ( req.body.
|
|
1210
|
+
if ( req.body.infrafilterIssue == 'Live Stores' || req.body.infrafilterIssue == 'Total Stores' ) {
|
|
1138
1211
|
count = await aggregateStore( storesQuery );
|
|
1139
1212
|
} else {
|
|
1140
1213
|
count = await aggregateTangoTicket( query );
|
|
1141
1214
|
}
|
|
1142
1215
|
if ( req.body.limit && req.body.offset && !req.body.export ) {
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
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 );
|
|
1147
1225
|
storesQuery.push(
|
|
1148
|
-
|
|
1149
|
-
{
|
|
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
|
+
},
|
|
1150
1263
|
);
|
|
1151
1264
|
}
|
|
1265
|
+
|
|
1152
1266
|
let storesList;
|
|
1153
|
-
if ( req.body.
|
|
1267
|
+
if ( req.body.infrafilterIssue == 'Live Stores' || req.body.infrafilterIssue == 'Total Stores' ) {
|
|
1154
1268
|
storesList = await aggregateStore( storesQuery );
|
|
1155
1269
|
} else {
|
|
1156
1270
|
storesList = await aggregateTangoTicket( query );
|
|
1157
1271
|
}
|
|
1158
|
-
|
|
1159
1272
|
if ( storesList.length == 0 ) {
|
|
1160
1273
|
return res.sendError( 'no data', 204 );
|
|
1161
1274
|
}
|
|
1162
1275
|
let data = {};
|
|
1163
1276
|
let result = [];
|
|
1277
|
+
let inputData = req.body;
|
|
1164
1278
|
for ( const store of storesList ) {
|
|
1165
1279
|
data.storeId = store.storeId;
|
|
1166
1280
|
data.storeName = store.storeName;
|
|
@@ -1179,82 +1293,64 @@ export async function hourWiseDownstores( req, res ) {
|
|
|
1179
1293
|
}
|
|
1180
1294
|
}
|
|
1181
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
|
+
} ) );
|
|
1182
1304
|
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
'bool': {
|
|
1196
|
-
'must': [
|
|
1197
|
-
{
|
|
1198
|
-
'term': {
|
|
1199
|
-
'doc.date.keyword': dayjs( inputData.Date ).format( 'DD-MM-YYYY' ),
|
|
1200
|
-
},
|
|
1201
|
-
},
|
|
1202
|
-
{
|
|
1203
|
-
'term': {
|
|
1204
|
-
'doc.store_id.keyword': data.storeId,
|
|
1205
|
-
},
|
|
1206
|
-
},
|
|
1207
|
-
{
|
|
1208
|
-
'terms': {
|
|
1209
|
-
'doc.hour.keyword': [ obj.hour ],
|
|
1210
|
-
},
|
|
1211
|
-
},
|
|
1212
|
-
],
|
|
1213
|
-
|
|
1214
|
-
},
|
|
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
|
+
],
|
|
1215
1317
|
},
|
|
1318
|
+
},
|
|
1319
|
+
},
|
|
1320
|
+
);
|
|
1216
1321
|
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
const sum = streamwiseDowntime.reduce( ( accumulator, currentValue ) => {
|
|
1221
|
-
return accumulator + currentValue.down_time;
|
|
1222
|
-
}, 0 );
|
|
1223
|
-
|
|
1224
|
-
// Calculate the average
|
|
1225
|
-
const average = sum / streamwiseDowntime.length;
|
|
1226
|
-
obj[obj.startTime + '-' + obj.endTime] = Math.round( average );
|
|
1227
|
-
} else {
|
|
1228
|
-
obj[obj.startTime + '-' + obj.endTime] = '';
|
|
1229
|
-
}
|
|
1322
|
+
const streamwiseDowntime = downTime.body.hits.hits.length > 0 ?
|
|
1323
|
+
downTime.body.hits.hits[0]._source.doc.streamwise_downtime :
|
|
1324
|
+
[];
|
|
1230
1325
|
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
mergedData[key] = obj[key];
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
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;
|
|
1247
1339
|
}
|
|
1248
|
-
}
|
|
1340
|
+
}
|
|
1341
|
+
return acc;
|
|
1342
|
+
}, {
|
|
1343
|
+
storeName: data.storeName,
|
|
1344
|
+
storeId: data.storeId,
|
|
1345
|
+
PrimaryIssue: data.primaryIssue,
|
|
1346
|
+
} );
|
|
1249
1347
|
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
Reject( err );
|
|
1255
|
-
}
|
|
1256
|
-
} );
|
|
1348
|
+
return [ mergedData ];
|
|
1349
|
+
} catch ( err ) {
|
|
1350
|
+
throw err;
|
|
1351
|
+
}
|
|
1257
1352
|
}
|
|
1353
|
+
|
|
1258
1354
|
export async function ticketCountSplit( req, res ) {
|
|
1259
1355
|
try {
|
|
1260
1356
|
const inputData = req.body;
|