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.
@@ -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 == 'All Issues' ) {
322
- issueStatus = [ 'notidentified', 'identified' ];
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 query = [ {
340
+ let pendingquery = [];
341
+ pendingquery.push( {
342
342
  $match: {
343
343
  $and: [
344
- { issueType: 'infra' },
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
- $project: {
356
- storeId: '$basicDetails.storeId',
357
- clientId: '$basicDetails.clientId',
358
- ticketId: 1,
359
- storeName: '$basicDetails.storeName',
360
- clientName: '$basicDetails.clientName',
361
- status: 1,
362
- createdAt: 1,
363
- issueIdentifiedDate: '$ticketDetails.issueIdentifiedDate',
364
- issueClosedDate: '$issueClosedDate',
365
- primaryIssue: {
366
- $filter: {
367
- input: '$ticketActivity',
368
- as: 'item',
369
- cond: { $eq: [ '$$item.actionType', 'issueUpdate' ] },
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
- $unwind: {
376
- path: '$primaryIssue', preserveNullAndEmptyArrays: true,
388
+ {
389
+ $unwind: {
390
+ path: '$primaryIssue',
391
+ preserveNullAndEmptyArrays: true,
392
+ },
377
393
  },
378
- },
379
- {
380
- $unwind: {
381
- path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
394
+ {
395
+ $unwind: {
396
+ path: '$primaryIssue.reasons',
397
+ preserveNullAndEmptyArrays: true,
398
+ },
382
399
  },
383
- },
384
- {
385
- $unwind: {
386
- path: '$primaryIssue.reasons.secondaryIssue', preserveNullAndEmptyArrays: true,
400
+ {
401
+ $unwind: {
402
+ path: '$primaryIssue.reasons.secondaryIssue',
403
+ preserveNullAndEmptyArrays: true,
404
+ },
387
405
  },
388
- },
389
- {
390
- $project: {
391
- storeId: 1,
392
- clientId: 1,
393
- storeName: 1,
394
- createdAt: 1,
395
- ticketId: 1,
396
- clientName: 1,
397
- actionBy: '$primaryIssue.actionBy',
398
- issueIdentifiedDate: { $ifNull: [ '$issueIdentifiedDate', '' ] },
399
- issueClosedDate: { $ifNull: [ '$issueClosedDate', '' ] },
400
- status: 1,
401
- primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '-' ] },
402
- 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
+ },
403
421
  },
404
- },
405
- {
406
- $group: {
407
- _id: '$ticketId',
408
- storeId: { $first: '$storeId' },
409
- clientId: { $first: '$clientId' },
410
- ticketId: { $first: '$ticketId' },
411
- actionBy: { $first: '$actionBy' },
412
- storeName: { $first: '$storeName' },
413
- clientName: { $first: '$clientName' },
414
- createdAt: { $first: '$createdAt' },
415
- issueIdentifiedDate: { $last: '$issueIdentifiedDate' },
416
- issueClosedDate: { $last: '$issueClosedDate' },
417
- status: { $last: '$status' },
418
- primaryIssue: { $last: '$primaryIssue' },
419
- 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
+ },
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
- for ( let store of infrastores ) {
441
- infraissueStore.push( store.storeId );
442
- }
443
- let result = [];
444
- for ( let data of totalnumberstores ) {
445
- if ( infraissueStore.length > 0 && !infraissueStore.includes( data ) ) {
446
- result.push( data );
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
- if ( req.body.infrafilterIssue && req.body.infrafilterIssue != '' &&
460
- req.body.infrafilterIssue != 'Identified Issues' &&
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
- if ( req.body.searchValue && req.body.searchValue != '' ) {
470
- query.push( {
471
- $match: {
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
- query.push( {
498
- $sort: { [req.body.sortColumName]: req.body.sortBy },
499
- } );
500
- storesQuery.push( {
501
- $sort: { [req.body.sortColumName]: req.body.sortBy },
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
- query.push(
512
- { $skip: ( req.body.offset - 1 ) * req.body.limit },
513
- { $limit: Number( req.body.limit ) },
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
- { $skip: ( req.body.offset - 1 ) * req.body.limit },
517
- { $limit: Number( req.body.limit ) },
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
- result.forEach( ( element ) => {
529
- exportdata.push( {
530
- 'Created On': element.createdAt,
531
- 'StoreID': element.storeId,
532
- 'StoreName': element.storeName,
533
- 'Primary Issue': element.primaryIssue,
534
- 'Sub Issue': element.secondaryIssue,
535
- 'Issue Identified on': element.issueIdentifiedDate? dayjs( element.issueIdentifiedDate ).tz( 'Asia/Kolkata' ).format( 'YYYY-MM-DD HH:mm A' ):'',
536
- 'Status': element.status,
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 inputData = req.body;
948
- inputData.Date = dayjs( req.body.toDate ).format( 'YYYY-MM-DD' );
949
- let issueStatus = [ 'identified' ];
950
- 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' ) {
951
1013
  issueStatus = [ 'notidentified' ];
952
1014
  };
953
- if ( req.body.filterIssue == 'All Issues' ) {
954
- issueStatus = [ 'notidentified', 'identified' ];
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: new Date( req.body.toDate ) } },
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 query = [ {
1033
+ let pendingquery = [];
1034
+ pendingquery.push( {
976
1035
  $match: {
977
1036
  $and: [
978
- { 'basicDetails.clientId': req.body.clientId },
979
- { 'basicDetails.storeId': { $in: totalnumberstores } },
1037
+ { issueType: 'installation' },
980
1038
  { 'status': { $ne: 'closed' } },
981
- { issueType: 'infra' },
982
- { 'ticketDetails.issueStatus': { $in: issueStatus } },
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
- $project: {
989
- storeId: '$basicDetails.storeId',
990
- storeName: '$basicDetails.storeName',
991
- primaryIssue: {
992
- $filter: {
993
- input: '$ticketActivity',
994
- as: 'item',
995
- 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
+ },
996
1078
  },
997
1079
  },
998
1080
  },
999
- },
1000
- {
1001
- $unwind: {
1002
- path: '$primaryIssue', preserveNullAndEmptyArrays: true,
1081
+ {
1082
+ $unwind: {
1083
+ path: '$primaryIssue',
1084
+ preserveNullAndEmptyArrays: true,
1085
+ },
1003
1086
  },
1004
- },
1005
- {
1006
- $unwind: {
1007
- path: '$primaryIssue.reasons', preserveNullAndEmptyArrays: true,
1087
+ {
1088
+ $unwind: {
1089
+ path: '$primaryIssue.reasons',
1090
+ preserveNullAndEmptyArrays: true,
1091
+ },
1008
1092
  },
1009
- },
1010
- {
1011
- $project: {
1012
- storeId: 1,
1013
- storeName: 1,
1014
- primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', 'NotIdentified' ] },
1093
+ {
1094
+ $unwind: {
1095
+ path: '$primaryIssue.reasons.secondaryIssue',
1096
+ preserveNullAndEmptyArrays: true,
1097
+ },
1015
1098
  },
1016
- },
1017
- {
1018
- $group: {
1019
- _id: '$storeId',
1020
- storeId: { $first: '$storeId' },
1021
- storeName: { $first: '$storeName' },
1022
- 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
+ },
1023
1131
  },
1024
- },
1025
1132
  ];
1133
+
1026
1134
  let storesQuery = [];
1027
- if ( req.body.filterIssue == 'Total Stores' ) {
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
- { 'createdAt': { $lte: new Date( req.body.toDate ) } },
1141
+ { 'storeId': { $nin: installpendingticket } },
1142
+ { 'createdAt': { $lte: date.end } },
1035
1143
  ],
1036
1144
  },
1037
1145
  },
1038
1146
  );
1039
1147
  }
1040
- if ( req.body.filterIssue == 'Live Stores' ) {
1148
+ if ( req.body.infrafilterIssue == 'Live Stores' ) {
1041
1149
  let infrastores = await aggregateTangoTicket( query );
1042
- let infraissueStore = [];
1043
- for ( let store of infrastores ) {
1044
- infraissueStore.push( store.storeId );
1045
- }
1046
- let result = [];
1047
- for ( let data of totalnumberstores ) {
1048
- if ( infraissueStore.length > 0 && !infraissueStore.includes( data ) ) {
1049
- result.push( data );
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
- 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 ) ) {
1063
1170
  query.push( {
1064
1171
  $match: {
1065
- $or: [
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
- storesQuery.push( {
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
- if ( req.body.sortColumName && req.body.sortColumName != '' && req.body.sortBy && req.body.sortBy != '' ) {
1081
- query.push( {
1082
- $sort: { [req.body.sortColumName]: req.body.sortBy },
1083
- } );
1084
- storesQuery.push( {
1085
- $sort: { [req.body.sortColumName]: req.body.sortBy },
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.filterIssue && req.body.filterIssue != '' &&
1089
- req.body.filterIssue != 'Identified Issues' &&
1090
- req.body.filterIssue != 'Issues Not Identified' &&
1091
- req.body.filterIssue != 'All Issues' ) {
1092
- query.push( {
1093
- $match: {
1094
- primaryIssue: req.body.filterIssue,
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.filterIssue == 'Live Stores' || req.body.filterIssue == 'Total Stores' ) {
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
- query.push(
1107
- { $skip: ( req.body.offset - 1 ) * req.body.limit },
1108
- { $limit: Number( req.body.limit ) },
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
- { $skip: ( req.body.offset - 1 ) * req.body.limit },
1112
- { $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
+ },
1113
1263
  );
1114
1264
  }
1265
+
1115
1266
  let storesList;
1116
- if ( req.body.filterIssue == 'Live Stores' || req.body.filterIssue == 'Total Stores' ) {
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
- function downStoresCheck( data, inputData ) {
1147
- return new Promise( async ( Resolve, Reject ) => {
1148
- try {
1149
- let TimeSlots = generateTimeSlots( 8, 22, 60, inputData.Date );
1150
- let timewise = [];
1151
- for ( const obj of TimeSlots ) {
1152
- obj.startTime = dayjs( obj.from ).format( 'hh:mm A' );
1153
- obj.endTime = dayjs( obj.to ).format( 'hh:mm A' );
1154
- const downTime = await getOpenSearchData( JSON.parse( process.env.OPENSEARCH ).downTimeHourly,
1155
- {
1156
- 'size': 1,
1157
- 'query': {
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
- let streamwiseDowntime = downTime.body.hits.hits.length > 0 ? downTime.body.hits.hits[0]._source.doc.streamwise_downtime : [];
1182
- if ( streamwiseDowntime.length > 0 ) {
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
- timewise.push( obj );
1195
- }
1196
- const mergedData = {
1197
- storeName: data.storeName,
1198
- storeId: data.storeId,
1199
- PrimaryIssue: data.primaryIssue,
1200
- };
1201
- timewise.forEach( ( obj ) => {
1202
- for ( const key in obj ) {
1203
- if ( key !== 'hour' && key !== 'from' && key !== 'to' && key !== 'startTime' && key !== 'endTime' && key !== 'clientId' ) {
1204
- if ( mergedData[key] ) {
1205
- mergedData[key] += obj[key];
1206
- } else {
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
- // Create an array with the merged data.
1214
- const mergedArray = [ mergedData ];
1215
- Resolve( mergedArray );
1216
- } catch ( err ) {
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;