tango-app-api-infra 3.0.110-dev → 3.0.112-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.
@@ -349,92 +349,95 @@ export async function infraIssuesTable( req, res ) {
349
349
  },
350
350
  } );
351
351
  let pendingstorecount = await aggregateTangoTicket( pendingquery );
352
- let installpendingticket = [];
353
- for ( let store of pendingstorecount ) {
354
- installpendingticket.push( store.basicDetails.storeId );
355
- }
352
+ let installpendingticket = pendingstorecount.map( ( store ) => store.basicDetails.storeId );
356
353
 
357
- let query = [ {
358
- $match: {
359
- $and: [
360
- { issueType: 'infra' },
361
- { status: { $ne: 'closed' } },
362
- { 'basicDetails.clientId': { $in: req.body.clientId } },
363
- { 'basicDetails.storeId': { $in: totalnumberstores } },
364
- { 'ticketDetails.issueStatus': { $in: issueStatus } },
365
- { createdAt: { $lte: date.end } },
366
- ],
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
367
  },
368
- },
369
- {
370
- $project: {
371
- storeId: '$basicDetails.storeId',
372
- clientId: '$basicDetails.clientId',
373
- ticketId: 1,
374
- storeName: '$basicDetails.storeName',
375
- clientName: '$basicDetails.clientName',
376
- status: 1,
377
- createdAt: 1,
378
- issueIdentifiedDate: '$ticketDetails.issueIdentifiedDate',
379
- issueClosedDate: '$issueClosedDate',
380
- primaryIssue: {
381
- $filter: {
382
- input: '$ticketActivity',
383
- as: 'item',
384
- cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
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
+ },
385
385
  },
386
386
  },
387
387
  },
388
- },
389
- {
390
- $unwind: {
391
- path: '$primaryIssue', preserveNullAndEmptyArrays: true,
388
+ {
389
+ $unwind: {
390
+ path: '$primaryIssue',
391
+ preserveNullAndEmptyArrays: true,
392
+ },
392
393
  },
393
- },
394
- {
395
- $unwind: {
396
- path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
394
+ {
395
+ $unwind: {
396
+ path: '$primaryIssue.reasons',
397
+ preserveNullAndEmptyArrays: true,
398
+ },
397
399
  },
398
- },
399
- {
400
- $unwind: {
401
- path: '$primaryIssue.reasons.secondaryIssue', preserveNullAndEmptyArrays: true,
400
+ {
401
+ $unwind: {
402
+ path: '$primaryIssue.reasons.secondaryIssue',
403
+ preserveNullAndEmptyArrays: true,
404
+ },
402
405
  },
403
- },
404
- {
405
- $project: {
406
- storeId: 1,
407
- clientId: 1,
408
- storeName: 1,
409
- createdAt: 1,
410
- ticketId: 1,
411
- clientName: 1,
412
- actionBy: '$primaryIssue.actionBy',
413
- issueIdentifiedDate: { $ifNull: [ '$issueIdentifiedDate', '' ] },
414
- issueClosedDate: { $ifNull: [ '$issueClosedDate', '' ] },
415
- status: 1,
416
- primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '-' ] },
417
- secondaryIssue: { $ifNull: [ '$primaryIssue.reasons.secondaryIssue.name', '-' ] },
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
+ },
418
421
  },
419
- },
420
- {
421
- $group: {
422
- _id: '$ticketId',
423
- storeId: { $first: '$storeId' },
424
- clientId: { $first: '$clientId' },
425
- ticketId: { $first: '$ticketId' },
426
- actionBy: { $first: '$actionBy' },
427
- storeName: { $first: '$storeName' },
428
- clientName: { $first: '$clientName' },
429
- createdAt: { $first: '$createdAt' },
430
- issueIdentifiedDate: { $last: '$issueIdentifiedDate' },
431
- issueClosedDate: { $last: '$issueClosedDate' },
432
- status: { $last: '$status' },
433
- primaryIssue: { $last: '$primaryIssue' },
434
- secondaryIssue: { $last: '$secondaryIssue' },
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
+ },
435
438
  },
436
- },
437
439
  ];
440
+
438
441
  let storesQuery = [];
439
442
  if ( req.body.infrafilterIssue == 'Total Stores' ) {
440
443
  storesQuery.push( {
@@ -451,16 +454,14 @@ export async function infraIssuesTable( req, res ) {
451
454
  }
452
455
  if ( req.body.infrafilterIssue == 'Live Stores' ) {
453
456
  let infrastores = await aggregateTangoTicket( query );
454
- let infraissueStore = [];
455
- for ( let store of infrastores ) {
456
- infraissueStore.push( store.storeId );
457
- }
458
- let result = [];
459
- for ( let data of totalnumberstores ) {
460
- if ( infraissueStore.length > 0 && !infraissueStore.includes( data )&&!installpendingticket.includes( data ) ) {
461
- result.push( data );
462
- }
463
- }
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
+
464
465
  storesQuery.push(
465
466
  {
466
467
  $match: {
@@ -471,34 +472,29 @@ export async function infraIssuesTable( req, res ) {
471
472
  },
472
473
  );
473
474
  }
474
- if ( req.body.infrafilterIssue && req.body.infrafilterIssue != '' &&
475
- req.body.infrafilterIssue != 'Identified Issues' &&
476
- req.body.infrafilterIssue != 'Issues Not Identified' &&
477
- 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 ) ) {
478
477
  query.push( {
479
478
  $match: {
480
479
  primaryIssue: req.body.infrafilterIssue,
481
480
  },
482
481
  } );
483
482
  }
484
- if ( req.body.searchValue && req.body.searchValue != '' ) {
485
- query.push( {
486
- $match: {
487
- $or: [
488
- { storeId: { $regex: req.body.searchValue, $options: 'i' } },
489
- { storeName: { $regex: req.body.searchValue, $options: 'i' } },
490
- ],
491
- },
492
- } );
493
- storesQuery.push( {
483
+
484
+ if ( req.body.searchValue && req.body.searchValue !== '' ) {
485
+ const searchCondition = {
494
486
  $match: {
495
487
  $or: [
496
488
  { storeId: { $regex: req.body.searchValue, $options: 'i' } },
497
489
  { storeName: { $regex: req.body.searchValue, $options: 'i' } },
498
490
  ],
499
491
  },
500
- } );
492
+ };
493
+
494
+ query.push( searchCondition );
495
+ storesQuery.push( searchCondition );
501
496
  }
497
+
502
498
  if ( req.body.filter && req.body.filter.length > 0 ) {
503
499
  query.push(
504
500
  {
@@ -524,52 +520,56 @@ export async function infraIssuesTable( req, res ) {
524
520
  count = await aggregateTangoTicket( query );
525
521
  }
526
522
  if ( req.body.limit && req.body.offset && !req.body.export ) {
527
- query.push(
528
- { $skip: ( req.body.offset - 1 ) * req.body.limit },
529
- { $limit: Number( req.body.limit ) },
530
- );
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 );
531
532
  storesQuery.push(
532
- { $skip: ( req.body.offset - 1 ) * req.body.limit },
533
- { $limit: Number( req.body.limit ) },
534
- );
535
- storesQuery.push( {
536
- $lookup: {
537
- from: 'clients',
538
- let: { clientId: '$clientId' },
539
- pipeline: [
540
- {
541
- $match: {
542
- $expr: {
543
- $and: [
544
- { $eq: [ '$clientId', '$$clientId' ] },
545
- ],
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
+ },
546
547
  },
547
- },
548
-
548
+ {
549
+ $project: {
550
+ clientName: 1,
551
+ },
552
+ },
553
+ ],
554
+ as: 'client',
549
555
  },
550
- {
551
- $project: {
552
- clientName: 1,
553
- },
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,
554
568
  },
555
- ], as: 'client',
556
- },
557
- },
558
- {
559
- $unwind: { path: '$client', preserveNullAndEmptyArrays: true },
560
- },
561
- {
562
- $project: {
563
- clientName: '$client.clientName',
564
- storeId: 1,
565
- clientId: 1,
566
- storeName: 1,
567
- status: 1,
568
- createdAt: 1,
569
- },
570
- },
569
+ },
571
570
  );
572
571
  }
572
+
573
573
  let result;
574
574
  if ( req.body.infrafilterIssue == 'Live Stores' || req.body.infrafilterIssue == 'Total Stores' ) {
575
575
  result = await aggregateStore( storesQuery );
@@ -577,30 +577,30 @@ export async function infraIssuesTable( req, res ) {
577
577
  result = await aggregateTangoTicket( query );
578
578
  }
579
579
  if ( req.body.export && result.length > 0 ) {
580
- const exportdata = [];
581
- result.forEach( ( element ) => {
582
- if ( req.body.infrafilterIssue == 'Live Stores' || req.body.infrafilterIssue == 'Total Stores' ) {
583
- exportdata.push( {
580
+ const exportdata = result.map( ( element ) => {
581
+ if ( req.body.infrafilterIssue === 'Live Stores' || req.body.infrafilterIssue === 'Total Stores' ) {
582
+ return {
584
583
  'Created On': element.createdAt,
585
584
  'StoreID': element.storeId,
586
585
  'StoreName': element.storeName,
587
586
  'Status': element.status,
588
- } );
587
+ };
589
588
  } else {
590
- exportdata.push( {
589
+ return {
591
590
  'Created On': element.createdAt,
592
591
  'StoreID': element.storeId,
593
592
  'StoreName': element.storeName,
594
593
  'Primary Issue': element.primaryIssue,
595
594
  'Sub Issue': element.secondaryIssue,
596
- 'Issue Identified on': element.issueIdentifiedDate? dayjs( element.issueIdentifiedDate ).tz( 'Asia/Kolkata' ).format( 'YYYY-MM-DD HH:mm A' ):'',
595
+ 'Issue Identified on': element.issueIdentifiedDate ? dayjs( element.issueIdentifiedDate ).tz( 'Asia/Kolkata' ).format( 'YYYY-MM-DD HH:mm A' ) : '',
597
596
  'Status': element.status,
598
- } );
597
+ };
599
598
  }
600
599
  } );
601
600
  await download( exportdata, res );
602
601
  return;
603
602
  }
603
+
604
604
  if ( result.length > 0 ) {
605
605
  res.sendSuccess( {
606
606
  count: count.length,
@@ -1006,110 +1006,155 @@ function generateTimeSlots( startHour, endHour, interval, time ) {
1006
1006
  };
1007
1007
  export async function hourWiseDownstores( req, res ) {
1008
1008
  try {
1009
- let inputData = req.body;
1010
- inputData.Date = dayjs( req.body.toDate ).format( 'YYYY-MM-DD' );
1011
- let issueStatus = [ 'identified' ];
1012
- if ( req.body.filterIssue == 'Issues Not Identified' ) {
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' ) {
1013
1013
  issueStatus = [ 'notidentified' ];
1014
1014
  };
1015
- if ( req.body.filterIssue == 'All Issues' ) {
1016
- issueStatus = [ 'notidentified', 'identified' ];
1017
- };
1018
- if ( req.body.filterIssue == 'Live Stores' ) {
1019
- issueStatus = [ 'notidentified', 'identified' ];
1015
+ if ( req.body.infrafilterIssue == 'Identified Issues' ) {
1016
+ issueStatus = [ 'identified' ];
1020
1017
  };
1021
1018
 
1019
+
1022
1020
  let totalstores = await aggregateStore( [ {
1023
1021
  $match: {
1024
1022
  '$and': [
1025
- { 'clientId': req.body.clientId },
1023
+ { 'clientId': { $in: req.body.clientId } },
1026
1024
  { 'status': 'active' },
1027
- { 'createdAt': { $lte: new Date( req.body.toDate ) } },
1025
+ { 'createdAt': { $lte: date.end } },
1028
1026
  ],
1029
1027
  },
1030
1028
  } ] );
1031
-
1032
1029
  let totalnumberstores = [];
1033
1030
  for ( let store of totalstores ) {
1034
1031
  totalnumberstores.push( store.storeId );
1035
1032
  }
1036
- let query = [ {
1033
+ let pendingquery = [];
1034
+ pendingquery.push( {
1037
1035
  $match: {
1038
1036
  $and: [
1039
- { 'basicDetails.clientId': req.body.clientId },
1040
- { 'basicDetails.storeId': { $in: totalnumberstores } },
1037
+ { issueType: 'installation' },
1041
1038
  { 'status': { $ne: 'closed' } },
1042
- { issueType: 'infra' },
1043
- { 'ticketDetails.issueStatus': { $in: issueStatus } },
1044
- { 'issueDate': { $lte: new Date( req.body.toDate ) } },
1039
+ { 'basicDetails.clientId': { $in: req.body.clientId } },
1040
+ { createdAt: { $lte: date.end } },
1045
1041
  ],
1046
1042
  },
1047
- },
1048
- {
1049
- $project: {
1050
- storeId: '$basicDetails.storeId',
1051
- storeName: '$basicDetails.storeName',
1052
- primaryIssue: {
1053
- $filter: {
1054
- input: '$ticketActivity',
1055
- as: 'item',
1056
- cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
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
+ },
1057
1078
  },
1058
1079
  },
1059
1080
  },
1060
- },
1061
- {
1062
- $unwind: {
1063
- path: '$primaryIssue', preserveNullAndEmptyArrays: true,
1081
+ {
1082
+ $unwind: {
1083
+ path: '$primaryIssue',
1084
+ preserveNullAndEmptyArrays: true,
1085
+ },
1064
1086
  },
1065
- },
1066
- {
1067
- $unwind: {
1068
- path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
1087
+ {
1088
+ $unwind: {
1089
+ path: '$primaryIssue.reasons',
1090
+ preserveNullAndEmptyArrays: true,
1091
+ },
1069
1092
  },
1070
- },
1071
- {
1072
- $project: {
1073
- storeId: 1,
1074
- storeName: 1,
1075
- primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', 'NotIdentified' ] },
1093
+ {
1094
+ $unwind: {
1095
+ path: '$primaryIssue.reasons.secondaryIssue',
1096
+ preserveNullAndEmptyArrays: true,
1097
+ },
1076
1098
  },
1077
- },
1078
- {
1079
- $group: {
1080
- _id: '$storeId',
1081
- storeId: { $first: '$storeId' },
1082
- storeName: { $first: '$storeName' },
1083
- primaryIssue: { $last: '$primaryIssue' },
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
+ },
1084
1131
  },
1085
- },
1086
1132
  ];
1133
+
1087
1134
  let storesQuery = [];
1088
- if ( req.body.filterIssue == 'Total Stores' ) {
1135
+ if ( req.body.infrafilterIssue == 'Total Stores' ) {
1089
1136
  storesQuery.push( {
1090
1137
  $match: {
1091
1138
  '$and': [
1092
- { 'clientId': req.body.clientId },
1093
- { 'edge.firstFile': true },
1139
+ { 'clientId': { $in: req.body.clientId } },
1094
1140
  { 'status': 'active' },
1095
- { 'createdAt': { $lte: new Date( req.body.toDate ) } },
1141
+ { 'storeId': { $nin: installpendingticket } },
1142
+ { 'createdAt': { $lte: date.end } },
1096
1143
  ],
1097
1144
  },
1098
1145
  },
1099
1146
  );
1100
1147
  }
1101
- if ( req.body.filterIssue == 'Live Stores' ) {
1148
+ if ( req.body.infrafilterIssue == 'Live Stores' ) {
1102
1149
  let infrastores = await aggregateTangoTicket( query );
1103
- let infraissueStore = [];
1104
- for ( let store of infrastores ) {
1105
- infraissueStore.push( store.storeId );
1106
- }
1107
- let result = [];
1108
- for ( let data of totalnumberstores ) {
1109
- if ( infraissueStore.length > 0 && !infraissueStore.includes( data ) ) {
1110
- result.push( data );
1111
- }
1112
- }
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
+
1113
1158
  storesQuery.push(
1114
1159
  {
1115
1160
  $match: {
@@ -1120,71 +1165,116 @@ export async function hourWiseDownstores( req, res ) {
1120
1165
  },
1121
1166
  );
1122
1167
  }
1123
- if ( req.body.searchValue && req.body.searchValue !== '' ) {
1168
+ const excludedIssues = [ 'Identified Issues', 'Issues Not Identified', 'All Issues' ];
1169
+ if ( req.body.infrafilterIssue && !excludedIssues.includes( req.body.infrafilterIssue ) ) {
1124
1170
  query.push( {
1125
1171
  $match: {
1126
- $or: [
1127
- { storeName: { $regex: req.body.searchValue, $options: 'i' } },
1128
- { storeId: { $regex: req.body.searchValue, $options: 'i' } },
1129
- ],
1172
+ primaryIssue: req.body.infrafilterIssue,
1130
1173
  },
1131
1174
  } );
1132
- storesQuery.push( {
1175
+ }
1176
+
1177
+ if ( req.body.searchValue && req.body.searchValue !== '' ) {
1178
+ const searchCondition = {
1133
1179
  $match: {
1134
1180
  $or: [
1135
- { storeName: { $regex: req.body.searchValue, $options: 'i' } },
1136
1181
  { storeId: { $regex: req.body.searchValue, $options: 'i' } },
1182
+ { storeName: { $regex: req.body.searchValue, $options: 'i' } },
1137
1183
  ],
1138
1184
  },
1139
- } );
1185
+ };
1186
+
1187
+ query.push( searchCondition );
1188
+ storesQuery.push( searchCondition );
1140
1189
  }
1141
- if ( req.body.sortColumName && req.body.sortColumName != '' && req.body.sortBy && req.body.sortBy != '' ) {
1142
- query.push( {
1143
- $sort: { [req.body.sortColumName]: req.body.sortBy },
1144
- } );
1145
- storesQuery.push( {
1146
- $sort: { [req.body.sortColumName]: req.body.sortBy },
1147
- } );
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
+ );
1148
1199
  }
1149
- if ( req.body.filterIssue && req.body.filterIssue != '' &&
1150
- req.body.filterIssue != 'Identified Issues' &&
1151
- req.body.filterIssue != 'Issues Not Identified' &&
1152
- req.body.filterIssue != 'All Issues' ) {
1153
- query.push( {
1154
- $match: {
1155
- primaryIssue: req.body.filterIssue,
1156
- },
1157
- } );
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 );
1158
1208
  }
1159
-
1160
1209
  let count;
1161
- if ( req.body.filterIssue == 'Live Stores' || req.body.filterIssue == 'Total Stores' ) {
1210
+ if ( req.body.infrafilterIssue == 'Live Stores' || req.body.infrafilterIssue == 'Total Stores' ) {
1162
1211
  count = await aggregateStore( storesQuery );
1163
1212
  } else {
1164
1213
  count = await aggregateTangoTicket( query );
1165
1214
  }
1166
1215
  if ( req.body.limit && req.body.offset && !req.body.export ) {
1167
- query.push(
1168
- { $skip: ( req.body.offset - 1 ) * req.body.limit },
1169
- { $limit: Number( req.body.limit ) },
1170
- );
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 );
1171
1225
  storesQuery.push(
1172
- { $skip: ( req.body.offset - 1 ) * req.body.limit },
1173
- { $limit: Number( req.body.limit ) },
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
+ },
1174
1263
  );
1175
1264
  }
1265
+
1176
1266
  let storesList;
1177
- if ( req.body.filterIssue == 'Live Stores' || req.body.filterIssue == 'Total Stores' ) {
1267
+ if ( req.body.infrafilterIssue == 'Live Stores' || req.body.infrafilterIssue == 'Total Stores' ) {
1178
1268
  storesList = await aggregateStore( storesQuery );
1179
1269
  } else {
1180
1270
  storesList = await aggregateTangoTicket( query );
1181
1271
  }
1182
-
1183
1272
  if ( storesList.length == 0 ) {
1184
1273
  return res.sendError( 'no data', 204 );
1185
1274
  }
1186
1275
  let data = {};
1187
1276
  let result = [];
1277
+ let inputData = req.body;
1188
1278
  for ( const store of storesList ) {
1189
1279
  data.storeId = store.storeId;
1190
1280
  data.storeName = store.storeName;
@@ -1203,82 +1293,64 @@ export async function hourWiseDownstores( req, res ) {
1203
1293
  }
1204
1294
  }
1205
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
+ } ) );
1206
1304
 
1207
- function downStoresCheck( data, inputData ) {
1208
- return new Promise( async ( Resolve, Reject ) => {
1209
- try {
1210
- let TimeSlots = generateTimeSlots( 8, 22, 60, inputData.Date );
1211
- let timewise = [];
1212
- for ( const obj of TimeSlots ) {
1213
- obj.startTime = dayjs( obj.from ).format( 'hh:mm A' );
1214
- obj.endTime = dayjs( obj.to ).format( 'hh:mm A' );
1215
- const downTime = await getOpenSearchData( JSON.parse( process.env.OPENSEARCH ).downTimeHourly,
1216
- {
1217
- 'size': 1,
1218
- 'query': {
1219
- 'bool': {
1220
- 'must': [
1221
- {
1222
- 'term': {
1223
- 'doc.date.keyword': dayjs( inputData.Date ).format( 'DD-MM-YYYY' ),
1224
- },
1225
- },
1226
- {
1227
- 'term': {
1228
- 'doc.store_id.keyword': data.storeId,
1229
- },
1230
- },
1231
- {
1232
- 'terms': {
1233
- 'doc.hour.keyword': [ obj.hour ],
1234
- },
1235
- },
1236
- ],
1237
-
1238
- },
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
+ ],
1239
1317
  },
1318
+ },
1319
+ },
1320
+ );
1240
1321
 
1241
- } );
1242
- let streamwiseDowntime = downTime.body.hits.hits.length > 0 ? downTime.body.hits.hits[0]._source.doc.streamwise_downtime : [];
1243
- if ( streamwiseDowntime.length > 0 ) {
1244
- const sum = streamwiseDowntime.reduce( ( accumulator, currentValue ) => {
1245
- return accumulator + currentValue.down_time;
1246
- }, 0 );
1247
-
1248
- // Calculate the average
1249
- const average = sum / streamwiseDowntime.length;
1250
- obj[obj.startTime + '-' + obj.endTime] = Math.round( average );
1251
- } else {
1252
- obj[obj.startTime + '-' + obj.endTime] = '';
1253
- }
1322
+ const streamwiseDowntime = downTime.body.hits.hits.length > 0 ?
1323
+ downTime.body.hits.hits[0]._source.doc.streamwise_downtime :
1324
+ [];
1254
1325
 
1255
- timewise.push( obj );
1256
- }
1257
- const mergedData = {
1258
- storeName: data.storeName,
1259
- storeId: data.storeId,
1260
- PrimaryIssue: data.primaryIssue,
1261
- };
1262
- timewise.forEach( ( obj ) => {
1263
- for ( const key in obj ) {
1264
- if ( key !== 'hour' && key !== 'from' && key !== 'to' && key !== 'startTime' && key !== 'endTime' && key !== 'clientId' ) {
1265
- if ( mergedData[key] ) {
1266
- mergedData[key] += obj[key];
1267
- } else {
1268
- mergedData[key] = obj[key];
1269
- }
1270
- }
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;
1271
1339
  }
1272
- } );
1340
+ }
1341
+ return acc;
1342
+ }, {
1343
+ storeName: data.storeName,
1344
+ storeId: data.storeId,
1345
+ PrimaryIssue: data.primaryIssue,
1346
+ } );
1273
1347
 
1274
- // Create an array with the merged data.
1275
- const mergedArray = [ mergedData ];
1276
- Resolve( mergedArray );
1277
- } catch ( err ) {
1278
- Reject( err );
1279
- }
1280
- } );
1348
+ return [ mergedData ];
1349
+ } catch ( err ) {
1350
+ throw err;
1351
+ }
1281
1352
  }
1353
+
1282
1354
  export async function ticketCountSplit( req, res ) {
1283
1355
  try {
1284
1356
  const inputData = req.body;