tango-app-api-infra 3.9.1 → 3.9.3

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 CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "tango-app-api-infra",
3
- "version": "3.9.1",
3
+ "version": "3.9.3",
4
4
  "description": "infra",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "scripts": {
8
- "start": "nodemon --exec \"eslint --fix . && node app.js\""
8
+ "start": "nodemon --exec \"eslint --fix . && node index.js\""
9
9
  },
10
10
  "engines": {
11
11
  "node": ">=18.10.0"
@@ -15,9 +15,9 @@ import { countDocumentsClusters } from '../services/cluster.service.js';
15
15
  export async function infraCard( req, res ) {
16
16
  try {
17
17
  let date = await getUTC( new Date( req.body.fromDate ), new Date( req.body.toDate ) );
18
- let storecountQuery ={ 'clientId': { $in: req.body.clientId }, 'createdAt': { $lte: date.end }, 'status': 'active' };
18
+ let storecountQuery = { 'clientId': { $in: req.body.clientId }, 'createdAt': { $lte: date.end }, 'status': 'active' };
19
19
 
20
- if ( req.user&&req.user.userType ==='client'&&req.user.role!='superadmin' ) {
20
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
21
21
  storecountQuery = { ...storecountQuery, ...{ storeId: { $in: req.body.assignedStores } } };
22
22
  }
23
23
 
@@ -39,7 +39,7 @@ export async function infraCard( req, res ) {
39
39
  },
40
40
  ];
41
41
 
42
- if ( req.user&&req.user.userType ==='client'&&req.user.role!='superadmin' ) {
42
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
43
43
  yetToInstallQuery.push(
44
44
  {
45
45
  $match: {
@@ -49,8 +49,8 @@ export async function infraCard( req, res ) {
49
49
  );
50
50
  }
51
51
  let yettoInstallCount = await aggregateTangoTicket( yetToInstallQuery );
52
- storeCount = storeCount-yettoInstallCount.length;
53
- let totalStoreQuery =[ {
52
+ storeCount = storeCount - yettoInstallCount.length;
53
+ let totalStoreQuery = [ {
54
54
  $match: {
55
55
  '$and': [
56
56
  { 'clientId': { $in: req.body.clientId } },
@@ -59,7 +59,7 @@ export async function infraCard( req, res ) {
59
59
  ],
60
60
  },
61
61
  } ];
62
- if ( req.user&&req.user.userType ==='client'&&req.user.role!='superadmin' ) {
62
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
63
63
  totalStoreQuery.push(
64
64
  {
65
65
  $match: {
@@ -210,18 +210,18 @@ export async function infraCard( req, res ) {
210
210
  } );
211
211
  response.unshift( {
212
212
  name: 'All Issues',
213
- count: infraStoreCount.length > 0 ? req.body.filter && req.body.filter.length > 0?ticketList.length:( infraStoreCount[0].notidentifiedcount+ticketList.length ): 0,
213
+ count: infraStoreCount.length > 0 ? req.body.filter && req.body.filter.length > 0 ? ticketList.length : ( infraStoreCount[0].notidentifiedcount + ticketList.length ) : 0,
214
214
  } );
215
215
  response.push( {
216
216
  name: 'Issues Not Identified',
217
- count: infraStoreCount.length > 0 ?( req.body.filter && req.body.filter.length > 0 )?0: infraStoreCount[0].notidentifiedcount : 0,
217
+ count: infraStoreCount.length > 0 ? ( req.body.filter && req.body.filter.length > 0 ) ? 0 : infraStoreCount[0].notidentifiedcount : 0,
218
218
  } );
219
219
  res.sendSuccess( {
220
220
  total: storeCount,
221
221
  liveStoreCount: infraStoreCount.length > 0 ? storeCount - infraStoreCount[0].infraCount : storeCount,
222
- infraStoreCount: infraStoreCount.length > 0 ? infraStoreCount[0].notidentifiedcount+ticketList.length : 0,
222
+ infraStoreCount: infraStoreCount.length > 0 ? infraStoreCount[0].notidentifiedcount + ticketList.length : 0,
223
223
  identifiedcount: infraStoreCount.length > 0 ? ticketList.length : 0,
224
- notidentifiedcount: infraStoreCount.length > 0 ?( req.body.filter && req.body.filter.length > 0 )?0: infraStoreCount[0].notidentifiedcount : 0,
224
+ notidentifiedcount: infraStoreCount.length > 0 ? ( req.body.filter && req.body.filter.length > 0 ) ? 0 : infraStoreCount[0].notidentifiedcount : 0,
225
225
  infraIssues: response,
226
226
  } );
227
227
  } catch ( error ) {
@@ -238,7 +238,7 @@ export async function installationCard( req, res ) {
238
238
  };
239
239
 
240
240
 
241
- if ( req.user&&req.user.userType ==='client'&&req.user.role!='superadmin' ) {
241
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
242
242
  baseQuery = { ...baseQuery, ...{ storeId: { $in: req.body.assignedStores } } };
243
243
  }
244
244
  let onboardQuery = { ...baseQuery };
@@ -264,7 +264,7 @@ export async function installationCard( req, res ) {
264
264
  },
265
265
  },
266
266
  ];
267
- if ( req.user&&req.user.userType ==='client'&&req.user.role!='superadmin' ) {
267
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
268
268
  ticketbaseQuery.push(
269
269
  {
270
270
  $match: {
@@ -350,8 +350,8 @@ export async function installationCard( req, res ) {
350
350
  res.sendSuccess( {
351
351
  onboardedStoresCount: onboardedCount,
352
352
  inactiveStoresCount: deactiveCount,
353
- installedStoresCount: installedCount-yettoInstallCount.length,
354
- yettoInstallCount: yettoInstallCount.length-installFailedCount.length,
353
+ installedStoresCount: installedCount - yettoInstallCount.length,
354
+ yettoInstallCount: yettoInstallCount.length - installFailedCount.length,
355
355
  installFailedCount: installFailedCount.length,
356
356
  infraIssues: response,
357
357
  } );
@@ -381,7 +381,7 @@ export async function infraIssuesTable( req, res ) {
381
381
  ],
382
382
  },
383
383
  } ];
384
- if ( req.user&&req.user.userType ==='client'&&req.user.role!='superadmin' ) {
384
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
385
385
  totalStoreQuery.push(
386
386
  {
387
387
  $match: {
@@ -406,7 +406,7 @@ export async function infraIssuesTable( req, res ) {
406
406
  ],
407
407
  },
408
408
  } );
409
- if ( req.user&&req.user.userType ==='client'&&req.user.role!='superadmin' ) {
409
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
410
410
  pendingquery.push(
411
411
  {
412
412
  $match: {
@@ -443,6 +443,13 @@ export async function infraIssuesTable( req, res ) {
443
443
  createdAt: 1,
444
444
  issueIdentifiedDate: '$ticketDetails.issueIdentifiedDate',
445
445
  issueClosedDate: '$issueClosedDate',
446
+ otherscomment: {
447
+ $filter: {
448
+ input: '$ticketActivity',
449
+ as: 'item',
450
+ cond: { $eq: [ '$$item.actionType', 'comment' ] },
451
+ },
452
+ },
446
453
  primaryIssue: {
447
454
  $filter: {
448
455
  input: '$ticketActivity',
@@ -452,6 +459,11 @@ export async function infraIssuesTable( req, res ) {
452
459
  },
453
460
  },
454
461
  },
462
+ {
463
+ $unwind: {
464
+ path: '$otherscomment', preserveNullAndEmptyArrays: true,
465
+ },
466
+ },
455
467
  {
456
468
  $unwind: {
457
469
  path: '$primaryIssue',
@@ -478,6 +490,8 @@ export async function infraIssuesTable( req, res ) {
478
490
  createdAt: 1,
479
491
  ticketId: 1,
480
492
  clientName: 1,
493
+ commentText: { $ifNull: [ '$primaryIssue.comment', '-' ] },
494
+ otherscomment: { $ifNull: [ '$otherscomment.comment', '-' ] },
481
495
  issueIdentifiedBy: { $ifNull: [ '$primaryIssue.actionBy', '' ] },
482
496
  issueIdentifiedDate: { $ifNull: [ '$issueIdentifiedDate', '' ] },
483
497
  issueClosedDate: { $ifNull: [ '$issueClosedDate', '' ] },
@@ -501,6 +515,7 @@ export async function infraIssuesTable( req, res ) {
501
515
  status: { $last: '$status' },
502
516
  primaryIssue: { $last: '$primaryIssue' },
503
517
  secondaryIssue: { $last: '$secondaryIssue' },
518
+ commentText: { $last: '$commentText' },
504
519
  },
505
520
  },
506
521
  ];
@@ -539,7 +554,7 @@ export async function infraIssuesTable( req, res ) {
539
554
  },
540
555
  );
541
556
 
542
- if ( infraissueStore&&infraissueStore.length==0 ) {
557
+ if ( infraissueStore && infraissueStore.length == 0 ) {
543
558
  storesQuery = [ {
544
559
  $match: {
545
560
  '$and': [
@@ -552,7 +567,7 @@ export async function infraIssuesTable( req, res ) {
552
567
  } ];
553
568
  }
554
569
  }
555
- if ( req.user&&req.user.userType ==='client'&&req.user.role!='superadmin' ) {
570
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
556
571
  storesQuery.push(
557
572
  {
558
573
  $match: {
@@ -682,10 +697,12 @@ export async function infraIssuesTable( req, res ) {
682
697
  'Created On': dayjs( element.createdAt ).format( 'DD MMM, YYYY' ),
683
698
  'StoreID': element.storeId,
684
699
  'StoreName': element.storeName,
700
+ 'clientName': element.clientName,
685
701
  'Primary Issue': element.primaryIssue,
686
702
  'Sub Issue': element.secondaryIssue,
687
703
  'Issue Identified on': element.issueIdentifiedDate ? dayjs( element.issueIdentifiedDate ).format( 'DD MMM, YYYY' ) : '',
688
704
  'Status': element.status,
705
+ 'Comment': element.otherscomment ? element.otherscomment : element.commentText,
689
706
  };
690
707
  }
691
708
  } );
@@ -720,7 +737,7 @@ export async function InstallationIssuesTable( req, res ) {
720
737
  ],
721
738
  },
722
739
  } );
723
- if ( req.user&&req.user.userType ==='client'&&req.user.role!='superadmin' ) {
740
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
724
741
  query.push(
725
742
  {
726
743
  $match: {
@@ -792,7 +809,7 @@ export async function InstallationIssuesTable( req, res ) {
792
809
  },
793
810
  );
794
811
  let storesQuery = [];
795
- if ( req.user&&req.user.userType ==='client'&&req.user.role!='superadmin' ) {
812
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
796
813
  storesQuery.push(
797
814
  {
798
815
  $match: {
@@ -1154,7 +1171,7 @@ export async function hourWiseDownstores( req, res ) {
1154
1171
  ],
1155
1172
  },
1156
1173
  } ];
1157
- if ( req.user&&req.user.userType ==='client' &&req.user.role!='superadmin' ) {
1174
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
1158
1175
  totalStoreQuery.push(
1159
1176
  {
1160
1177
  $match: {
@@ -1179,7 +1196,7 @@ export async function hourWiseDownstores( req, res ) {
1179
1196
  ],
1180
1197
  },
1181
1198
  } );
1182
- if ( req.user&&req.user.userType ==='client' &&req.user.role!='superadmin' ) {
1199
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
1183
1200
  pendingquery.push(
1184
1201
  {
1185
1202
  $match: {
@@ -1311,7 +1328,7 @@ export async function hourWiseDownstores( req, res ) {
1311
1328
  },
1312
1329
  },
1313
1330
  );
1314
- if ( infraissueStore&&infraissueStore.length==0 ) {
1331
+ if ( infraissueStore && infraissueStore.length == 0 ) {
1315
1332
  storesQuery = [ {
1316
1333
  $match: {
1317
1334
  '$and': [
@@ -1324,7 +1341,7 @@ export async function hourWiseDownstores( req, res ) {
1324
1341
  } ];
1325
1342
  }
1326
1343
  }
1327
- if ( req.user&&req.user.userType ==='client' ) {
1344
+ if ( req.user && req.user.userType === 'client' ) {
1328
1345
  storesQuery.push(
1329
1346
  {
1330
1347
  $match: {
@@ -1475,7 +1492,7 @@ async function downStoresCheck( data, inputData ) {
1475
1492
  startTime: dayjs( slot.from ).format( 'hh:mm A' ),
1476
1493
  endTime: dayjs( slot.to ).format( 'hh:mm A' ),
1477
1494
  } ) );
1478
- let Totaldowntime=0;
1495
+ let Totaldowntime = 0;
1479
1496
 
1480
1497
  const downTimePromises = formattedTimeSlots.map( async ( obj ) => {
1481
1498
  const downTime = await getOpenSearchData(
@@ -1500,7 +1517,7 @@ async function downStoresCheck( data, inputData ) {
1500
1517
  const average = streamwiseDowntime.length ?
1501
1518
  Math.round( streamwiseDowntime.reduce( ( acc, curr ) => acc + curr.down_time, 0 ) / streamwiseDowntime.length ) :
1502
1519
  '';
1503
- Totaldowntime= Number( Totaldowntime ) + Number( average );
1520
+ Totaldowntime = Number( Totaldowntime ) + Number( average );
1504
1521
  return { ...obj, [`${obj.startTime}-${obj.endTime}`]: average };
1505
1522
  } );
1506
1523
 
@@ -1538,7 +1555,7 @@ export async function ticketCountSplit( req, res ) {
1538
1555
  { issueType: { $in: [ 'highcount', 'lowcount' ] } },
1539
1556
 
1540
1557
  ];
1541
- if ( req.user&&req.user.userType ==='client'&&req.user.role!='superadmin' ) {
1558
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
1542
1559
  filter.push( { 'basicDetails.storeId': { $in: req.body.assignedStores } } );
1543
1560
  }
1544
1561
  if ( req.user.userType === 'client' ) {
@@ -1619,7 +1636,7 @@ export async function overViewTable( req, res ) {
1619
1636
  'basicDetails.clientId': { $in: inputData.clientId },
1620
1637
  },
1621
1638
  ];
1622
- if ( req.user&&req.user.userType ==='client' ) {
1639
+ if ( req.user && req.user.userType === 'client' ) {
1623
1640
  filter.push( { 'basicDetails.storeId': { $in: req.body.assignedStores } } );
1624
1641
  }
1625
1642
  if ( req.user.userType === 'client' ) {
@@ -1630,7 +1647,7 @@ export async function overViewTable( req, res ) {
1630
1647
  issueType: { $in: inputData.issueType },
1631
1648
  } );
1632
1649
  }
1633
- if ( inputData?.status && inputData?.status!='' ) {
1650
+ if ( inputData?.status && inputData?.status != '' ) {
1634
1651
  filter.push( {
1635
1652
  status: inputData?.status,
1636
1653
  } );
@@ -1670,7 +1687,8 @@ export async function overViewTable( req, res ) {
1670
1687
  if ( inputData.sortColumnName ) {
1671
1688
  const sortBy = inputData.sortBy || -1;
1672
1689
  query.push( {
1673
- $sort: { [inputData.sortColumnName]: sortBy,
1690
+ $sort: {
1691
+ [inputData.sortColumnName]: sortBy,
1674
1692
  },
1675
1693
  } );
1676
1694
  }
@@ -1717,7 +1735,7 @@ export async function ticketCount( req, res ) {
1717
1735
  },
1718
1736
 
1719
1737
  ];
1720
- if ( req.user&&req.user.userType ==='client' &&req.user.role!='superadmin' ) {
1738
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
1721
1739
  filter.push( { 'basicDetails.storeId': { $in: req.body.assignedStores } } );
1722
1740
  }
1723
1741
  if ( req.user.userType === 'client' ) {
@@ -1783,7 +1801,7 @@ export async function ticketCount( req, res ) {
1783
1801
  };
1784
1802
  export async function checkPermission( req, res, next ) {
1785
1803
  try {
1786
- let result =[];
1804
+ let result = [];
1787
1805
  if ( req.user.role !== 'superadmin' && req.user.userType == 'client' ) {
1788
1806
  const assignedUser = await findUserAssignedStore( { userEmail: req.user.email } );
1789
1807
  if ( assignedUser.length == 0 ) {
@@ -1875,9 +1893,9 @@ export async function checkPermission( req, res, next ) {
1875
1893
  result = await aggregateUserAssignedStore( assignedQuery );
1876
1894
  break;
1877
1895
  }
1878
- if ( result&&result.length>0 ) {
1896
+ if ( result && result.length > 0 ) {
1879
1897
  const uniqueArray = [ ...new Set( result[0].storeList ) ];
1880
- req.body.assignedStores =uniqueArray;
1898
+ req.body.assignedStores = uniqueArray;
1881
1899
  }
1882
1900
  }
1883
1901
  next();
@@ -1889,9 +1907,9 @@ export async function checkPermission( req, res, next ) {
1889
1907
 
1890
1908
  export async function getcount( req, res ) {
1891
1909
  try {
1892
- let storecountQuery ={ 'clientId': { $in: req.body.clientId }, 'status': 'active' };
1910
+ let storecountQuery = { 'clientId': { $in: req.body.clientId }, 'status': 'active' };
1893
1911
 
1894
- if ( req.user&&req.user.userType ==='client'&&req.user.role!='superadmin' ) {
1912
+ if ( req.user && req.user.userType === 'client' && req.user.role != 'superadmin' ) {
1895
1913
  storecountQuery = { ...storecountQuery, ...{ storeId: { $in: req.body.assignedStores } } };
1896
1914
  }
1897
1915
 
@@ -1,9 +1,14 @@
1
1
  import { chunkArray, download, logger, sendMessageToFIFOQueue, sendMessageToQueue } from 'tango-app-api-middleware';
2
2
  import { bulkUpdate, getOpenSearchById, getOpenSearchCount, getOpenSearchData, insertWithId, updateOpenSearchData } from 'tango-app-api-middleware/src/utils/openSearch.js';
3
3
  import { findOneStore } from '../services/store.service.js';
4
- import dayjs from 'dayjs';
5
4
  import { countDocumnetsCamera } from '../services/camera.service.js';
6
5
  import { findOneRevopDownload, upsertRevopDownload } from '../services/revopDownload.service.js';
6
+ import dayjs from 'dayjs';
7
+ import utc from 'dayjs/plugin/utc.js';
8
+ import timezone from 'dayjs/plugin/timezone.js';
9
+
10
+ dayjs.extend( utc );
11
+ dayjs.extend( timezone );
7
12
 
8
13
  export async function createTicket( req, res ) {
9
14
  try {
@@ -727,7 +732,7 @@ export async function updateStatus( req, res ) {
727
732
  logger.info( { 'Note': `Queue doesn't send` } );
728
733
  }
729
734
  } catch ( error ) {
730
- const err = error.messgae || 'Internal Server Error';
735
+ const err = error.message || 'Internal Server Error';
731
736
  logger.error( { error: error, data: req.body, function: 'infra-footfallDirectory-updateStatus' } );
732
737
  return res.sendError( err, 500 );
733
738
  }
@@ -755,6 +760,7 @@ export async function updateTicketStatus( data, openSearch, temp, user ) {
755
760
  data.approverUserName = user?.userName || '';
756
761
  data.approverEmail = user?.email || '';
757
762
  data.approverRole = user?.role || '';
763
+ data.updatedAt = new Date();
758
764
  }
759
765
  let tempId = [];
760
766
  const { _id, ...updateData } = data;
@@ -1011,12 +1017,12 @@ export async function sendSqsMessage( inputData, tempId, getStoreType, storeId )
1011
1017
  } );
1012
1018
  return false;
1013
1019
  } else {
1014
- const id =`${storeId}_${inputData.dateString.split( '-' ).reverse().join( '-' )}_${getStoreType > 0? "live":"reduction"}_${Date.now()}`
1020
+ const id =`${storeId}_${inputData.dateString.split( '-' ).reverse().join( '-' )}_${getStoreType > 0? 'live':'reduction'}_${Date.now()}`;
1015
1021
  const logs = {
1016
- QueueUrl: sqsProduceQueue.QueueUrl,
1017
- MessageBody: sqsProduceQueue.MessageBody,
1018
- sqsQueue:sqsQueue,
1019
- store_id: storeId,
1022
+ QueueUrl: sqsProduceQueue.QueueUrl,
1023
+ MessageBody: sqsProduceQueue.MessageBody,
1024
+ sqsQueue: sqsQueue,
1025
+ store_id: storeId,
1020
1026
  store_date: inputData.dateString.split( '-' ).reverse().join( '-' ),
1021
1027
  bucket_name: '',
1022
1028
  zone_id: 'traffic_zone',
@@ -1024,9 +1030,10 @@ export async function sendSqsMessage( inputData, tempId, getStoreType, storeId )
1024
1030
  revop_type: 'footfall',
1025
1031
  temp_id: tempId,
1026
1032
  time: Date.now(),
1027
- createdAt:new Date()
1028
- }
1029
- await insertWithId(openSearch.revopsLog,id,logs)
1033
+ createdAt: new Date(),
1034
+ createIST: dayjs().tz( 'Asia/Kolkata' ).format( 'YYYY-MM-DD' ),
1035
+ };
1036
+ await insertWithId( openSearch.revopsLog, id, logs );
1030
1037
  return true;
1031
1038
  }
1032
1039
  }
@@ -1497,4 +1504,3 @@ async function extractTempIds( document ) {
1497
1504
  return result;
1498
1505
  }
1499
1506
 
1500
-
@@ -826,7 +826,7 @@ export async function checkStoreTimezoneMatchesInterval( times, storeTimezone )
826
826
  const currentStoreTime = dayjs().tz( storeTimezone );
827
827
  const intervalTime = dayjs.tz( `${currentStoreTime.format( 'YYYY-MM-DD' )} ${interval}`, 'YYYY-MM-DD HH:mm', storeTimezone );
828
828
  const diffInMinutes = intervalTime.diff( currentStoreTime, 'minute' );
829
- // console.log( diffInMinutes );
829
+ console.log( diffInMinutes );
830
830
  return diffInMinutes >= 0 && diffInMinutes <= 15;
831
831
  } );
832
832
  };
@@ -917,7 +917,7 @@ export async function infraReportSent( req, res ) {
917
917
  status: 1,
918
918
  ticketDetails: 1,
919
919
  issueClosedDate: 1,
920
- ommentText: { $ifNull: [ '$primaryIssue.comment', '-' ] },
920
+ commentText: { $ifNull: [ '$primaryIssue.comment', '-' ] },
921
921
  otherscomment: { $ifNull: [ '$otherscomment.comment', '-' ] },
922
922
  primaryIssue: { $ifNull: [ '$primaryIssue.reasons.primaryIssue', '-' ] },
923
923
  secondaryIssue: { $ifNull: [ '$primaryIssue.reasons.secondaryIssue.name', '-' ] },
@@ -1436,7 +1436,7 @@ export async function edgeApplogsCheck( req, res ) {
1436
1436
  item.ticketId === ticket.ticketId,
1437
1437
  );
1438
1438
  if ( !existsInArray ) {
1439
- if ( diffInMinutes>60 ) {
1439
+ if ( diffInMinutes>60 &&diffInMinutes<=180 ) {
1440
1440
  findissueEdgeApp = {
1441
1441
  ticketId: ticket.ticketId,
1442
1442
  edgelog: findissue,
@@ -160,7 +160,7 @@ export async function storeTicketList( req, res ) {
160
160
  primaryIssue: { $last: '$primaryIssue' },
161
161
  secondaryIssue: { $last: '$secondaryIssue' },
162
162
  otherscomment: { $last: '$otherscomment' },
163
-
163
+ otherscomment: { $last: '$otherscomment' },
164
164
  },
165
165
  },
166
166
  {
@@ -170,7 +170,7 @@ export async function storeTicketList( req, res ) {
170
170
  },
171
171
  );
172
172
 
173
- if ( req.body.filter &&req.body.filter.length>0 ) {
173
+ if ( req.body.filter && req.body.filter.length > 0 ) {
174
174
  query.push( {
175
175
  $match: {
176
176
  primaryIssue: { $in: req.body.filter },
@@ -185,7 +185,7 @@ export async function storeTicketList( req, res ) {
185
185
  'STORE ID': element.storeId,
186
186
  'TICKET ID': element.ticketId,
187
187
  'DATE': dayjs( element.createdAt ).format( 'DD MMM, YYYY' ),
188
- 'ISSUE CLOSED DATE': element.issueClosedDate?dayjs( element.issueClosedDate ).format( 'DD MMM, YYYY' ):'',
188
+ 'ISSUE CLOSED DATE': element.issueClosedDate ? dayjs( element.issueClosedDate ).format( 'DD MMM, YYYY' ) : '',
189
189
  'PRIMARY ISSUE': element.primaryIssue,
190
190
  'SECONDARY ISSUE': element.secondaryIssue,
191
191
  'STATUS': element.status,
@@ -359,6 +359,21 @@ export async function edgeAppLogTable( req, res ) {
359
359
  sort: [ { timestamp: { order: 'desc' } } ],
360
360
  _source: [ 'data.files_pushed', 'data.files_generated', 'data.occuringTime' ],
361
361
  };
362
+ const videoCountQuery = {
363
+ size: 100,
364
+ query: {
365
+ bool: {
366
+ must: [
367
+ { term: { 'log_type.keyword': 'Application' } },
368
+ { term: { 'store_date.keyword': date } },
369
+ { term: { 'storeId.keyword': storeId } },
370
+ { term: { 'log_subtype.keyword': 'VideoFileUpload_Status' } },
371
+ ],
372
+ },
373
+ },
374
+ sort: [ { timestamp: { order: 'desc' } } ],
375
+ _source: [ 'data.files_pushed', 'data.files_generated', 'data.occuringTime' ],
376
+ };
362
377
 
363
378
  const downTimeQuery = {
364
379
  size: 100,
@@ -374,15 +389,17 @@ export async function edgeAppLogTable( req, res ) {
374
389
  };
375
390
 
376
391
  // Execute all queries in parallel
377
- const [ speedTestResult, fileCountResult, downtimeResult ] = await Promise.all( [
392
+ const [ speedTestResult, fileCountResult, videoCountResult, downtimeResult ] = await Promise.all( [
378
393
  getOpenSearchData( JSON.parse( process.env.OPENSEARCH ).edgeAppSystemLogs, internetSpeedQuery ),
379
394
  getOpenSearchData( JSON.parse( process.env.OPENSEARCH ).edgeAppSystemLogs, fileCountQuery ),
395
+ getOpenSearchData( JSON.parse( process.env.OPENSEARCH ).edgeAppSystemLogs, videoCountQuery ),
380
396
  getOpenSearchData( JSON.parse( process.env.OPENSEARCH ).downTimeHourly, downTimeQuery ),
381
397
  ] );
382
398
  // Process results
383
399
  const speedTestData = speedTestResult?.body?.hits?.hits ?? [];
384
400
  const fileCountData = fileCountResult?.body?.hits?.hits ?? [];
385
401
  const downtimeData = downtimeResult?.body?.hits?.hits ?? [];
402
+ const videofileCountData = videoCountResult?.body?.hits?.hits ?? [];
386
403
 
387
404
  for ( const obj of timeSlots ) {
388
405
  if ( ( obj.hour ).toString().length === 1 ) {
@@ -397,7 +414,7 @@ export async function edgeAppLogTable( req, res ) {
397
414
  const speedTest = speedTestData.find(
398
415
  ( item ) => Number( item._source.data.occuringTime.split( ':' )[0] ) === Number( hour ),
399
416
  );
400
- if ( speedTest&&speedTest._source.data.upload_Speed =='0 bytes' ) {
417
+ if ( speedTest && speedTest._source.data.upload_Speed == '0 bytes' ) {
401
418
  obj.Internetspeed = '0 MB/sec';
402
419
  } else {
403
420
  obj.Internetspeed = speedTest ? `${bytesToMB( speedTest._source.data.upload_Speed.split( '.' )[0] ).toFixed( 2 )} MB/sec` : '';
@@ -411,6 +428,13 @@ export async function edgeAppLogTable( req, res ) {
411
428
 
412
429
  obj.files_pushed = fileCounts.reduce( ( sum, item ) => sum + Number( item._source.data.files_pushed ), 0 ) || '';
413
430
  obj.files_generated = fileCounts.reduce( ( sum, item ) => sum + Number( item._source.data.files_generated ), 0 ) || '';
431
+ // video File counts
432
+ const videofileCounts = videofileCountData.filter(
433
+ ( item ) => Number( item._source.data.occuringTime.split( ':' )[0] ) === Number( hour ),
434
+ );
435
+
436
+ obj.videofiles_pushed = videofileCounts.reduce( ( sum, item ) => sum + Number( item._source.data.files_pushed ), 0 ) || '';
437
+ obj.videofiles_generated = videofileCounts.reduce( ( sum, item ) => sum + Number( item._source.data.files_generated ), 0 ) || '';
414
438
 
415
439
  // Downtime
416
440
  const downtime = downtimeData.find( ( item ) => Number( item._source.doc.hour ) === Number( hour ) );
@@ -431,10 +455,12 @@ export async function edgeAppLogTable( req, res ) {
431
455
  if ( req.body.export ) {
432
456
  const exportData = timeSlots.map( ( element ) => ( {
433
457
  'Time Stamp': `${element.startTime}-${element.endTime}`,
434
- 'Downtime': element.downtime?element.downtime +' Mins':'--',
458
+ 'Downtime': element.downtime ? element.downtime + ' Mins' : '--',
435
459
  'Avg Internet Speed': element.Internetspeed,
436
- 'Files Generated': element.files_generated,
437
- 'Files Pushed': element.files_pushed,
460
+ 'Tracking Files Generated': element.videofiles_generated,
461
+ 'Tracking Files Pushed': element.videofiles_pushed,
462
+ 'Traffic Files Generated': element.files_generated,
463
+ 'Traffic Files Pushed': element.files_pushed,
438
464
  } ) );
439
465
  await download( exportData, res );
440
466
  return;
@@ -815,7 +841,7 @@ export async function streamwiseDowntime( req, res ) {
815
841
  const downTimeIndex = parsedOpenSearch.downTimeHourly;
816
842
 
817
843
  const batchRequests = TimeSlots.map( async ( obj ) => {
818
- if ( ( obj.hour ).toString().length ===1 ) {
844
+ if ( ( obj.hour ).toString().length === 1 ) {
819
845
  obj.hour = obj.hour.toString().padStart( 2, '0' );
820
846
  }
821
847
 
@@ -854,6 +880,249 @@ export async function streamwiseDowntime( req, res ) {
854
880
  return res.sendError( error, 500 );
855
881
  }
856
882
  }
883
+ export async function edgeAppCameralogs( req, res ) {
884
+ try {
885
+ const store = await findOneStore( { storeId: req.body.storeId } );
886
+ if ( !store ) {
887
+ return res.sendError( 'Store Not found', 204 );
888
+ }
889
+
890
+ let startHour = parseInt( store.storeProfile.open.split( ':' )[0], 10 );
891
+ let endHour = parseInt( store.storeProfile.close.split( ':' )[0], 10 );
892
+ const interval = 60; // 1 hour in minutes
893
+ const timeSlots = generateTimeSlots( startHour, endHour, interval, req );
894
+
895
+ const date = dayjs( timeSlots[0].from ).format( 'DD-MM-YYYY' );
896
+ const storeId = req.body.storeId;
897
+ const streamName = req.body.stream;
898
+
899
+ const internetSpeedQuery = {
900
+ size: 100,
901
+ query: {
902
+ bool: {
903
+ must: [
904
+ { term: { 'log_type.keyword': 'Application' } },
905
+ { term: { 'store_date.keyword': date } },
906
+ { term: { 'storeId.keyword': storeId } },
907
+ { term: { 'log_subtype.keyword': 'Speed_Test' } },
908
+ ],
909
+ },
910
+ },
911
+ sort: [ { timestamp: { order: 'desc' } } ],
912
+ _source: [ 'data.upload_Speed', 'data.occuringTime' ],
913
+ };
914
+
915
+ const fileCountQuery = {
916
+ size: 100,
917
+ query: {
918
+ bool: {
919
+ must: [
920
+ { term: { 'log_type.keyword': 'Application' } },
921
+ { term: { 'store_date.keyword': date } },
922
+ { term: { 'storeId.keyword': storeId } },
923
+ { term: { 'data.stream_name.keyword': streamName } },
924
+ { term: { 'log_subtype.keyword': 'Zip_File_Count' } },
925
+ ],
926
+ },
927
+ },
928
+ sort: [ { timestamp: { order: 'desc' } } ],
929
+ _source: [ 'data.files_pushed', 'data.files_generated', 'data.occuringTime' ],
930
+ };
931
+ const videoCountQuery = {
932
+ size: 100,
933
+ query: {
934
+ bool: {
935
+ must: [
936
+ { term: { 'log_type.keyword': 'Application' } },
937
+ { term: { 'store_date.keyword': date } },
938
+ { term: { 'storeId.keyword': storeId } },
939
+ { term: { 'data.stream_name.keyword': streamName } },
940
+
941
+ { term: { 'log_subtype.keyword': 'VideoFileUpload_Status' } },
942
+ ],
943
+ },
944
+ },
945
+ sort: [ { timestamp: { order: 'desc' } } ],
946
+ _source: [ 'data.files_pushed', 'data.files_generated', 'data.occuringTime' ],
947
+ };
948
+
949
+ const downTimeQuery = {
950
+ size: 100,
951
+ query: {
952
+ bool: {
953
+ must: [
954
+ { term: { 'doc.date.keyword': date } },
955
+ { term: { 'doc.store_id.keyword': storeId } },
956
+ ],
957
+ },
958
+ },
959
+ _source: [ 'doc.streamwise_downtime', 'doc.hour' ],
960
+ };
961
+
962
+ // Execute all queries in parallel
963
+ const [ speedTestResult, fileCountResult, videoCountResult, downtimeResult ] = await Promise.all( [
964
+ getOpenSearchData( JSON.parse( process.env.OPENSEARCH ).edgeAppSystemLogs, internetSpeedQuery ),
965
+ getOpenSearchData( JSON.parse( process.env.OPENSEARCH ).edgeAppSystemLogs, fileCountQuery ),
966
+ getOpenSearchData( JSON.parse( process.env.OPENSEARCH ).edgeAppSystemLogs, videoCountQuery ),
967
+ getOpenSearchData( JSON.parse( process.env.OPENSEARCH ).downTimeHourly, downTimeQuery ),
968
+ ] );
969
+ // Process results
970
+ const speedTestData = speedTestResult?.body?.hits?.hits ?? [];
971
+ const fileCountData = fileCountResult?.body?.hits?.hits ?? [];
972
+ const downtimeData = downtimeResult?.body?.hits?.hits ?? [];
973
+ const videofileCountData = videoCountResult?.body?.hits?.hits ?? [];
974
+
975
+ for ( const obj of timeSlots ) {
976
+ if ( ( obj.hour ).toString().length === 1 ) {
977
+ obj.hour = obj.hour.toString().padStart( 2, '0' );
978
+ }
979
+ const hour = obj.hour;
980
+ obj.startTime = dayjs( obj.from ).format( 'hh:mm A' );
981
+ obj.endTime = dayjs( obj.to ).format( 'hh:mm A' );
982
+
983
+ // Internet speed
984
+
985
+ const speedTest = speedTestData.find(
986
+ ( item ) => Number( item._source.data.occuringTime.split( ':' )[0] ) === Number( hour ),
987
+ );
988
+ if ( speedTest && speedTest._source.data.upload_Speed == '0 bytes' ) {
989
+ obj.Internetspeed = '0 MB/sec';
990
+ } else {
991
+ obj.Internetspeed = speedTest ? `${bytesToMB( speedTest._source.data.upload_Speed.split( '.' )[0] ).toFixed( 2 )} MB/sec` : '';
992
+ }
993
+
994
+
995
+ // File counts
996
+ const fileCounts = fileCountData.filter(
997
+ ( item ) => Number( item._source.data.occuringTime.split( ':' )[0] ) === Number( hour ),
998
+ );
999
+
1000
+ obj.files_pushed = fileCounts.reduce( ( sum, item ) => sum + Number( item._source.data.files_pushed ), 0 ) || '';
1001
+ obj.files_generated = fileCounts.reduce( ( sum, item ) => sum + Number( item._source.data.files_generated ), 0 ) || '';
1002
+ // video File counts
1003
+ const videofileCounts = videofileCountData.filter(
1004
+ ( item ) => Number( item._source.data.occuringTime.split( ':' )[0] ) === Number( hour ),
1005
+ );
1006
+
1007
+ obj.videofiles_pushed = videofileCounts.reduce( ( sum, item ) => sum + Number( item._source.data.files_pushed ), 0 ) || '';
1008
+ obj.videofiles_generated = videofileCounts.reduce( ( sum, item ) => sum + Number( item._source.data.files_generated ), 0 ) || '';
1009
+
1010
+ // Downtime
1011
+ const downtime = downtimeData.find( ( item ) => Number( item._source.doc.hour ) === Number( hour ) );
1012
+
1013
+ if ( downtime ) {
1014
+ const streamwiseDowntime = downtime._source.doc.streamwise_downtime || [];
1015
+
1016
+ const downtimeData = streamwiseDowntime.find( ( item ) => item.stream === streamName );
1017
+ if ( downtimeData ) {
1018
+ obj.downtime = downtimeData?.down_time;
1019
+ } else {
1020
+ obj.downtime = '';
1021
+ }
1022
+ } else {
1023
+ obj.downtime = '';
1024
+ }
1025
+ }
1026
+
1027
+ if ( req.body.export ) {
1028
+ const exportData = timeSlots.map( ( element ) => ( {
1029
+ 'Time Stamp': `${element.startTime}-${element.endTime}`,
1030
+ 'Downtime': element.downtime ? element.downtime + ' Mins' : '--',
1031
+ 'Avg Internet Speed': element.Internetspeed,
1032
+ 'Tracking Files Generated': element.videofiles_generated,
1033
+ 'Tracking Files Pushed': element.videofiles_pushed,
1034
+ 'Traffic Files Generated': element.files_generated,
1035
+ 'Traffic Files Pushed': element.files_pushed,
1036
+ } ) );
1037
+ await download( exportData, res );
1038
+ return;
1039
+ }
1040
+ let totalCount = 0;
1041
+ const query = {
1042
+ 'size': 10000,
1043
+ 'query': {
1044
+ bool: {
1045
+ must: [
1046
+ {
1047
+ term: {
1048
+ 'store_date.keyword': dayjs( req.body.Date ).format( 'DD-MM-YYYY' ),
1049
+ },
1050
+ },
1051
+ {
1052
+ term: {
1053
+ 'store_id.keyword': req.body.storeId,
1054
+ },
1055
+ },
1056
+ ],
1057
+ },
1058
+ },
1059
+ 'sort': [ { timestamp: { order: 'desc' } } ],
1060
+ '_source': [ 'fileSize', 'store_id', 'stream_id' ],
1061
+
1062
+ };
1063
+
1064
+ const storeSizeData = await getOpenSearchData(
1065
+ JSON.parse( process.env.OPENSEARCH ).edgeAppFilelogs,
1066
+ query,
1067
+ );
1068
+ if ( storeSizeData?.body?.hits?.hits == undefined || storeSizeData?.body?.hits?.hits == null ) {
1069
+ return res.sendError( { message: 'Data not found' }, 204 );
1070
+ }
1071
+
1072
+ for ( const count of storeSizeData.body?.hits?.hits ) {
1073
+ totalCount += Number( count._source.fileSize );
1074
+ }
1075
+
1076
+ const queryAvg = {
1077
+ query: {
1078
+ bool: {
1079
+ must: [
1080
+ {
1081
+ term: {
1082
+ 'store_date.keyword': dayjs( req.body.Date ).format( 'DD-MM-YYYY' ),
1083
+ },
1084
+ },
1085
+ {
1086
+ term: {
1087
+ 'store_id.keyword': req.body.storeId,
1088
+ },
1089
+ },
1090
+ ],
1091
+ },
1092
+ },
1093
+ sort: [ { timestamp: { order: 'desc' } } ],
1094
+ _source: [ 'fileSize', 'store_id', 'stream_id' ],
1095
+ aggs: {
1096
+ // Grouping by store_id
1097
+ grouped_by_store_id: {
1098
+ terms: {
1099
+ field: 'stream_id.keyword', // Group by store_id
1100
+ size: 1000, // Limit the number of groups (adjust based on needs)
1101
+ },
1102
+ },
1103
+ },
1104
+ };
1105
+
1106
+ const storeAvgSizeData = await getOpenSearchData(
1107
+ JSON.parse( process.env.OPENSEARCH ).edgeAppFilelogs,
1108
+ queryAvg,
1109
+ );
1110
+
1111
+
1112
+ res.sendSuccess( {
1113
+ result: timeSlots,
1114
+ totalData: {
1115
+ totalCount: totalCount,
1116
+ avgCount: totalCount / ( storeAvgSizeData.body.aggregations.grouped_by_store_id.buckets.length ),
1117
+ totalCam: storeAvgSizeData.body.aggregations.grouped_by_store_id.buckets.length,
1118
+
1119
+ },
1120
+ } );
1121
+ } catch ( error ) {
1122
+ logger.error( { error: error, function: 'streamwiseDowntime' } );
1123
+ return res.sendError( error, 500 );
1124
+ }
1125
+ }
857
1126
 
858
1127
 
859
1128
  export async function livecountCheck( inputData, singleDate, req ) {
@@ -916,7 +1185,7 @@ export async function livecountCheck( inputData, singleDate, req ) {
916
1185
 
917
1186
  export async function edgeappFileSize( req, res ) {
918
1187
  try {
919
- let totalCount=0;
1188
+ let totalCount = 0;
920
1189
  const query = {
921
1190
  'size': 10000,
922
1191
  'query': {
@@ -944,12 +1213,12 @@ export async function edgeappFileSize( req, res ) {
944
1213
  JSON.parse( process.env.OPENSEARCH ).edgeAppFilelogs,
945
1214
  query,
946
1215
  );
947
- if ( storeSizeData?.body?.hits?.hits ==undefined|| storeSizeData?.body?.hits?.hits ==null ) {
1216
+ if ( storeSizeData?.body?.hits?.hits == undefined || storeSizeData?.body?.hits?.hits == null ) {
948
1217
  return res.sendError( { message: 'Data not found' }, 204 );
949
1218
  }
950
1219
 
951
1220
  for ( const count of storeSizeData.body?.hits?.hits ) {
952
- totalCount+=Number( count._source.fileSize );
1221
+ totalCount += Number( count._source.fileSize );
953
1222
  }
954
1223
 
955
1224
  const queryAvg = {
@@ -989,7 +1258,7 @@ export async function edgeappFileSize( req, res ) {
989
1258
 
990
1259
  res.sendSuccess( {
991
1260
  totalCount: totalCount,
992
- avgCount: totalCount/( storeAvgSizeData.body.aggregations.grouped_by_store_id.buckets.length ),
1261
+ avgCount: totalCount / ( storeAvgSizeData.body.aggregations.grouped_by_store_id.buckets.length ),
993
1262
  totalCam: storeAvgSizeData.body.aggregations.grouped_by_store_id.buckets.length,
994
1263
  } );
995
1264
  } catch ( error ) {
@@ -208,7 +208,7 @@ export const footfallDirectoryDocs = {
208
208
  },
209
209
 
210
210
  '/v3/footfall-directory-tagging/update-status': {
211
- get: {
211
+ put: {
212
212
  tags: [ 'Footfall Directory Ticket' ],
213
213
  description: 'approve or reject the ticket status',
214
214
  operationId: 'update-status',
@@ -1,7 +1,7 @@
1
1
 
2
2
  import express from 'express';
3
3
  import { isAllowedSessionHandler } from 'tango-app-api-middleware';
4
- import { storeTicketList, storeTicketcard, edgeAppLogTable, viewedgeAppLog, isAllowedStore, cameraAngleChange, datewiseDowntime, streamwiseDowntime, edgeappFileSize } from '../controllers/storeInfra.controlller.js';
4
+ import { storeTicketList, storeTicketcard, edgeAppLogTable, viewedgeAppLog, isAllowedStore, cameraAngleChange, edgeAppCameralogs, datewiseDowntime, streamwiseDowntime, edgeappFileSize } from '../controllers/storeInfra.controlller.js';
5
5
  export const storeInfraRouter = express.Router();
6
6
 
7
7
  storeInfraRouter.post( '/storeTicketList', isAllowedSessionHandler, isAllowedStore, storeTicketList );
@@ -11,5 +11,6 @@ storeInfraRouter.post( '/viewedgeAppLog', isAllowedSessionHandler, isAllowedStor
11
11
  storeInfraRouter.post( '/cameraAngleChange', isAllowedSessionHandler, isAllowedStore, cameraAngleChange );
12
12
  storeInfraRouter.post( '/datewiseDowntime', isAllowedSessionHandler, isAllowedStore, datewiseDowntime );
13
13
  storeInfraRouter.post( '/streamwiseDowntime', isAllowedSessionHandler, isAllowedStore, streamwiseDowntime );
14
+ storeInfraRouter.post( '/edgeAppCameralogs', isAllowedSessionHandler, isAllowedStore, edgeAppCameralogs );
14
15
 
15
16
  storeInfraRouter.post( '/edgeappFileSize', isAllowedSessionHandler, isAllowedStore, edgeappFileSize );