tango-app-api-analysis-zone 3.4.0 → 3.7.1-alpha.1
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.
|
|
3
|
+
"version": "3.7.1-alpha.1",
|
|
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.
|
|
24
|
+
"tango-app-api-middleware": "^3.1.77",
|
|
25
25
|
"winston": "^3.13.1",
|
|
26
26
|
"winston-daily-rotate-file": "^5.0.0"
|
|
27
27
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { logger, download } from 'tango-app-api-middleware';
|
|
1
|
+
import { logger, download, convertSecondstoTimeFormat } from 'tango-app-api-middleware';
|
|
2
2
|
import { findOneUserAssignedStore } from '../services/userAssignedStore.service.js';
|
|
3
3
|
|
|
4
4
|
// Lamda Service Call //
|
|
@@ -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
|
}
|
|
@@ -298,26 +298,28 @@ export const zoneInteractionTable430 = async ( req, res ) => {
|
|
|
298
298
|
let resultData = await LamdaServiceCall( LamdaURL, reqestData );
|
|
299
299
|
if ( resultData ) {
|
|
300
300
|
if ( resultData.status_code == '200' ) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
301
|
+
resultData.data[0].assist_time_string = await convertSecondstoTimeFormat( resultData.data[0].assist_time );
|
|
302
|
+
resultData.data[0].avg_interaction_time_string = await convertSecondstoTimeFormat( resultData.data[0].avg_interaction_time );
|
|
303
|
+
// if ( reqestData.export ) {
|
|
304
|
+
// if ( resultData.data.length>0 ) {
|
|
305
|
+
// const exportdata = [];
|
|
306
|
+
// resultData.data.forEach( ( element ) => {
|
|
307
|
+
// exportdata.push( {
|
|
308
|
+
// 'Passer By': element.passer_by || '--',
|
|
309
|
+
// 'Footfall': element.footfall || '--',
|
|
310
|
+
// 'Drop In Rate': element.drop_in_rate +'%',
|
|
311
|
+
// 'Customer Attended ': element.customer_attended || '--',
|
|
312
|
+
// 'Interation Rate ': element.interaction_rate +'%',
|
|
313
|
+
// 'Billing Conversion': element.footfall_overamin_inzone ?? '--',
|
|
314
|
+
// 'Billing Conversion Rate': element.billing_conversion_rate +'%',
|
|
315
|
+
// 'Greetings Count': element.greeting_count ?? '--',
|
|
316
|
+
// } );
|
|
317
|
+
// } );
|
|
318
|
+
// return await download( exportdata, res );
|
|
319
|
+
// } else {
|
|
320
|
+
// return res.sendError( 'No Content', 204 );
|
|
321
|
+
// }
|
|
322
|
+
// }
|
|
321
323
|
return res.sendSuccess( resultData );
|
|
322
324
|
} else {
|
|
323
325
|
return res.sendError( 'No Content', 204 );
|
|
@@ -420,7 +422,7 @@ export const zoneInteractionTableExport430 = async ( req, res ) => {
|
|
|
420
422
|
exportdata.push( {
|
|
421
423
|
'Store Id': element.store_id || '--',
|
|
422
424
|
'Date': element.date || '--',
|
|
423
|
-
'Customer spent more than 10 mins': element.customer_count_over10min
|
|
425
|
+
'Customer spent more than 10 mins': element.customer_count_over10min ?? '--',
|
|
424
426
|
'Billing Conversion': element.billing_conversion || '--',
|
|
425
427
|
} );
|
|
426
428
|
} );
|
|
@@ -455,7 +457,7 @@ export const zoneConcentrationTableExport = async ( req, res ) => {
|
|
|
455
457
|
exportdata.push( {
|
|
456
458
|
'Date': element.Date,
|
|
457
459
|
'Zone Name': element.zoneName,
|
|
458
|
-
'Footfall(Actuals)': element.footfallCount
|
|
460
|
+
'Footfall(Actuals)': element.footfallCount ?? '--',
|
|
459
461
|
'DwellTime(Average)': element.avgDwellTime || '--',
|
|
460
462
|
'Concentration': element.concentrationRate +'%',
|
|
461
463
|
} );
|
|
@@ -492,7 +494,7 @@ export const zoneSegmentationV1Export = async ( req, res ) => {
|
|
|
492
494
|
const exportItem = {
|
|
493
495
|
'Date': element.date,
|
|
494
496
|
'Entrance': element.category,
|
|
495
|
-
'Entrance wise footfall': element.value,
|
|
497
|
+
'Entrance wise footfall': element.value ?? '--',
|
|
496
498
|
};
|
|
497
499
|
if ( clientId === '463' ) {
|
|
498
500
|
exportItem['Concentration Rate'] = element?.concentrationRate ? element?.concentrationRate + '%' : '--';
|
|
@@ -526,21 +528,24 @@ export const zoneInteractionTable430Export = async ( req, res ) => {
|
|
|
526
528
|
if ( reqestData.export ) {
|
|
527
529
|
if ( resultData.data.length>0 ) {
|
|
528
530
|
const exportdata = [];
|
|
529
|
-
|
|
531
|
+
for ( let element of resultData.data ) {
|
|
532
|
+
element.assist_time_string = await convertSecondstoTimeFormat( element.assist_time );
|
|
533
|
+
element.avg_interaction_time_string = await convertSecondstoTimeFormat( element.avg_interaction_time );
|
|
530
534
|
exportdata.push( {
|
|
531
535
|
'Date': element.date || '--',
|
|
532
536
|
'Passer By': element.passer_by || '--',
|
|
533
537
|
'Footfall': element.footfall || '--',
|
|
534
538
|
'Drop In Rate': element.drop_in_rate +'%',
|
|
535
|
-
'Greetings Count': element.greeting_count
|
|
539
|
+
'Greetings Count': element.greeting_count ?? '--',
|
|
536
540
|
'Greetings Rate': ( ( element.greeting_count / element.footfall ) * 100 ).toFixed( 1 ) + '%' || '--',
|
|
537
541
|
'Customer Interacted': element.customer_attended || '--',
|
|
538
542
|
'Interation Rate ': element.interaction_rate +'%',
|
|
539
|
-
'Avg Time
|
|
540
|
-
'
|
|
543
|
+
'Avg Time Taken to Assist a Customer': element.avg_interaction_time_string ?? '--',
|
|
544
|
+
'Avg Time Spent with Customer': element.assist_time_string ?? '--',
|
|
545
|
+
'Billing Conversion': element.footfall_overamin_inzone ?? '--',
|
|
541
546
|
'Billing Conversion Rate': element.billing_conversion_rate +'%',
|
|
542
547
|
} );
|
|
543
|
-
}
|
|
548
|
+
}
|
|
544
549
|
return await download( exportdata, res );
|
|
545
550
|
} else {
|
|
546
551
|
return res.sendError( 'No Content', 204 );
|
|
@@ -554,6 +559,7 @@ export const zoneInteractionTable430Export = async ( req, res ) => {
|
|
|
554
559
|
return res.sendError( 'No Content', 204 );
|
|
555
560
|
}
|
|
556
561
|
} catch ( error ) {
|
|
562
|
+
// console.log( 'error', error );
|
|
557
563
|
logger.error( { error: error, message: req.query, function: 'zoneInteractionTable430Export' } );
|
|
558
564
|
return res.sendError( { error: error }, 500 );
|
|
559
565
|
}
|
|
@@ -591,7 +597,7 @@ export const zoneSegmentationTableExport = async ( req, res ) => {
|
|
|
591
597
|
resultData.zoneConcentrationData.forEach( ( element ) => {
|
|
592
598
|
exportdata.push( {
|
|
593
599
|
'Zone Name': element?.zoneName || '--',
|
|
594
|
-
'Footfall': element?.footfallCount
|
|
600
|
+
'Footfall': element?.footfallCount ?? '--',
|
|
595
601
|
'Avg.Dwell Time (Mins)': element?.avgDwellTime || '--',
|
|
596
602
|
'Trolley': element?.Trolley ? element?.Trolley: 0,
|
|
597
603
|
'Basket': element?.Basket ? element?.Basket : 0,
|
|
@@ -652,7 +658,7 @@ export const zonePasserByTable430Export = async ( req, res ) => {
|
|
|
652
658
|
exportdata.push( {
|
|
653
659
|
'Date': element?.date_string || '--',
|
|
654
660
|
'Camera Name': element?.streamName || '--',
|
|
655
|
-
'Passer-by Count': element?.passerby_count
|
|
661
|
+
'Passer-by Count': element?.passerby_count ?? '--',
|
|
656
662
|
} );
|
|
657
663
|
} );
|
|
658
664
|
return await download( exportdata, res );
|
|
@@ -676,7 +682,7 @@ export const zonePasserByTable430Export = async ( req, res ) => {
|
|
|
676
682
|
export const interactionTableV1 = async ( req, res ) => {
|
|
677
683
|
try {
|
|
678
684
|
let reqestData = req.body;
|
|
679
|
-
let LamdaURL = 'https://
|
|
685
|
+
let LamdaURL = 'https://x5rjtf6uylkgie62dwmp2dpjra0txbve.lambda-url.ap-south-1.on.aws/';
|
|
680
686
|
let resultData = await LamdaServiceCall( LamdaURL, reqestData );
|
|
681
687
|
if ( resultData ) {
|
|
682
688
|
if ( resultData.status_code == '200' ) {
|
|
@@ -692,4 +698,115 @@ export const interactionTableV1 = async ( req, res ) => {
|
|
|
692
698
|
return res.sendError( { error: error }, 500 );
|
|
693
699
|
}
|
|
694
700
|
};
|
|
701
|
+
export const interactionTable430Export = async ( req, res ) => {
|
|
702
|
+
try {
|
|
703
|
+
let reqestData = req.body;
|
|
704
|
+
if ( reqestData.export ) {
|
|
705
|
+
reqestData.limit = 10000;
|
|
706
|
+
}
|
|
707
|
+
let LamdaURL = 'https://x5rjtf6uylkgie62dwmp2dpjra0txbve.lambda-url.ap-south-1.on.aws/';
|
|
708
|
+
let resultData = await LamdaServiceCall( LamdaURL, reqestData );
|
|
709
|
+
if ( resultData ) {
|
|
710
|
+
if ( resultData.status_code == '200' ) {
|
|
711
|
+
if ( reqestData.export ) {
|
|
712
|
+
if ( resultData.data.length > 0 ) {
|
|
713
|
+
const exportdata = [];
|
|
714
|
+
resultData.data.forEach( ( element ) => {
|
|
715
|
+
exportdata.push( {
|
|
716
|
+
'Date': element?.storeDate || '--',
|
|
717
|
+
'Category': element?.category || '--',
|
|
718
|
+
'Value': element?.value ?? '--',
|
|
719
|
+
} );
|
|
720
|
+
} );
|
|
721
|
+
return await download( exportdata, res );
|
|
722
|
+
} else {
|
|
723
|
+
return res.sendError( 'No Content', 204 );
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
return res.sendSuccess( resultData );
|
|
727
|
+
} else {
|
|
728
|
+
return res.sendError( 'No Content', 204 );
|
|
729
|
+
}
|
|
730
|
+
} else {
|
|
731
|
+
return res.sendError( 'No Content', 204 );
|
|
732
|
+
}
|
|
733
|
+
} catch ( error ) {
|
|
734
|
+
logger.error( { error: error, message: req.query, function: 'interactionTable430Export' } );
|
|
735
|
+
return res.sendError( { error: error }, 500 );
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
export const ZonewiseCustomerFunnelV1 = async ( req, res ) => {
|
|
739
|
+
try {
|
|
740
|
+
let reqestData = req.body;
|
|
741
|
+
let LamdaURL = 'https://7q6v4wppeubi5kgdffwm37az2e0bfkak.lambda-url.ap-south-1.on.aws/';
|
|
742
|
+
let resultData = await LamdaServiceCall( LamdaURL, reqestData );
|
|
743
|
+
if ( resultData ) {
|
|
744
|
+
if ( resultData.status_code == '200' ) {
|
|
745
|
+
resultData.data[0].assist_time_string = await convertSecondstoTimeFormat( resultData.data[0].assist_time );
|
|
746
|
+
resultData.data[0].avg_interaction_time_string = await convertSecondstoTimeFormat( resultData.data[0].avg_interaction_time );
|
|
747
|
+
return res.sendSuccess( resultData );
|
|
748
|
+
} else {
|
|
749
|
+
return res.sendError( 'No Content', 204 );
|
|
750
|
+
}
|
|
751
|
+
} else {
|
|
752
|
+
return res.sendError( 'No Content', 204 );
|
|
753
|
+
}
|
|
754
|
+
} catch ( error ) {
|
|
755
|
+
logger.error( { error: error, message: req.query, function: 'ZonewiseCustomerFunnelV1' } );
|
|
756
|
+
return res.sendError( { error: error }, 500 );
|
|
757
|
+
}
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
export const ZonewiseCustomerFunnelExport = async ( req, res ) => {
|
|
761
|
+
try {
|
|
762
|
+
let reqestData = req.body;
|
|
763
|
+
let LamdaURL = 'https://7q6v4wppeubi5kgdffwm37az2e0bfkak.lambda-url.ap-south-1.on.aws/';
|
|
764
|
+
let resultData = await LamdaServiceCall( LamdaURL, reqestData );
|
|
765
|
+
if ( resultData ) {
|
|
766
|
+
if ( resultData.status_code == '200' ) {
|
|
767
|
+
// resultData.data[0].assist_time_string = await convertSecondstoTimeFormat( resultData.data[0].assist_time );
|
|
768
|
+
// resultData.data[0].avg_interaction_time_string = await convertSecondstoTimeFormat( resultData.data[0].avg_interaction_time );
|
|
769
|
+
if ( reqestData.export ) {
|
|
770
|
+
if ( resultData.data.length > 0 ) {
|
|
771
|
+
const exportdata = [];
|
|
772
|
+
for ( let element of resultData.data ) {
|
|
773
|
+
element.assist_time_string = await convertSecondstoTimeFormat( element.assist_time );
|
|
774
|
+
element.avg_interaction_time_string = await convertSecondstoTimeFormat( element.avg_interaction_time );
|
|
775
|
+
const row = {
|
|
776
|
+
'Date': element.date || '--',
|
|
777
|
+
'Footfall': element.footfall ?? '--',
|
|
778
|
+
'Greetings Count': element.greeting_count ?? '--',
|
|
779
|
+
'Greetings Rate': ( element.greeting_count && element.footfall ) ? ( ( element.greeting_count / element.footfall ) * 100 ).toFixed( 1 ) + '%': '--',
|
|
780
|
+
'Customer Interacted': element.customer_attended ?? '--',
|
|
781
|
+
'Interation Rate ': element.interaction_rate != null ? element.interaction_rate + '%' : '--',
|
|
782
|
+
'Avg Time Taken to Assist a Customer': element.avg_interaction_time_string ?? '--',
|
|
783
|
+
'Avg Time Spent with Customer': element.assist_time_string ?? '--',
|
|
784
|
+
};
|
|
785
|
+
if ( element.footfall_overamin_inzone != null ) {
|
|
786
|
+
row['Billing Conversion'] = element.footfall_overamin_inzone;
|
|
787
|
+
}
|
|
788
|
+
if ( element.billing_conversion_rate != null ) {
|
|
789
|
+
row['Billing Conversion Rate'] = element.billing_conversion_rate + '%';
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
exportdata.push( row );
|
|
793
|
+
};
|
|
794
|
+
return await download( exportdata, res );
|
|
795
|
+
} else {
|
|
796
|
+
return res.sendError( 'No Content', 204 );
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
return res.sendSuccess( resultData );
|
|
800
|
+
} else {
|
|
801
|
+
return res.sendError( 'No Content', 204 );
|
|
802
|
+
}
|
|
803
|
+
} else {
|
|
804
|
+
return res.sendError( 'No Content', 204 );
|
|
805
|
+
}
|
|
806
|
+
} catch ( error ) {
|
|
807
|
+
// console.log( 'error', error );
|
|
808
|
+
logger.error( { error: error, message: req.query, function: 'ZonewiseCustomerFunnelExport' } );
|
|
809
|
+
return res.sendError( { error: error }, 500 );
|
|
810
|
+
}
|
|
811
|
+
};
|
|
695
812
|
|
|
@@ -314,19 +314,19 @@ 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
|
|
318
|
-
if ( resultData
|
|
319
|
-
const exportdata = [];
|
|
320
|
-
resultData.customerJourneyTableData.forEach( ( element ) => {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
} );
|
|
329
|
-
return await download(
|
|
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
|
+
return await download( resultData.customerJourneyTableData, res );
|
|
330
330
|
} else {
|
|
331
331
|
return res.sendError( 'No Content', 204 );
|
|
332
332
|
}
|
|
@@ -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,9 @@ import {
|
|
|
36
36
|
zonePasserByTableV1,
|
|
37
37
|
zonePasserByTable430Export,
|
|
38
38
|
interactionTableV1,
|
|
39
|
+
interactionTable430Export,
|
|
40
|
+
ZonewiseCustomerFunnelV1,
|
|
41
|
+
ZonewiseCustomerFunnelExport,
|
|
39
42
|
} from '../controllers/analysisZoneV1.controllers.js';
|
|
40
43
|
|
|
41
44
|
analysisZoneRouter
|
|
@@ -141,5 +144,21 @@ analysisZoneRouter
|
|
|
141
144
|
userType: [ 'tango', 'client' ], access: [
|
|
142
145
|
{ featureName: 'TangoEye', name: 'ZoneTag', permissions: [] },
|
|
143
146
|
],
|
|
144
|
-
} ), validate( validationDtos.validatezoneSegmaentationTableParams ), interactionTableV1 )
|
|
147
|
+
} ), validate( validationDtos.validatezoneSegmaentationTableParams ), interactionTableV1 )
|
|
148
|
+
.post( '/interactionTable_430Export', isAllowedSessionHandler, isAllowedClient, accessVerification( {
|
|
149
|
+
userType: [ 'tango', 'client' ], access: [
|
|
150
|
+
{ featureName: 'TangoEye', name: 'ZoneTag', permissions: [] },
|
|
151
|
+
],
|
|
152
|
+
} ), validate( validationDtos.validatezoneSegmaentationTableParams ), interactionTable430Export )
|
|
153
|
+
.post( '/ZonewiseCustomerFunnel_v1', isAllowedSessionHandler, isAllowedClient, accessVerification( {
|
|
154
|
+
userType: [ 'tango', 'client' ], access: [
|
|
155
|
+
{ featureName: 'TangoEye', name: 'ZoneTag', permissions: [] },
|
|
156
|
+
],
|
|
157
|
+
} ), validate( validationDtos.validatezoneSegmaentationTableParams ), ZonewiseCustomerFunnelV1 )
|
|
158
|
+
.post( '/ZonewiseCustomerFunnel_Export', isAllowedSessionHandler, isAllowedClient, accessVerification( {
|
|
159
|
+
userType: [ 'tango', 'client' ], access: [
|
|
160
|
+
{ featureName: 'TangoEye', name: 'ZoneTag', permissions: [] },
|
|
161
|
+
],
|
|
162
|
+
} ), validate( validationDtos.validatezoneInteractionTable430ExportParams ), ZonewiseCustomerFunnelExport );
|
|
163
|
+
|
|
145
164
|
export default analysisZoneRouter;
|