tango-app-api-analysis-traffic 3.0.0-alpha.7 → 3.0.0-alpha.8

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,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-analysis-traffic",
3
- "version": "3.0.0-alpha.7",
3
+ "version": "3.0.0-alpha.8",
4
4
  "description": "Traffic Analysis",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -14,6 +14,7 @@
14
14
  "license": "ISC",
15
15
  "dependencies": {
16
16
  "aws-sdk": "^2.1665.0",
17
+ "dayjs": "^1.11.13",
17
18
  "dotenv": "^16.4.5",
18
19
  "express": "^4.19.2",
19
20
  "handlebars": "^4.7.8",
@@ -1,10 +1,13 @@
1
- import { logger } from 'tango-app-api-middleware';
1
+ import { logger, download } from 'tango-app-api-middleware';
2
2
  import * as clientService from '../services/clients.services.js';
3
3
  import {
4
4
  aggregateStore,
5
5
  } from '../services/stores.service.js';
6
6
  import { aggregateUserAssignedStore, findOneUserAssignedStore } from '../services/userAssignedStore.service.js';
7
7
  import { aggregateGroup } from '../services/group.service.js';
8
+ import dayjs from 'dayjs';
9
+ import mongoose from 'mongoose';
10
+ const ObjectId = mongoose.Types.ObjectId;
8
11
 
9
12
  // Lamda Service Call //
10
13
  async function LamdaServiceCall( url, data ) {
@@ -99,6 +102,7 @@ export const recapVideoV1 = async ( req, res ) => {
99
102
  export const densityDwellV1 = async ( req, res ) => {
100
103
  try {
101
104
  let reqestData = req.body;
105
+ reqestData.hourFormat = 12;
102
106
  let LamdaURL = 'https://wh2d4dkgsao5kbwpjxbmchcjja0cxjhv.lambda-url.ap-south-1.on.aws/';
103
107
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
104
108
  if ( resultData ) {
@@ -139,6 +143,7 @@ export const overallCardsV1 = async ( req, res ) => {
139
143
  export const overallHourlyChartV1 = async ( req, res ) => {
140
144
  try {
141
145
  let reqestData = req.body;
146
+ reqestData.hourFormat = 12;
142
147
  let LamdaURL = 'https://p3xcs56mkjj4sfugvsibhyto3i0gdbda.lambda-url.ap-south-1.on.aws/';
143
148
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
144
149
  if ( resultData ) {
@@ -239,6 +244,7 @@ export const buyerChartV1 = async ( req, res ) => {
239
244
  export const footfallDirectoryFoldersV1 = async ( req, res ) => {
240
245
  try {
241
246
  let reqestData = req.body;
247
+ reqestData.hourFormat = 12;
242
248
  let LamdaURL = 'https://waxlhd7lfdlmyrkrdyv77najka0ayihq.lambda-url.ap-south-1.on.aws/';
243
249
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
244
250
  if ( resultData ) {
@@ -283,7 +289,26 @@ export const summaryTableV1 = async ( req, res ) => {
283
289
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
284
290
  if ( resultData ) {
285
291
  if ( resultData.status_code == '200' ) {
286
- return res.sendSuccess( resultData );
292
+ if ( reqestData.export ) {
293
+ if ( resultData.summaryData.length>0 ) {
294
+ const exportdata = [];
295
+ resultData.summaryData.forEach( ( element ) => {
296
+ exportdata.push( {
297
+ 'storeName': element.storeName,
298
+ 'storeId': element.storeId,
299
+ 'potentialBuyersCount': element.potentialBuyersCount,
300
+ 'bouncedCounte': element.bouncedCount,
301
+ 'engagersCount': element.engagersCount,
302
+ 'conversionRate': element.conversionRate,
303
+ } );
304
+ } );
305
+ return await download( exportdata, res );
306
+ } else {
307
+ return res.sendError( 'No Content', 204 );
308
+ }
309
+ } else {
310
+ return res.sendSuccess( resultData );
311
+ }
287
312
  } else {
288
313
  return res.sendError( 'No Content', 204 );
289
314
  }
@@ -362,7 +387,7 @@ export const storesMapV1 = async ( req, res ) => {
362
387
  const storeList = [
363
388
  {
364
389
  $match: {
365
- clientId: { $eq: '11' },
390
+ clientId: { $eq: reqestData.clientId },
366
391
  storeId: { $in: reqestData.storeId },
367
392
  $and: [
368
393
  { 'storeProfile.latitude': { $exists: true } },
@@ -383,11 +408,11 @@ export const storesMapV1 = async ( req, res ) => {
383
408
  'businessType': 1,
384
409
  'storeType': 1,
385
410
  'avgFootfall': '100',
386
- 'avgWeekdayFootfall': '30',
387
- 'avgWeekendFootfall': '60',
388
- 'hourlyFootfall': '60',
389
- 'openTime': '10:31 AM',
390
- 'closeTime': '10:31 PM',
411
+ 'avgWeekdayFootfall': '',
412
+ 'avgWeekendFootfall': '',
413
+ 'hourlyFootfall': '',
414
+ 'openTime': '',
415
+ 'closeTime': '',
391
416
  },
392
417
  },
393
418
  {
@@ -402,23 +427,45 @@ export const storesMapV1 = async ( req, res ) => {
402
427
  if ( !getStores ) {
403
428
  return res.sendError( 'No Content', 204 );
404
429
  } else {
405
- // let LamdaURL = 'https://luliwxsfuncjvpjbbilhwxp52q0zacvc.lambda-url.ap-south-1.on.aws/';
406
- // let resultData = await LamdaServiceCall( LamdaURL, reqestData );
407
- // if ( resultData ) {
408
- // if ( resultData.status_code == '200' ) {
409
- // return res.sendSuccess( resultData );
410
- // } else {
411
- // return res.sendError( 'No Content', 204 );
412
- // }
413
- // } else {
414
- // return res.sendError( 'No Content', 204 );
415
- // }
430
+ if ( getStores.length >0 ) {
431
+ reqestData.fromDate = reqestData.storeDate;
432
+ reqestData.toDate = reqestData.storeDate;
433
+ let hourlyLamdaURL = 'https://ksxkjnhwwzvrgp7ngttw2ribsy0twqip.lambda-url.ap-south-1.on.aws/';
434
+ let hourlyResultData = await LamdaServiceCall( hourlyLamdaURL, reqestData );
435
+ if ( hourlyResultData && hourlyResultData.status_code == '200' && hourlyResultData.hourData.length>0 ) {
436
+ for ( let i = 0; i < getStores.length; i++ ) {
437
+ for ( let j = 0; j < hourlyResultData.hourData.length; j++ ) {
438
+ if ( getStores[i].storeId == hourlyResultData.hourData[j].storeId ) {
439
+ getStores[i].hourlyFootfall = hourlyResultData.hourData[j].hourlyFootfall;
440
+ getStores[i].openTime = hourlyResultData.hourData[j].openTime;
441
+ getStores[i].closeTime = hourlyResultData.hourData[j].closeTime;
442
+ }
443
+ }
444
+ }
445
+ }
446
+ let fromDate = new Date( dayjs( reqestData.fromDate ).subtract( 30, 'days' ) );
447
+ reqestData.fromDate = dayjs( fromDate ).format( 'YYYY-MM-DD' );
448
+ let footfallLamdaURL = 'https://3ircml3r6dm7fbiif3ti2wwdee0zqhyb.lambda-url.ap-south-1.on.aws/';
449
+ let footfallResultData = await LamdaServiceCall( footfallLamdaURL, reqestData );
450
+ if ( footfallResultData && footfallResultData.status_code == '200' && footfallResultData.avgData.length>0 ) {
451
+ for ( let k = 0; k < getStores.length; k++ ) {
452
+ for ( let l = 0; l < footfallResultData.avgData.length; l++ ) {
453
+ if ( getStores[k].storeId == footfallResultData.avgData[l].storeId ) {
454
+ getStores[k].avgWeekendFootfall = footfallResultData.avgData[l].avgWeekendFootfall;
455
+ getStores[k].avgWeekdayFootfall = footfallResultData.avgData[l].avgWeekdayFootfall;
456
+ getStores[k].avgFootfall = footfallResultData.avgData[l].avgFootfall;
457
+ }
458
+ }
459
+ }
460
+ }
461
+ return res.sendSuccess( { storeData: getStores } );
462
+ } else {
463
+ return res.sendError( 'No Content', 204 );
464
+ }
416
465
  }
417
-
418
- return res.sendSuccess( getStores );
419
466
  } catch ( error ) {
420
- console.log( 'error =>', error );
421
- logger.error( { error: error, message: req.query, function: 'trafficCards' } );
467
+ console.log( 'storesMapV1 error =>', error );
468
+ logger.error( { error: error, message: req.query, function: 'storesMapV1' } );
422
469
  return res.sendError( { error: error }, 500 );
423
470
  }
424
471
  };
@@ -480,31 +527,40 @@ export const headerGroupsV1 = async ( req, res ) => {
480
527
  let getUserType = req.user.userType;
481
528
  let getRole = req.user.role;
482
529
  let groupIds;
483
- if ( getUserType == 'tango' ) {
484
- groupIds = await getGroupIds( requestData.clientId );
485
- } else if ( getUserType == 'client' ) {
486
- if ( getRole == 'superadmin' ) {
487
- groupIds = await getGroupIds( requestData.clientId );
530
+ if ( requestData.city && requestData.city.length>0 ) {
531
+ let getGroupIds = await getCityStores( requestData.clientId, getUserEmail, getRole, requestData.city, getUserType );
532
+ if ( getGroupIds && getGroupIds.length>0 ) {
533
+ groupIds = getGroupIds;
488
534
  } else {
489
- const assignedQuery = {
490
- clientId: requestData.clientId,
491
- userEmail: getUserEmail,
492
- };
493
- const getAssignedType = await findOneUserAssignedStore( assignedQuery );
494
- if ( getAssignedType ) {
495
- if ( getAssignedType.userType == 'client' ) {
496
- if ( getAssignedType.assignedType == 'group' ) {
497
- groupIds = await getAssignedGroupIds( requestData.clientId, getUserEmail );
535
+ groupIds = [];
536
+ }
537
+ } else {
538
+ if ( getUserType == 'tango' ) {
539
+ groupIds = await getGroupIds( requestData.clientId );
540
+ } else if ( getUserType == 'client' ) {
541
+ if ( getRole == 'superadmin' ) {
542
+ groupIds = await getGroupIds( requestData.clientId );
543
+ } else {
544
+ const assignedQuery = {
545
+ clientId: requestData.clientId,
546
+ userEmail: getUserEmail,
547
+ };
548
+ const getAssignedType = await findOneUserAssignedStore( assignedQuery );
549
+ if ( getAssignedType ) {
550
+ if ( getAssignedType.userType == 'client' ) {
551
+ if ( getAssignedType.assignedType == 'group' ) {
552
+ groupIds = await getAssignedGroupIds( requestData.clientId, getUserEmail );
553
+ }
554
+ } else {
555
+ groupIds = [];
498
556
  }
499
557
  } else {
500
558
  groupIds = [];
501
559
  }
502
- } else {
503
- groupIds = [];
504
560
  }
561
+ } else {
562
+ groupIds = [];
505
563
  }
506
- } else {
507
- groupIds = [];
508
564
  }
509
565
 
510
566
  if ( groupIds && groupIds.length > 0 ) {
@@ -1002,6 +1058,129 @@ async function getAssignedGroupIds( userClientId, getUserEmail ) {
1002
1058
  }
1003
1059
  }
1004
1060
 
1061
+ async function getCityStores( userClientId, getUserEmail, getRole, requestCity, getUserType ) {
1062
+ try {
1063
+ if ( userClientId && userClientId !='' && getUserEmail && getUserEmail !='', getRole && getRole !='', requestCity && requestCity.length>0 ) {
1064
+ let cityStores = await getLocationStores( userClientId, requestCity );
1065
+ if ( cityStores && cityStores.length > 0 ) {
1066
+ let storeGroups = await getGroupStoresIds( userClientId, cityStores, getRole, getUserType, getUserEmail );
1067
+ if ( storeGroups && storeGroups.length > 0 ) {
1068
+ return storeGroups;
1069
+ } else {
1070
+ return false;
1071
+ }
1072
+ } else {
1073
+ return false;
1074
+ }
1075
+ } else {
1076
+ return false;
1077
+ }
1078
+ } catch ( error ) {
1079
+ console.log( 'getAssignedGroupIds error =>', error );
1080
+ logger.error( { error: error, message: data, function: 'getAssignedGroupIds' } );
1081
+ }
1082
+ }
1083
+
1084
+ async function getGroupStoresIds( userClientId, storeIds, getRole, getUserType, getUserEmail ) {
1085
+ try {
1086
+ if ( userClientId && userClientId !='' && storeIds && storeIds !='' && getRole && getRole !='' && getUserType && getUserType !='', getUserEmail && getUserEmail !='' ) {
1087
+ let groupQuery = [];
1088
+ if ( getUserType == 'client' ) {
1089
+ if ( getRole == 'superadmin' ) {
1090
+ groupQuery = [
1091
+ {
1092
+ $match: {
1093
+ $and: [
1094
+ { clientId: { $eq: userClientId } },
1095
+ { storeList: { $in: storeIds } },
1096
+ ],
1097
+ },
1098
+ },
1099
+ {
1100
+ $group: {
1101
+ _id: null,
1102
+ groupName: { $push: '$_id' },
1103
+ },
1104
+ },
1105
+ ];
1106
+ } else {
1107
+ let getAssignedGroupIds = [
1108
+ {
1109
+ $match: {
1110
+ $and: [
1111
+ { clientId: { $eq: userClientId } },
1112
+ { userEmail: { $eq: getUserEmail } },
1113
+ ],
1114
+ },
1115
+ },
1116
+ {
1117
+ $group: {
1118
+ _id: null,
1119
+ groupName: { $push: '$assignedValue' },
1120
+ },
1121
+ },
1122
+ ];
1123
+ const assignedGroups = await aggregateUserAssignedStore( getAssignedGroupIds );
1124
+ if ( assignedGroups && assignedGroups.length>0 && assignedGroups[0]?.groupName.length > 0 ) {
1125
+ let uniqueGroups = [ ...new Set( assignedGroups[0].groupName ) ];
1126
+ let uniqueGroupIds = [];
1127
+ for ( let i = 0; i < uniqueGroups.length; i++ ) {
1128
+ uniqueGroupIds.push( new ObjectId( uniqueGroups[i] ) );
1129
+ }
1130
+ groupQuery = [
1131
+ {
1132
+ $match: {
1133
+ $and: [
1134
+ { clientId: { $eq: userClientId } },
1135
+ { storeList: { $in: storeIds } },
1136
+ { _id: { $in: uniqueGroupIds } },
1137
+ ],
1138
+ },
1139
+ },
1140
+ {
1141
+ $group: {
1142
+ _id: null,
1143
+ groupName: { $push: '$_id' },
1144
+ },
1145
+ },
1146
+ ];
1147
+ }
1148
+ }
1149
+ } else if ( getUserType == 'tango' ) {
1150
+ groupQuery = [
1151
+ {
1152
+ $match: {
1153
+ $and: [
1154
+ { clientId: { $eq: userClientId } },
1155
+ { storeList: { $in: storeIds } },
1156
+ ],
1157
+ },
1158
+ },
1159
+ {
1160
+ $group: {
1161
+ _id: null,
1162
+ groupName: { $push: '$_id' },
1163
+ },
1164
+ },
1165
+ ];
1166
+ }
1167
+
1168
+ const groupGroupIds = await aggregateGroup( groupQuery );
1169
+ if ( groupGroupIds && groupGroupIds.length>0 && groupGroupIds[0]?.groupName.length > 0 ) {
1170
+ let uniqueGroupIds = [ ...new Set( groupGroupIds[0].groupName ) ];
1171
+ return uniqueGroupIds;
1172
+ } else {
1173
+ return false;
1174
+ }
1175
+ } else {
1176
+ return false;
1177
+ }
1178
+ } catch ( error ) {
1179
+ console.log( 'getGroupIds error =>', error );
1180
+ logger.error( { error: error, message: data, function: 'getGroupIds' } );
1181
+ }
1182
+ }
1183
+
1005
1184
  export async function isAllowedClient( req, res, next ) {
1006
1185
  try {
1007
1186
  let reqestData = req.body;
@@ -42,7 +42,6 @@ export const validateRecapVideoParams = {
42
42
  export const validateDensityDwellSchema = joi.object( {
43
43
  ...baseSchema,
44
44
  dateRange: joi.number().required(),
45
- hourFormat: joi.number().required(),
46
45
  } );
47
46
 
48
47
  export const validateDensityDwellParams = {
@@ -61,7 +60,6 @@ export const validateOverallCardsParams = {
61
60
 
62
61
  export const validateOverallHourlyChartSchema = joi.object( {
63
62
  ...baseSchema,
64
- hourFormat: joi.number().required(),
65
63
  processType: joi.string().required(),
66
64
  } );
67
65
 
@@ -140,6 +138,7 @@ export const validateSummaryTableSchema = joi.object( {
140
138
  sort: joi.string().optional().allow( '' ),
141
139
  limit: joi.number().required(),
142
140
  offset: joi.number().required(),
141
+ export: joi.boolean().required(),
143
142
  } );
144
143
 
145
144
  export const validateSummaryTableParams = {