tango-app-api-analysis-zone 3.4.0 → 3.7.1-alpha.10

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-zone",
3
- "version": "3.4.0",
3
+ "version": "3.7.1-alpha.10",
4
4
  "description": "zone Analysis",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -21,7 +21,7 @@
21
21
  "mongodb": "^6.8.0",
22
22
  "nodemon": "^3.1.4",
23
23
  "tango-api-schema": "^2.2.21",
24
- "tango-app-api-middleware": "^3.1.45",
24
+ "tango-app-api-middleware": "^3.6.8",
25
25
  "winston": "^3.13.1",
26
26
  "winston-daily-rotate-file": "^5.0.0"
27
27
  },
@@ -1,6 +1,6 @@
1
- import { logger, download } from 'tango-app-api-middleware';
1
+ import { logger, download, downloadint, convertSecondstoTimeFormat } from 'tango-app-api-middleware';
2
2
  import { findOneUserAssignedStore } from '../services/userAssignedStore.service.js';
3
-
3
+ import * as clientService from '../services/clients.services.js';
4
4
  // Lamda Service Call //
5
5
  async function LamdaServiceCall( url, data ) {
6
6
  try {
@@ -19,7 +19,7 @@ async function LamdaServiceCall( url, data ) {
19
19
  const json = await response.json();
20
20
  return json;
21
21
  } catch ( error ) {
22
- console.log( 'error =>', error );
22
+ // console.log( 'error =>', error );
23
23
  logger.error( { error: error, message: data, function: 'LamdaServiceCall' } );
24
24
  }
25
25
  }
@@ -108,7 +108,7 @@ export const zoneSummaryTableV1 = async ( req, res ) => {
108
108
  try {
109
109
  let reqestData = req.body;
110
110
  if ( reqestData.export ) {
111
- reqestData.limit = 1000;
111
+ reqestData.limit = 10000;
112
112
  }
113
113
  let LamdaURL = 'https://hxpnn5weq3lm4nqouk4pjm3chy0jmqdb.lambda-url.ap-south-1.on.aws/';
114
114
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
@@ -123,6 +123,8 @@ export const zoneSummaryTableV1 = async ( req, res ) => {
123
123
  'Zone Name': element.zoneName,
124
124
  'Store Name': element.storeName,
125
125
  'Store ID': element.storeId,
126
+ ...( element.storefootfallCount !== undefined && { 'Store FF': element.storefootfallCount } ),
127
+ ...( element.nob !== undefined && { 'Zone Wise NoB': element.nob } ),
126
128
  'Zone Conc.Rate': element.concentrationRate,
127
129
  'Avg Dwell Time (Mins)': element.avgDwellTime,
128
130
  'Zone FF': element.footfallCount,
@@ -138,7 +140,7 @@ export const zoneSummaryTableV1 = async ( req, res ) => {
138
140
  'Female': element.femaleCount,
139
141
  } );
140
142
  } );
141
- return await download( exportdata, res );
143
+ return await downloadint( exportdata, res );
142
144
  } else {
143
145
  return res.sendError( 'No Content', 204 );
144
146
  }
@@ -298,26 +300,28 @@ export const zoneInteractionTable430 = async ( req, res ) => {
298
300
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
299
301
  if ( resultData ) {
300
302
  if ( resultData.status_code == '200' ) {
301
- if ( reqestData.export ) {
302
- if ( resultData.data.length>0 ) {
303
- const exportdata = [];
304
- resultData.data.forEach( ( element ) => {
305
- exportdata.push( {
306
- 'Passer By': element.passer_by || '--',
307
- 'Footfall': element.footfall || '--',
308
- 'Drop In Rate': element.drop_in_rate +'%',
309
- 'Customer Attended ': element.customer_attended || '--',
310
- 'Interation Rate ': element.interaction_rate +'%',
311
- 'Billing Conversion': element.footfall_overamin_inzone || '--',
312
- 'Billing Conversion Rate': element.billing_conversion_rate +'%',
313
- 'Greetings Count': element.greeting_count || '--',
314
- } );
315
- } );
316
- return await download( exportdata, res );
317
- } else {
318
- return res.sendError( 'No Content', 204 );
319
- }
320
- }
303
+ resultData.data[0].assist_time_string = await convertSecondstoTimeFormat( resultData.data[0].assist_time );
304
+ resultData.data[0].avg_interaction_time_string = await convertSecondstoTimeFormat( resultData.data[0].avg_interaction_time );
305
+ // if ( reqestData.export ) {
306
+ // if ( resultData.data.length>0 ) {
307
+ // const exportdata = [];
308
+ // resultData.data.forEach( ( element ) => {
309
+ // exportdata.push( {
310
+ // 'Passer By': element.passer_by || '--',
311
+ // 'Footfall': element.footfall || '--',
312
+ // 'Drop In Rate': element.drop_in_rate +'%',
313
+ // 'Customer Attended ': element.customer_attended || '--',
314
+ // 'Interation Rate ': element.interaction_rate +'%',
315
+ // 'Billing Conversion': element.footfall_overamin_inzone ?? '--',
316
+ // 'Billing Conversion Rate': element.billing_conversion_rate +'%',
317
+ // 'Greetings Count': element.greeting_count ?? '--',
318
+ // } );
319
+ // } );
320
+ // return await download( exportdata, res );
321
+ // } else {
322
+ // return res.sendError( 'No Content', 204 );
323
+ // }
324
+ // }
321
325
  return res.sendSuccess( resultData );
322
326
  } else {
323
327
  return res.sendError( 'No Content', 204 );
@@ -420,7 +424,7 @@ export const zoneInteractionTableExport430 = async ( req, res ) => {
420
424
  exportdata.push( {
421
425
  'Store Id': element.store_id || '--',
422
426
  'Date': element.date || '--',
423
- 'Customer spent more than 10 mins': element.customer_count_over10min || '--',
427
+ 'Customer spent more than 10 mins': element.customer_count_over10min ?? '--',
424
428
  'Billing Conversion': element.billing_conversion || '--',
425
429
  } );
426
430
  } );
@@ -455,7 +459,7 @@ export const zoneConcentrationTableExport = async ( req, res ) => {
455
459
  exportdata.push( {
456
460
  'Date': element.Date,
457
461
  'Zone Name': element.zoneName,
458
- 'Footfall(Actuals)': element.footfallCount || '--',
462
+ 'Footfall(Actuals)': element.footfallCount ?? '--',
459
463
  'DwellTime(Average)': element.avgDwellTime || '--',
460
464
  'Concentration': element.concentrationRate +'%',
461
465
  } );
@@ -492,7 +496,7 @@ export const zoneSegmentationV1Export = async ( req, res ) => {
492
496
  const exportItem = {
493
497
  'Date': element.date,
494
498
  'Entrance': element.category,
495
- 'Entrance wise footfall': element.value,
499
+ 'Entrance wise footfall': element.value ?? '--',
496
500
  };
497
501
  if ( clientId === '463' ) {
498
502
  exportItem['Concentration Rate'] = element?.concentrationRate ? element?.concentrationRate + '%' : '--';
@@ -526,21 +530,24 @@ export const zoneInteractionTable430Export = async ( req, res ) => {
526
530
  if ( reqestData.export ) {
527
531
  if ( resultData.data.length>0 ) {
528
532
  const exportdata = [];
529
- resultData.data.forEach( ( element ) => {
533
+ for ( let element of resultData.data ) {
534
+ element.assist_time_string = await convertSecondstoTimeFormat( element.assist_time );
535
+ element.avg_interaction_time_string = await convertSecondstoTimeFormat( element.avg_interaction_time );
530
536
  exportdata.push( {
531
537
  'Date': element.date || '--',
532
538
  'Passer By': element.passer_by || '--',
533
539
  'Footfall': element.footfall || '--',
534
540
  'Drop In Rate': element.drop_in_rate +'%',
535
- 'Greetings Count': element.greeting_count || '--',
541
+ 'Greetings Count': element.greeting_count ?? '--',
536
542
  'Greetings Rate': ( ( element.greeting_count / element.footfall ) * 100 ).toFixed( 1 ) + '%' || '--',
537
543
  'Customer Interacted': element.customer_attended || '--',
538
544
  'Interation Rate ': element.interaction_rate +'%',
539
- 'Avg Time To Interact': element.avg_interaction_time || '--',
540
- 'Billing Conversion': element.footfall_overamin_inzone || '--',
545
+ 'Avg Time Taken to Assist a Customer': element.avg_interaction_time_string ?? '--',
546
+ 'Avg Time Spent with Customer': element.assist_time_string ?? '--',
547
+ 'Billing Conversion': element.footfall_overamin_inzone ?? '--',
541
548
  'Billing Conversion Rate': element.billing_conversion_rate +'%',
542
549
  } );
543
- } );
550
+ }
544
551
  return await download( exportdata, res );
545
552
  } else {
546
553
  return res.sendError( 'No Content', 204 );
@@ -554,6 +561,7 @@ export const zoneInteractionTable430Export = async ( req, res ) => {
554
561
  return res.sendError( 'No Content', 204 );
555
562
  }
556
563
  } catch ( error ) {
564
+ // console.log( 'error', error );
557
565
  logger.error( { error: error, message: req.query, function: 'zoneInteractionTable430Export' } );
558
566
  return res.sendError( { error: error }, 500 );
559
567
  }
@@ -591,7 +599,7 @@ export const zoneSegmentationTableExport = async ( req, res ) => {
591
599
  resultData.zoneConcentrationData.forEach( ( element ) => {
592
600
  exportdata.push( {
593
601
  'Zone Name': element?.zoneName || '--',
594
- 'Footfall': element?.footfallCount || '--',
602
+ 'Footfall': element?.footfallCount ?? '--',
595
603
  'Avg.Dwell Time (Mins)': element?.avgDwellTime || '--',
596
604
  'Trolley': element?.Trolley ? element?.Trolley: 0,
597
605
  'Basket': element?.Basket ? element?.Basket : 0,
@@ -652,7 +660,7 @@ export const zonePasserByTable430Export = async ( req, res ) => {
652
660
  exportdata.push( {
653
661
  'Date': element?.date_string || '--',
654
662
  'Camera Name': element?.streamName || '--',
655
- 'Passer-by Count': element?.passerby_count || '--',
663
+ 'Passer-by Count': element?.passerby_count ?? '--',
656
664
  } );
657
665
  } );
658
666
  return await download( exportdata, res );
@@ -676,7 +684,7 @@ export const zonePasserByTable430Export = async ( req, res ) => {
676
684
  export const interactionTableV1 = async ( req, res ) => {
677
685
  try {
678
686
  let reqestData = req.body;
679
- let LamdaURL = 'https://ciwoce4ore3iyx5x5eicp2lpii0yutva.lambda-url.ap-south-1.on.aws/';
687
+ let LamdaURL = 'https://x5rjtf6uylkgie62dwmp2dpjra0txbve.lambda-url.ap-south-1.on.aws/';
680
688
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
681
689
  if ( resultData ) {
682
690
  if ( resultData.status_code == '200' ) {
@@ -692,4 +700,363 @@ export const interactionTableV1 = async ( req, res ) => {
692
700
  return res.sendError( { error: error }, 500 );
693
701
  }
694
702
  };
703
+ export const interactionTable430Export = async ( req, res ) => {
704
+ try {
705
+ let reqestData = req.body;
706
+ if ( reqestData.export ) {
707
+ reqestData.limit = 10000;
708
+ }
709
+ let LamdaURL = 'https://x5rjtf6uylkgie62dwmp2dpjra0txbve.lambda-url.ap-south-1.on.aws/';
710
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
711
+ if ( resultData ) {
712
+ if ( resultData.status_code == '200' ) {
713
+ if ( reqestData.export ) {
714
+ if ( resultData.data.length > 0 ) {
715
+ const exportdata = [];
716
+ resultData.data.forEach( ( element ) => {
717
+ exportdata.push( {
718
+ 'Date': element?.storeDate || '--',
719
+ 'Category': element?.category || '--',
720
+ 'Value': element?.value ?? '--',
721
+ } );
722
+ } );
723
+ return await download( exportdata, res );
724
+ } else {
725
+ return res.sendError( 'No Content', 204 );
726
+ }
727
+ }
728
+ return res.sendSuccess( resultData );
729
+ } else {
730
+ return res.sendError( 'No Content', 204 );
731
+ }
732
+ } else {
733
+ return res.sendError( 'No Content', 204 );
734
+ }
735
+ } catch ( error ) {
736
+ logger.error( { error: error, message: req.query, function: 'interactionTable430Export' } );
737
+ return res.sendError( { error: error }, 500 );
738
+ }
739
+ };
740
+ export const ZonewiseCustomerFunnelV1 = async ( req, res ) => {
741
+ try {
742
+ let reqestData = req.body;
743
+ let LamdaURL = 'https://7q6v4wppeubi5kgdffwm37az2e0bfkak.lambda-url.ap-south-1.on.aws/';
744
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
745
+ if ( resultData ) {
746
+ if ( resultData.status_code == '200' ) {
747
+ resultData.data[0].assist_time_string = await convertSecondstoTimeFormat( resultData.data[0].assist_time );
748
+ resultData.data[0].avg_interaction_time_string = await convertSecondstoTimeFormat( resultData.data[0].avg_interaction_time );
749
+ return res.sendSuccess( resultData );
750
+ } else {
751
+ return res.sendError( 'No Content', 204 );
752
+ }
753
+ } else {
754
+ return res.sendError( 'No Content', 204 );
755
+ }
756
+ } catch ( error ) {
757
+ logger.error( { error: error, message: req.query, function: 'ZonewiseCustomerFunnelV1' } );
758
+ return res.sendError( { error: error }, 500 );
759
+ }
760
+ };
761
+
762
+ export const ZonewiseCustomerFunnelExport = async ( req, res ) => {
763
+ try {
764
+ let reqestData = req.body;
765
+ let LamdaURL = 'https://7q6v4wppeubi5kgdffwm37az2e0bfkak.lambda-url.ap-south-1.on.aws/';
766
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
767
+ if ( resultData ) {
768
+ if ( resultData.status_code == '200' ) {
769
+ // resultData.data[0].assist_time_string = await convertSecondstoTimeFormat( resultData.data[0].assist_time );
770
+ // resultData.data[0].avg_interaction_time_string = await convertSecondstoTimeFormat( resultData.data[0].avg_interaction_time );
771
+ if ( reqestData.export ) {
772
+ if ( resultData.data.length > 0 ) {
773
+ const exportdata = [];
774
+ for ( let element of resultData.data ) {
775
+ element.assist_time_string = await convertSecondstoTimeFormat( element.assist_time );
776
+ element.avg_interaction_time_string = await convertSecondstoTimeFormat( element.avg_interaction_time );
777
+ const row = {
778
+ 'Date': element.date || '--',
779
+ 'Footfall': element.footfall ?? '--',
780
+ 'Greetings Count': element.greeting_count ?? '--',
781
+ 'Greetings Rate': ( element.greeting_count && element.footfall ) ? ( ( element.greeting_count / element.footfall ) * 100 ).toFixed( 1 ) + '%': '--',
782
+ 'Customer Interacted': element.customer_attended ?? '--',
783
+ 'Interation Rate ': element.interaction_rate != null ? element.interaction_rate + '%' : '--',
784
+ 'Avg Time Taken to Assist a Customer': element.avg_interaction_time_string ?? '--',
785
+ 'Avg Time Spent with Customer': element.assist_time_string ?? '--',
786
+ };
787
+ if ( element.footfall_overamin_inzone != null ) {
788
+ row['Billing Conversion'] = element.footfall_overamin_inzone;
789
+ }
790
+ if ( element.billing_conversion_rate != null ) {
791
+ row['Billing Conversion Rate'] = element.billing_conversion_rate + '%';
792
+ }
793
+
794
+ exportdata.push( row );
795
+ };
796
+ return await download( exportdata, res );
797
+ } else {
798
+ return res.sendError( 'No Content', 204 );
799
+ }
800
+ }
801
+ return res.sendSuccess( resultData );
802
+ } else {
803
+ return res.sendError( 'No Content', 204 );
804
+ }
805
+ } else {
806
+ return res.sendError( 'No Content', 204 );
807
+ }
808
+ } catch ( error ) {
809
+ // console.log( 'error', error );
810
+ logger.error( { error: error, message: req.query, function: 'ZonewiseCustomerFunnelExport' } );
811
+ return res.sendError( { error: error }, 500 );
812
+ }
813
+ };
814
+
815
+
816
+ // new Pantprojects api for Zone FF V2
817
+ export const getZoneAPIFFV2 = async ( req, res ) => {
818
+ try {
819
+ let reqestData = req.body;
820
+ let LamdaURL = 'https://kxz75vd4lsgpf4ykytgmyllmoa0xwixt.lambda-url.ap-south-1.on.aws/';
821
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
822
+ if ( resultData ) {
823
+ return res.sendSuccess( resultData );
824
+ } else {
825
+ return res.sendError( 'No Content', 204 );
826
+ }
827
+ } catch ( error ) {
828
+ logger.error( { error: error, message: req.query, function: 'getZoneAPIFFV2' } );
829
+ return res.sendError( { error: error }, 500 );
830
+ }
831
+ };
832
+
833
+ export const getNewZoneFFV2 = async ( req, res ) => {
834
+ try {
835
+ let reqestData = req.body;
836
+ let LamdaURL = 'https://gcizlv6zpfhvwyrqzgpjsxneoi0rfnuc.lambda-url.ap-south-1.on.aws/';
837
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
838
+ if ( resultData ) {
839
+ if ( resultData.status_code == '200' ) {
840
+ return res.sendSuccess( resultData );
841
+ } else {
842
+ return res.sendError( 'No Content', 204 );
843
+ }
844
+ } else {
845
+ return res.sendError( 'No Content', 204 );
846
+ }
847
+ } catch ( error ) {
848
+ logger.error( { error: error, message: req.query, function: 'getNewZoneFFV2' } );
849
+ return res.sendError( { error: error }, 500 );
850
+ }
851
+ };
852
+ export const getSelectedZoneFFV2 = async ( req, res ) => {
853
+ try {
854
+ let reqestData = req.body;
855
+ let LamdaURL = 'https://6adocjaelheviyminlomqqncmi0japrn.lambda-url.ap-south-1.on.aws/';
856
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
857
+ if ( resultData ) {
858
+ if ( resultData.status_code == '200' ) {
859
+ if ( reqestData.export ) {
860
+ const exportdata = [];
861
+ const element = resultData.data;
862
+ const row = {
863
+ 'Store Name': element.storeName || '--',
864
+ 'Overall FF': ( element.zone1FF ?? element.zone2FF ?? element.zone3FF ) != null ?
865
+ element.overallFootfall ?? '--' :
866
+ '--',
867
+ 'NOB': element.noB ?? '--',
868
+ };
869
+
870
+ // Conditionally add zone values if present
871
+ if ( element.zone1FF !== undefined && element.zone1FF !== null ) {
872
+ row['Zone 1 FF'] = element.zone1FF;
873
+ }
874
+ if ( element.zone2FF !== undefined && element.zone2FF !== null ) {
875
+ row['Zone 2 FF'] = element.zone2FF;
876
+ }
877
+ if ( element.zone3FF !== undefined && element.zone3FF !== null ) {
878
+ row['Zone 3 FF'] = element.zone3FF;
879
+ }
880
+ if ( element.zone1Percentage !== undefined && element.zone1Percentage !== null ) {
881
+ row['Zone 1 Conc %'] = element.zone1Percentage !== undefined ?`${element.zone1Percentage}%` : '--';
882
+ }
883
+ if ( element.zone2Percentage !== undefined && element.zone2Percentage !== null ) {
884
+ row['Zone 2 Conc %'] = element.zone2Percentage !== undefined ? `${element.zone2Percentage}%` : '--';
885
+ }
886
+ if ( element.zone3Percentage !== undefined && element.zone3Percentage !== null ) {
887
+ row['Zone 3 Conc %'] = element.zone3Percentage !== undefined ? `${element.zone3Percentage}%` : '--';
888
+ }
889
+
890
+
891
+ exportdata.push( row );
892
+
893
+ return await downloadint( exportdata, res );
894
+ }
895
+ return res.sendSuccess( resultData );
896
+ } else {
897
+ return res.sendError( 'No Content', 204 );
898
+ }
899
+ } else {
900
+ return res.sendError( 'No Content', 204 );
901
+ }
902
+ } catch ( error ) {
903
+ logger.error( { error: error, message: req.query, function: 'getSelectedZoneFFV2' } );
904
+ return res.sendError( { error: error }, 500 );
905
+ }
906
+ };
907
+
908
+ // end v2 API's for pantprojects//
909
+ // pant New Api start date 19-12-2025
910
+
911
+
912
+ export const getNewHoTColdZoneV1 = async ( req, res ) => {
913
+ try {
914
+ let reqestData = req.body;
915
+ let LamdaURL = 'https://j7e5uxgkna6qnuu4vip57kl2wu0pqxza.lambda-url.ap-south-1.on.aws/';
916
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
917
+ if ( resultData ) {
918
+ return res.sendSuccess( resultData );
919
+ } else {
920
+ return res.sendError( 'No Content', 204 );
921
+ }
922
+ } catch ( error ) {
923
+ logger.error( { error: error, message: req.query, function: 'getNewHoTColdZoneV1' } );
924
+ return res.sendError( { error: error }, 500 );
925
+ }
926
+ };
927
+
928
+ export const getNewZoneShopperAnalysisV1 = async ( req, res ) => {
929
+ try {
930
+ const reqestData = req.body;
931
+
932
+ const getClientData = await getClientConfig( reqestData.clientId );
933
+ if ( !getClientData ) {
934
+ return res.sendError( 'Invalid Client Id', 400 );
935
+ }
936
+
937
+ reqestData.featureConfigs = getClientData.featureConfigs;
938
+
939
+ const LamdaURL =
940
+ 'https://sekueyolczfjl2ggy4hadzxxxu0zqcmt.lambda-url.ap-south-1.on.aws/';
941
+
942
+ const resultData = await LamdaServiceCall( LamdaURL, reqestData );
943
+
944
+ if ( !resultData || resultData.status_code !== '200' ) {
945
+ return res.sendError( 'No Content', 204 );
946
+ }
947
+ if ( reqestData.export && resultData.shopperJourneyExportData?.length ) {
948
+ const finalRow = {
949
+ 'Overall FF': resultData['Overall FF'] ?? 0,
950
+ 'NOB': resultData.NoB ?? 0,
951
+ };
952
+
953
+ resultData.shopperJourneyExportData.forEach( ( zoneObj ) => {
954
+ Object.entries( zoneObj ).forEach( ( [ key, value ] ) => {
955
+ finalRow[key] = value ?? 0;
956
+ } );
957
+ } );
958
+
959
+ return await downloadint( [ finalRow ], res );
960
+ }
961
+
962
+ return res.sendSuccess( resultData );
963
+ } catch ( error ) {
964
+ logger.error( {
965
+ error,
966
+ message: req.query,
967
+ function: 'getNewZoneShopperAnalysisV1',
968
+ } );
969
+ return res.sendError( { error }, 500 );
970
+ }
971
+ };
972
+
973
+
974
+ export const getNewZoneShopperBubbleChartV1 = async ( req, res ) => {
975
+ try {
976
+ let reqestData = req.body;
977
+ let LamdaURL = 'https://iqh6vcxtdxeszpfgdenhsrnvwq0rseou.lambda-url.ap-south-1.on.aws/';
978
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
979
+ if ( resultData ) {
980
+ if ( resultData.status_code == '200' ) {
981
+ return res.sendSuccess( resultData );
982
+ } else {
983
+ return res.sendError( 'No Content', 204 );
984
+ }
985
+ } else {
986
+ return res.sendError( 'No Content', 204 );
987
+ }
988
+ } catch ( error ) {
989
+ logger.error( { error: error, message: req.query, function: 'getNewZoneShopperBubbleChartV1' } );
990
+ return res.sendError( { error: error }, 500 );
991
+ }
992
+ };
993
+
994
+ export const getNewCustomerTravelZoneV1 = async ( req, res ) => {
995
+ try {
996
+ let reqestData = req.body;
997
+ let LamdaURL = 'https://id7qgpex6qbft4kcnloqdrby2q0hyldr.lambda-url.ap-south-1.on.aws/';
998
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
999
+ if ( resultData ) {
1000
+ if ( resultData.status_code == '200' ) {
1001
+ return res.sendSuccess( resultData );
1002
+ } else {
1003
+ return res.sendError( 'No Content', 204 );
1004
+ }
1005
+ } else {
1006
+ return res.sendError( 'No Content', 204 );
1007
+ }
1008
+ } catch ( error ) {
1009
+ logger.error( { error: error, message: req.query, function: 'getNewCustomerTravelZoneV1' } );
1010
+ return res.sendError( { error: error }, 500 );
1011
+ }
1012
+ };
1013
+
1014
+ export const getNewAnalysisZoneV1 = async ( req, res ) => {
1015
+ try {
1016
+ let reqestData = req.body;
1017
+ let LamdaURL = 'https://udcada6kh2bpchpgmigky4bxee0drhwb.lambda-url.ap-south-1.on.aws/';
1018
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
1019
+ if ( resultData ) {
1020
+ return res.sendSuccess( resultData );
1021
+ } else {
1022
+ return res.sendError( 'No Content', 204 );
1023
+ }
1024
+ } catch ( error ) {
1025
+ logger.error( { error: error, message: req.query, function: 'getNewAnalysisZoneV1' } );
1026
+ return res.sendError( { error: error }, 500 );
1027
+ }
1028
+ };
1029
+
1030
+ export const getOverallStoreCardsV1 = async ( req, res ) => {
1031
+ try {
1032
+ let reqestData = req.body;
1033
+ let LamdaURL = 'https://fdeqsx2kouac3n4wodmczoxyke0xpikn.lambda-url.ap-south-1.on.aws/';
1034
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
1035
+ if ( resultData ) {
1036
+ if ( resultData.status_code == '200' ) {
1037
+ return res.sendSuccess( resultData );
1038
+ } else {
1039
+ return res.sendError( 'No Content', 204 );
1040
+ }
1041
+ } else {
1042
+ return res.sendError( 'No Content', 204 );
1043
+ }
1044
+ } catch ( error ) {
1045
+ logger.error( { error: error, message: req.query, function: 'getOverallStoreCardsV1' } );
1046
+ return res.sendError( { error: error }, 500 );
1047
+ }
1048
+ };
1049
+
1050
+ async function getClientConfig( clientId ) {
1051
+ try {
1052
+ 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, 'clientName': 1 } );
1053
+ if ( !getClientData ) {
1054
+ return false;
1055
+ }
1056
+ return getClientData;
1057
+ } catch ( error ) {
1058
+ logger.error( { error: error, message: data, function: 'getClientConfig' } );
1059
+ return false;
1060
+ }
1061
+ }
695
1062
 
@@ -1,4 +1,4 @@
1
- import { logger, download } from 'tango-app-api-middleware';
1
+ import { logger, downloadint } from 'tango-app-api-middleware';
2
2
  import { findOneUserAssignedStore } from '../services/userAssignedStore.service.js';
3
3
 
4
4
  // Lamda Service Call //
@@ -89,7 +89,7 @@ export const zoneSummaryTableV2 = async ( req, res ) => {
89
89
  try {
90
90
  let reqestData = req.body;
91
91
  if ( reqestData.export ) {
92
- reqestData.limit = 1000;
92
+ reqestData.limit = 10000;
93
93
  }
94
94
  let LamdaURL = 'https://obtvnopiiuwlsrjygprlvjp2p40wokyd.lambda-url.ap-south-1.on.aws/';
95
95
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
@@ -104,7 +104,7 @@ export const zoneSummaryTableV2 = async ( req, res ) => {
104
104
  'StoreId': element.storeId,
105
105
  'Date': element.date,
106
106
  'Zone Name': element.zoneName,
107
- 'Zone Conc.Rate': element.concentrationRate,
107
+ 'Impression Rate': element.impressionRate,
108
108
  'Avg Dwell Time': element.avgDwellTime,
109
109
  'Zone FF': element.footfallCount,
110
110
  'Zone Bounced': element.bouncedCount,
@@ -119,7 +119,7 @@ export const zoneSummaryTableV2 = async ( req, res ) => {
119
119
  'Female': element.femaleCount,
120
120
  } );
121
121
  } );
122
- return await download( exportdata, res );
122
+ return await downloadint( exportdata, res );
123
123
  } else {
124
124
  return res.sendError( 'No Content', 204 );
125
125
  }
@@ -314,19 +314,20 @@ export const customerJourneyTableV2 = async ( req, res ) => {
314
314
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
315
315
  if ( resultData ) {
316
316
  if ( resultData.status_code == '200' ) {
317
- if ( reqestData.export ) {
318
- if ( resultData.customerJourneyTableData.length>0 ) {
319
- const exportdata = [];
320
- resultData.customerJourneyTableData.forEach( ( element ) => {
321
- exportdata.push( {
322
- 'Zone Name': element.zoneName,
323
- 'No of Stores': element.noOfStores,
324
- 'Zone FF': element.zoneFF,
325
- 'Impressions': element.impressions,
326
- 'Avg Dwell Time': element.AvgDwellTime,
327
- } );
328
- } );
329
- return await download( exportdata, res );
317
+ if ( reqestData?.export ) {
318
+ if ( resultData?.customerJourneyTableData.length ) {
319
+ // const exportdata = [];
320
+ // resultData.customerJourneyTableData.forEach( ( element ) => {
321
+ // exportdata.push( {
322
+ // 'Zone Name': element.zoneName,
323
+ // 'No of Stores': element.noOfStores,
324
+ // 'Zone FF': element.zoneFF,
325
+ // 'Impressions': element.impressions,
326
+ // 'Avg Dwell Time': element.AvgDwellTime,
327
+ // } );
328
+ // } );
329
+ resultData.customerJourneyTableData = [ Object.fromEntries( resultData.customerJourneyTableData ) ];
330
+ return await download( resultData.customerJourneyTableData, res );
330
331
  } else {
331
332
  return res.sendError( 'No Content', 204 );
332
333
  }
@@ -11,6 +11,7 @@ const baseSchema = {
11
11
  // Schema for Card Funnel
12
12
  export const validateCardsAgeAnalysisSchema = joi.object( {
13
13
  ...baseSchema,
14
+ zoneName: joi.string().optional().allow( '' ),
14
15
  } );
15
16
 
16
17
  export const validateCardsAgeAnalysisParams = {
@@ -258,6 +259,7 @@ export const validateZoneSegmentationExportParams = {
258
259
  export const validatezoneInteractionTable430ExportSchema = joi.object( {
259
260
  ...baseSchema,
260
261
  export: joi.boolean().optional().allow( '' ),
262
+ zoneName: joi.string().optional().allow( '' ),
261
263
  } );
262
264
 
263
265
  export const validatezoneInteractionTable430ExportParams = {
@@ -36,6 +36,18 @@ import {
36
36
  zonePasserByTableV1,
37
37
  zonePasserByTable430Export,
38
38
  interactionTableV1,
39
+ interactionTable430Export,
40
+ ZonewiseCustomerFunnelV1,
41
+ ZonewiseCustomerFunnelExport,
42
+ getNewZoneFFV2,
43
+ getSelectedZoneFFV2,
44
+ getZoneAPIFFV2,
45
+ getNewHoTColdZoneV1,
46
+ getNewZoneShopperAnalysisV1,
47
+ getNewZoneShopperBubbleChartV1,
48
+ getNewCustomerTravelZoneV1,
49
+ getNewAnalysisZoneV1,
50
+ getOverallStoreCardsV1,
39
51
  } from '../controllers/analysisZoneV1.controllers.js';
40
52
 
41
53
  analysisZoneRouter
@@ -141,5 +153,31 @@ analysisZoneRouter
141
153
  userType: [ 'tango', 'client' ], access: [
142
154
  { featureName: 'TangoEye', name: 'ZoneTag', permissions: [] },
143
155
  ],
144
- } ), validate( validationDtos.validatezoneSegmaentationTableParams ), interactionTableV1 );
156
+ } ), validate( validationDtos.validatezoneSegmaentationTableParams ), interactionTableV1 )
157
+ .post( '/interactionTable_430Export', isAllowedSessionHandler, isAllowedClient, accessVerification( {
158
+ userType: [ 'tango', 'client' ], access: [
159
+ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [] },
160
+ ],
161
+ } ), validate( validationDtos.validatezoneSegmaentationTableParams ), interactionTable430Export )
162
+ .post( '/ZonewiseCustomerFunnel_v1', isAllowedSessionHandler, isAllowedClient, accessVerification( {
163
+ userType: [ 'tango', 'client' ], access: [
164
+ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [] },
165
+ ],
166
+ } ), validate( validationDtos.validatezoneSegmaentationTableParams ), ZonewiseCustomerFunnelV1 )
167
+ .post( '/ZonewiseCustomerFunnel_Export', isAllowedSessionHandler, isAllowedClient, accessVerification( {
168
+ userType: [ 'tango', 'client' ], access: [
169
+ { featureName: 'TangoEye', name: 'ZoneTag', permissions: [] },
170
+ ],
171
+ } ), validate( validationDtos.validatezoneInteractionTable430ExportParams ), ZonewiseCustomerFunnelExport )
172
+
173
+
174
+ .post( '/getNewZoneFF_v2', getNewZoneFFV2 )
175
+ .post( '/getSelectedZoneFF_v2', getSelectedZoneFFV2 )
176
+ .post( '/getZoneAPI_v2', getZoneAPIFFV2 )
177
+ .post( '/getNewHoTColdZone_v1', isAllowedSessionHandler, isAllowedClient, validate( validationDtos.validateTopPerformingZonesSchema ), getNewHoTColdZoneV1 )
178
+ .post( '/getNewZoneShopperAnalysis_v1', getNewZoneShopperAnalysisV1 )
179
+ .post( '/getNewZoneShopperBubbleChart_v1', isAllowedSessionHandler, isAllowedClient, validate( validationDtos.validateTopPerformingZonesSchema ), getNewZoneShopperBubbleChartV1 )
180
+ .post( '/getNewCustomerTravelZone_v1', isAllowedSessionHandler, isAllowedClient, validate( validationDtos.validateTopPerformingZonesSchema ), getNewCustomerTravelZoneV1 )
181
+ .post( '/getNewAnalysisZone_v1', isAllowedSessionHandler, isAllowedClient, validate( validationDtos.validateTopPerformingZonesSchema ), getNewAnalysisZoneV1 )
182
+ .post( '/getOverallStoreCards_v1', isAllowedSessionHandler, isAllowedClient, validate( validationDtos.validateTopPerformingZonesSchema ), getOverallStoreCardsV1 );
145
183
  export default analysisZoneRouter;
@@ -0,0 +1,23 @@
1
+ import model from 'tango-api-schema';
2
+
3
+ export const find = ( query = {}, record = {} ) => {
4
+ return model.clientModel.find( query, record );
5
+ };
6
+
7
+ export const findOne = ( query = {}, record = {} ) => {
8
+ return model.clientModel.findOne( query, record ).sort( { updatedAt: -1 } );
9
+ };
10
+
11
+ export const updateOne = ( query = {}, record = {} ) => {
12
+ return model.clientModel.updateOne( query, { $set: record } );
13
+ };
14
+
15
+ export const aggregate = ( query = [] ) => {
16
+ return model.clientModel.aggregate( query );
17
+ };
18
+
19
+ export const getClientCount = ( query = {} ) => {
20
+ return model.clientModel.count( query );
21
+ };
22
+
23
+