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.
@@ -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
+ }
@@ -6,12 +6,12 @@ const baseSchema = {
6
6
  storeId: joi.array().required().empty(),
7
7
  fromDate: joi.string().required(),
8
8
  toDate: joi.string().required(),
9
+ valueType: joi.string().optional().allow( '' ),
9
10
  };
10
11
 
11
12
  // Schema for Card Funnel
12
13
  export const validateCardFunnelSchema = joi.object( {
13
14
  ...baseSchema,
14
- valueType: joi.string().required(),
15
15
  } );
16
16
 
17
17
  export const validateCardFunnelParams = {
@@ -21,7 +21,6 @@ export const validateCardFunnelParams = {
21
21
  // Schema for Card Graph (extends baseSchema with additional fields)
22
22
  export const validateCardGraphSchema = joi.object( {
23
23
  ...baseSchema,
24
- valueType: joi.string().required(),
25
24
  dateType: joi.string().required(),
26
25
  } );
27
26
 
@@ -42,7 +41,6 @@ export const validateRecapVideoParams = {
42
41
  export const validateDensityDwellSchema = joi.object( {
43
42
  ...baseSchema,
44
43
  dateRange: joi.number().required(),
45
- hourFormat: joi.number().required(),
46
44
  } );
47
45
 
48
46
  export const validateDensityDwellParams = {
@@ -61,7 +59,6 @@ export const validateOverallCardsParams = {
61
59
 
62
60
  export const validateOverallHourlyChartSchema = joi.object( {
63
61
  ...baseSchema,
64
- hourFormat: joi.number().required(),
65
62
  processType: joi.string().required(),
66
63
  } );
67
64
 
@@ -135,11 +132,12 @@ export const validateFootfallDirectoryParams = {
135
132
  export const validateSummaryTableSchema = joi.object( {
136
133
  ...baseSchema,
137
134
  valueType: joi.string().required(),
138
- search: joi.string().optional(),
139
- sortBy: joi.number().optional(),
140
- sort: joi.string().optional(),
135
+ search: joi.string().optional().allow( '' ),
136
+ sortBy: joi.number().optional().allow( '' ),
137
+ sort: joi.string().optional().allow( '' ),
141
138
  limit: joi.number().required(),
142
139
  offset: joi.number().required(),
140
+ export: joi.boolean().required(),
143
141
  } );
144
142
 
145
143
  export const validateSummaryTableParams = {
@@ -148,11 +146,14 @@ export const validateSummaryTableParams = {
148
146
 
149
147
  export const validateFootfallTrendSchema = joi.object( {
150
148
  ...baseSchema,
149
+ dateType: joi.string().required(),
151
150
  filterBy: joi.string().required(),
152
- processType: joi.string().required(),
151
+ processType: joi.string().optional().allow( '' ),
153
152
  forecast: joi.boolean().optional(),
154
153
  limit: joi.number().required(),
155
154
  offset: joi.number().required(),
155
+ sortBy: joi.number().optional().allow( '' ),
156
+ sort: joi.string().optional().allow( '' ),
156
157
  } );
157
158
 
158
159
  export const validateFootfallTrendParams = {
@@ -177,6 +178,16 @@ export const validateStoresMapParams = {
177
178
  body: validateStoresMapSchema,
178
179
  };
179
180
 
181
+ export const validateperformanceMatrixSchema = joi.object( {
182
+ ...baseSchema,
183
+ processtype1: joi.string().required(),
184
+ processtype2: joi.string().required(),
185
+ } );
186
+
187
+ export const validateperformanceMatrixParams = {
188
+ body: validateperformanceMatrixSchema,
189
+ };
190
+
180
191
  export const validateHeaderSchema = joi.object( {
181
192
  clientId: joi.string().required(),
182
193
  city: joi.array().required(),
@@ -186,3 +197,22 @@ export const validateHeaderSchema = joi.object( {
186
197
  export const validateHeaderParams = {
187
198
  body: validateHeaderSchema,
188
199
  };
200
+
201
+ export const getMyProductSchema = joi.object( {
202
+ clientId: joi.string().required(),
203
+ storeId: joi.array().optional().empty(),
204
+ } );
205
+
206
+ export const getMyProductParams = {
207
+ body: getMyProductSchema,
208
+ };
209
+
210
+ export const getStoreCameraImageSchema = joi.object( {
211
+ clientId: joi.string().required(),
212
+ storeId: joi.array().optional().empty(),
213
+ storeDate: joi.string().required(),
214
+ } );
215
+
216
+ export const getStoreCameraImageParams = {
217
+ body: getStoreCameraImageSchema,
218
+ };