tango-app-api-analysis-traffic 3.0.0-alpha.4 → 3.0.0-alpha.6

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.4",
3
+ "version": "3.0.0-alpha.6",
4
4
  "description": "Traffic Analysis",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -1677,7 +1677,6 @@ export const footfallTrend = async ( req, res ) => {
1677
1677
  }
1678
1678
  };
1679
1679
 
1680
-
1681
1680
  export const storesMap = async ( req, res ) => {
1682
1681
  try {
1683
1682
  let reqestData = req.body;
@@ -1752,11 +1751,27 @@ export const performanceMatrix = async ( req, res ) => {
1752
1751
  }
1753
1752
 
1754
1753
  let result = {
1755
- 'downTime': 22,
1756
- 'health': 'GOOD',
1757
- 'recapVideoData': [
1758
- { 'thumbImage': 'https://123', 'videoURL': 'https://123' },
1759
- { 'thumbImage': 'https://123', 'videoURL': 'https://123' },
1754
+ 'performanceData': [
1755
+ {
1756
+ 'storeId': '11-1',
1757
+ 'storeName': 'Lositon',
1758
+ 'avgFootfall': 50,
1759
+ 'avgOpenTime': '10:31 AM',
1760
+ 'avgCloseTime': '10:31 PM',
1761
+ 'top': '40%',
1762
+ 'left': '45%',
1763
+ 'position': 'High_High',
1764
+ },
1765
+ {
1766
+ 'storeId': '11-2',
1767
+ 'storeName': 'Lositon-1',
1768
+ 'avgFootfall': 50,
1769
+ 'avgOpenTime': '10:31 AM',
1770
+ 'avgCloseTime': '10:31 PM',
1771
+ 'top': '40%',
1772
+ 'left': '45%',
1773
+ 'position': 'High_Low',
1774
+ },
1760
1775
  ],
1761
1776
  };
1762
1777
  return res.sendSuccess( result );
@@ -336,6 +336,26 @@ export const storeOperationV1 = async ( req, res ) => {
336
336
  }
337
337
  };
338
338
 
339
+ export const performanceMatrixV1 = async ( req, res ) => {
340
+ try {
341
+ let reqestData = req.body;
342
+ let LamdaURL = 'https://5l3pjpivqpyboludmbridailpu0axrov.lambda-url.ap-south-1.on.aws/';
343
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
344
+ if ( resultData ) {
345
+ if ( resultData.status_code == '200' ) {
346
+ return res.sendSuccess( resultData );
347
+ } else {
348
+ return res.sendError( 'No Content', 204 );
349
+ }
350
+ } else {
351
+ return res.sendError( 'No Content', 204 );
352
+ }
353
+ } catch ( error ) {
354
+ logger.error( { error: error, message: req.query, function: 'performanceMatrixV1' } );
355
+ return res.sendError( { error: error }, 500 );
356
+ }
357
+ };
358
+
339
359
  export const storesMapV1 = async ( req, res ) => {
340
360
  try {
341
361
  let reqestData = req.body;
@@ -408,8 +428,9 @@ export const headerLocationsV1 = async ( req, res ) => {
408
428
  let reqestData = req.body;
409
429
  let getUserEmail = req.user.email;
410
430
  let getUserType = req.user.userType;
431
+ let getRole = req.user.role;
411
432
  let getClientId = reqestData.clientId;
412
- let totalStores = await getAllStores( getUserEmail, getClientId, getUserType );
433
+ let totalStores = await getAllStores( getUserEmail, getClientId, getUserType, getRole );
413
434
  if ( totalStores && totalStores.length>0 ) {
414
435
  let storeQuery = [
415
436
  {
@@ -457,30 +478,33 @@ export const headerGroupsV1 = async ( req, res ) => {
457
478
  let requestData = req.body;
458
479
  let getUserEmail = req.user.email;
459
480
  let getUserType = req.user.userType;
460
- const assignedQuery = {
461
- clientId: requestData.clientId,
462
- userEmail: getUserEmail,
463
- };
481
+ let getRole = req.user.role;
464
482
  let groupIds;
465
- const getAssignedType = await findOneUserAssignedStore( assignedQuery );
466
- if ( getAssignedType ) {
467
- if ( getAssignedType.userType == 'client' ) {
468
- if ( getAssignedType.assignedType == 'allstores' ) {
469
- groupIds = await getGroupIds( requestData.clientId );
470
- } else if ( getAssignedType.assignedType == 'group' ) {
471
- groupIds = await getAssignedGroupIds( requestData.clientId, getUserEmail );
472
- }
473
- } else if ( getAssignedType.userType == 'tango' ) {
483
+ if ( getUserType == 'tango' ) {
484
+ groupIds = await getGroupIds( requestData.clientId );
485
+ } else if ( getUserType == 'client' ) {
486
+ if ( getRole == 'superadmin' ) {
474
487
  groupIds = await getGroupIds( requestData.clientId );
475
488
  } else {
476
- groupIds = [];
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 );
498
+ }
499
+ } else {
500
+ groupIds = [];
501
+ }
502
+ } else {
503
+ groupIds = [];
504
+ }
477
505
  }
478
506
  } else {
479
- if ( getUserType == 'tango' ) {
480
- groupIds = await getGroupIds( requestData.clientId );
481
- } else {
482
- return res.sendError( 'No User Assign', 400 );
483
- }
507
+ groupIds = [];
484
508
  }
485
509
 
486
510
  if ( groupIds && groupIds.length > 0 ) {
@@ -521,8 +545,9 @@ export const headerStoresV1 = async ( req, res ) => {
521
545
  let reqestData = req.body;
522
546
  let getUserEmail = req.user.email;
523
547
  let getUserType = req.user.userType;
548
+ let getRole = req.user.role;
524
549
  let getClientId = reqestData.clientId;
525
- let totalStores = await getAllStores( getUserEmail, getClientId, getUserType );
550
+ let totalStores = await getAllStores( getUserEmail, getClientId, getUserType, getRole );
526
551
  if ( totalStores && totalStores.length>0 ) {
527
552
  let storeQuery = [];
528
553
  if ( reqestData.city.length>0 && reqestData.group.length>0 ) {
@@ -585,7 +610,7 @@ export const headerStoresV1 = async ( req, res ) => {
585
610
  },
586
611
  ];
587
612
  } else {
588
- let totalStores = await getAllStores( getUserEmail, getClientId, getUserType );
613
+ let totalStores = await getAllStores( getUserEmail, getClientId, getUserType, getRole );
589
614
  storeQuery = [
590
615
  {
591
616
  $match: {
@@ -620,64 +645,59 @@ export const headerStoresV1 = async ( req, res ) => {
620
645
  }
621
646
  };
622
647
 
623
- async function getAllStores( getUserEmail, getClientId, getUserType ) {
648
+ async function getAllStores( getUserEmail, getClientId, getUserType, getRole ) {
624
649
  try {
625
- if ( getUserEmail && getUserEmail !='' ) {
626
- const assignedQuery = {
627
- clientId: getClientId,
628
- userEmail: getUserEmail,
629
- };
630
- const getAssignedType = await findOneUserAssignedStore( assignedQuery );
631
- if ( getAssignedType ) {
632
- if ( getAssignedType.userType == 'client' ) {
633
- if ( getAssignedType.assignedType && getAssignedType.assignedType !='' ) {
634
- let overAllStores = [];
635
- switch ( getAssignedType.assignedType ) {
636
- case 'store':
637
- let getAS = await getAssignedStores( getClientId, getUserEmail, 'store' );
638
- if ( getAS && getAS.length >0 ) {
639
- overAllStores = getAS;
640
- }
641
- break;
642
- case 'group':
643
- let getAGS = await getAssignedGroupStores( getClientId, getUserEmail, 'group' );
644
- if ( getAGS && getAGS.length >0 ) {
645
- overAllStores = getAGS;
646
- }
647
- break;
648
- case 'allstores':
649
- let getAllS = await getAssignedAllStores( getClientId );
650
- if ( getAllS && getAllS.length >0 ) {
651
- overAllStores = getAllS;
652
- }
653
- break;
654
- default:
655
- break;
656
- }
657
- return overAllStores;
658
- } else {
659
- return false;
660
- }
661
- } else if ( getAssignedType.userType == 'tango' ) {
662
- let overAllStores = [];
663
- let getAllS = await getAssignedAllStores( getClientId );
664
- if ( getAllS && getAllS.length >0 ) {
665
- overAllStores = getAllS;
666
- }
667
- return overAllStores;
668
- } else {
669
- return false;
650
+ if ( getUserEmail && getUserEmail !='' && getClientId && getClientId !='' && getUserType && getUserType !='' && getRole && getRole!='' ) {
651
+ let overAllStores = [];
652
+ if ( getUserType == 'tango' ) {
653
+ let getAllS = await getAssignedAllStores( getClientId );
654
+ if ( getAllS && getAllS.length >0 ) {
655
+ overAllStores = getAllS;
670
656
  }
671
- } else {
672
- if ( getUserType && getUserType == 'tango' ) {
673
- let overAllStores = [];
657
+ return overAllStores;
658
+ } else if ( getUserType == 'client' ) {
659
+ if ( getRole == 'superadmin' ) {
674
660
  let getAllS = await getAssignedAllStores( getClientId );
675
661
  if ( getAllS && getAllS.length >0 ) {
676
662
  overAllStores = getAllS;
677
663
  }
678
664
  return overAllStores;
679
665
  } else {
680
- return false;
666
+ const assignedQuery = {
667
+ clientId: getClientId,
668
+ userEmail: getUserEmail,
669
+ };
670
+ const getAssignedType = await findOneUserAssignedStore( assignedQuery );
671
+ if ( getAssignedType ) {
672
+ if ( getAssignedType.userType == 'client' ) {
673
+ if ( getAssignedType.assignedType && getAssignedType.assignedType !='' ) {
674
+ let overAllStores = [];
675
+ switch ( getAssignedType.assignedType ) {
676
+ case 'store':
677
+ let getAS = await getAssignedStores( getClientId, getUserEmail, 'store' );
678
+ if ( getAS && getAS.length >0 ) {
679
+ overAllStores = getAS;
680
+ }
681
+ break;
682
+ case 'group':
683
+ let getAGS = await getAssignedGroupStores( getClientId, getUserEmail, 'group' );
684
+ if ( getAGS && getAGS.length >0 ) {
685
+ overAllStores = getAGS;
686
+ }
687
+ break;
688
+ default:
689
+ break;
690
+ }
691
+ return overAllStores;
692
+ } else {
693
+ return false;
694
+ }
695
+ } else {
696
+ return false;
697
+ }
698
+ } else {
699
+ return false;
700
+ }
681
701
  }
682
702
  }
683
703
  } else {
@@ -981,3 +1001,41 @@ async function getAssignedGroupIds( userClientId, getUserEmail ) {
981
1001
  logger.error( { error: error, message: data, function: 'getAssignedGroupIds' } );
982
1002
  }
983
1003
  }
1004
+
1005
+ export async function isAllowedClient( req, res, next ) {
1006
+ try {
1007
+ let reqestData = req.body;
1008
+ let getUserEmail = req.user.email;
1009
+ let getUserType = req.user.userType;
1010
+ let getClientId = req.user.clientId;
1011
+ let getRole = req.user.role;
1012
+ if ( getUserType == 'tango' ) {
1013
+ if ( getRole == 'superadmin' ) {
1014
+ next();
1015
+ } else {
1016
+ const assignedQuery = {
1017
+ userEmail: getUserEmail,
1018
+ assignedType: 'client',
1019
+ assignedValue: reqestData.clientId,
1020
+ };
1021
+ const getAssignedType = await findOneUserAssignedStore( assignedQuery );
1022
+ if ( getAssignedType ) {
1023
+ next();
1024
+ } else {
1025
+ return res.sendError( 'Client Not Assigned', 400 );
1026
+ }
1027
+ }
1028
+ } else if ( getUserType == 'client' ) {
1029
+ if ( getClientId == reqestData.clientId ) {
1030
+ next();
1031
+ } else {
1032
+ return res.sendError( 'Client Not Assigned', 400 );
1033
+ }
1034
+ } else {
1035
+ return res.sendError( 'Client Not Assigned', 400 );
1036
+ }
1037
+ } catch ( error ) {
1038
+ logger.error( { error: error, function: 'isAllowedClient' } );
1039
+ return res.sendError( error, 500 );
1040
+ }
1041
+ }
@@ -0,0 +1,586 @@
1
+ import { logger } from 'tango-app-api-middleware';
2
+ // import * as clientService from '../services/clients.services.js';
3
+ import {
4
+ aggregateStore,
5
+ } from '../services/stores.service.js';
6
+ import { aggregateUserAssignedStore, findOneUserAssignedStore } from '../services/userAssignedStore.service.js';
7
+ import { aggregateGroup } from '../services/group.service.js';
8
+
9
+ export const headerLocationsV2 = async ( req, res ) => {
10
+ try {
11
+ let reqestData = req.body;
12
+ let getUserEmail = req.user.email;
13
+ let getUserType = req.user.userType;
14
+ let getClientId = reqestData.clientId;
15
+ let totalStores = await getAllStores( getUserEmail, getClientId, getUserType );
16
+ if ( totalStores && totalStores.length>0 ) {
17
+ let storeQuery = [
18
+ {
19
+ $match: {
20
+ $and: [
21
+ { clientId: { $eq: getClientId } },
22
+ { storeId: { $in: totalStores } },
23
+ ],
24
+ },
25
+ },
26
+ {
27
+ $group: {
28
+ _id: '$storeProfile.city',
29
+ },
30
+ },
31
+ {
32
+ $project: {
33
+ _id: 0,
34
+ city: '$_id',
35
+ },
36
+ },
37
+ {
38
+ $sort: {
39
+ city: -1,
40
+ },
41
+ },
42
+ ];
43
+ const cityList = await aggregateStore( storeQuery );
44
+ if ( cityList && cityList.length > 0 ) {
45
+ return res.sendSuccess( { locationData: cityList } );
46
+ } else {
47
+ return res.sendError( 'No City', 400 );
48
+ }
49
+ } else {
50
+ return res.sendError( 'No stores', 400 );
51
+ }
52
+ } catch ( error ) {
53
+ logger.error( { error: error, message: req.query, function: 'trafficCards' } );
54
+ return res.sendError( { error: error }, 500 );
55
+ }
56
+ };
57
+
58
+ export const headerGroupsV2 = async ( req, res ) => {
59
+ try {
60
+ let requestData = req.body;
61
+ let getUserEmail = req.user.email;
62
+ let getUserType = req.user.userType;
63
+ const assignedQuery = {
64
+ clientId: requestData.clientId,
65
+ userEmail: getUserEmail,
66
+ };
67
+ let groupIds;
68
+ const getAssignedType = await findOneUserAssignedStore( assignedQuery );
69
+ if ( getAssignedType ) {
70
+ if ( getAssignedType.userType == 'client' ) {
71
+ if ( getAssignedType.assignedType == 'allstores' ) {
72
+ groupIds = await getGroupIds( requestData.clientId );
73
+ } else if ( getAssignedType.assignedType == 'group' ) {
74
+ groupIds = await getAssignedGroupIds( requestData.clientId, getUserEmail );
75
+ }
76
+ } else if ( getAssignedType.userType == 'tango' ) {
77
+ groupIds = await getGroupIds( requestData.clientId );
78
+ } else {
79
+ groupIds = [];
80
+ }
81
+ } else {
82
+ if ( getUserType == 'tango' ) {
83
+ groupIds = await getGroupIds( requestData.clientId );
84
+ } else {
85
+ return res.sendError( 'No User Assign', 400 );
86
+ }
87
+ }
88
+
89
+ if ( groupIds && groupIds.length > 0 ) {
90
+ let groupQuery = [
91
+ {
92
+ $match: {
93
+ $and: [
94
+ { clientId: { $eq: requestData.clientId } },
95
+ { _id: { $in: groupIds } },
96
+ ],
97
+ },
98
+ },
99
+ {
100
+ $project: {
101
+ _id: 0,
102
+ groupName: 1,
103
+ },
104
+ },
105
+ ];
106
+ const groupResult = await aggregateGroup( groupQuery );
107
+ if ( groupResult && groupResult.length > 0 ) {
108
+ return res.sendSuccess( { groupData: groupResult } );
109
+ } else {
110
+ return res.sendError( 'No Group', 400 );
111
+ }
112
+ } else {
113
+ return res.sendError( 'No Group', 400 );
114
+ }
115
+ } catch ( error ) {
116
+ console.log( 'error =>', error );
117
+ logger.error( { error: error, message: req.query, function: 'trafficCards' } );
118
+ return res.sendError( { error: error }, 500 );
119
+ }
120
+ };
121
+
122
+ export const headerStoresV2 = async ( req, res ) => {
123
+ try {
124
+ let reqestData = req.body;
125
+ let getUserEmail = req.user.email;
126
+ let getUserType = req.user.userType;
127
+ let getClientId = reqestData.clientId;
128
+ let totalStores = await getAllStores( getUserEmail, getClientId, getUserType );
129
+ if ( totalStores && totalStores.length>0 ) {
130
+ let storeQuery = [];
131
+ if ( reqestData.city.length>0 && reqestData.group.length>0 ) {
132
+ let unqueCityStores = await getLocationStores( getClientId, reqestData.city );
133
+ let unqueGroupStores = await getGroupStores( getClientId, reqestData.group );
134
+ storeQuery = [
135
+ {
136
+ $match: {
137
+ $and: [
138
+ { storeId: { $in: totalStores } },
139
+ { storeId: { $in: unqueCityStores } },
140
+ { storeId: { $in: unqueGroupStores } },
141
+ ],
142
+ },
143
+ },
144
+ {
145
+ $project: {
146
+ _id: 0,
147
+ storeId: '$storeId',
148
+ storeName: '$storeName',
149
+ },
150
+ },
151
+ ];
152
+ } else if ( reqestData.city.length>0 ) {
153
+ let unqueCityStores = await getLocationStores( getClientId, reqestData.city );
154
+ storeQuery = [
155
+ {
156
+ $match: {
157
+ $and: [
158
+ { storeId: { $in: totalStores } },
159
+ { storeId: { $in: unqueCityStores } },
160
+ ],
161
+ },
162
+ },
163
+ {
164
+ $project: {
165
+ _id: 0,
166
+ storeId: '$storeId',
167
+ storeName: '$storeName',
168
+ },
169
+ },
170
+ ];
171
+ } else if ( reqestData.group.length>0 ) {
172
+ let unqueGroupStores = await getGroupStores( getClientId, reqestData.group );
173
+ storeQuery = [
174
+ {
175
+ $match: {
176
+ $and: [
177
+ { storeId: { $in: totalStores } },
178
+ { storeId: { $in: unqueGroupStores } },
179
+ ],
180
+ },
181
+ },
182
+ {
183
+ $project: {
184
+ _id: 0,
185
+ storeId: '$storeId',
186
+ storeName: '$storeName',
187
+ },
188
+ },
189
+ ];
190
+ } else {
191
+ let totalStores = await getAllStores( getUserEmail, getClientId, getUserType );
192
+ storeQuery = [
193
+ {
194
+ $match: {
195
+ $and: [
196
+ { storeId: { $in: totalStores } },
197
+ ],
198
+ },
199
+ },
200
+ {
201
+ $project: {
202
+ _id: 0,
203
+ storeId: '$storeId',
204
+ storeName: '$storeName',
205
+ },
206
+ },
207
+ ];
208
+ }
209
+
210
+ const storeList = await aggregateStore( storeQuery );
211
+ if ( storeList && storeList.length > 0 ) {
212
+ return res.sendSuccess( { storesData: storeList } );
213
+ } else {
214
+ return res.sendError( 'No Stores', 400 );
215
+ }
216
+ } else {
217
+ return res.sendError( 'No Stores', 400 );
218
+ }
219
+ } catch ( error ) {
220
+ console.log( 'headerStoresV1 =>', error );
221
+ logger.error( { error: error, message: req.query, function: 'headerStoresV1' } );
222
+ return res.sendError( { error: error }, 500 );
223
+ }
224
+ };
225
+
226
+ async function getAllStores( getUserEmail, getClientId, getUserType ) {
227
+ try {
228
+ if ( getUserEmail && getUserEmail !='' ) {
229
+ const assignedQuery = {
230
+ clientId: getClientId,
231
+ userEmail: getUserEmail,
232
+ };
233
+ const getAssignedType = await findOneUserAssignedStore( assignedQuery );
234
+ if ( getAssignedType ) {
235
+ if ( getAssignedType.userType == 'client' ) {
236
+ if ( getAssignedType.assignedType && getAssignedType.assignedType !='' ) {
237
+ let overAllStores = [];
238
+ switch ( getAssignedType.assignedType ) {
239
+ case 'store':
240
+ let getAS = await getAssignedStores( getClientId, getUserEmail, 'store' );
241
+ if ( getAS && getAS.length >0 ) {
242
+ overAllStores = getAS;
243
+ }
244
+ break;
245
+ case 'group':
246
+ let getAGS = await getAssignedGroupStores( getClientId, getUserEmail, 'group' );
247
+ if ( getAGS && getAGS.length >0 ) {
248
+ overAllStores = getAGS;
249
+ }
250
+ break;
251
+ case 'allstores':
252
+ let getAllS = await getAssignedAllStores( getClientId );
253
+ if ( getAllS && getAllS.length >0 ) {
254
+ overAllStores = getAllS;
255
+ }
256
+ break;
257
+ default:
258
+ break;
259
+ }
260
+ return overAllStores;
261
+ } else {
262
+ return false;
263
+ }
264
+ } else if ( getAssignedType.userType == 'tango' ) {
265
+ let overAllStores = [];
266
+ let getAllS = await getAssignedAllStores( getClientId );
267
+ if ( getAllS && getAllS.length >0 ) {
268
+ overAllStores = getAllS;
269
+ }
270
+ return overAllStores;
271
+ } else {
272
+ return false;
273
+ }
274
+ } else {
275
+ if ( getUserType && getUserType == 'tango' ) {
276
+ let overAllStores = [];
277
+ let getAllS = await getAssignedAllStores( getClientId );
278
+ if ( getAllS && getAllS.length >0 ) {
279
+ overAllStores = getAllS;
280
+ }
281
+ return overAllStores;
282
+ } else {
283
+ return false;
284
+ }
285
+ }
286
+ } else {
287
+ return false;
288
+ }
289
+ } catch ( error ) {
290
+ console.log( 'getAllStores =>', error );
291
+ logger.error( { error: error, message: req.query, function: 'getAllStores' } );
292
+ }
293
+ };
294
+
295
+ async function getAssignedStores( clientId, userEmail, assignedType ) {
296
+ try {
297
+ if ( clientId && clientId !='' && userEmail && userEmail !='' && assignedType && assignedType !='' ) {
298
+ let storeQuery = [
299
+ {
300
+ $match: {
301
+ $and: [
302
+ { clientId: { $eq: clientId } },
303
+ { userEmail: { $eq: userEmail } },
304
+ { assignedType: { $eq: assignedType } },
305
+ ],
306
+ },
307
+ },
308
+ {
309
+ $group: {
310
+ _id: null,
311
+ stores: { $push: '$assignedValue' },
312
+ },
313
+ },
314
+ ];
315
+ const storeList = await aggregateUserAssignedStore( storeQuery );
316
+ if ( storeList && storeList.length>0 && storeList[0]?.stores.length > 0 ) {
317
+ let uniqueStores = [ ...new Set( storeList[0].stores ) ];
318
+ return uniqueStores;
319
+ } else {
320
+ return false;
321
+ }
322
+ } else {
323
+ return false;
324
+ }
325
+ } catch ( error ) {
326
+ console.log( 'getAssignedStores error =>', error );
327
+ logger.error( { error: error, message: data, function: 'getAssignedStores' } );
328
+ }
329
+ }
330
+
331
+ async function getAssignedGroupStores( clientId, userEmail, assignedType ) {
332
+ try {
333
+ if ( clientId && clientId !='' && userEmail && userEmail !='' && assignedType && assignedType !='' ) {
334
+ const groupQuery = [
335
+ {
336
+ $match: {
337
+ $and: [
338
+ { clientId: { $eq: clientId } },
339
+ { userEmail: { $eq: userEmail } },
340
+ { assignedType: { $eq: assignedType } },
341
+ ],
342
+ },
343
+ },
344
+ {
345
+ $lookup: {
346
+ from: 'groups',
347
+ let: { groupId: { $toObjectId: '$assignedValue' } },
348
+ pipeline: [
349
+ {
350
+ $match: {
351
+ $expr: {
352
+ $eq: [ '$_id', '$$groupId' ],
353
+ },
354
+ },
355
+ },
356
+ {
357
+ $project: {
358
+ _id: 0,
359
+ storeList: 1,
360
+ },
361
+ },
362
+ ], as: 'groups',
363
+ },
364
+ },
365
+ {
366
+ $unwind: {
367
+ path: '$groups', preserveNullAndEmptyArrays: true,
368
+ },
369
+ },
370
+ {
371
+ $unwind: {
372
+ path: '$groups.storeList', preserveNullAndEmptyArrays: true,
373
+ },
374
+ },
375
+ {
376
+ $group: {
377
+ _id: null,
378
+ stores: { $push: '$groups.storeList' },
379
+ },
380
+ },
381
+ ];
382
+ const groupStoreList = await aggregateUserAssignedStore( groupQuery );
383
+ if ( groupStoreList && groupStoreList.length>0 && groupStoreList[0]?.stores.length > 0 ) {
384
+ let uniqueStores = [ ...new Set( groupStoreList[0].stores ) ];
385
+ return uniqueStores;
386
+ } else {
387
+ return false;
388
+ }
389
+ } else {
390
+ return false;
391
+ }
392
+ } catch ( error ) {
393
+ console.log( 'getAssignedGroupStores error =>', error );
394
+ logger.error( { error: error, message: data, function: 'getAssignedGroupStores' } );
395
+ }
396
+ }
397
+
398
+ async function getAssignedAllStores( userClientId ) {
399
+ try {
400
+ if ( userClientId && userClientId !='' ) {
401
+ let storeQuery = [
402
+ {
403
+ $match: {
404
+ $and: [
405
+ { clientId: { $eq: userClientId } },
406
+ { status: { $eq: 'active' } },
407
+ ],
408
+ },
409
+ },
410
+ {
411
+ $group: {
412
+ _id: null,
413
+ stores: { $push: '$storeId' },
414
+ },
415
+ },
416
+ ];
417
+ const storeList = await aggregateStore( storeQuery );
418
+ if ( storeList && storeList.length>0 && storeList[0]?.stores.length > 0 ) {
419
+ let uniqueStores = [ ...new Set( storeList[0].stores ) ];
420
+ return uniqueStores;
421
+ } else {
422
+ return false;
423
+ }
424
+ } else {
425
+ return false;
426
+ }
427
+ } catch ( error ) {
428
+ console.log( 'getAssignedAllStores error =>', error );
429
+ logger.error( { error: error, message: data, function: 'getAssignedAllStores' } );
430
+ }
431
+ }
432
+
433
+ async function getGroupStores( userClientId, groupList ) {
434
+ try {
435
+ if ( userClientId && userClientId !='' && groupList && groupList.length >0 ) {
436
+ let groupQuery = [
437
+ {
438
+ $match: {
439
+ $and: [
440
+ { clientId: { $eq: userClientId } },
441
+ { groupName: { $in: groupList } },
442
+ ],
443
+ },
444
+ },
445
+ {
446
+ $unwind: {
447
+ path: '$storeList', preserveNullAndEmptyArrays: true,
448
+ },
449
+ },
450
+ {
451
+ $group: {
452
+ _id: null,
453
+ stores: { $push: '$storeList' },
454
+ },
455
+ },
456
+ ];
457
+ const groupStoreList = await aggregateGroup( groupQuery );
458
+ if ( groupStoreList && groupStoreList.length>0 && groupStoreList[0]?.stores.length > 0 ) {
459
+ let uniqueStores = [ ...new Set( groupStoreList[0].stores ) ];
460
+ return uniqueStores;
461
+ } else {
462
+ return false;
463
+ }
464
+ } else {
465
+ return false;
466
+ }
467
+ } catch ( error ) {
468
+ console.log( 'getGroupStores error =>', error );
469
+ logger.error( { error: error, message: data, function: 'getGroupStores' } );
470
+ }
471
+ }
472
+
473
+ async function getLocationStores( userClientId, cityList ) {
474
+ try {
475
+ if ( userClientId && userClientId !='' && cityList && cityList.length >0 ) {
476
+ let storeQuery = [
477
+ {
478
+ $match: {
479
+ $and: [
480
+ { clientId: { $eq: userClientId } },
481
+ { 'storeProfile.city': { $in: cityList } },
482
+ ],
483
+ },
484
+ },
485
+ {
486
+ $project: {
487
+ _id: 0,
488
+ storeId: '$storeId',
489
+ },
490
+ },
491
+ {
492
+ $group: {
493
+ _id: null,
494
+ stores: { $push: '$storeId' },
495
+ },
496
+ },
497
+ ];
498
+ const cityStoreList = await aggregateStore( storeQuery );
499
+ if ( cityStoreList && cityStoreList.length>0 && cityStoreList[0]?.stores.length > 0 ) {
500
+ let uniqueStores = [ ...new Set( cityStoreList[0].stores ) ];
501
+ return uniqueStores;
502
+ } else {
503
+ return false;
504
+ }
505
+ } else {
506
+ return false;
507
+ }
508
+ } catch ( error ) {
509
+ console.log( 'getLocationStores error =>', error );
510
+ logger.error( { error: error, message: data, function: 'getLocationStores' } );
511
+ }
512
+ }
513
+
514
+ async function getGroupIds( userClientId ) {
515
+ try {
516
+ if ( userClientId && userClientId !='' ) {
517
+ let groupQuery = [
518
+ {
519
+ $match: {
520
+ $and: [
521
+ { clientId: { $eq: userClientId } },
522
+ ],
523
+ },
524
+ },
525
+ {
526
+ $group: {
527
+ _id: null,
528
+ groupName: { $push: '$_id' },
529
+ },
530
+ },
531
+ ];
532
+ const groupGroupIds = await aggregateGroup( groupQuery );
533
+ if ( groupGroupIds && groupGroupIds.length>0 && groupGroupIds[0]?.groupName.length > 0 ) {
534
+ let uniqueGroupIds = [ ...new Set( groupGroupIds[0].groupName ) ];
535
+ return uniqueGroupIds;
536
+ } else {
537
+ return false;
538
+ }
539
+ } else {
540
+ return false;
541
+ }
542
+ } catch ( error ) {
543
+ console.log( 'getGroupIds error =>', error );
544
+ logger.error( { error: error, message: data, function: 'getGroupIds' } );
545
+ }
546
+ }
547
+
548
+ async function getAssignedGroupIds( userClientId, getUserEmail ) {
549
+ try {
550
+ if ( userClientId && userClientId !='' && getUserEmail && getUserEmail !='' ) {
551
+ let groupQuery = [
552
+ {
553
+ $match: {
554
+ $and: [
555
+ { clientId: { $eq: userClientId } },
556
+ { userEmail: { $eq: getUserEmail } },
557
+ { assignedType: { $eq: 'group' } },
558
+ ],
559
+ },
560
+ },
561
+ {
562
+ $group: {
563
+ _id: null,
564
+ groupName: { $push: '$assignedValue' },
565
+ },
566
+ },
567
+ ];
568
+ const groupStoreList = await aggregateUserAssignedStore( groupQuery );
569
+ if ( groupStoreList && groupStoreList.length>0 && groupStoreList[0]?.groupName.length > 0 ) {
570
+ let uniqueGroupIdsData = [ ...new Set( groupStoreList[0].groupName ) ];
571
+ let uniqueGroupIds = [];
572
+ for ( let i = 0; i < uniqueGroupIdsData.length; i++ ) {
573
+ uniqueGroupIds.push( new ObjectId( uniqueGroupIdsData[i] ) );
574
+ }
575
+ return uniqueGroupIds;
576
+ } else {
577
+ return false;
578
+ }
579
+ } else {
580
+ return false;
581
+ }
582
+ } catch ( error ) {
583
+ console.log( 'getAssignedGroupIds error =>', error );
584
+ logger.error( { error: error, message: data, function: 'getAssignedGroupIds' } );
585
+ }
586
+ }
@@ -135,9 +135,9 @@ export const validateFootfallDirectoryParams = {
135
135
  export const validateSummaryTableSchema = joi.object( {
136
136
  ...baseSchema,
137
137
  valueType: joi.string().required(),
138
- search: joi.string().optional(),
139
- sortBy: joi.number().optional(),
140
- sort: joi.string().optional(),
138
+ search: joi.string().optional().allow( '' ),
139
+ sortBy: joi.number().optional().allow( '' ),
140
+ sort: joi.string().optional().allow( '' ),
141
141
  limit: joi.number().required(),
142
142
  offset: joi.number().required(),
143
143
  } );
@@ -148,11 +148,14 @@ export const validateSummaryTableParams = {
148
148
 
149
149
  export const validateFootfallTrendSchema = joi.object( {
150
150
  ...baseSchema,
151
+ dateType: joi.string().required(),
151
152
  filterBy: joi.string().required(),
152
153
  processType: joi.string().required(),
153
154
  forecast: joi.boolean().optional(),
154
155
  limit: joi.number().required(),
155
156
  offset: joi.number().required(),
157
+ sortBy: joi.number().optional().allow( '' ),
158
+ sort: joi.string().optional().allow( '' ),
156
159
  } );
157
160
 
158
161
  export const validateFootfallTrendParams = {
@@ -177,6 +180,16 @@ export const validateStoresMapParams = {
177
180
  body: validateStoresMapSchema,
178
181
  };
179
182
 
183
+ export const validateperformanceMatrixSchema = joi.object( {
184
+ ...baseSchema,
185
+ processtype1: joi.string().required(),
186
+ processtype2: joi.string().required(),
187
+ } );
188
+
189
+ export const validateperformanceMatrixParams = {
190
+ body: validateperformanceMatrixSchema,
191
+ };
192
+
180
193
  export const validateHeaderSchema = joi.object( {
181
194
  clientId: joi.string().required(),
182
195
  city: joi.array().required(),
@@ -45,10 +45,12 @@ import {
45
45
  summaryTableV1,
46
46
  footfallTrendV1,
47
47
  storeOperationV1,
48
+ performanceMatrixV1,
48
49
  storesMapV1,
49
50
  headerStoresV1,
50
51
  headerLocationsV1,
51
52
  headerGroupsV1,
53
+ isAllowedClient,
52
54
  } from '../controllers/tangoTrafficV1.controllers.js';
53
55
 
54
56
 
@@ -75,97 +77,102 @@ analysisTrafficRouter
75
77
  .post( '/headerLocations', headerLocations )
76
78
  .post( '/headerGroups', headerGroups )
77
79
  .post( '/headerStores', headerStores )
78
- .post( '/cardsFunnel_v1', isAllowedSessionHandler, authorize( {
80
+ .post( '/cardsFunnel_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
79
81
  userType: [ 'tango', 'client' ], access: [
80
82
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
81
83
  ],
82
84
  } ), validate( validationDtos.validateCardFunnelParams ), cardsFunnelV1 )
83
- .post( '/cardsGraphs_v1', isAllowedSessionHandler, authorize( {
85
+ .post( '/cardsGraphs_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
84
86
  userType: [ 'tango', 'client' ], access: [
85
87
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
86
88
  ],
87
89
  } ), validate( validationDtos.validateCardGraphParams ), cardsGraphsV1 )
88
- .post( '/recapVideo_v1', isAllowedSessionHandler, authorize( {
90
+ .post( '/recapVideo_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
89
91
  userType: [ 'tango', 'client' ], access: [
90
92
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
91
93
  ],
92
94
  } ), validate( validationDtos.validateRecapVideoParams ), recapVideoV1 )
93
- .post( '/densityDwell_v1', isAllowedSessionHandler, authorize( {
95
+ .post( '/densityDwell_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
94
96
  userType: [ 'tango', 'client' ], access: [
95
97
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
96
98
  ],
97
99
  } ), validate( validationDtos.validateDensityDwellParams ), densityDwellV1 )
98
- .post( '/overallCards_v1', isAllowedSessionHandler, authorize( {
100
+ .post( '/overallCards_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
99
101
  userType: [ 'tango', 'client' ], access: [
100
102
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
101
103
  ],
102
104
  } ), validate( validationDtos.validateOverallCardsParams ), overallCardsV1 )
103
- .post( '/overallHourlyChart_v1', isAllowedSessionHandler, authorize( {
105
+ .post( '/overallHourlyChart_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
104
106
  userType: [ 'tango', 'client' ], access: [
105
107
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
106
108
  ],
107
109
  } ), validate( validationDtos.validateOverallHourlyChartParams ), overallHourlyChartV1 )
108
- .post( '/overallChart_v1', isAllowedSessionHandler, authorize( {
110
+ .post( '/overallChart_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
109
111
  userType: [ 'tango', 'client' ], access: [
110
112
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
111
113
  ],
112
114
  } ), validate( validationDtos.validateOverallCharParams ), overallChartV1 )
113
- .post( '/singleStoreChart_v1', isAllowedSessionHandler, authorize( {
115
+ .post( '/singleStoreChart_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
114
116
  userType: [ 'tango', 'client' ], access: [
115
117
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
116
118
  ],
117
119
  } ), validate( validationDtos.validateSingleStoreChartParams ), singleStoreChartV1 )
118
- .post( '/demographicChart_v1', isAllowedSessionHandler, authorize( {
120
+ .post( '/demographicChart_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
119
121
  userType: [ 'tango', 'client' ], access: [
120
122
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
121
123
  ],
122
124
  } ), validate( validationDtos.validateDemographicChartParams ), demographicChartV1 )
123
- .post( '/buyerChart_v1', isAllowedSessionHandler, authorize( {
125
+ .post( '/buyerChart_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
124
126
  userType: [ 'tango', 'client' ], access: [
125
127
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
126
128
  ],
127
129
  } ), validate( validationDtos.validateBuyerChartParams ), buyerChartV1 )
128
- .post( '/footfallDirectoryFolders_v1', isAllowedSessionHandler, authorize( {
130
+ .post( '/footfallDirectoryFolders_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
129
131
  userType: [ 'tango', 'client' ], access: [
130
132
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
131
133
  ],
132
134
  } ), validate( validationDtos.validateFootfallDirectoryFoldersParams ), footfallDirectoryFoldersV1 )
133
- .post( '/footfallDirectory_v1', isAllowedSessionHandler, authorize( {
135
+ .post( '/footfallDirectory_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
134
136
  userType: [ 'tango', 'client' ], access: [
135
137
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
136
138
  ],
137
139
  } ), validate( validationDtos.validateFootfallDirectoryParams ), footfallDirectoryV1 )
138
- .post( '/summaryTable_v1', isAllowedSessionHandler, authorize( {
140
+ .post( '/summaryTable_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
139
141
  userType: [ 'tango', 'client' ], access: [
140
142
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
141
143
  ],
142
144
  } ), validate( validationDtos.validateSummaryTableParams ), summaryTableV1 )
143
- .post( '/footfallTrend_v1', isAllowedSessionHandler, authorize( {
145
+ .post( '/footfallTrend_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
144
146
  userType: [ 'tango', 'client' ], access: [
145
147
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
146
148
  ],
147
149
  } ), validate( validationDtos.validateFootfallTrendParams ), footfallTrendV1 )
148
- .post( '/storeOperation_v1', isAllowedSessionHandler, authorize( {
150
+ .post( '/storeOperation_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
149
151
  userType: [ 'tango', 'client' ], access: [
150
152
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
151
153
  ],
152
154
  } ), validate( validationDtos.validateStoreOperationParams ), storeOperationV1 )
153
- .post( '/storesMap_v1', isAllowedSessionHandler, authorize( {
155
+ .post( '/performanceMatrix_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
156
+ userType: [ 'tango', 'client' ], access: [
157
+ { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
158
+ ],
159
+ } ), validate( validationDtos.validateperformanceMatrixParams ), performanceMatrixV1 )
160
+ .post( '/storesMap_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
154
161
  userType: [ 'tango', 'client' ], access: [
155
162
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
156
163
  ],
157
164
  } ), validate( validationDtos.validateStoresMapParams ), storesMapV1 )
158
- .post( '/headerLocations_v1', isAllowedSessionHandler, authorize( {
165
+ .post( '/headerLocations_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
159
166
  userType: [ 'tango', 'client' ], access: [
160
167
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
161
168
  ],
162
169
  } ), validate( validationDtos.validateHeaderParams ), headerLocationsV1 )
163
- .post( '/headerGroups_v1', isAllowedSessionHandler, authorize( {
170
+ .post( '/headerGroups_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
164
171
  userType: [ 'tango', 'client' ], access: [
165
172
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
166
173
  ],
167
174
  } ), validate( validationDtos.validateHeaderParams ), headerGroupsV1 )
168
- .post( '/headerStores_v1', isAllowedSessionHandler, authorize( {
175
+ .post( '/headerStores_v1', isAllowedSessionHandler, isAllowedClient, authorize( {
169
176
  userType: [ 'tango', 'client' ], access: [
170
177
  { featureName: 'analytics', name: 'tangoTraffic', permissions: [ 'isView' ] },
171
178
  ],