tango-app-api-analysis-traffic 3.0.0-alpha.2 → 3.0.0-alpha.21

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.
@@ -1,10 +1,15 @@
1
- import { logger } from 'tango-app-api-middleware';
1
+ import { logger, download, signedUrl } from 'tango-app-api-middleware';
2
2
  import * as clientService from '../services/clients.services.js';
3
3
  import {
4
4
  aggregateStore,
5
+ findOneStore,
5
6
  } from '../services/stores.service.js';
6
7
  import { aggregateUserAssignedStore, findOneUserAssignedStore } from '../services/userAssignedStore.service.js';
7
8
  import { aggregateGroup } from '../services/group.service.js';
9
+ import dayjs from 'dayjs';
10
+ import mongoose from 'mongoose';
11
+ const ObjectId = mongoose.Types.ObjectId;
12
+ import { findCamera } from '../services/camera.service.js';
8
13
 
9
14
  // Lamda Service Call //
10
15
  async function LamdaServiceCall( url, data ) {
@@ -24,8 +29,8 @@ async function LamdaServiceCall( url, data ) {
24
29
  const json = await response.json();
25
30
  return json;
26
31
  } catch ( error ) {
27
- console.log( 'error =>', error );
28
32
  logger.error( { error: error, message: data, function: 'LamdaServiceCall' } );
33
+ return false;
29
34
  }
30
35
  }
31
36
 
@@ -99,6 +104,7 @@ export const recapVideoV1 = async ( req, res ) => {
99
104
  export const densityDwellV1 = async ( req, res ) => {
100
105
  try {
101
106
  let reqestData = req.body;
107
+ reqestData.hourFormat = 12;
102
108
  let LamdaURL = 'https://wh2d4dkgsao5kbwpjxbmchcjja0cxjhv.lambda-url.ap-south-1.on.aws/';
103
109
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
104
110
  if ( resultData ) {
@@ -119,6 +125,14 @@ export const densityDwellV1 = async ( req, res ) => {
119
125
  export const overallCardsV1 = async ( req, res ) => {
120
126
  try {
121
127
  let reqestData = req.body;
128
+ if ( reqestData.processType && reqestData.processType == 'missedOpportunity' ) {
129
+ let getClientData = await clientService.findOne( { clientId: reqestData.clientId } );
130
+ if ( !getClientData ) {
131
+ return res.sendError( 'Invalid Client Id', 400 );
132
+ }
133
+ reqestData.currency = getClientData.paymentInvoice?.currencyType || 'INR';
134
+ reqestData.revenue = getClientData.averageTransactionValue || '0';
135
+ }
122
136
  let LamdaURL = 'https://dugu3ghkgalnpaydf2wdjp37240pzcmy.lambda-url.ap-south-1.on.aws/';
123
137
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
124
138
  if ( resultData ) {
@@ -139,6 +153,7 @@ export const overallCardsV1 = async ( req, res ) => {
139
153
  export const overallHourlyChartV1 = async ( req, res ) => {
140
154
  try {
141
155
  let reqestData = req.body;
156
+ reqestData.hourFormat = 12;
142
157
  let LamdaURL = 'https://p3xcs56mkjj4sfugvsibhyto3i0gdbda.lambda-url.ap-south-1.on.aws/';
143
158
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
144
159
  if ( resultData ) {
@@ -239,6 +254,7 @@ export const buyerChartV1 = async ( req, res ) => {
239
254
  export const footfallDirectoryFoldersV1 = async ( req, res ) => {
240
255
  try {
241
256
  let reqestData = req.body;
257
+ reqestData.hourFormat = 12;
242
258
  let LamdaURL = 'https://waxlhd7lfdlmyrkrdyv77najka0ayihq.lambda-url.ap-south-1.on.aws/';
243
259
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
244
260
  if ( resultData ) {
@@ -283,7 +299,39 @@ export const summaryTableV1 = async ( req, res ) => {
283
299
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
284
300
  if ( resultData ) {
285
301
  if ( resultData.status_code == '200' ) {
286
- return res.sendSuccess( resultData );
302
+ if ( reqestData.export ) {
303
+ if ( resultData.summaryData.length>0 ) {
304
+ const exportdata = [];
305
+ resultData.summaryData.forEach( ( element ) => {
306
+ exportdata.push( {
307
+ 'Store Name': element.storeName,
308
+ 'Store Id': element.storeId,
309
+ 'Footfall Count': element.footfallCount,
310
+ 'Bounced Count': element.bouncedCount,
311
+ 'Engagers Count': element.engagersCount,
312
+ 'Conversion Rate': element.conversionRate,
313
+ 'PotentialBuyers Count': element.potentialBuyersCount,
314
+ 'MissedOpportunity Count': element.missedOpportunityCount,
315
+ 'AVG Dwell Time': element.avgDwellTime,
316
+ 'AVG InfraDown Time': element.avgInfraDowntime,
317
+ 'Male': element.male,
318
+ 'Female': element.female,
319
+ 'below12': element.below12,
320
+ '13-19': element['13-19'],
321
+ '20-30': element['20-30'],
322
+ '31-40': element['31-40'],
323
+ '41-50': element['41-50'],
324
+ '51-60': element['51-60'],
325
+ '60 above': element['60 above'],
326
+ } );
327
+ } );
328
+ return await download( exportdata, res );
329
+ } else {
330
+ return res.sendError( 'No Content', 204 );
331
+ }
332
+ } else {
333
+ return res.sendSuccess( resultData );
334
+ }
287
335
  } else {
288
336
  return res.sendError( 'No Content', 204 );
289
337
  }
@@ -336,19 +384,59 @@ export const storeOperationV1 = async ( req, res ) => {
336
384
  }
337
385
  };
338
386
 
387
+ export const performanceMatrixV1 = async ( req, res ) => {
388
+ try {
389
+ let reqestData = req.body;
390
+ let LamdaURL = 'https://5l3pjpivqpyboludmbridailpu0axrov.lambda-url.ap-south-1.on.aws/';
391
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
392
+ if ( resultData ) {
393
+ if ( resultData.status_code == '200' ) {
394
+ return res.sendSuccess( resultData );
395
+ } else {
396
+ return res.sendError( 'No Content', 204 );
397
+ }
398
+ } else {
399
+ return res.sendError( 'No Content', 204 );
400
+ }
401
+ } catch ( error ) {
402
+ logger.error( { error: error, message: req.query, function: 'performanceMatrixV1' } );
403
+ return res.sendError( { error: error }, 500 );
404
+ }
405
+ };
406
+
407
+ export const zoneDwellTimeSplitV1 = async ( req, res ) => {
408
+ try {
409
+ let reqestData = req.body;
410
+ let LamdaURL = 'https://7tfzazsi6lcejnjdzijv7bwg7y0yxhdx.lambda-url.ap-south-1.on.aws/';
411
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
412
+ if ( resultData ) {
413
+ if ( resultData.status_code == '200' ) {
414
+ return res.sendSuccess( resultData );
415
+ } else {
416
+ return res.sendError( 'No Content', 204 );
417
+ }
418
+ } else {
419
+ return res.sendError( 'No Content', 204 );
420
+ }
421
+ } catch ( error ) {
422
+ logger.error( { error: error, message: req.query, function: 'trafficCards' } );
423
+ return res.sendError( { error: error }, 500 );
424
+ }
425
+ };
426
+
339
427
  export const storesMapV1 = async ( req, res ) => {
340
428
  try {
341
429
  let reqestData = req.body;
342
430
  const storeList = [
343
431
  {
344
432
  $match: {
345
- clientId: { $eq: '11' },
433
+ clientId: { $eq: reqestData.clientId },
346
434
  storeId: { $in: reqestData.storeId },
347
435
  $and: [
348
436
  { 'storeProfile.latitude': { $exists: true } },
349
437
  { 'storeProfile.latitude': { $gt: 0 } },
350
- { 'storeProfile.latitude': { $exists: true } },
351
- { 'storeProfile.latitude': { $gt: 0 } },
438
+ { 'storeProfile.longitude': { $exists: true } },
439
+ { 'storeProfile.longitude': { $gt: 0 } },
352
440
  ],
353
441
  },
354
442
  },
@@ -359,15 +447,17 @@ export const storesMapV1 = async ( req, res ) => {
359
447
  'storeName': 1,
360
448
  'appId': 1,
361
449
  'storeProfile': 1,
450
+ 'lat': '$storeProfile.latitude',
451
+ 'lng': '$storeProfile.longitude',
362
452
  'spocDetails': { $arrayElemAt: [ '$spocDetails', 0 ] },
363
453
  'businessType': 1,
364
454
  'storeType': 1,
365
- 'avgFootfall': '100',
366
- 'avgWeekdayFootfall': '30',
367
- 'avgWeekendFootfall': '60',
368
- 'hourlyFootfall': '60',
369
- 'openTime': '10:31 AM',
370
- 'closeTime': '10:31 PM',
455
+ 'avgFootfall': '',
456
+ 'avgWeekdayFootfall': '',
457
+ 'avgWeekendFootfall': '',
458
+ 'hourlyFootfall': '',
459
+ 'openTime': '',
460
+ 'closeTime': '',
371
461
  },
372
462
  },
373
463
  {
@@ -382,23 +472,14 @@ export const storesMapV1 = async ( req, res ) => {
382
472
  if ( !getStores ) {
383
473
  return res.sendError( 'No Content', 204 );
384
474
  } else {
385
- // let LamdaURL = 'https://luliwxsfuncjvpjbbilhwxp52q0zacvc.lambda-url.ap-south-1.on.aws/';
386
- // let resultData = await LamdaServiceCall( LamdaURL, reqestData );
387
- // if ( resultData ) {
388
- // if ( resultData.status_code == '200' ) {
389
- // return res.sendSuccess( resultData );
390
- // } else {
391
- // return res.sendError( 'No Content', 204 );
392
- // }
393
- // } else {
394
- // return res.sendError( 'No Content', 204 );
395
- // }
475
+ if ( getStores.length >0 ) {
476
+ return res.sendSuccess( { storeData: getStores } );
477
+ } else {
478
+ return res.sendError( 'No Content', 204 );
479
+ }
396
480
  }
397
-
398
- return res.sendSuccess( getStores );
399
481
  } catch ( error ) {
400
- console.log( 'error =>', error );
401
- logger.error( { error: error, message: req.query, function: 'trafficCards' } );
482
+ logger.error( { error: error, message: req.query, function: 'storesMapV1' } );
402
483
  return res.sendError( { error: error }, 500 );
403
484
  }
404
485
  };
@@ -407,13 +488,16 @@ export const headerLocationsV1 = async ( req, res ) => {
407
488
  try {
408
489
  let reqestData = req.body;
409
490
  let getUserEmail = req.user.email;
491
+ let getUserType = req.user.userType;
492
+ let getRole = req.user.role;
410
493
  let getClientId = reqestData.clientId;
411
- let totalStores = await getAllStores( getUserEmail, getClientId );
494
+ let totalStores = await getAllStores( getUserEmail, getClientId, getUserType, getRole );
412
495
  if ( totalStores && totalStores.length>0 ) {
413
496
  let storeQuery = [
414
497
  {
415
498
  $match: {
416
499
  $and: [
500
+ { clientId: { $eq: getClientId } },
417
501
  { storeId: { $in: totalStores } },
418
502
  ],
419
503
  },
@@ -452,68 +536,75 @@ export const headerLocationsV1 = async ( req, res ) => {
452
536
 
453
537
  export const headerGroupsV1 = async ( req, res ) => {
454
538
  try {
455
- // let requestData = req.body;
539
+ let requestData = req.body;
456
540
  let getUserEmail = req.user.email;
457
- let groupQuery = [
458
- {
459
- $match: {
460
- $and: [
461
- { userEmail: { $eq: getUserEmail } },
462
- { assignedType: { $eq: 'group' } },
463
- ],
464
- },
465
- },
466
- {
467
- $group: {
468
- _id: '$assignedValue',
469
- },
470
- },
471
- {
472
- $lookup: {
473
- from: 'groups',
474
- let: { groupId: { $toObjectId: '$_id' } },
475
- pipeline: [
476
- {
477
- $match: {
478
- $expr: {
479
- $eq: [ '$_id', '$$groupId' ],
480
- },
481
- },
482
- },
483
- {
484
- $project: {
485
- _id: 0,
486
- groupName: 1,
487
- },
488
- },
489
- ], as: 'groups',
490
- },
491
- },
492
- {
493
- $unwind: {
494
- path: '$groups', preserveNullAndEmptyArrays: true,
495
- },
496
- },
497
- {
498
- $unwind: {
499
- path: '$groups.groupName', preserveNullAndEmptyArrays: true,
541
+ let getUserType = req.user.userType;
542
+ let getRole = req.user.role;
543
+ let groupIds;
544
+ if ( requestData.city && requestData.city.length>0 ) {
545
+ let getGroupIds = await getCityStores( requestData.clientId, getUserEmail, getRole, requestData.city, getUserType );
546
+ if ( getGroupIds && getGroupIds.length>0 ) {
547
+ groupIds = getGroupIds;
548
+ } else {
549
+ groupIds = [];
550
+ }
551
+ } else {
552
+ if ( getUserType == 'tango' ) {
553
+ groupIds = await getGroupIds( requestData.clientId );
554
+ } else if ( getUserType == 'client' ) {
555
+ if ( getRole == 'superadmin' ) {
556
+ groupIds = await getGroupIds( requestData.clientId );
557
+ } else {
558
+ const assignedQuery = {
559
+ clientId: requestData.clientId,
560
+ userEmail: getUserEmail,
561
+ };
562
+ const getAssignedType = await findOneUserAssignedStore( assignedQuery );
563
+ if ( getAssignedType ) {
564
+ if ( getAssignedType.userType == 'client' ) {
565
+ if ( getAssignedType.assignedType == 'group' ) {
566
+ groupIds = await getAssignedGroupIds( requestData.clientId, getUserEmail );
567
+ }
568
+ } else {
569
+ groupIds = [];
570
+ }
571
+ } else {
572
+ groupIds = [];
573
+ }
574
+ }
575
+ } else {
576
+ groupIds = [];
577
+ }
578
+ }
579
+
580
+ if ( groupIds && groupIds.length > 0 ) {
581
+ let groupQuery = [
582
+ {
583
+ $match: {
584
+ $and: [
585
+ { clientId: { $eq: requestData.clientId } },
586
+ { _id: { $in: groupIds } },
587
+ ],
588
+ },
500
589
  },
501
- },
502
- {
503
- $project: {
504
- _id: 0,
505
- groupName: '$groups.groupName',
590
+ {
591
+ $project: {
592
+ _id: 0,
593
+ groupName: 1,
594
+ },
506
595
  },
507
- },
508
- ];
509
- const groupList = await aggregateUserAssignedStore( groupQuery );
510
- if ( groupList && groupList.length > 0 ) {
511
- return res.sendSuccess( { groupData: groupList } );
596
+ ];
597
+ const groupResult = await aggregateGroup( groupQuery );
598
+ if ( groupResult && groupResult.length > 0 ) {
599
+ return res.sendSuccess( { groupData: groupResult } );
600
+ } else {
601
+ return res.sendError( 'No Group', 400 );
602
+ }
512
603
  } else {
513
604
  return res.sendError( 'No Group', 400 );
514
605
  }
515
606
  } catch ( error ) {
516
- logger.error( { error: error, message: req.query, function: 'trafficCards' } );
607
+ logger.error( { error: error, message: req.query, function: 'headerGroupsV1' } );
517
608
  return res.sendError( { error: error }, 500 );
518
609
  }
519
610
  };
@@ -522,8 +613,10 @@ export const headerStoresV1 = async ( req, res ) => {
522
613
  try {
523
614
  let reqestData = req.body;
524
615
  let getUserEmail = req.user.email;
616
+ let getUserType = req.user.userType;
617
+ let getRole = req.user.role;
525
618
  let getClientId = reqestData.clientId;
526
- let totalStores = await getAllStores( getUserEmail, getClientId );
619
+ let totalStores = await getAllStores( getUserEmail, getClientId, getUserType, getRole );
527
620
  if ( totalStores && totalStores.length>0 ) {
528
621
  let storeQuery = [];
529
622
  if ( reqestData.city.length>0 && reqestData.group.length>0 ) {
@@ -586,7 +679,7 @@ export const headerStoresV1 = async ( req, res ) => {
586
679
  },
587
680
  ];
588
681
  } else {
589
- let totalStores = await getAllStores( getUserEmail, getClientId );
682
+ let totalStores = await getAllStores( getUserEmail, getClientId, getUserType, getRole );
590
683
  storeQuery = [
591
684
  {
592
685
  $match: {
@@ -607,7 +700,7 @@ export const headerStoresV1 = async ( req, res ) => {
607
700
 
608
701
  const storeList = await aggregateStore( storeQuery );
609
702
  if ( storeList && storeList.length > 0 ) {
610
- return res.sendSuccess( storeList );
703
+ return res.sendSuccess( { storesData: storeList } );
611
704
  } else {
612
705
  return res.sendError( 'No Stores', 400 );
613
706
  }
@@ -615,72 +708,70 @@ export const headerStoresV1 = async ( req, res ) => {
615
708
  return res.sendError( 'No Stores', 400 );
616
709
  }
617
710
  } catch ( error ) {
618
- console.log( 'headerStoresV1 =>', error );
619
711
  logger.error( { error: error, message: req.query, function: 'headerStoresV1' } );
620
712
  return res.sendError( { error: error }, 500 );
621
713
  }
622
714
  };
623
715
 
624
- async function getAllStores( getUserEmail, getClientId ) {
716
+ async function getAllStores( getUserEmail, getClientId, getUserType, getRole ) {
625
717
  try {
626
- if ( getUserEmail && getUserEmail !='' ) {
627
- const assignedQuery = {
628
- clientId: getClientId,
629
- userEmail: getUserEmail,
630
- };
631
- const getAssignedType = await findOneUserAssignedStore( assignedQuery );
632
- if ( getAssignedType ) {
633
- if ( getAssignedType.userType == 'client' ) {
634
- if ( getAssignedType.assignedType && getAssignedType.assignedType !='' ) {
635
- let overAllStores = [];
636
- switch ( getAssignedType.assignedType ) {
637
- case 'store':
638
- let getAS = await getAssignedStores( getClientId, getUserEmail, 'store' );
639
- if ( getAS && getAS.length >0 ) {
640
- overAllStores = getAS;
641
- }
642
- break;
643
- case 'group':
644
- let getAGS = await getAssignedGroupStores( getClientId, getUserEmail, 'group' );
645
- if ( getAGS && getAGS.length >0 ) {
646
- overAllStores = getAGS;
647
- }
648
- break;
649
- case 'allstores':
650
- let getAllS = await getAssignedAllStores( getClientId );
651
- if ( getAllS && getAllS.length >0 ) {
652
- overAllStores = getAllS;
653
- }
654
- break;
655
- default:
656
- break;
657
- }
658
- return overAllStores;
659
- } else {
660
- return false;
718
+ if ( getUserEmail && getUserEmail !='' && getClientId && getClientId !='' && getUserType && getUserType !='' && getRole && getRole!='' ) {
719
+ let overAllStores = [];
720
+ if ( getUserType == 'tango' ) {
721
+ let getAllS = await getAssignedAllStores( getClientId );
722
+ if ( getAllS && getAllS.length >0 ) {
723
+ overAllStores = getAllS;
724
+ }
725
+ return overAllStores;
726
+ } else if ( getUserType == 'client' ) {
727
+ if ( getRole == 'superadmin' ) {
728
+ let getAllS = await getAssignedAllStores( getClientId );
729
+ if ( getAllS && getAllS.length >0 ) {
730
+ overAllStores = getAllS;
661
731
  }
662
- } else if ( getAssignedType.userType == 'tango' ) {
663
- if ( getAssignedType.assignedType && getAssignedType.assignedType !='' ) {
664
- let overAllStores = [];
665
- let getAllS = await getAssignedAllStores( getClientId );
666
- if ( getAllS && getAllS.length >0 ) {
667
- overAllStores = getAllS;
732
+ return overAllStores;
733
+ } else {
734
+ const assignedQuery = {
735
+ clientId: getClientId,
736
+ userEmail: getUserEmail,
737
+ };
738
+ const getAssignedType = await findOneUserAssignedStore( assignedQuery );
739
+ if ( getAssignedType ) {
740
+ if ( getAssignedType.userType == 'client' ) {
741
+ if ( getAssignedType.assignedType && getAssignedType.assignedType !='' ) {
742
+ let overAllStores = [];
743
+ switch ( getAssignedType.assignedType ) {
744
+ case 'store':
745
+ let getAS = await getAssignedStores( getClientId, getUserEmail, 'store' );
746
+ if ( getAS && getAS.length >0 ) {
747
+ overAllStores = getAS;
748
+ }
749
+ break;
750
+ case 'group':
751
+ let getAGS = await getAssignedGroupStores( getClientId, getUserEmail, 'group' );
752
+ if ( getAGS && getAGS.length >0 ) {
753
+ overAllStores = getAGS;
754
+ }
755
+ break;
756
+ default:
757
+ break;
758
+ }
759
+ return overAllStores;
760
+ } else {
761
+ return false;
762
+ }
763
+ } else {
764
+ return false;
668
765
  }
669
- return overAllStores;
670
766
  } else {
671
767
  return false;
672
768
  }
673
- } else {
674
- return false;
675
769
  }
676
- } else {
677
- return false;
678
770
  }
679
771
  } else {
680
772
  return false;
681
773
  }
682
774
  } catch ( error ) {
683
- console.log( 'getAllStores =>', error );
684
775
  logger.error( { error: error, message: req.query, function: 'getAllStores' } );
685
776
  }
686
777
  };
@@ -716,8 +807,8 @@ async function getAssignedStores( clientId, userEmail, assignedType ) {
716
807
  return false;
717
808
  }
718
809
  } catch ( error ) {
719
- console.log( 'getAssignedStores error =>', error );
720
810
  logger.error( { error: error, message: data, function: 'getAssignedStores' } );
811
+ return false;
721
812
  }
722
813
  }
723
814
 
@@ -783,8 +874,8 @@ async function getAssignedGroupStores( clientId, userEmail, assignedType ) {
783
874
  return false;
784
875
  }
785
876
  } catch ( error ) {
786
- console.log( 'getAssignedGroupStores error =>', error );
787
877
  logger.error( { error: error, message: data, function: 'getAssignedGroupStores' } );
878
+ return false;
788
879
  }
789
880
  }
790
881
 
@@ -818,8 +909,8 @@ async function getAssignedAllStores( userClientId ) {
818
909
  return false;
819
910
  }
820
911
  } catch ( error ) {
821
- console.log( 'getAssignedAllStores error =>', error );
822
912
  logger.error( { error: error, message: data, function: 'getAssignedAllStores' } );
913
+ return false;
823
914
  }
824
915
  }
825
916
 
@@ -858,8 +949,8 @@ async function getGroupStores( userClientId, groupList ) {
858
949
  return false;
859
950
  }
860
951
  } catch ( error ) {
861
- console.log( 'getGroupStores error =>', error );
862
952
  logger.error( { error: error, message: data, function: 'getGroupStores' } );
953
+ return false;
863
954
  }
864
955
  }
865
956
 
@@ -899,7 +990,390 @@ async function getLocationStores( userClientId, cityList ) {
899
990
  return false;
900
991
  }
901
992
  } catch ( error ) {
902
- console.log( 'getLocationStores error =>', error );
903
993
  logger.error( { error: error, message: data, function: 'getLocationStores' } );
994
+ return false;
995
+ }
996
+ }
997
+
998
+ async function getGroupIds( userClientId ) {
999
+ try {
1000
+ if ( userClientId && userClientId !='' ) {
1001
+ let groupQuery = [
1002
+ {
1003
+ $match: {
1004
+ $and: [
1005
+ { clientId: { $eq: userClientId } },
1006
+ ],
1007
+ },
1008
+ },
1009
+ {
1010
+ $group: {
1011
+ _id: null,
1012
+ groupName: { $push: '$_id' },
1013
+ },
1014
+ },
1015
+ ];
1016
+ const groupGroupIds = await aggregateGroup( groupQuery );
1017
+ if ( groupGroupIds && groupGroupIds.length>0 && groupGroupIds[0]?.groupName.length > 0 ) {
1018
+ let uniqueGroupIds = [ ...new Set( groupGroupIds[0].groupName ) ];
1019
+ return uniqueGroupIds;
1020
+ } else {
1021
+ return false;
1022
+ }
1023
+ } else {
1024
+ return false;
1025
+ }
1026
+ } catch ( error ) {
1027
+ logger.error( { error: error, message: data, function: 'getGroupIds' } );
1028
+ return false;
904
1029
  }
905
1030
  }
1031
+
1032
+ async function getAssignedGroupIds( userClientId, getUserEmail ) {
1033
+ try {
1034
+ if ( userClientId && userClientId !='' && getUserEmail && getUserEmail !='' ) {
1035
+ let groupQuery = [
1036
+ {
1037
+ $match: {
1038
+ $and: [
1039
+ { clientId: { $eq: userClientId } },
1040
+ { userEmail: { $eq: getUserEmail } },
1041
+ { assignedType: { $eq: 'group' } },
1042
+ ],
1043
+ },
1044
+ },
1045
+ {
1046
+ $group: {
1047
+ _id: null,
1048
+ groupName: { $push: '$assignedValue' },
1049
+ },
1050
+ },
1051
+ ];
1052
+ const groupStoreList = await aggregateUserAssignedStore( groupQuery );
1053
+ if ( groupStoreList && groupStoreList.length>0 && groupStoreList[0]?.groupName.length > 0 ) {
1054
+ let uniqueGroupIdsData = [ ...new Set( groupStoreList[0].groupName ) ];
1055
+ let uniqueGroupIds = [];
1056
+ for ( let i = 0; i < uniqueGroupIdsData.length; i++ ) {
1057
+ uniqueGroupIds.push( new ObjectId( uniqueGroupIdsData[i] ) );
1058
+ }
1059
+ return uniqueGroupIds;
1060
+ } else {
1061
+ return false;
1062
+ }
1063
+ } else {
1064
+ return false;
1065
+ }
1066
+ } catch ( error ) {
1067
+ logger.error( { error: error, message: data, function: 'getAssignedGroupIds' } );
1068
+ return false;
1069
+ }
1070
+ }
1071
+
1072
+ async function getCityStores( userClientId, getUserEmail, getRole, requestCity, getUserType ) {
1073
+ try {
1074
+ if ( userClientId && userClientId !='' && getUserEmail && getUserEmail !='', getRole && getRole !='', requestCity && requestCity.length>0 ) {
1075
+ let cityStores = await getLocationStores( userClientId, requestCity );
1076
+ if ( cityStores && cityStores.length > 0 ) {
1077
+ let storeGroups = await getGroupStoresIds( userClientId, cityStores, getRole, getUserType, getUserEmail );
1078
+ if ( storeGroups && storeGroups.length > 0 ) {
1079
+ return storeGroups;
1080
+ } else {
1081
+ return false;
1082
+ }
1083
+ } else {
1084
+ return false;
1085
+ }
1086
+ } else {
1087
+ return false;
1088
+ }
1089
+ } catch ( error ) {
1090
+ logger.error( { error: error, message: data, function: 'getAssignedGroupIds' } );
1091
+ return false;
1092
+ }
1093
+ }
1094
+
1095
+ async function getGroupStoresIds( userClientId, storeIds, getRole, getUserType, getUserEmail ) {
1096
+ try {
1097
+ if ( userClientId && userClientId !='' && storeIds && storeIds !='' && getRole && getRole !='' && getUserType && getUserType !='', getUserEmail && getUserEmail !='' ) {
1098
+ let groupQuery = [];
1099
+ if ( getUserType == 'client' ) {
1100
+ if ( getRole == 'superadmin' ) {
1101
+ groupQuery = [
1102
+ {
1103
+ $match: {
1104
+ $and: [
1105
+ { clientId: { $eq: userClientId } },
1106
+ { storeList: { $in: storeIds } },
1107
+ ],
1108
+ },
1109
+ },
1110
+ {
1111
+ $group: {
1112
+ _id: null,
1113
+ groupName: { $push: '$_id' },
1114
+ },
1115
+ },
1116
+ ];
1117
+ } else {
1118
+ let getAssignedGroupIds = [
1119
+ {
1120
+ $match: {
1121
+ $and: [
1122
+ { clientId: { $eq: userClientId } },
1123
+ { userEmail: { $eq: getUserEmail } },
1124
+ ],
1125
+ },
1126
+ },
1127
+ {
1128
+ $group: {
1129
+ _id: null,
1130
+ groupName: { $push: '$assignedValue' },
1131
+ },
1132
+ },
1133
+ ];
1134
+ const assignedGroups = await aggregateUserAssignedStore( getAssignedGroupIds );
1135
+ if ( assignedGroups && assignedGroups.length>0 && assignedGroups[0]?.groupName.length > 0 ) {
1136
+ let uniqueGroups = [ ...new Set( assignedGroups[0].groupName ) ];
1137
+ let uniqueGroupIds = [];
1138
+ for ( let i = 0; i < uniqueGroups.length; i++ ) {
1139
+ uniqueGroupIds.push( new ObjectId( uniqueGroups[i] ) );
1140
+ }
1141
+ groupQuery = [
1142
+ {
1143
+ $match: {
1144
+ $and: [
1145
+ { clientId: { $eq: userClientId } },
1146
+ { storeList: { $in: storeIds } },
1147
+ { _id: { $in: uniqueGroupIds } },
1148
+ ],
1149
+ },
1150
+ },
1151
+ {
1152
+ $group: {
1153
+ _id: null,
1154
+ groupName: { $push: '$_id' },
1155
+ },
1156
+ },
1157
+ ];
1158
+ }
1159
+ }
1160
+ } else if ( getUserType == 'tango' ) {
1161
+ groupQuery = [
1162
+ {
1163
+ $match: {
1164
+ $and: [
1165
+ { clientId: { $eq: userClientId } },
1166
+ { storeList: { $in: storeIds } },
1167
+ ],
1168
+ },
1169
+ },
1170
+ {
1171
+ $group: {
1172
+ _id: null,
1173
+ groupName: { $push: '$_id' },
1174
+ },
1175
+ },
1176
+ ];
1177
+ }
1178
+
1179
+ const groupGroupIds = await aggregateGroup( groupQuery );
1180
+ if ( groupGroupIds && groupGroupIds.length>0 && groupGroupIds[0]?.groupName.length > 0 ) {
1181
+ let uniqueGroupIds = [ ...new Set( groupGroupIds[0].groupName ) ];
1182
+ return uniqueGroupIds;
1183
+ } else {
1184
+ return false;
1185
+ }
1186
+ } else {
1187
+ return false;
1188
+ }
1189
+ } catch ( error ) {
1190
+ logger.error( { error: error, message: data, function: 'getGroupIds' } );
1191
+ return false;
1192
+ }
1193
+ }
1194
+
1195
+ export async function isAllowedClient( req, res, next ) {
1196
+ try {
1197
+ let reqestData = req.body;
1198
+ let getUserEmail = req.user.email;
1199
+ let getUserType = req.user.userType;
1200
+ let getClientId = req.user.clientId;
1201
+ let getRole = req.user.role;
1202
+ if ( getUserType == 'tango' ) {
1203
+ if ( getRole == 'superadmin' ) {
1204
+ next();
1205
+ } else {
1206
+ const assignedQuery = {
1207
+ userEmail: getUserEmail,
1208
+ assignedType: 'client',
1209
+ assignedValue: reqestData.clientId,
1210
+ };
1211
+ const getAssignedType = await findOneUserAssignedStore( assignedQuery );
1212
+ if ( getAssignedType ) {
1213
+ next();
1214
+ } else {
1215
+ return res.sendError( 'Client Not Assigned', 400 );
1216
+ }
1217
+ }
1218
+ } else if ( getUserType == 'client' ) {
1219
+ if ( getClientId == reqestData.clientId ) {
1220
+ next();
1221
+ } else {
1222
+ return res.sendError( 'Client Not Assigned', 400 );
1223
+ }
1224
+ } else {
1225
+ return res.sendError( 'Client Not Assigned', 400 );
1226
+ }
1227
+ } catch ( error ) {
1228
+ logger.error( { error: error, function: 'isAllowedClient' } );
1229
+ return res.sendError( error, 500 );
1230
+ }
1231
+ }
1232
+
1233
+ export const getMySubscription = async ( req, res ) => {
1234
+ try {
1235
+ let reqestData = req.body;
1236
+ let getClientData = await clientService.findOne( { clientId: reqestData.clientId }, { planDetails: 1 } );
1237
+ if ( getClientData ) {
1238
+ if ( getClientData.planDetails && getClientData.planDetails.product && getClientData.planDetails.product.length>0 ) {
1239
+ let clientSubscription = {};
1240
+ let clientProducts = {
1241
+ tangoTraffic: false,
1242
+ tangoZone: false,
1243
+ tangoTrax: false,
1244
+ };
1245
+ clientSubscription.subscriptionType = getClientData.planDetails.subscriptionType;
1246
+ let actualProduct = getClientData.planDetails.product;
1247
+ for ( let clientIndex = 0; clientIndex < actualProduct.length; clientIndex++ ) {
1248
+ if ( actualProduct[clientIndex].productName == 'tangoTraffic' ) {
1249
+ clientProducts.tangoTraffic = true;
1250
+ }
1251
+ if ( actualProduct[clientIndex].productName == 'tangoZone' ) {
1252
+ clientProducts.tangoZone = true;
1253
+ }
1254
+ if ( actualProduct[clientIndex].tangoTrax == 'tangoTrax' ) {
1255
+ clientProducts.tangoTrax = true;
1256
+ }
1257
+ }
1258
+ clientSubscription.product = clientProducts;
1259
+ let storeSubscription = {};
1260
+ let storeProducts = {
1261
+ tangoTraffic: false,
1262
+ tangoZone: false,
1263
+ tangoTrax: false,
1264
+ };
1265
+ if ( reqestData.storeId && reqestData.storeId.length>0 ) {
1266
+ let getStoreData = await findOneStore( { clientId: reqestData.clientId, storeId: { $in: reqestData.storeId[0] } }, { product: 1 } );
1267
+ if ( getStoreData ) {
1268
+ for ( let storeIndex = 0; storeIndex < getStoreData.product.length; storeIndex++ ) {
1269
+ if ( getStoreData.product[storeIndex] == 'tangoTraffic' ) {
1270
+ storeProducts.tangoTraffic = true;
1271
+ }
1272
+ if ( getStoreData.product[storeIndex] == 'tangoZone' ) {
1273
+ storeProducts.tangoZone = true;
1274
+ }
1275
+ if ( getStoreData.product[storeIndex] == 'tangoTrax' ) {
1276
+ storeProducts.tangoTrax = true;
1277
+ }
1278
+ }
1279
+ storeSubscription.product = storeProducts;
1280
+ } else {
1281
+ storeSubscription.product = [];
1282
+ }
1283
+ } else {
1284
+ storeSubscription.product = [];
1285
+ }
1286
+ let resultData = { clientSubscription, storeSubscription };
1287
+ return res.sendSuccess( resultData );
1288
+ } else {
1289
+ return res.sendError( 'Not Subscribe', 400 );
1290
+ }
1291
+ } else {
1292
+ return res.sendError( 'Invalid Client Id', 400 );
1293
+ }
1294
+ } catch ( error ) {
1295
+ logger.error( { error: error, message: req.query, function: 'getMySubscription' } );
1296
+ return res.sendError( { error: error }, 500 );
1297
+ }
1298
+ };
1299
+
1300
+ export const getStoreMapData = async ( req, res ) => {
1301
+ try {
1302
+ let reqestData = req.body;
1303
+ if ( reqestData.storeId && reqestData.storeId.length > 0 ) {
1304
+ let cameraBaseImage = '';
1305
+ const bucket= JSON.parse( process.env.BUCKET );
1306
+ if ( bucket && bucket.baseImage && bucket.baseImage != '' ) {
1307
+ const camera = await findCamera( { storeId: reqestData.storeId[0], isUp: true, isActivated: true }, { thumbnailImage: 1 } );
1308
+ if ( camera && camera.thumbnailImage && camera.thumbnailImage != '' ) {
1309
+ const params = {
1310
+ file_path: camera.thumbnailImage,
1311
+ Bucket: bucket.baseImage,
1312
+ };
1313
+ cameraBaseImage = await signedUrl( params );
1314
+ }
1315
+ }
1316
+ reqestData.fromDate = reqestData.storeDate;
1317
+ reqestData.toDate = reqestData.storeDate;
1318
+ let avgData = {
1319
+ 'avgFootfall': '',
1320
+ 'avgWeekdayFootfall': '',
1321
+ 'avgWeekendFootfall': '',
1322
+ };
1323
+ let hourlyData = {
1324
+ 'hourlyFootfall': '',
1325
+ 'openTime': '',
1326
+ 'closeTime': '',
1327
+ };
1328
+ let hourlyLamdaURL = 'https://ksxkjnhwwzvrgp7ngttw2ribsy0twqip.lambda-url.ap-south-1.on.aws/';
1329
+ let hourlyResultData = await LamdaServiceCall( hourlyLamdaURL, reqestData );
1330
+ if ( hourlyResultData && hourlyResultData.hourData.length>0 ) {
1331
+ hourlyData.hourlyFootfall = hourlyResultData.hourData[0].hourlyFootfall;
1332
+ hourlyData.openTime = hourlyResultData.hourData[0].openTime;
1333
+ hourlyData.closeTime = hourlyResultData.hourData[0].closeTime;
1334
+ }
1335
+ let fromDate = new Date( dayjs( reqestData.fromDate ).subtract( 30, 'days' ) );
1336
+ reqestData.fromDate = dayjs( fromDate ).format( 'YYYY-MM-DD' );
1337
+ let footfallLamdaURL = 'https://3ircml3r6dm7fbiif3ti2wwdee0zqhyb.lambda-url.ap-south-1.on.aws/';
1338
+ let footfallResultData = await LamdaServiceCall( footfallLamdaURL, reqestData );
1339
+ if ( footfallResultData && footfallResultData.avgData.length>0 ) {
1340
+ avgData.avgFootfall = footfallResultData.avgData[0].avgFootfall;
1341
+ avgData.avgWeekdayFootfall = footfallResultData.avgData[0].avgWeekdayFootfall;
1342
+ avgData.avgWeekendFootfall = footfallResultData.avgData[0].avgWeekendFootfall;
1343
+ }
1344
+ return res.sendSuccess( { cameraBaseImage: cameraBaseImage, hourlyData: hourlyData, avgData: avgData } );
1345
+ } else {
1346
+ return res.sendError( 'Store Id rewuired', 400 );
1347
+ }
1348
+ } catch ( error ) {
1349
+ logger.error( { error: error, message: req.query, function: 'getMySubscription' } );
1350
+ return res.sendError( { error: error }, 500 );
1351
+ }
1352
+ };
1353
+
1354
+ // async function getGeocodedAddress( lat, lng ) {
1355
+ // try {
1356
+ // const apiKey = 'AIzaSyDlOezgwQO0JviD0aizrCuN1FY9tcWfR3o'; // Use this if you're using dotenv
1357
+ // const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${apiKey}`;
1358
+
1359
+ // const requestOptions = {
1360
+ // method: 'GET',
1361
+ // headers: {
1362
+ // 'Content-Type': 'application/json',
1363
+ // },
1364
+ // };
1365
+ // const response = await fetch( url, requestOptions );
1366
+ // console.log( 'response =>', response );
1367
+ // if ( !response.ok ) {
1368
+ // throw new Error( `Response status: ${response.status}` );
1369
+ // return false;
1370
+ // }
1371
+ // const json = await response.json();
1372
+ // return json;
1373
+ // } catch ( error ) {
1374
+ // console.log( 'getGeocodedAddress error =>', error );
1375
+ // logger.error( { error: error, message: data, function: 'getGeocodedAddress' } );
1376
+ // }
1377
+ // }
1378
+ // let getGEO = await getGeocodedAddress( 12.900260100404893, 80.23384232089138 );
1379
+ // console.log( 'getGEO =>', getGEO );