tango-app-api-analysis-traffic 3.5.0-alpha.4 → 3.8.0-alpha.0
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/.eslintrc.cjs +1 -1
- package/README.md +28 -28
- package/package.json +3 -3
- package/src/controllers/revop.controller.js +1 -10
- package/src/controllers/tangoTraffic.controllers.js +0 -1
- package/src/controllers/tangoTrafficV2.controllers.js +0 -10
- package/src/controllers/tangoTrafficV3.controllers.js +41 -18
package/.eslintrc.cjs
CHANGED
package/README.md
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
# README #
|
|
2
|
-
|
|
3
|
-
This README would normally document whatever steps are necessary to get your application up and running.
|
|
4
|
-
|
|
5
|
-
### What is this repository for? ###
|
|
6
|
-
|
|
7
|
-
* Quick summary
|
|
8
|
-
* Version
|
|
9
|
-
* [Learn Markdown](https://bitbucket.org/tutorials/markdowndemo)
|
|
10
|
-
|
|
11
|
-
### How do I get set up? ###
|
|
12
|
-
|
|
13
|
-
* Summary of set up
|
|
14
|
-
* Configuration
|
|
15
|
-
* Dependencies
|
|
16
|
-
* Database configuration
|
|
17
|
-
* How to run tests
|
|
18
|
-
* Deployment instructions
|
|
19
|
-
|
|
20
|
-
### Contribution guidelines ###
|
|
21
|
-
|
|
22
|
-
* Writing tests
|
|
23
|
-
* Code review
|
|
24
|
-
* Other guidelines
|
|
25
|
-
|
|
26
|
-
### Who do I talk to? ###
|
|
27
|
-
|
|
28
|
-
* Repo owner or admin
|
|
1
|
+
# README #
|
|
2
|
+
|
|
3
|
+
This README would normally document whatever steps are necessary to get your application up and running.
|
|
4
|
+
|
|
5
|
+
### What is this repository for? ###
|
|
6
|
+
|
|
7
|
+
* Quick summary
|
|
8
|
+
* Version
|
|
9
|
+
* [Learn Markdown](https://bitbucket.org/tutorials/markdowndemo)
|
|
10
|
+
|
|
11
|
+
### How do I get set up? ###
|
|
12
|
+
|
|
13
|
+
* Summary of set up
|
|
14
|
+
* Configuration
|
|
15
|
+
* Dependencies
|
|
16
|
+
* Database configuration
|
|
17
|
+
* How to run tests
|
|
18
|
+
* Deployment instructions
|
|
19
|
+
|
|
20
|
+
### Contribution guidelines ###
|
|
21
|
+
|
|
22
|
+
* Writing tests
|
|
23
|
+
* Code review
|
|
24
|
+
* Other guidelines
|
|
25
|
+
|
|
26
|
+
### Who do I talk to? ###
|
|
27
|
+
|
|
28
|
+
* Repo owner or admin
|
|
29
29
|
* Other community or team contact
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-analysis-traffic",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0-alpha.0",
|
|
4
4
|
"description": "Traffic Analysis",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"mongodb": "^6.8.0",
|
|
24
24
|
"nodemon": "^3.1.4",
|
|
25
25
|
"swagger-ui-express": "^5.0.1",
|
|
26
|
-
"tango-api-schema": "^2.2.
|
|
27
|
-
"tango-app-api-middleware": "^3.1.
|
|
26
|
+
"tango-api-schema": "^2.2.192",
|
|
27
|
+
"tango-app-api-middleware": "^3.1.86",
|
|
28
28
|
"winston": "^3.13.1",
|
|
29
29
|
"winston-daily-rotate-file": "^5.0.0"
|
|
30
30
|
},
|
|
@@ -40,8 +40,6 @@ export async function getconfig( req, res ) {
|
|
|
40
40
|
export async function revoptagging( req, res ) {
|
|
41
41
|
try {
|
|
42
42
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
43
|
-
console.log( req.body );
|
|
44
|
-
console.log( req.body.length );
|
|
45
43
|
for ( let item of req.body ) {
|
|
46
44
|
let searchQuery={
|
|
47
45
|
'size': 1,
|
|
@@ -70,14 +68,11 @@ export async function revoptagging( req, res ) {
|
|
|
70
68
|
|
|
71
69
|
let respo= await getOpenSearchData( openSearch.revops, searchQuery );
|
|
72
70
|
const revopData = respo?.body?.hits?.hits;
|
|
73
|
-
console.log( '====>data exists', revopData );
|
|
74
71
|
if ( revopData&& revopData.length>0 ) {
|
|
75
|
-
|
|
76
|
-
console.log( result );
|
|
72
|
+
await updateOpenSearchData( openSearch.revops, revopData[0]._id, { doc: item } );
|
|
77
73
|
} else {
|
|
78
74
|
item.createdAt = new Date();
|
|
79
75
|
item.updatedAt = new Date();
|
|
80
|
-
console.log( 'insertData', item );
|
|
81
76
|
await insertOpenSearchData( openSearch.revops, item );
|
|
82
77
|
}
|
|
83
78
|
}
|
|
@@ -103,7 +98,6 @@ async function getClientConfig( clientId ) {
|
|
|
103
98
|
export async function getrevoptagging( req, res ) {
|
|
104
99
|
try {
|
|
105
100
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
106
|
-
console.log( req.body );
|
|
107
101
|
let searchQuery={
|
|
108
102
|
'size': 1,
|
|
109
103
|
'query': {
|
|
@@ -130,7 +124,6 @@ export async function getrevoptagging( req, res ) {
|
|
|
130
124
|
};
|
|
131
125
|
let respo= await getOpenSearchData( openSearch.revops, searchQuery );
|
|
132
126
|
const revopData = respo?.body?.hits?.hits;
|
|
133
|
-
console.log( revopData );
|
|
134
127
|
if ( revopData.length>0 ) {
|
|
135
128
|
return res.sendSuccess( revopData[0]._source );
|
|
136
129
|
} else {
|
|
@@ -169,7 +162,6 @@ export async function revoptaggingcount( req, res ) {
|
|
|
169
162
|
let resultData = await LamdaServiceCall( LamdaURL, reqestData );
|
|
170
163
|
if ( resultData ) {
|
|
171
164
|
if ( resultData.status_code == '200' ) {
|
|
172
|
-
console.log( resultData );
|
|
173
165
|
let footfallcount = Math.round( ( resultData.card.footfall.count*getClientData?.revopConfig?.limit )/100 );
|
|
174
166
|
let nonShopperQuery={
|
|
175
167
|
'size': 1000,
|
|
@@ -198,7 +190,6 @@ export async function revoptaggingcount( req, res ) {
|
|
|
198
190
|
};
|
|
199
191
|
let nonShopperrespose= await getOpenSearchData( openSearch.revops, nonShopperQuery );
|
|
200
192
|
const nonShopper = nonShopperrespose?.body?.hits?.hits.length;
|
|
201
|
-
console.log( '---->', footfallcount, nonShopper );
|
|
202
193
|
penndingcount = footfallcount-nonShopper;
|
|
203
194
|
|
|
204
195
|
return res.sendSuccess( { count: penndingcount } );
|
|
@@ -1726,7 +1726,6 @@ export const storesMap = async ( req, res ) => {
|
|
|
1726
1726
|
|
|
1727
1727
|
return res.sendSuccess( getStores );
|
|
1728
1728
|
} catch ( error ) {
|
|
1729
|
-
console.log( 'error =>', error );
|
|
1730
1729
|
logger.error( { error: error, message: req.query, function: 'trafficCards' } );
|
|
1731
1730
|
return res.sendError( { error: error }, 500 );
|
|
1732
1731
|
}
|
|
@@ -113,7 +113,6 @@ export const headerGroupsV2 = async ( req, res ) => {
|
|
|
113
113
|
return res.sendError( 'No Group', 400 );
|
|
114
114
|
}
|
|
115
115
|
} catch ( error ) {
|
|
116
|
-
console.log( 'error =>', error );
|
|
117
116
|
logger.error( { error: error, message: req.query, function: 'trafficCards' } );
|
|
118
117
|
return res.sendError( { error: error }, 500 );
|
|
119
118
|
}
|
|
@@ -217,7 +216,6 @@ export const headerStoresV2 = async ( req, res ) => {
|
|
|
217
216
|
return res.sendError( 'No Stores', 400 );
|
|
218
217
|
}
|
|
219
218
|
} catch ( error ) {
|
|
220
|
-
console.log( 'headerStoresV1 =>', error );
|
|
221
219
|
logger.error( { error: error, message: req.query, function: 'headerStoresV1' } );
|
|
222
220
|
return res.sendError( { error: error }, 500 );
|
|
223
221
|
}
|
|
@@ -287,7 +285,6 @@ async function getAllStores( getUserEmail, getClientId, getUserType ) {
|
|
|
287
285
|
return false;
|
|
288
286
|
}
|
|
289
287
|
} catch ( error ) {
|
|
290
|
-
console.log( 'getAllStores =>', error );
|
|
291
288
|
logger.error( { error: error, message: req.query, function: 'getAllStores' } );
|
|
292
289
|
}
|
|
293
290
|
};
|
|
@@ -323,7 +320,6 @@ async function getAssignedStores( clientId, userEmail, assignedType ) {
|
|
|
323
320
|
return false;
|
|
324
321
|
}
|
|
325
322
|
} catch ( error ) {
|
|
326
|
-
console.log( 'getAssignedStores error =>', error );
|
|
327
323
|
logger.error( { error: error, message: data, function: 'getAssignedStores' } );
|
|
328
324
|
}
|
|
329
325
|
}
|
|
@@ -390,7 +386,6 @@ async function getAssignedGroupStores( clientId, userEmail, assignedType ) {
|
|
|
390
386
|
return false;
|
|
391
387
|
}
|
|
392
388
|
} catch ( error ) {
|
|
393
|
-
console.log( 'getAssignedGroupStores error =>', error );
|
|
394
389
|
logger.error( { error: error, message: data, function: 'getAssignedGroupStores' } );
|
|
395
390
|
}
|
|
396
391
|
}
|
|
@@ -425,7 +420,6 @@ async function getAssignedAllStores( userClientId ) {
|
|
|
425
420
|
return false;
|
|
426
421
|
}
|
|
427
422
|
} catch ( error ) {
|
|
428
|
-
console.log( 'getAssignedAllStores error =>', error );
|
|
429
423
|
logger.error( { error: error, message: data, function: 'getAssignedAllStores' } );
|
|
430
424
|
}
|
|
431
425
|
}
|
|
@@ -465,7 +459,6 @@ async function getGroupStores( userClientId, groupList ) {
|
|
|
465
459
|
return false;
|
|
466
460
|
}
|
|
467
461
|
} catch ( error ) {
|
|
468
|
-
console.log( 'getGroupStores error =>', error );
|
|
469
462
|
logger.error( { error: error, message: data, function: 'getGroupStores' } );
|
|
470
463
|
}
|
|
471
464
|
}
|
|
@@ -506,7 +499,6 @@ async function getLocationStores( userClientId, cityList ) {
|
|
|
506
499
|
return false;
|
|
507
500
|
}
|
|
508
501
|
} catch ( error ) {
|
|
509
|
-
console.log( 'getLocationStores error =>', error );
|
|
510
502
|
logger.error( { error: error, message: data, function: 'getLocationStores' } );
|
|
511
503
|
}
|
|
512
504
|
}
|
|
@@ -540,7 +532,6 @@ async function getGroupIds( userClientId ) {
|
|
|
540
532
|
return false;
|
|
541
533
|
}
|
|
542
534
|
} catch ( error ) {
|
|
543
|
-
console.log( 'getGroupIds error =>', error );
|
|
544
535
|
logger.error( { error: error, message: data, function: 'getGroupIds' } );
|
|
545
536
|
}
|
|
546
537
|
}
|
|
@@ -580,7 +571,6 @@ async function getAssignedGroupIds( userClientId, getUserEmail ) {
|
|
|
580
571
|
return false;
|
|
581
572
|
}
|
|
582
573
|
} catch ( error ) {
|
|
583
|
-
console.log( 'getAssignedGroupIds error =>', error );
|
|
584
574
|
logger.error( { error: error, message: data, function: 'getAssignedGroupIds' } );
|
|
585
575
|
}
|
|
586
576
|
}
|
|
@@ -593,14 +593,14 @@ export async function lambdaValuetoCurrencyConvert( LamdaURL, data, reqestData,
|
|
|
593
593
|
break;
|
|
594
594
|
}
|
|
595
595
|
} catch ( error ) {
|
|
596
|
-
|
|
596
|
+
logger.error( { error: `Error fetching currency data for ${countryData.currencyCode}` } );
|
|
597
597
|
}
|
|
598
598
|
|
|
599
599
|
|
|
600
600
|
index++;
|
|
601
601
|
}
|
|
602
602
|
} catch ( error ) {
|
|
603
|
-
|
|
603
|
+
logger.error( { error: error } );
|
|
604
604
|
}
|
|
605
605
|
}
|
|
606
606
|
|
|
@@ -679,14 +679,14 @@ export async function lambdaValuetoCurrencyConvertCard( LamdaURL, data, reqestDa
|
|
|
679
679
|
break;
|
|
680
680
|
}
|
|
681
681
|
} catch ( error ) {
|
|
682
|
-
|
|
682
|
+
logger.error( { error: `Error fetching currency data for ${countryData.currencyCode}` } );
|
|
683
683
|
}
|
|
684
684
|
|
|
685
685
|
|
|
686
686
|
index++;
|
|
687
687
|
}
|
|
688
688
|
} catch ( error ) {
|
|
689
|
-
|
|
689
|
+
logger.error( { error: error } );
|
|
690
690
|
}
|
|
691
691
|
}
|
|
692
692
|
|
|
@@ -1397,7 +1397,6 @@ export const footfallDirectoryV3 = async ( req, res ) => {
|
|
|
1397
1397
|
}
|
|
1398
1398
|
reqestData.featureConfigs = getClientData.featureConfigs;
|
|
1399
1399
|
let LamdaURL = 'https://waxlhd7lfdlmyrkrdyv77najka0ayihq.lambda-url.ap-south-1.on.aws/';
|
|
1400
|
-
console.log( LamdaURL );
|
|
1401
1400
|
let resultData = await LamdaServiceCall( LamdaURL, reqestData );
|
|
1402
1401
|
if ( resultData ) {
|
|
1403
1402
|
if ( resultData.status_code == '200' ) {
|
|
@@ -1434,9 +1433,11 @@ export const summaryTableV3 = async ( req, res ) => {
|
|
|
1434
1433
|
if ( !getClientData ) {
|
|
1435
1434
|
return res.sendError( 'Invalid Client Id', 400 );
|
|
1436
1435
|
}
|
|
1436
|
+
const isFootfallView =getClientData?.featureConfigs?.isFootfallView;
|
|
1437
1437
|
reqestData.featureConfigs = getClientData.featureConfigs;
|
|
1438
1438
|
let LamdaURL = 'https://ewen2vlmxmhieea4elztlbjuey0ddqee.lambda-url.ap-south-1.on.aws/';
|
|
1439
1439
|
let resultData;
|
|
1440
|
+
|
|
1440
1441
|
if ( reqestData.export ) {
|
|
1441
1442
|
let limit = 10000;
|
|
1442
1443
|
let count = 0;
|
|
@@ -1458,6 +1459,19 @@ export const summaryTableV3 = async ( req, res ) => {
|
|
|
1458
1459
|
}
|
|
1459
1460
|
} else {
|
|
1460
1461
|
resultData = await LamdaServiceCall( LamdaURL, reqestData );
|
|
1462
|
+
let temp=[];
|
|
1463
|
+
if ( isFootfallView === true && resultData && resultData.summaryData && resultData.summaryData.length > 0 ) {
|
|
1464
|
+
for ( const item of resultData?.summaryData ) {
|
|
1465
|
+
temp.push( {
|
|
1466
|
+
storeName: item.storeName,
|
|
1467
|
+
storeId: item.storeId,
|
|
1468
|
+
footfallCount: item.footfallCount,
|
|
1469
|
+
...( req.body.storeId.length ==1 )? { date: dayjs( item['date'] ).format( 'MMM DD,YYYY' ) } : {},
|
|
1470
|
+
avgInfraDowntime: item.avgInfraDowntime,
|
|
1471
|
+
} );
|
|
1472
|
+
}
|
|
1473
|
+
resultData.summaryData = temp;
|
|
1474
|
+
}
|
|
1461
1475
|
}
|
|
1462
1476
|
if ( resultData ) {
|
|
1463
1477
|
if ( resultData.status_code == '200' ) {
|
|
@@ -1469,7 +1483,7 @@ export const summaryTableV3 = async ( req, res ) => {
|
|
|
1469
1483
|
exportdata.push( {
|
|
1470
1484
|
'Store Name': element.storeName,
|
|
1471
1485
|
'Store ID': element.storeId,
|
|
1472
|
-
...( req.body.storeId.length ==1 ) ? { Date: element['date'] }:{},
|
|
1486
|
+
...( req.body.storeId.length ==1 ) ? { Date: dayjs( element['date'] ).format( 'MMM DD,YYYY' ) }:{},
|
|
1473
1487
|
'Footfall': element.footfallCount,
|
|
1474
1488
|
'Bounced Footfall': element.bouncedCount,
|
|
1475
1489
|
'Engagers': element.engagersCount,
|
|
@@ -1493,7 +1507,7 @@ export const summaryTableV3 = async ( req, res ) => {
|
|
|
1493
1507
|
exportdata.push( {
|
|
1494
1508
|
'Store Name': element.storeName,
|
|
1495
1509
|
'Store ID': element.storeId,
|
|
1496
|
-
...( req.body.storeId.length ==1 ) ? { Date: element['date'] }:{},
|
|
1510
|
+
...( req.body.storeId.length ==1 ) ? { Date: dayjs( element['date'] ).format( 'MMM DD,YYYY' ) }:{},
|
|
1497
1511
|
'Footfall': element.footfallCount,
|
|
1498
1512
|
...( bouncedLabel ? { [bouncedLabel]: element.bouncedCount } : {} ),
|
|
1499
1513
|
...( engagersLabel ? { [engagersLabel]: element.engagersCount } : {} ),
|
|
@@ -1512,11 +1526,19 @@ export const summaryTableV3 = async ( req, res ) => {
|
|
|
1512
1526
|
'Male': element.male,
|
|
1513
1527
|
'Female': element.female,
|
|
1514
1528
|
} );
|
|
1529
|
+
} else if ( isFootfallView === true ) {
|
|
1530
|
+
exportdata.push( {
|
|
1531
|
+
'Store Name': element.storeName,
|
|
1532
|
+
'Store ID': element.storeId,
|
|
1533
|
+
...( req.body.storeId.length ==1 ) ? { Date: dayjs( element['date'] ).format( 'MMM DD,YYYY' ) }:{},
|
|
1534
|
+
'Footfall': element.footfallCount,
|
|
1535
|
+
'Avg Infra DownTime': element.avgInfraDowntime,
|
|
1536
|
+
} );
|
|
1515
1537
|
} else {
|
|
1516
1538
|
exportdata.push( {
|
|
1517
1539
|
'Store Name': element.storeName,
|
|
1518
1540
|
'Store ID': element.storeId,
|
|
1519
|
-
...( req.body.storeId.length ==1 ) ? { Date: element['date'] }:{},
|
|
1541
|
+
...( req.body.storeId.length ==1 ) ? { Date: dayjs( element['date'] ).format( 'MMM DD,YYYY' ) }:{},
|
|
1520
1542
|
'Footfall': element.footfallCount,
|
|
1521
1543
|
'Bounced Footfall': element.bouncedCount,
|
|
1522
1544
|
'Engagers': element.engagersCount,
|
|
@@ -1552,8 +1574,9 @@ export const summaryTableV3 = async ( req, res ) => {
|
|
|
1552
1574
|
return res.sendError( 'No Content', 204 );
|
|
1553
1575
|
}
|
|
1554
1576
|
} catch ( error ) {
|
|
1577
|
+
const err= error.message || 'Internal Server Error';
|
|
1555
1578
|
logger.error( { error: error, message: req.query, function: 'summaryTableV3' } );
|
|
1556
|
-
return res.sendError(
|
|
1579
|
+
return res.sendError( err, 500 );
|
|
1557
1580
|
}
|
|
1558
1581
|
};
|
|
1559
1582
|
|
|
@@ -2909,7 +2932,7 @@ async function getGroupStoresIds( userClientId, storeIds, getRole, getUserType,
|
|
|
2909
2932
|
|
|
2910
2933
|
async function getClientConfig( clientId ) {
|
|
2911
2934
|
try {
|
|
2912
|
-
let getClientData = await clientService.findOne( { clientId: clientId }, { 'paymentInvoice.currencyType': 1, 'averageTransactionValue': 1, 'featureConfigs.billableCalculation': 1, 'featureConfigs.missedOpportunityCalculation': 1, 'featureConfigs.conversionCalculation': 1, 'featureConfigs.open': 1, 'featureConfigs.close': 1, 'isFootfallAuditStores': 1, 'featureConfigs.bouncedLimit': 1, 'featureConfigs.conversion': 1 } );
|
|
2935
|
+
let getClientData = await clientService.findOne( { clientId: clientId }, { 'paymentInvoice.currencyType': 1, 'averageTransactionValue': 1, 'featureConfigs.billableCalculation': 1, 'featureConfigs.missedOpportunityCalculation': 1, 'featureConfigs.conversionCalculation': 1, 'featureConfigs.open': 1, 'featureConfigs.close': 1, 'isFootfallAuditStores': 1, 'featureConfigs.bouncedLimit': 1, 'featureConfigs.conversion': 1, 'featureConfigs.isFootfallView': 1 } );
|
|
2913
2936
|
if ( !getClientData ) {
|
|
2914
2937
|
return false;
|
|
2915
2938
|
}
|
|
@@ -3022,19 +3045,19 @@ export const getStoreMapDataV3 = async ( req, res ) => {
|
|
|
3022
3045
|
};
|
|
3023
3046
|
let hourlyLamdaURL = 'https://ksxkjnhwwzvrgp7ngttw2ribsy0twqip.lambda-url.ap-south-1.on.aws/';
|
|
3024
3047
|
let hourlyResultData = await LamdaServiceCall( hourlyLamdaURL, reqestData );
|
|
3025
|
-
if ( hourlyResultData && hourlyResultData
|
|
3026
|
-
hourlyData.hourlyFootfall = hourlyResultData.hourData[0]
|
|
3027
|
-
hourlyData.openTime = hourlyResultData.hourData[0]
|
|
3028
|
-
hourlyData.closeTime = hourlyResultData.hourData[0]
|
|
3048
|
+
if ( hourlyResultData && hourlyResultData?.hourData?.length>0 ) {
|
|
3049
|
+
hourlyData.hourlyFootfall = hourlyResultData.hourData?.[0]?.hourlyFootfall;
|
|
3050
|
+
hourlyData.openTime = hourlyResultData.hourData?.[0]?.openTime;
|
|
3051
|
+
hourlyData.closeTime = hourlyResultData.hourData?.[0]?.closeTime;
|
|
3029
3052
|
}
|
|
3030
3053
|
let fromDate = new Date( dayjs( reqestData.fromDate ).subtract( 30, 'days' ) );
|
|
3031
3054
|
reqestData.fromDate = dayjs( fromDate ).format( 'YYYY-MM-DD' );
|
|
3032
3055
|
let footfallLamdaURL = 'https://z3pzvj23qgvqkfixbwvdp2hlw40nexbf.lambda-url.ap-south-1.on.aws/';
|
|
3033
3056
|
let footfallResultData = await LamdaServiceCall( footfallLamdaURL, reqestData );
|
|
3034
|
-
if ( footfallResultData && footfallResultData
|
|
3035
|
-
avgData.avgFootfall = footfallResultData.avgData[0]
|
|
3036
|
-
avgData.avgWeekdayFootfall = footfallResultData.avgData[0]
|
|
3037
|
-
avgData.avgWeekendFootfall = footfallResultData.avgData[0]
|
|
3057
|
+
if ( footfallResultData && footfallResultData?.avgData&&footfallResultData?.avgData?.length>0 ) {
|
|
3058
|
+
avgData.avgFootfall = footfallResultData.avgData?.[0]?.avgFootfall;
|
|
3059
|
+
avgData.avgWeekdayFootfall = footfallResultData.avgData?.[0]?.avgWeekdayFootfall;
|
|
3060
|
+
avgData.avgWeekendFootfall = footfallResultData.avgData?.[0]?.avgWeekendFootfall;
|
|
3038
3061
|
}
|
|
3039
3062
|
return res.sendSuccess( { cameraBaseImage: cameraBaseImage, hourlyData: hourlyData, avgData: avgData } );
|
|
3040
3063
|
} else {
|