tango-app-api-trax 1.0.0-alpha-task.130

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.
Files changed (49) hide show
  1. package/.eslintrc.cjs +41 -0
  2. package/README.md +29 -0
  3. package/fir-51e77-firebase-adminsdk-x3sdp-fd902b74ae.json +14 -0
  4. package/index.js +12 -0
  5. package/package.json +43 -0
  6. package/src/controllers/download.controller.js +544 -0
  7. package/src/controllers/gallery.controller.js +457 -0
  8. package/src/controllers/internalTrax.controller.js +989 -0
  9. package/src/controllers/locus.controller.js +214 -0
  10. package/src/controllers/mobileTrax.controller.js +2327 -0
  11. package/src/controllers/teaxFlag.controller.js +2699 -0
  12. package/src/controllers/trax.controller.js +2214 -0
  13. package/src/controllers/traxDashboard.controllers.js +3523 -0
  14. package/src/dtos/dashboardValidation.dtos.js +143 -0
  15. package/src/dtos/downloadValidation.dtos.js +44 -0
  16. package/src/dtos/validation.dtos.js +138 -0
  17. package/src/hbs/login-otp.hbs +944 -0
  18. package/src/routes/download.router.js +23 -0
  19. package/src/routes/gallery.routes.js +28 -0
  20. package/src/routes/internalTraxApi.router.js +19 -0
  21. package/src/routes/locus.router.js +16 -0
  22. package/src/routes/mobileTrax.routes.js +25 -0
  23. package/src/routes/trax.routes.js +24 -0
  24. package/src/routes/traxDashboard.routes.js +59 -0
  25. package/src/routes/traxFlag.router.js +74 -0
  26. package/src/services/app.service.js +10 -0
  27. package/src/services/approver.service.js +20 -0
  28. package/src/services/authentication.service.js +6 -0
  29. package/src/services/checklist.service.js +31 -0
  30. package/src/services/checklistAssign.service.js +31 -0
  31. package/src/services/checklistQuestion.service.js +31 -0
  32. package/src/services/checklistlog.service.js +35 -0
  33. package/src/services/clientRequest.service.js +5 -0
  34. package/src/services/clients.services.js +23 -0
  35. package/src/services/domain.service.js +28 -0
  36. package/src/services/download.services.js +38 -0
  37. package/src/services/group.service.js +22 -0
  38. package/src/services/lenskartEmployeeMapping.service.js +15 -0
  39. package/src/services/locus.service.js +34 -0
  40. package/src/services/otp.service.js +14 -0
  41. package/src/services/processedTaskConfig.service.js +32 -0
  42. package/src/services/processedTaskList.service.js +30 -0
  43. package/src/services/processedchecklist.services.js +36 -0
  44. package/src/services/processedchecklistconfig.services.js +35 -0
  45. package/src/services/store.service.js +31 -0
  46. package/src/services/tagging.service.js +5 -0
  47. package/src/services/ticket.service.js +15 -0
  48. package/src/services/user.service.js +25 -0
  49. package/src/services/userAssignedstores.service.js +10 -0
@@ -0,0 +1,2699 @@
1
+ import { download, logger } from 'tango-app-api-middleware';
2
+ import { aggregate } from '../services/processedchecklist.services.js';
3
+ import dayjs from 'dayjs';
4
+ import * as processedchecklistService from '../services/processedchecklist.services.js';
5
+ import * as processedchecklistconfigService from '../services/processedchecklistconfig.services.js';
6
+
7
+
8
+ import utc from 'dayjs/plugin/utc.js';
9
+ dayjs.extend( utc );
10
+ import mongoose from 'mongoose';
11
+
12
+ export const overallFlagMetrics = async ( req, res ) => {
13
+ try {
14
+ const pipeline = [
15
+ {
16
+ $facet: {
17
+ currentPeriod: [
18
+ {
19
+ $match: {
20
+ $and: [
21
+ { client_id: req.body.clientId },
22
+ {
23
+ store_id: {
24
+ $in: req.body.stores,
25
+ },
26
+ },
27
+ {
28
+ date_iso: {
29
+ $gte: new Date( req.body.startDate ),
30
+ },
31
+ },
32
+ {
33
+ date_iso: {
34
+ $lte: new Date( req.body.endDate ),
35
+ },
36
+ },
37
+ ],
38
+ },
39
+ },
40
+ {
41
+ $project: {
42
+ timeFlag: 1,
43
+ questionFlag: 1,
44
+ mobileDetectionFlag: 1,
45
+ storeOpenCloseFlag: 1,
46
+ uniformDetectionFlag: 1,
47
+ },
48
+ },
49
+ {
50
+ $group: {
51
+ _id: '',
52
+ questionFlag: {
53
+ $sum: '$questionFlag',
54
+ },
55
+ timeFlag: { $sum: '$timeFlag' },
56
+ detectionFlags: {
57
+ $sum: {
58
+ $cond: [
59
+ {
60
+ $or: [
61
+ {
62
+ $gt: [
63
+ '$mobileDetectionFlag',
64
+ 0,
65
+ ],
66
+ },
67
+ {
68
+ $gt: [
69
+ '$storeOpenCloseFlag',
70
+ 0,
71
+ ],
72
+ },
73
+ {
74
+ $gt: [
75
+ '$uniformDetectionFlag',
76
+ 0,
77
+ ],
78
+ },
79
+ ],
80
+ },
81
+ 1,
82
+ 0,
83
+ ],
84
+ },
85
+ },
86
+ },
87
+ },
88
+ {
89
+ $addFields: {
90
+ totalFlags: {
91
+ $add: [
92
+ '$questionFlag',
93
+ '$timeFlag',
94
+ '$detectionFlags',
95
+ ],
96
+ },
97
+ },
98
+ },
99
+ {
100
+ $project: {
101
+ _id: 0,
102
+ },
103
+ },
104
+ ],
105
+ last7Days: [
106
+ {
107
+ $match: {
108
+ $and: [
109
+ { client_id: req.body.clientId },
110
+ {
111
+ store_id: {
112
+ $in: req.body.stores,
113
+ },
114
+ },
115
+ {
116
+ date_iso: {
117
+ $gte: dayjs.utc( req.body.endDate ).subtract( 7, 'days' ).startOf( 'day' ).toDate(),
118
+ },
119
+ },
120
+ {
121
+ date_iso: {
122
+ $lte: dayjs.utc( req.body.startDate ).subtract( 1, 'day' ).startOf( 'day' ).toDate(),
123
+ },
124
+ },
125
+ ],
126
+ },
127
+ },
128
+ {
129
+ $project: {
130
+ timeFlag: 1,
131
+ questionFlag: 1,
132
+ mobileDetectionFlag: 1,
133
+ storeOpenCloseFlag: 1,
134
+ uniformDetectionFlag: 1,
135
+ },
136
+ },
137
+ {
138
+ $group: {
139
+ _id: '',
140
+ questionFlag: {
141
+ $sum: '$questionFlag',
142
+ },
143
+ timeFlag: { $sum: '$timeFlag' },
144
+ detectionFlags: {
145
+ $sum: {
146
+ $cond: [
147
+ {
148
+ $or: [
149
+ {
150
+ $gt: [
151
+ '$mobileDetectionFlag',
152
+ 0,
153
+ ],
154
+ },
155
+ {
156
+ $gt: [
157
+ '$storeOpenCloseFlag',
158
+ 0,
159
+ ],
160
+ },
161
+ {
162
+ $gt: [
163
+ '$uniformDetectionFlag',
164
+ 0,
165
+ ],
166
+ },
167
+ ],
168
+ },
169
+ 1,
170
+ 0,
171
+ ],
172
+ },
173
+ },
174
+ },
175
+ },
176
+ // {
177
+ // $addFields: {
178
+ // questionFlag: {
179
+ // $round: [
180
+ // { $divide: [ '$questionFlag', 7 ] },
181
+ // 0,
182
+ // ],
183
+ // },
184
+ // timeFlag: {
185
+ // $round: [
186
+ // { $divide: [ '$timeFlag', 7 ] },
187
+ // 0,
188
+ // ],
189
+ // },
190
+ // detectionFlags: {
191
+ // $round: [
192
+ // {
193
+ // $divide: [ '$detectionFlags', 7 ],
194
+ // },
195
+ // 0,
196
+ // ],
197
+ // },
198
+ // },
199
+ // },
200
+ ],
201
+ },
202
+ },
203
+ ];
204
+
205
+ const data = await aggregate( pipeline );
206
+
207
+ if ( !data[0]?.currentPeriod?.length ) {
208
+ return res.sendError( 'No data found', 204 );
209
+ }
210
+
211
+ if ( !data[0]?.last7Days?.length ) {
212
+ const resData = {
213
+ ...data[0].currentPeriod[0],
214
+ };
215
+ return res.sendSuccess( resData );
216
+ }
217
+
218
+ const firstDate = dayjs.utc( req.body.startDate );
219
+ const secondDate = dayjs.utc( req.body.endDate );
220
+
221
+ const daysDifference = secondDate.diff( firstDate, 'day' ) + 1;
222
+
223
+ const currentRangeData = {
224
+ questionFlag: Math.round( data[0].currentPeriod[0].questionFlag / daysDifference ),
225
+ timeFlag: Math.round( data[0].currentPeriod[0].timeFlag / daysDifference ),
226
+ detectionFlags: Math.round( data[0].currentPeriod[0].detectionFlags / daysDifference ),
227
+ };
228
+
229
+ const last7RangeData = {
230
+ questionFlag: Math.round( data[0].currentPeriod[0].questionFlag / 7 ),
231
+ timeFlag: Math.round( data[0].currentPeriod[0].timeFlag / 7 ),
232
+ detectionFlags: Math.round( data[0].currentPeriod[0].detectionFlags / 7 ),
233
+ };
234
+
235
+ function calculatePercentage( currentPeriod, last7Days ) {
236
+ // const current = currentPeriod[0];
237
+ // const last7 = last7Days[0];
238
+
239
+ const calculateDiffPercentage = ( currentValue, last7Value ) => {
240
+ if ( last7Value === 0 ) {
241
+ return currentValue === 0 ? 0 : ( currentValue > 0 ? 100 : -100 );
242
+ }
243
+ return Math.round( ( ( currentValue - last7Value ) / last7Value ) * 100 );
244
+ };
245
+
246
+ const percentageQuestionFlag = calculateDiffPercentage( currentPeriod.questionFlag, last7Days.questionFlag );
247
+ const percentageTimeFlag = calculateDiffPercentage( currentPeriod.timeFlag, last7Days.timeFlag );
248
+ const percentageDetectionFlags = calculateDiffPercentage( currentPeriod.detectionFlags, last7Days.detectionFlags );
249
+
250
+ return {
251
+ percentageQuestionFlag,
252
+ percentageTimeFlag,
253
+ percentageDetectionFlags,
254
+ };
255
+ }
256
+
257
+ const percentageData = calculatePercentage( currentRangeData, last7RangeData );
258
+
259
+ const resData = {
260
+ ...data[0].currentPeriod[0],
261
+ ...percentageData,
262
+ };
263
+
264
+ return res.sendSuccess( resData );
265
+ } catch ( error ) {
266
+ logger.error( { error: error, message: req.body, function: 'overallFlagMetrics' } );
267
+ return res.sendError( { error: error }, 500 );
268
+ }
269
+ };
270
+
271
+ export const checklistFlagsTable = async ( req, res ) => {
272
+ try {
273
+ const matchStage = {
274
+ $match: {
275
+ $and: [
276
+ { client_id: req.body.clientId },
277
+ {
278
+ store_id: {
279
+ $in: req.body.stores,
280
+ },
281
+ },
282
+ {
283
+ date_iso: {
284
+ $gte: new Date( req.body.startDate ),
285
+ },
286
+ },
287
+ {
288
+ date_iso: {
289
+ $lte: new Date( req.body.endDate ),
290
+ },
291
+ },
292
+ {
293
+ $or: [
294
+ { timeFlag: { $gt: 0 } },
295
+ { questionFlag: { $gt: 0 } },
296
+ { mobileDetectionFlag: { $gt: 0 } },
297
+ { storeOpenCloseFlag: { $gt: 0 } },
298
+ { uniformDetectionFlag: { $gt: 0 } },
299
+ ],
300
+ },
301
+ ],
302
+ },
303
+ };
304
+
305
+ const pipeline = [
306
+ matchStage,
307
+ {
308
+ $project: {
309
+ sourceCheckList_id: 1,
310
+ checkListName: 1,
311
+ storeCount: 1,
312
+ store_id: 1,
313
+ checkListType: 1,
314
+ flags: [
315
+ {
316
+ flagType: 'Not Submitted',
317
+ flagValue: '$timeFlag',
318
+ },
319
+ {
320
+ flagType: 'Question',
321
+ flagValue: '$questionFlag',
322
+ },
323
+ {
324
+ flagType: 'Mobile Detection',
325
+ flagValue: '$mobileDetectionFlag',
326
+ },
327
+ {
328
+ flagType: 'Store Open/Close',
329
+ flagValue: '$storeOpenCloseFlag',
330
+ },
331
+ {
332
+ flagType: 'Uniform Detection',
333
+ flagValue: '$uniformDetectionFlag',
334
+ },
335
+ ],
336
+ },
337
+ },
338
+ {
339
+ $unwind: '$flags',
340
+ },
341
+ {
342
+ $match: {
343
+ 'flags.flagValue': { $gt: 0 },
344
+ },
345
+ },
346
+ {
347
+ $group: {
348
+ _id: {
349
+ sourceCheckList_id: '$sourceCheckList_id',
350
+ flagType: '$flags.flagType',
351
+ },
352
+ checkListName: { $last: '$checkListName' },
353
+ checkListType: { $last: '$checkListType' },
354
+ checkListChar: {
355
+ $last: {
356
+ $substr: [ '$checkListName', 0, 2 ],
357
+ },
358
+ },
359
+ storeCount: { $max: '$storeCount' },
360
+ flaggedChecklist: { $sum: 1 },
361
+ flagType: { $last: '$flags.flagType' },
362
+ uniqueStores: { $addToSet: '$store_id' },
363
+ },
364
+ },
365
+ {
366
+ $project: {
367
+ _id: 1,
368
+ checkListName: 1,
369
+ checkListChar: 1,
370
+ checkListType: 1,
371
+ storeCount: 1,
372
+ flaggedChecklist: 1,
373
+ flagType: 1,
374
+ flagedStores: { $size: '$uniqueStores' },
375
+ },
376
+ },
377
+ ];
378
+
379
+ if ( req.body?.sortColumn && req.body?.sortBy ) {
380
+ pipeline.push(
381
+ {
382
+ $addFields: {
383
+ sortField: {
384
+ $toLower: `$${req.body.sortColumn}`,
385
+ },
386
+ },
387
+ },
388
+ {
389
+ $sort: {
390
+ [req.body.sortColumn]: req.body.sortBy,
391
+ },
392
+ },
393
+ );
394
+ }
395
+
396
+ pipeline.push(
397
+ {
398
+ $project: {
399
+ sortField: 0,
400
+ },
401
+ },
402
+
403
+ );
404
+
405
+ const facetStage = {
406
+ $facet: {
407
+ data: [
408
+ {
409
+ $skip: ( ( req.body.offset - 1 ) * req.body.limit ),
410
+ },
411
+ {
412
+ $limit: ( req.body.limit ),
413
+ },
414
+ ],
415
+ pageInfo: [
416
+ {
417
+ $count: 'count',
418
+ },
419
+ ],
420
+ },
421
+ };
422
+
423
+
424
+ pipeline.push( facetStage );
425
+
426
+ pipeline.push( {
427
+ $unwind: {
428
+ path: '$pageInfo',
429
+ },
430
+ } );
431
+
432
+ if ( req.body.isExport ) {
433
+ facetStage.$facet.data = [];
434
+ }
435
+
436
+
437
+ const data = await aggregate( pipeline );
438
+
439
+ if ( !data[0] ) {
440
+ return res.sendError( 'No data found', 204 );
441
+ }
442
+
443
+ if ( req.body.isExport ) {
444
+ const exportResult = [];
445
+ for ( let checklist of data[0].data ) {
446
+ exportResult.push( {
447
+ 'Checklist Name': checklist.checkListName ||'',
448
+ 'Flag Type': checklist.flagType||'',
449
+ 'Assigned Stores': checklist.storeCount||'',
450
+ 'Fragged Stores': checklist.flagedStores || '',
451
+ 'Flagged Count': checklist.flaggedChecklist||'',
452
+ } );
453
+ }
454
+ await download( exportResult, res );
455
+ return;
456
+ }
457
+
458
+ return res.sendSuccess( data[0] );
459
+ } catch ( error ) {
460
+ logger.error( { error: error, function: 'subscribedStoreList' } );
461
+ return res.sendError( error, 500 );
462
+ }
463
+ };
464
+
465
+ export const flagChecklistCards = async ( req, res ) => {
466
+ try {
467
+ let requestData = req.body;
468
+ let resultData = await checklistCardData( requestData.checklistType );
469
+ return res.sendSuccess( resultData );
470
+ } catch ( error ) {
471
+ console.log( 'error =>', error );
472
+ logger.error( { error: error, function: 'subscribedStoreList' } );
473
+ return res.sendError( error, 500 );
474
+ }
475
+ };
476
+
477
+ export const flagChecklistComparisonCards = async ( req, res ) => {
478
+ try {
479
+ let requestData = req.body;
480
+ let resultData = await checklistComparisonData( requestData.checklistType );
481
+ return res.sendSuccess( resultData );
482
+ } catch ( error ) {
483
+ console.log( 'error =>', error );
484
+ logger.error( { error: error, function: 'subscribedStoreList' } );
485
+ return res.sendError( error, 500 );
486
+ }
487
+ };
488
+
489
+ export const flagChecklistTable = async ( req, res ) => {
490
+ try {
491
+ let requestData = req.body;
492
+ let resultData = await tableData( requestData.checklistType );
493
+ return res.sendSuccess( resultData );
494
+ } catch ( error ) {
495
+ console.log( 'error =>', error );
496
+ logger.error( { error: error, function: 'subscribedStoreList' } );
497
+ return res.sendError( error, 500 );
498
+ }
499
+ };
500
+
501
+ export const flagCards = async ( req, res ) => {
502
+ try {
503
+ let requestData = req.body;
504
+ let resultData = await flagCardData( requestData.checklistType );
505
+ return res.sendSuccess( resultData );
506
+ } catch ( error ) {
507
+ console.log( 'error =>', error );
508
+ logger.error( { error: error, function: 'subscribedStoreList' } );
509
+ return res.sendError( error, 500 );
510
+ }
511
+ };
512
+
513
+ export const flagComparisonCards = async ( req, res ) => {
514
+ try {
515
+ let requestData = req.body;
516
+ let resultData = await falgComparisonData( requestData.checklistType );
517
+ return res.sendSuccess( resultData );
518
+ } catch ( error ) {
519
+ console.log( 'error =>', error );
520
+ logger.error( { error: error, function: 'subscribedStoreList' } );
521
+ return res.sendError( error, 500 );
522
+ }
523
+ };
524
+
525
+ export const flagTables = async ( req, res ) => {
526
+ try {
527
+ let requestData = req.body;
528
+ let resultData = await flagTableData( requestData.checklistType );
529
+ return res.sendSuccess( resultData );
530
+ } catch ( error ) {
531
+ console.log( 'error =>', error );
532
+ logger.error( { error: error, function: 'subscribedStoreList' } );
533
+ return res.sendError( error, 500 );
534
+ }
535
+ };
536
+
537
+ export const checklistDropdown = async ( req, res ) => {
538
+ try {
539
+ let requestData = req.body;
540
+ let resultData = await checklistDropdownData( requestData.checklistType );
541
+ return res.sendSuccess( resultData );
542
+ } catch ( error ) {
543
+ console.log( 'error =>', error );
544
+ logger.error( { error: error, function: 'subscribedStoreList' } );
545
+ return res.sendError( error, 500 );
546
+ }
547
+ };
548
+
549
+ export const flagCardsV1 = async ( req, res ) => {
550
+ try {
551
+ const { clientId, storeId, fromDate, toDate } = req.body;
552
+ const adjustedToDate = new Date( new Date( toDate ).setUTCHours( 23, 59, 59, 999 ) );
553
+ const adjustedFromDate = new Date( fromDate );
554
+
555
+ const flagCards = {
556
+ totalFlag: 0,
557
+ questionFlag: { count: 0 },
558
+ delayInSubmission: { count: 0 },
559
+ detectionFlag: { count: 0 },
560
+ };
561
+
562
+ const findQuery = [
563
+ {
564
+ $match: {
565
+ client_id: clientId,
566
+ store_id: { $in: storeId },
567
+ date_iso: { $gte: adjustedFromDate, $lte: adjustedToDate },
568
+ },
569
+ },
570
+ {
571
+ $project: {
572
+ questionFlag: 1,
573
+ timeFlag: 1,
574
+ },
575
+ },
576
+ {
577
+ $group: {
578
+ _id: null,
579
+ totalFlag: { $sum: { $add: [ '$questionFlag', '$timeFlag' ] } },
580
+ questionFlag: { $sum: '$questionFlag' },
581
+ delayInSubmission: { $sum: '$timeFlag' },
582
+ },
583
+ },
584
+ ];
585
+
586
+ const getOverallChecklistData = await processedchecklistService.aggregate( findQuery );
587
+
588
+ if ( !getOverallChecklistData.length ) {
589
+ const resVal = {
590
+ 'flagCards': {
591
+ 'totalFlag': 0,
592
+ 'questionFlag': {
593
+ 'count': 0,
594
+ },
595
+ 'delayInSubmission': {
596
+ 'count': 0,
597
+ },
598
+ 'detectionFlag': {
599
+ 'count': 0,
600
+ },
601
+ },
602
+ };
603
+ return res.sendSuccess( resVal );
604
+ }
605
+
606
+ const [ data ] = getOverallChecklistData;
607
+ if ( data.totalFlag ) flagCards.totalFlag = data.totalFlag;
608
+ if ( data.questionFlag ) flagCards.questionFlag.count = data.questionFlag;
609
+ if ( data.delayInSubmission ) flagCards.delayInSubmission.count = data.delayInSubmission;
610
+
611
+ const detectionPayload = { fromDate, toDate, storeId, clientId };
612
+ const lambdaURL = 'https://f65azvtljclaxp6l7rnx65cdmm0lcgvp.lambda-url.ap-south-1.on.aws/';
613
+ const resultData = await LamdaServiceCall( lambdaURL, detectionPayload );
614
+
615
+ if ( resultData && resultData.status_code === '200' ) {
616
+ flagCards.detectionFlag.count = resultData.totalDetection;
617
+ flagCards.totalFlag += flagCards.detectionFlag.count;
618
+ }
619
+
620
+ return res.sendSuccess( { flagCards } );
621
+ } catch ( error ) {
622
+ console.error( 'Error in flagCardsV1:', error );
623
+ logger.error( { error, function: 'flagCardsV1' } );
624
+ return res.sendError( error, 500 );
625
+ }
626
+ };
627
+
628
+
629
+ export const flagComparisonCardsV1 = async ( req, res ) => {
630
+ try {
631
+ let requestData = req.body;
632
+ let toDate = new Date( requestData.toDate );
633
+ let userTimezoneOffset = toDate.getTimezoneOffset() * 60000;
634
+ toDate = new Date( toDate.getTime() - userTimezoneOffset );
635
+ toDate.setUTCHours( 23, 59, 59, 59 );
636
+
637
+ let rangeOneFromDate;
638
+ let rangeOneToDate;
639
+ let rangeTwoFromDate;
640
+ let rangeTwoToDate;
641
+ if ( requestData.dateType == 'weekly' ) {
642
+ rangeOneFromDate = new Date( requestData.toDate );
643
+ rangeOneFromDate.setDate( rangeOneFromDate.getDate() - 6 );
644
+ rangeOneToDate = new Date( requestData.toDate );
645
+ rangeOneToDate = new Date( rangeOneToDate.getTime() - userTimezoneOffset );
646
+ rangeOneToDate.setUTCHours( 23, 59, 59, 59 );
647
+ rangeTwoToDate = new Date( requestData.toDate );
648
+ rangeTwoToDate.setDate( rangeTwoToDate.getDate() - 7 );
649
+ rangeTwoFromDate = new Date( rangeTwoToDate );
650
+ rangeTwoFromDate.setDate( rangeTwoFromDate.getDate() - 6 );
651
+ rangeTwoToDate = new Date( rangeTwoToDate.getTime() - userTimezoneOffset );
652
+ rangeTwoToDate.setUTCHours( 23, 59, 59, 59 );
653
+ } else if ( requestData.dateType == 'monthly' ) {
654
+ rangeOneFromDate = new Date( requestData.toDate );
655
+ rangeOneFromDate.setDate( rangeOneFromDate.getDate() - 30 );
656
+ rangeOneToDate = new Date( requestData.toDate );
657
+ rangeOneToDate = new Date( rangeOneToDate.getTime() - userTimezoneOffset );
658
+ rangeOneToDate.setUTCHours( 23, 59, 59, 59 );
659
+ rangeTwoToDate = new Date( requestData.toDate );
660
+ rangeTwoToDate.setDate( rangeTwoToDate.getDate() - 31 );
661
+ rangeTwoFromDate = new Date( rangeTwoToDate );
662
+ rangeTwoFromDate.setDate( rangeTwoFromDate.getDate() - 30 );
663
+ rangeTwoToDate = new Date( rangeTwoToDate.getTime() - userTimezoneOffset );
664
+ rangeTwoToDate.setUTCHours( 23, 59, 59, 59 );
665
+ } else {
666
+ rangeOneFromDate = new Date( requestData.toDate );
667
+ rangeOneFromDate.setDate( rangeOneFromDate.getDate() - 0 );
668
+ rangeOneToDate = new Date( requestData.toDate );
669
+ rangeOneToDate = new Date( rangeOneToDate.getTime() - userTimezoneOffset );
670
+ rangeOneToDate.setUTCHours( 23, 59, 59, 59 );
671
+ rangeTwoToDate = new Date( requestData.toDate );
672
+ rangeTwoToDate.setDate( rangeTwoToDate.getDate() - 1 );
673
+ rangeTwoFromDate = new Date( rangeTwoToDate );
674
+ rangeTwoFromDate.setDate( rangeTwoFromDate.getDate() - 0 );
675
+ rangeTwoToDate = new Date( rangeTwoToDate.getTime() - userTimezoneOffset );
676
+ rangeTwoToDate.setUTCHours( 23, 59, 59, 59 );
677
+ }
678
+
679
+ const createFindQuery = ( fromDate, toDate ) => [
680
+ { $match: { client_id: requestData.clientId, store_id: { $in: requestData.storeId }, date_iso: { $gte: fromDate, $lte: toDate } } },
681
+ {
682
+ $project: {
683
+ timeFlag: 1,
684
+ questionFlag: 1,
685
+ },
686
+ },
687
+ {
688
+ $group: {
689
+ _id: '',
690
+ questionFlag: { $sum: '$questionFlag' },
691
+ delayInSubmission: { $sum: '$timeFlag' },
692
+ },
693
+ },
694
+ ];
695
+
696
+ const calculateComparison = ( rangeOneVal, rangeTwoVal ) => {
697
+ if ( rangeOneVal === 0 ) {
698
+ return { comparisonData: 0, ComparisonFlag: false };
699
+ }
700
+
701
+ let comparisonData = Math.abs( ( ( rangeOneVal - rangeTwoVal ) / rangeTwoVal ) * 100 );
702
+ if ( comparisonData === Infinity ) comparisonData = 0;
703
+ comparisonData = comparisonData % 1 === 0 ? comparisonData.toFixed( 0 ) : comparisonData.toFixed( 1 );
704
+
705
+ comparisonData = parseInt( comparisonData );
706
+
707
+
708
+ const ComparisonFlag = rangeOneVal > rangeTwoVal;
709
+
710
+ return { comparisonData, ComparisonFlag };
711
+ };
712
+
713
+ const getDetectionCount = async ( fromDate, toDate ) => {
714
+ const detectionPayload = {
715
+ fromDate: dayjs( fromDate ).format( 'YYYY-MM-DD' ),
716
+ toDate: dayjs( toDate ).startOf( 'day' ).format( 'YYYY-MM-DD' ),
717
+ storeId: requestData.storeId,
718
+ clientId: requestData.clientId,
719
+ };
720
+
721
+ console.log( dayjs( fromDate ).format( 'YYYY-MM-DD' ), 'from date' );
722
+
723
+ console.log( dayjs( toDate ).subtract( 1, 'day' ).format( 'YYYY-MM-DD' ), 'current' );
724
+
725
+ console.log( dayjs( toDate ).format( 'YYYY-MM-DD' ), 'previous' );
726
+
727
+ console.log( dayjs( toDate ).startOf( 'day' ).subtract( 1, 'day' ).format( 'YYYY-MM-DD' ), 'new start of' );
728
+
729
+ const LamdaURL = 'https://f65azvtljclaxp6l7rnx65cdmm0lcgvp.lambda-url.ap-south-1.on.aws/';
730
+ const resultData = await LamdaServiceCall( LamdaURL, detectionPayload );
731
+
732
+ if ( resultData?.status_code === '200' ) {
733
+ return resultData.totalDetection;
734
+ }
735
+ return 0;
736
+ };
737
+
738
+ const [ rangeOneData, rangeTwoData, rangeOneDetectionCount, rangeTwoDetectionCount ] = await Promise.all( [
739
+ processedchecklistService.aggregate( createFindQuery( rangeOneFromDate, rangeOneToDate ) ),
740
+ processedchecklistService.aggregate( createFindQuery( rangeTwoFromDate, rangeTwoToDate ) ),
741
+ getDetectionCount( rangeOneFromDate, rangeOneToDate ),
742
+ getDetectionCount( rangeTwoFromDate, rangeTwoToDate ),
743
+ ] );
744
+
745
+ const flagComparisonCards = {
746
+ questionComparisonFlag: { comparisonData: 0, ComparisonFlag: false },
747
+ delayInSubmissionComparisonFlag: { comparisonData: 0, ComparisonFlag: false },
748
+ detectionComparisonFlag: { comparisonData: 0, ComparisonFlag: false },
749
+ };
750
+
751
+ if ( rangeOneData.length && rangeTwoData.length ) {
752
+ flagComparisonCards.questionComparisonFlag = calculateComparison( rangeOneData[0].questionFlag, rangeTwoData[0].questionFlag );
753
+ flagComparisonCards.delayInSubmissionComparisonFlag = calculateComparison( rangeOneData[0].delayInSubmission, rangeTwoData[0].delayInSubmission );
754
+ flagComparisonCards.detectionComparisonFlag = calculateComparison( rangeOneDetectionCount, rangeTwoDetectionCount );
755
+ }
756
+
757
+ return res.sendSuccess( { flagComparisonCards } );
758
+ } catch ( error ) {
759
+ console.log( 'error =>', error );
760
+ logger.error( { error, function: 'flagComparisonCardsV1' } );
761
+ return res.sendError( error, 500 );
762
+ }
763
+ };
764
+
765
+
766
+ export const flagTablesV1 = async ( req, res ) => {
767
+ try {
768
+ let requestData = req.body;
769
+ let fromDate = new Date( requestData.fromDate );
770
+ let toDate = new Date( requestData.toDate );
771
+ let userTimezoneOffset = toDate.getTimezoneOffset() * 60000;
772
+ toDate = new Date( toDate.getTime() - userTimezoneOffset );
773
+ toDate.setUTCHours( 23, 59, 59, 59 );
774
+ let result = {};
775
+
776
+ let findQuery = [];
777
+ let findAndQuery = [];
778
+ findAndQuery.push(
779
+ { client_id: requestData.clientId },
780
+ { $or: [ { store_id: { $in: requestData.storeId } }, { aiStoreList: { $in: requestData.storeId } } ] },
781
+ { date_iso: { $gte: fromDate } },
782
+ { date_iso: { $lte: toDate } },
783
+ );
784
+
785
+ if ( requestData?.filter === 'all' ) {
786
+ findAndQuery.push( { $or: [ { questionFlag: { $gte: 1 } }, { timeFlag: { $gte: 1 } }, { checkListType: { $ne: 'custom' } } ] } );
787
+ } else if ( requestData?.filter === 'question' ) {
788
+ findAndQuery.push( { checkListType: 'custom' } );
789
+ findAndQuery.push( { questionFlag: { $gte: 1 } } );
790
+ } else if ( requestData?.filter === 'time' ) {
791
+ findAndQuery.push( { checkListType: 'custom' } );
792
+ findAndQuery.push( { timeFlag: { $gte: 1 } } );
793
+ } else if ( requestData?.filter === 'detection' ) {
794
+ findAndQuery.push( { checkListType: { $ne: 'custom' } } );
795
+ }
796
+
797
+ findQuery.push( { $match: { $and: findAndQuery } } );
798
+
799
+ if ( requestData.searchValue && requestData.searchValue != '' ) {
800
+ findQuery.push( { $match: { $or: [ { checkListName: { $regex: requestData.searchValue, $options: 'i' } } ] } } );
801
+ }
802
+
803
+ findQuery.push( {
804
+ $project: {
805
+ sourceCheckList_id: 1,
806
+ checkListId: 1,
807
+ checkListName: 1,
808
+ storeCount: 1,
809
+ createdBy: 1,
810
+ createdByName: 1,
811
+ checklistStatus: 1,
812
+ timeFlag: 1,
813
+ questionFlag: 1,
814
+ questionCount: 1,
815
+ mobileDetectionFlag: 1,
816
+ storeOpenCloseFlag: 1,
817
+ uniformDetectionFlag: 1,
818
+ checkListType: 1,
819
+ scheduleRepeatedType: 1,
820
+ store_id: 1,
821
+ aiStoreList: 1,
822
+ },
823
+ } );
824
+
825
+ findQuery.push( {
826
+ $group: {
827
+ _id: '$sourceCheckList_id',
828
+ checkListName: { $last: '$checkListName' },
829
+ checkListChar: { $last: { $substr: [ '$checkListName', 0, 2 ] } },
830
+ sourceCheckList_id: { $last: '$sourceCheckList_id' },
831
+ checkListType: { $last: '$checkListType' },
832
+ storeCount: { $sum: 1 },
833
+ storeCountAi: { $max: '$storeCount' },
834
+ flaggedStores: {
835
+ $addToSet: {
836
+ $cond: [
837
+ {
838
+ $or: [
839
+ { $gt: [ '$timeFlag', 0 ] },
840
+ { $gt: [ '$questionFlag', 0 ] },
841
+ { $gt: [ '$mobileDetectionFlag', 0 ] },
842
+ { $gt: [ '$storeOpenCloseFlag', 0 ] },
843
+ { $gt: [ '$uniformDetectionFlag', 0 ] },
844
+ { $gt: [ '$customerUnattended', 0 ] },
845
+ { $gt: [ '$staffLeftInTheMiddle', 0 ] },
846
+ ],
847
+ },
848
+ '$store_id',
849
+ '$$REMOVE',
850
+ ],
851
+ },
852
+ },
853
+ flagCount: {
854
+ $sum: {
855
+ $add: [ '$questionFlag', '$timeFlag' ],
856
+ },
857
+ // $sum: {
858
+ // $cond: [ {
859
+ // $or: [
860
+ // { $gt: [ '$timeFlag', 0 ] },
861
+ // { $gt: [ '$questionFlag', 0 ] },
862
+ // { $gt: [ '$mobileDetectionFlag', 0 ] },
863
+ // { $gt: [ '$storeOpenCloseFlag', 0 ] },
864
+ // { $gt: [ '$uniformDetectionFlag', 0 ] },
865
+ // ],
866
+ // }, 1, 0 ],
867
+ // },
868
+ },
869
+ submittedChecklist: {
870
+ $sum: {
871
+ $cond: [ { $eq: [ '$checklistStatus', 'submit' ] }, 1, 0 ],
872
+ },
873
+ },
874
+ questionFlag: {
875
+ $sum: '$questionFlag',
876
+ // $sum: {
877
+ // $cond: [ { $gt: [ '$questionFlag', 0 ] }, 1, 0 ],
878
+ // },
879
+ },
880
+ timeFlag: {
881
+ $sum: '$timeFlag',
882
+ },
883
+ questionCount: {
884
+ $sum: '$questionCount',
885
+ // $sum: {
886
+ // $cond: [ { $gt: [ '$questionCount', 0 ] }, 1, 0 ],
887
+ // },
888
+ },
889
+ aiStoreList: { $max: '$aiStoreList' },
890
+ submittedQuestionCount: {
891
+ $sum: {
892
+ $cond: [
893
+ { $eq: [ '$checklistStatus', 'submit' ] },
894
+ '$questionCount', // Sum this field if status is 'submit'
895
+ 0, // Otherwise, add 0
896
+ ],
897
+ },
898
+ },
899
+ },
900
+ } );
901
+
902
+ findQuery.push( {
903
+ $project: {
904
+ assignedStores: '$storeCount',
905
+ assignedStoresAi: '$storeCountAi',
906
+ checkListName: 1,
907
+ checkListChar: 1,
908
+ sourceCheckList_id: 1,
909
+ checkListType: 1,
910
+ flagType: 1,
911
+ uniqueFlaggedStores: 1,
912
+ flaggedStores: { $size: '$flaggedStores' },
913
+ flagCount: 1,
914
+ questionCount: 1,
915
+ correctAnswers: { $subtract: [ '$submittedQuestionCount', '$questionFlag' ] },
916
+ // customType: {
917
+ // $cond: { if: { $gte: [ '$questionFlag', 1 ] }, then: 'question', else: {
918
+ // $cond: { if: { $gte: [ '$timeFlag', 1 ] }, then: 'time', else: '' },
919
+ // },
920
+ // },
921
+ // },
922
+ customQuestionFlagCount: '$questionFlag',
923
+ customTimeFlagCount: '$timeFlag',
924
+ // correctAnswers: '$questionFlag',
925
+ aiStoreList: 1,
926
+ },
927
+ } );
928
+
929
+ findQuery.push( {
930
+ $project: {
931
+ checkListName: 1,
932
+ checkListChar: 1,
933
+ sourceCheckList_id: 1,
934
+ checkListType: 1,
935
+ flagType: 1,
936
+ assignedStores: 1,
937
+ assignedStoresAi: 1,
938
+ flaggedStores: 1,
939
+ flagCount: 1,
940
+ uniqueFlaggedStores: 1,
941
+ complianceRate: {
942
+ $cond: {
943
+ if: { $eq: [ '$questionCount', 0 ] },
944
+ then: 0,
945
+ else: {
946
+ $round: [ { $multiply: [ { $divide: [ '$correctAnswers', '$questionCount' ] }, 100 ] }, 2 ],
947
+ },
948
+ },
949
+ },
950
+ // customType: 1,
951
+ customQuestionFlagCount: 1,
952
+ customTimeFlagCount: 1,
953
+ aiStoreList: 1,
954
+
955
+ },
956
+ } );
957
+
958
+ let getTotalCount = await processedchecklistService.aggregate( findQuery );
959
+ if ( !getTotalCount.length ) {
960
+ return res.sendError( { error: 'No Data Found' }, 204 );
961
+ }
962
+
963
+ if ( requestData.sortColumnName && requestData.sortColumnName != '' && requestData.sortBy && requestData.sortBy !='' ) {
964
+ findQuery.push( { $sort: { [requestData.sortColumnName]: requestData.sortBy } } );
965
+ } else {
966
+ findQuery.push( { $sort: { ['submittedChecklist']: -1 } } );
967
+ }
968
+
969
+ if ( !requestData.export ) {
970
+ let limit = parseInt( requestData?.limit ) || 10;
971
+ let skip = limit * ( requestData?.offset ) || 0;
972
+ findQuery.push( { $skip: skip }, { $limit: limit } );
973
+ }
974
+
975
+
976
+ let getChecklistPerformanceData = await processedchecklistService.aggregate( findQuery );
977
+
978
+ if ( getChecklistPerformanceData.length ) {
979
+ const detectionChecklists = getChecklistPerformanceData?.filter( ( val ) => val?.checkListType !== 'custom' );
980
+
981
+ if ( detectionChecklists?.length ) {
982
+ const detectionPayload = {
983
+ 'fromDate': requestData.fromDate,
984
+ 'toDate': requestData.toDate,
985
+ 'storeId': requestData.storeId,
986
+ 'clientId': requestData.clientId,
987
+ };
988
+
989
+ let LamdaURL = 'https://f65azvtljclaxp6l7rnx65cdmm0lcgvp.lambda-url.ap-south-1.on.aws/';
990
+ let resultData = await LamdaServiceCall( LamdaURL, detectionPayload );
991
+ if ( resultData ) {
992
+ if ( resultData.status_code == '200' ) {
993
+ for ( let index = 0; index < getChecklistPerformanceData.length; index++ ) {
994
+ if ( getChecklistPerformanceData[index].checkListType !== 'custom' ) {
995
+ getChecklistPerformanceData[index].flagCount = resultData?.[getChecklistPerformanceData[index]?.checkListType] || 0;
996
+ getChecklistPerformanceData[index].flaggedStores = resultData?.[`${getChecklistPerformanceData[index]?.checkListType}_flaggedstores`] || 0;
997
+ getChecklistPerformanceData[index].assignedStores = getChecklistPerformanceData[index]?.aiStoreList?.filter( ( element ) => requestData.storeId.includes( element ) )?.length || 0;
998
+ getChecklistPerformanceData[index].complianceRate = ( 100- ( getChecklistPerformanceData[index].flaggedStores / getChecklistPerformanceData[index].assignedStores ) * 100 );
999
+ getChecklistPerformanceData[index].complianceRate = Math.min( 100, Math.max( 0, getChecklistPerformanceData[index].complianceRate ) );
1000
+ getChecklistPerformanceData[index].complianceRate = ( getChecklistPerformanceData[index].complianceRate % 1 === 0 ) ? getChecklistPerformanceData[index].complianceRate.toFixed( 0 ) : getChecklistPerformanceData[index].complianceRate.toFixed( 2 );
1001
+ }
1002
+ }
1003
+ }
1004
+ }
1005
+ }
1006
+ }
1007
+
1008
+ if ( requestData.export ) {
1009
+ const exportdata = [];
1010
+ getChecklistPerformanceData.forEach( ( element ) => {
1011
+ const data = {
1012
+ 'Checklist Name': element.checkListName,
1013
+ 'Flag Type': element?.checkListType === 'custom' ? 'Question' : 'Detection',
1014
+ 'Assigned Stores': element?.assignedStores,
1015
+ 'Flagged Stores': element?.flaggedStores,
1016
+ 'Compliance': element?.complianceRate,
1017
+ 'Flagged Count': element?.flagCount,
1018
+ 'Question Flags': element?.customQuestionFlagCount,
1019
+ 'Not Submitted Flags': element?.customTimeFlagCount,
1020
+ };
1021
+ if ( requestData?.filter === 'question' ) {
1022
+ delete data['Flagged Count'];
1023
+ delete data['Not Submitted Flags'];
1024
+ } else if ( requestData?.filter === 'time' ) {
1025
+ delete data['Flagged Count'];
1026
+ delete data['Question Flags'];
1027
+ } else if ( requestData?.filter === 'detection' ) {
1028
+ delete data['Not Submitted Flags'];
1029
+ delete data['Question Flags'];
1030
+ }
1031
+ exportdata.push( data );
1032
+ } );
1033
+ return await download( exportdata, res );
1034
+ }
1035
+
1036
+
1037
+ result.totalCount = getTotalCount.length;
1038
+ result.checklistPerformance = getChecklistPerformanceData;
1039
+ return res.sendSuccess( result );
1040
+ } catch ( error ) {
1041
+ console.log( 'error =>', error );
1042
+ logger.error( { error: error, message: req.query, function: 'checklistPerformance' } );
1043
+ return res.sendError( { error: error }, 500 );
1044
+ }
1045
+ };
1046
+
1047
+ async function checklistCardData( checklistType ) {
1048
+ try {
1049
+ let resData = {};
1050
+ switch ( checklistType ) {
1051
+ case 'storeopenandclose':
1052
+ resData.storeopenandcloseCards = {};
1053
+ resData.storeopenandcloseCards = {
1054
+ 'totalAssignedStores': { 'count': 300 },
1055
+ 'lateOpenStores': { 'count': 200 },
1056
+ 'earlyClosedStores': { 'count': 100 },
1057
+ 'complianceRate': { 'rate': 100 },
1058
+ };
1059
+ break;
1060
+ case 'mobileusagedetection':
1061
+ resData.mobileusagedetectionCards = {};
1062
+ resData.mobileusagedetectionCards = {
1063
+ 'totalAssignedStores': { 'count': 300 },
1064
+ 'flagIncidents': { 'count': 200 },
1065
+ 'complianceRate': { 'rate': 100 },
1066
+ };
1067
+ break;
1068
+ case 'uniformdetection':
1069
+ resData.uniformdetectionCards = {};
1070
+ resData.uniformdetectionCards = {
1071
+ 'totalAssignedStores': { 'count': 300 },
1072
+ 'flagIncidents': { 'count': 200 },
1073
+ 'complianceRate': { 'rate': 100 },
1074
+ };
1075
+ break;
1076
+ case 'customerunattended':
1077
+ resData.customerunattendedCards = {};
1078
+ resData.customerunattendedCards = {
1079
+ 'averageFootfall': {
1080
+ 'count': 300,
1081
+ },
1082
+ 'stafftoCustomerRatio': {
1083
+ 'ratio': '6:5',
1084
+ },
1085
+ 'attendedCustomers': {
1086
+ 'count': 100,
1087
+ },
1088
+ 'unattendedCustomers': {
1089
+ 'count': 100,
1090
+ },
1091
+ 'timeTakentoAssist': {
1092
+ 'mins': 100,
1093
+ },
1094
+ 'timeSpentwithCustomer': {
1095
+ 'mins': 100,
1096
+ },
1097
+ 'unattendedSummaryChart': {
1098
+ 'chart1': [
1099
+ {
1100
+ 'category': 'Un-Attended Peak Hours',
1101
+ 'value': 60,
1102
+ },
1103
+ {
1104
+ 'category': 'Un-Attended Non Peak Hours',
1105
+ 'value': 30,
1106
+ },
1107
+ {
1108
+ 'category': 'Un-Attended Customer Rate',
1109
+ 'value': 10,
1110
+ },
1111
+ ],
1112
+ 'chart2': [
1113
+ {
1114
+ 'category': 'Customer Attended Within Threshold',
1115
+ 'value': 60,
1116
+ },
1117
+ {
1118
+ 'category': 'Customer Attended After Threshold',
1119
+ 'value': 40,
1120
+ },
1121
+ ],
1122
+ },
1123
+ };
1124
+ break;
1125
+ case 'staffleftinthemiddle':
1126
+ resData.staffleftinthemiddleCards = {};
1127
+ resData.staffleftinthemiddleCards = {
1128
+ 'avgStaffPresent': {
1129
+ 'count': 300,
1130
+ },
1131
+ 'avgStaffleft': {
1132
+ 'count': 200,
1133
+ },
1134
+ 'avgStaffPresentInPeakHours': {
1135
+ 'rate': '6:5',
1136
+ },
1137
+ 'staffAvgPunctualityRate': {
1138
+ 'rate': 50,
1139
+ },
1140
+ 'staffAvgBreakHours': {
1141
+ 'mins': 100,
1142
+ },
1143
+ 'staffAvgProductiveHours': {
1144
+ 'mins': 100,
1145
+ },
1146
+ };
1147
+ break;
1148
+ case 'custom':
1149
+ resData.customCards = {};
1150
+ resData.customCards = {
1151
+ 'totalAssignedStores': {
1152
+ 'count': 300,
1153
+ },
1154
+ 'flagIncidents': {
1155
+ 'count': 200,
1156
+ },
1157
+ 'complianceRate': {
1158
+ 'count': 100,
1159
+ },
1160
+ };
1161
+ break;
1162
+ default:
1163
+ break;
1164
+ }
1165
+ return resData;
1166
+ } catch ( error ) {
1167
+ console.log( 'error =>', error );
1168
+ logger.error( { error: error, message: data, function: 'returnServerError' } );
1169
+ }
1170
+ }
1171
+
1172
+ async function checklistComparisonData( checklistType ) {
1173
+ try {
1174
+ let resData = {};
1175
+ switch ( checklistType ) {
1176
+ case 'storeopenandclose':
1177
+ resData.storeopenandcloseCards = {};
1178
+ resData.storeopenandcloseCards = {
1179
+ 'totalAssignedStores': {
1180
+ 'comparisonData': 40,
1181
+ 'ComparisonFlag': true,
1182
+ },
1183
+ 'lateOpenStores': {
1184
+ 'comparisonData': 50,
1185
+ 'ComparisonFlag': true,
1186
+ },
1187
+ 'earlyClosedStores': {
1188
+ 'comparisonData': 20,
1189
+ 'ComparisonFlag': false,
1190
+ },
1191
+ 'complianceRate': {
1192
+ 'comparisonData': 10,
1193
+ 'ComparisonFlag': false,
1194
+ },
1195
+ };
1196
+ break;
1197
+ case 'mobileusagedetection':
1198
+ resData.mobileusagedetectionCards = {};
1199
+ resData.mobileusagedetectionCards = {
1200
+ 'totalAssignedStores': {
1201
+ 'comparisonData': 40,
1202
+ 'ComparisonFlag': true,
1203
+ },
1204
+ 'flagIncidents': {
1205
+ 'comparisonData': 50,
1206
+ 'ComparisonFlag': false,
1207
+ },
1208
+ 'complianceRate': {
1209
+ 'comparisonData': 40,
1210
+ 'ComparisonFlag': true,
1211
+ },
1212
+ };
1213
+ break;
1214
+ case 'uniformdetection':
1215
+ resData.uniformdetectionCards = {};
1216
+ resData.uniformdetectionCards = {
1217
+ 'totalAssignedStores': {
1218
+ 'comparisonData': 40,
1219
+ 'ComparisonFlag': true,
1220
+ },
1221
+ 'flagIncidents': {
1222
+ 'comparisonData': 50,
1223
+ 'ComparisonFlag': false,
1224
+ },
1225
+ 'complianceRate': {
1226
+ 'comparisonData': 40,
1227
+ 'ComparisonFlag': true,
1228
+ },
1229
+ };
1230
+ break;
1231
+ case 'customerunattended':
1232
+ resData.customerunattendedCards = {};
1233
+ resData.customerunattendedCards = {
1234
+ 'averageFootfall': {
1235
+ 'comparisonData': 40,
1236
+ 'ComparisonFlag': true,
1237
+ },
1238
+ 'stafftoCustomerRatio': {
1239
+ 'comparisonData': 50,
1240
+ 'ComparisonFlag': true,
1241
+ },
1242
+ 'attendedCustomers': {
1243
+ 'comparisonData': 40,
1244
+ 'ComparisonFlag': false,
1245
+ },
1246
+ 'unattendedCustomers': {
1247
+ 'comparisonData': 10,
1248
+ 'ComparisonFlag': true,
1249
+ },
1250
+ 'timeTakentoAssist': {
1251
+ 'comparisonData': 30,
1252
+ 'ComparisonFlag': false,
1253
+ },
1254
+ 'timeSpentwithCustomer': {
1255
+ 'comparisonData': 40,
1256
+ 'ComparisonFlag': true,
1257
+ },
1258
+ };
1259
+ break;
1260
+ case 'staffleftinthemiddle':
1261
+ resData.staffleftinthemiddleCards = {};
1262
+ resData.staffleftinthemiddleCards = {
1263
+ 'avgStaffPresent': {
1264
+ 'comparisonData': 40,
1265
+ 'ComparisonFlag': false,
1266
+ },
1267
+ 'avgStaffleft': {
1268
+ 'comparisonData': 50,
1269
+ 'ComparisonFlag': true,
1270
+ },
1271
+ 'avgStaffPresentInPeakHours': {
1272
+ 'comparisonData': 30,
1273
+ 'ComparisonFlag': true,
1274
+ },
1275
+ 'staffAvgPunctualityRate': {
1276
+ 'comparisonData': 50,
1277
+ 'ComparisonFlag': true,
1278
+ },
1279
+ 'staffAvgBreakHours': {
1280
+ 'comparisonData': 40,
1281
+ 'ComparisonFlag': false,
1282
+ },
1283
+ 'staffAvgProductiveHours': {
1284
+ 'comparisonData': 60,
1285
+ 'ComparisonFlag': true,
1286
+ },
1287
+ };
1288
+ break;
1289
+ case 'custom':
1290
+ resData.customCards = {};
1291
+ resData.customCards = {
1292
+ 'totalAssignedStores': {
1293
+ 'comparisonData': 40,
1294
+ 'ComparisonFlag': true,
1295
+ },
1296
+ 'flagIncidents': {
1297
+ 'comparisonData': 20,
1298
+ 'ComparisonFlag': false,
1299
+ },
1300
+ 'complianceRate': {
1301
+ 'comparisonData': 10,
1302
+ 'ComparisonFlag': false,
1303
+ },
1304
+ };
1305
+ break;
1306
+ default:
1307
+ break;
1308
+ }
1309
+ return resData;
1310
+ } catch ( error ) {
1311
+ console.log( 'error =>', error );
1312
+ logger.error( { error: error, message: data, function: 'returnServerError' } );
1313
+ }
1314
+ }
1315
+
1316
+ async function tableData( checklistType ) {
1317
+ try {
1318
+ let resData = {};
1319
+ resData.totalCount = 300;
1320
+ switch ( checklistType ) {
1321
+ case 'storeopenandclose':
1322
+ resData.storeopenandcloseData = {};
1323
+ resData.storeopenandcloseData = [
1324
+ {
1325
+ 'date': '02 Aug, 2024',
1326
+ 'dateString': '2024-10-10',
1327
+ 'storeName': 'LKST400',
1328
+ 'storeId': '11-10',
1329
+ 'storeSpocEmail': 'olivia@yopmail.com',
1330
+ 'openTime': '09:00 AM',
1331
+ 'openTimeFlag': false,
1332
+ 'closeTime': '10:00 PM',
1333
+ 'closeTimeFlag': false,
1334
+ },
1335
+ {
1336
+ 'date': '02 Aug, 2024',
1337
+ 'dateString': '2024-10-10',
1338
+ 'storeName': 'LKST401',
1339
+ 'storeId': '11-11',
1340
+ 'storeSpocEmail': 'yamini@yopmail.com',
1341
+ 'openTime': '09:10 AM',
1342
+ 'openTimeFlag': true,
1343
+ 'closeTime': '10:00 PM',
1344
+ 'closeTimeFlag': false,
1345
+ },
1346
+ {
1347
+ 'date': '02 Aug, 2024',
1348
+ 'dateString': '2024-10-10',
1349
+ 'storeName': 'LKST402',
1350
+ 'storeId': '11-12',
1351
+ 'storeSpocEmail': 'balaji@yopmail.com',
1352
+ 'openTime': '09:00 AM',
1353
+ 'openTimeFlag': false,
1354
+ 'closeTime': '09:50 PM',
1355
+ 'closeTimeFlag': true,
1356
+ },
1357
+ {
1358
+ 'date': '02 Aug, 2024',
1359
+ 'dateString': '2024-10-10',
1360
+ 'storeName': 'LKST402',
1361
+ 'storeId': '11-12',
1362
+ 'storeSpocEmail': 'balaji@yopmail.com',
1363
+ 'openTime': '09:10 AM',
1364
+ 'openTimeFlag': true,
1365
+ 'closeTime': '09:50 PM',
1366
+ 'closeTimeFlag': true,
1367
+ },
1368
+ ];
1369
+ break;
1370
+ case 'mobileusagedetection':
1371
+ resData.mobileusagedetectionData = {};
1372
+ resData.mobileusagedetectionData = [
1373
+ {
1374
+ 'date': '02 Aug, 2024',
1375
+ 'dateString': '2024-10-10',
1376
+ 'storeName': 'LKST400',
1377
+ 'storeId': '11-10',
1378
+ 'storeSpocEmail': 'olivia@yopmail.com',
1379
+ 'detections': 50,
1380
+ },
1381
+ {
1382
+ 'date': '02 Aug, 2024',
1383
+ 'dateString': '2024-10-10',
1384
+ 'storeName': 'LKST401',
1385
+ 'storeId': '11-11',
1386
+ 'storeSpocEmail': 'yamini@yopmail.com',
1387
+ 'detections': 60,
1388
+ },
1389
+ {
1390
+ 'date': '02 Aug, 2024',
1391
+ 'dateString': '2024-10-10',
1392
+ 'storeName': 'LKST402',
1393
+ 'storeId': '11-12',
1394
+ 'storeSpocEmail': 'balaji@yopmail.com',
1395
+ 'detections': 70,
1396
+ },
1397
+ {
1398
+ 'date': '02 Aug, 2024',
1399
+ 'dateString': '2024-10-10',
1400
+ 'storeName': 'LKST402',
1401
+ 'storeId': '11-12',
1402
+ 'storeSpocEmail': 'balaji@yopmail.com',
1403
+ 'detections': 90,
1404
+ },
1405
+ ];
1406
+ break;
1407
+ case 'uniformdetection':
1408
+ resData.uniformdetectionData = {};
1409
+ resData.uniformdetectionData = [
1410
+ {
1411
+ 'date': '02 Aug, 2024',
1412
+ 'dateString': '2024-10-10',
1413
+ 'storeName': 'LKST400',
1414
+ 'storeId': '11-10',
1415
+ 'storeSpocEmail': 'olivia@yopmail.com',
1416
+ 'detections': 50,
1417
+ },
1418
+ {
1419
+ 'date': '02 Aug, 2024',
1420
+ 'dateString': '2024-10-10',
1421
+ 'storeName': 'LKST401',
1422
+ 'storeId': '11-11',
1423
+ 'storeSpocEmail': 'yamini@yopmail.com',
1424
+ 'detections': 60,
1425
+ },
1426
+ {
1427
+ 'date': '02 Aug, 2024',
1428
+ 'dateString': '2024-10-10',
1429
+ 'storeName': 'LKST402',
1430
+ 'storeId': '11-12',
1431
+ 'storeSpocEmail': 'balaji@yopmail.com',
1432
+ 'detections': 70,
1433
+ },
1434
+ {
1435
+ 'date': '02 Aug, 2024',
1436
+ 'dateString': '2024-10-10',
1437
+ 'storeName': 'LKST402',
1438
+ 'storeId': '11-12',
1439
+ 'storeSpocEmail': 'balaji@yopmail.com',
1440
+ 'detections': 90,
1441
+ },
1442
+ ];
1443
+ break;
1444
+ case 'customerunattended':
1445
+ resData.customerunattendedData = {};
1446
+ resData.customerunattendedData = [
1447
+ {
1448
+ 'date': '02 Aug, 2024',
1449
+ 'dateString': '2024-10-10',
1450
+ 'storeName': 'LKST400',
1451
+ 'storeId': '11-10',
1452
+ 'storeSpocEmail': 'olivia@yopmail.com',
1453
+ 'detections': 50,
1454
+ },
1455
+ {
1456
+ 'date': '02 Aug, 2024',
1457
+ 'dateString': '2024-10-10',
1458
+ 'storeName': 'LKST401',
1459
+ 'storeId': '11-11',
1460
+ 'storeSpocEmail': 'yamini@yopmail.com',
1461
+ 'detections': 60,
1462
+ },
1463
+ {
1464
+ 'date': '02 Aug, 2024',
1465
+ 'dateString': '2024-10-10',
1466
+ 'storeName': 'LKST402',
1467
+ 'storeId': '11-12',
1468
+ 'storeSpocEmail': 'balaji@yopmail.com',
1469
+ 'detections': 70,
1470
+ },
1471
+ {
1472
+ 'date': '02 Aug, 2024',
1473
+ 'dateString': '2024-10-10',
1474
+ 'storeName': 'LKST402',
1475
+ 'storeId': '11-12',
1476
+ 'storeSpocEmail': 'balaji@yopmail.com',
1477
+ 'detections': 90,
1478
+ },
1479
+ ];
1480
+ break;
1481
+ case 'staffleftinthemiddle':
1482
+ resData.staffleftinthemiddleData = {};
1483
+ resData.staffleftinthemiddleData = [
1484
+ {
1485
+ 'date': '02 Aug, 2024',
1486
+ 'dateString': '2024-10-10',
1487
+ 'storeName': 'LKST400',
1488
+ 'storeId': '11-10',
1489
+ 'storeSpocEmail': 'olivia@yopmail.com',
1490
+ 'detections': 50,
1491
+ },
1492
+ {
1493
+ 'date': '02 Aug, 2024',
1494
+ 'dateString': '2024-10-10',
1495
+ 'storeName': 'LKST401',
1496
+ 'storeId': '11-11',
1497
+ 'storeSpocEmail': 'yamini@yopmail.com',
1498
+ 'detections': 60,
1499
+ },
1500
+ {
1501
+ 'date': '02 Aug, 2024',
1502
+ 'dateString': '2024-10-10',
1503
+ 'storeName': 'LKST402',
1504
+ 'storeId': '11-12',
1505
+ 'storeSpocEmail': 'balaji@yopmail.com',
1506
+ 'detections': 70,
1507
+ },
1508
+ {
1509
+ 'date': '02 Aug, 2024',
1510
+ 'dateString': '2024-10-10',
1511
+ 'storeName': 'LKST402',
1512
+ 'storeId': '11-12',
1513
+ 'storeSpocEmail': 'balaji@yopmail.com',
1514
+ 'detections': 90,
1515
+ },
1516
+ ];
1517
+ break;
1518
+ case 'custom':
1519
+ resData.customData = {};
1520
+ resData.customData = [
1521
+ {
1522
+ 'date': '02 Aug, 2024',
1523
+ 'dateString': '2024-10-10',
1524
+ 'storeName': 'LKST400',
1525
+ 'storeId': '11-10',
1526
+ 'storeSpocEmail': 'olivia@yopmail.com',
1527
+ 'detections': 50,
1528
+ },
1529
+ {
1530
+ 'date': '02 Aug, 2024',
1531
+ 'dateString': '2024-10-10',
1532
+ 'storeName': 'LKST401',
1533
+ 'storeId': '11-11',
1534
+ 'storeSpocEmail': 'yamini@yopmail.com',
1535
+ 'detections': 60,
1536
+ },
1537
+ {
1538
+ 'date': '02 Aug, 2024',
1539
+ 'dateString': '2024-10-10',
1540
+ 'storeName': 'LKST402',
1541
+ 'storeId': '11-12',
1542
+ 'storeSpocEmail': 'balaji@yopmail.com',
1543
+ 'detections': 70,
1544
+ },
1545
+ {
1546
+ 'date': '02 Aug, 2024',
1547
+ 'dateString': '2024-10-10',
1548
+ 'storeName': 'LKST402',
1549
+ 'storeId': '11-12',
1550
+ 'storeSpocEmail': 'balaji@yopmail.com',
1551
+ 'detections': 90,
1552
+ },
1553
+ ];
1554
+ break;
1555
+ default:
1556
+ break;
1557
+ }
1558
+ return resData;
1559
+ } catch ( error ) {
1560
+ console.log( 'error =>', error );
1561
+ logger.error( { error: error, message: data, function: 'returnServerError' } );
1562
+ }
1563
+ }
1564
+
1565
+ async function flagCardData( checklistType ) {
1566
+ try {
1567
+ let resData = {};
1568
+ resData.flagCards = {
1569
+ 'totalFlag': 700,
1570
+ 'questionFlag': {
1571
+ 'count': 40,
1572
+ },
1573
+ 'delayInSubmission': {
1574
+ 'count': 50,
1575
+ },
1576
+ 'detectionFlag': {
1577
+ 'count': 20,
1578
+ },
1579
+ };
1580
+ return resData;
1581
+ } catch ( error ) {
1582
+ console.log( 'error =>', error );
1583
+ logger.error( { error: error, message: data, function: 'returnServerError' } );
1584
+ }
1585
+ }
1586
+
1587
+ async function falgComparisonData( checklistType ) {
1588
+ try {
1589
+ let resData = {};
1590
+ resData.flagComparisonCards = {
1591
+ 'questionComparisonFlag': {
1592
+ 'comparisonData': 40,
1593
+ 'ComparisonFlag': true,
1594
+ },
1595
+ 'delayInSubmissionComparisonFlag': {
1596
+ 'comparisonData': 50,
1597
+ 'ComparisonFlag': false,
1598
+ },
1599
+ 'detectionComparisonFlag': {
1600
+ 'comparisonData': 20,
1601
+ 'ComparisonFlag': true,
1602
+ },
1603
+ };
1604
+ return resData;
1605
+ } catch ( error ) {
1606
+ console.log( 'error =>', error );
1607
+ logger.error( { error: error, message: data, function: 'returnServerError' } );
1608
+ }
1609
+ }
1610
+
1611
+ async function flagTableData( checklistType ) {
1612
+ try {
1613
+ let resData = {};
1614
+ resData.totalCount = 300;
1615
+ resData.flagTableData = [
1616
+ {
1617
+ 'checklistName': 'Field VM- Store Visit Checklist',
1618
+ 'sourceCheckList_id': '668e3e1807d5312fa49b0046',
1619
+ 'checkListType': 'custom',
1620
+ 'flagType': 'Question',
1621
+ 'assignedStores': 400,
1622
+ 'flaggedStores': 50,
1623
+ 'flagCount': 30,
1624
+ 'complianceRate': 25,
1625
+ },
1626
+ {
1627
+ 'checklistName': 'DC Prep Checklist',
1628
+ 'sourceCheckList_id': '6690d95b747d2cc1f1167361',
1629
+ 'checkListType': 'custom',
1630
+ 'flagType': 'Question',
1631
+ 'assignedStores': 500,
1632
+ 'flaggedStores': 66,
1633
+ 'flagCount': 66,
1634
+ 'complianceRate': 89,
1635
+ },
1636
+ {
1637
+ 'checklistName': 'Store Open and Close',
1638
+ 'sourceCheckList_id': '6690d95b747d2cc1f1167361',
1639
+ 'checkListType': 'storeopenandclose',
1640
+ 'flagType': 'Question',
1641
+ 'assignedStores': 300,
1642
+ 'flaggedStores': 70,
1643
+ 'flagCount': 80,
1644
+ 'complianceRate': 25,
1645
+ },
1646
+ {
1647
+ 'checklistName': 'Mobileusage Detection',
1648
+ 'sourceCheckList_id': '6690d95b747d2cc1f1167361',
1649
+ 'checkListType': 'mobileusagedetection',
1650
+ 'flagType': 'Detection',
1651
+ 'assignedStores': 250,
1652
+ 'flaggedStores': 30,
1653
+ 'flagCount': 80,
1654
+ 'complianceRate': 77,
1655
+ },
1656
+ {
1657
+ 'checklistName': 'Uniform Detection',
1658
+ 'sourceCheckList_id': '6690d95b747d2cc1f1167361',
1659
+ 'checkListType': 'uniformdetection',
1660
+ 'flagType': 'Detection',
1661
+ 'assignedStores': 100,
1662
+ 'flaggedStores': 0,
1663
+ 'flagCount': 60,
1664
+ 'complianceRate': 45,
1665
+ },
1666
+ {
1667
+ 'checklistName': 'Customer Unattended',
1668
+ 'sourceCheckList_id': '6690d95b747d2cc1f1167361',
1669
+ 'checkListType': 'customerunattended',
1670
+ 'flagType': 'Detection',
1671
+ 'assignedStores': 200,
1672
+ 'flaggedStores': 20,
1673
+ 'flagCount': 70,
1674
+ 'complianceRate': 55,
1675
+ },
1676
+ {
1677
+ 'checklistName': 'Staff Left in The Middle',
1678
+ 'sourceCheckList_id': '6690d95b747d2cc1f1167361',
1679
+ 'checkListType': 'staffleftinthemiddle',
1680
+ 'flagType': 'Detection',
1681
+ 'assignedStores': 150,
1682
+ 'flaggedStores': 50,
1683
+ 'flagCount': 50,
1684
+ 'complianceRate': 30,
1685
+ },
1686
+ ];
1687
+ return resData;
1688
+ } catch ( error ) {
1689
+ console.log( 'error =>', error );
1690
+ logger.error( { error: error, message: data, function: 'returnServerError' } );
1691
+ }
1692
+ }
1693
+
1694
+ async function checklistDropdownData( checklistType ) {
1695
+ try {
1696
+ let resData = {};
1697
+ resData.checklistDropdownData = [
1698
+ {
1699
+ 'checklistName': 'Field VM- Store Visit Checklist',
1700
+ 'sourceCheckList_id': '668e3e1807d5312fa49b0046',
1701
+ 'checkListType': 'custom',
1702
+ 'createdByName': 'Yamini',
1703
+ 'storeCount': 1853,
1704
+ 'scheduleRepeatedType': 'weekly',
1705
+ 'scheduleStartTime': '12:00 PM',
1706
+ 'scheduleEndTime': '06:00 PM',
1707
+ 'publish': true,
1708
+ },
1709
+ {
1710
+ 'checklistName': 'DC Prep Checklist',
1711
+ 'sourceCheckList_id': '6690d95b747d2cc1f1167361',
1712
+ 'checkListType': 'custom',
1713
+ 'createdByName': 'Yamini',
1714
+ 'storeCount': 1853,
1715
+ 'scheduleRepeatedType': 'weekly',
1716
+ 'scheduleStartTime': '12:00 PM',
1717
+ 'scheduleEndTime': '06:00 PM',
1718
+ 'publish': true,
1719
+ },
1720
+ {
1721
+ 'checklistName': 'Store Open and Close',
1722
+ 'sourceCheckList_id': '6690d95b747d2cc1f1167362',
1723
+ 'checkListType': 'storeopenandclose',
1724
+ 'createdByName': 'Yamini',
1725
+ 'storeCount': 1853,
1726
+ 'scheduleRepeatedType': 'weekly',
1727
+ 'scheduleStartTime': '12:00 PM',
1728
+ 'scheduleEndTime': '06:00 PM',
1729
+ 'publish': true,
1730
+ },
1731
+ {
1732
+ 'checklistName': 'Mobileusage Detection',
1733
+ 'sourceCheckList_id': '6690d95b747d2cc1f1167363',
1734
+ 'checkListType': 'mobileusagedetection',
1735
+ 'createdByName': 'Yamini',
1736
+ 'storeCount': 1853,
1737
+ 'scheduleRepeatedType': 'weekly',
1738
+ 'scheduleStartTime': '12:00 PM',
1739
+ 'scheduleEndTime': '06:00 PM',
1740
+ 'publish': true,
1741
+ },
1742
+ {
1743
+ 'checklistName': 'Uniform Detection',
1744
+ 'sourceCheckList_id': '6690d95b747d2cc1f1167364',
1745
+ 'checkListType': 'uniformdetection',
1746
+ 'createdByName': 'Yamini',
1747
+ 'storeCount': 1853,
1748
+ 'scheduleRepeatedType': 'weekly',
1749
+ 'scheduleStartTime': '12:00 PM',
1750
+ 'scheduleEndTime': '06:00 PM',
1751
+ 'publish': true,
1752
+ },
1753
+ {
1754
+ 'checklistName': 'Customer Unattended',
1755
+ 'sourceCheckList_id': '6690d95b747d2cc1f1167365',
1756
+ 'checkListType': 'customerunattended',
1757
+ 'createdByName': 'Yamini',
1758
+ 'storeCount': 1853,
1759
+ 'scheduleRepeatedType': 'weekly',
1760
+ 'scheduleStartTime': '12:00 PM',
1761
+ 'scheduleEndTime': '06:00 PM',
1762
+ 'publish': true,
1763
+ },
1764
+ {
1765
+ 'checklistName': 'Staff Left in The Middle',
1766
+ 'sourceCheckList_id': '6690d95b747d2cc1f1167366',
1767
+ 'checkListType': 'staffleftinthemiddle',
1768
+ 'createdByName': 'Yamini',
1769
+ 'storeCount': 1853,
1770
+ 'scheduleRepeatedType': 'weekly',
1771
+ 'scheduleStartTime': '12:00 PM',
1772
+ 'scheduleEndTime': '06:00 PM',
1773
+ 'publish': true,
1774
+ },
1775
+ {
1776
+ 'checklistName': 'Field VM- Store Visit Checklist Field VM- Store Visit Checklist',
1777
+ 'sourceCheckList_id': '668e3e1807d5312fa49b0046',
1778
+ 'checkListType': 'custom',
1779
+ 'createdByName': 'Yamini',
1780
+ 'storeCount': 1853,
1781
+ 'scheduleRepeatedType': 'weekly',
1782
+ 'scheduleStartTime': '12:00 PM',
1783
+ 'scheduleEndTime': '06:00 PM',
1784
+ 'publish': true,
1785
+ },
1786
+ ];
1787
+ return resData;
1788
+ } catch ( error ) {
1789
+ console.log( 'error =>', error );
1790
+ logger.error( { error: error, message: data, function: 'returnServerError' } );
1791
+ }
1792
+ }
1793
+
1794
+
1795
+ // Lamda Service Call //
1796
+ async function LamdaServiceCall( url, data ) {
1797
+ try {
1798
+ const requestOptions = {
1799
+ method: 'POST',
1800
+ headers: {
1801
+ 'Content-Type': 'application/json',
1802
+ },
1803
+ body: JSON.stringify( data ),
1804
+ };
1805
+ const response = await fetch( url, requestOptions );
1806
+ if ( !response.ok ) {
1807
+ throw new Error( `Response status: ${response.status}` );
1808
+ return false;
1809
+ }
1810
+ const json = await response.json();
1811
+ return json;
1812
+ } catch ( error ) {
1813
+ logger.error( { error: error, message: data, function: 'LamdaServiceCall' } );
1814
+ return false;
1815
+ }
1816
+ }
1817
+
1818
+ export const flagChecklistCardsV1 = async ( req, res ) => {
1819
+ try {
1820
+ let reqestData = req.body;
1821
+
1822
+ if ( reqestData.ChecklistType == 'custom' ) {
1823
+ const pipeline = [
1824
+ {
1825
+ $match: {
1826
+ $and: [
1827
+ { client_id: reqestData?.clientId },
1828
+ { store_id: { $in: reqestData?.storeId } },
1829
+ { date_iso: { $gte: new Date( reqestData?.fromDate ) } },
1830
+ { date_iso: { $lte: dayjs.utc( reqestData.toDate ).endOf( 'day' ).toDate() } },
1831
+ { sourceCheckList_id: new mongoose.Types.ObjectId( reqestData.sourceCheckList_id ) },
1832
+ ],
1833
+ },
1834
+ },
1835
+ {
1836
+ $project: {
1837
+ storeCount: 1,
1838
+ sourceCheckList_id: 1,
1839
+ timeFlag: 1,
1840
+ questionFlag: 1,
1841
+ questionCount: 1,
1842
+ },
1843
+ },
1844
+ {
1845
+ $group: {
1846
+ _id: '$sourceCheckList_id',
1847
+ totalAssignedStores: {
1848
+ $max: '$storeCount',
1849
+ },
1850
+ flagIncidents: {
1851
+ $sum: { $add: [ '$questionFlag', '$timeFlag' ] },
1852
+ // $sum: {
1853
+ // $cond: [ {
1854
+ // $or: [
1855
+ // { $gt: [ '$timeFlag', 0 ] },
1856
+ // { $gt: [ '$questionFlag', 0 ] },
1857
+ // ],
1858
+ // }, 1, 0 ],
1859
+ // },
1860
+
1861
+ },
1862
+ questionFlag: {
1863
+ $sum: '$questionFlag',
1864
+ // $sum: {
1865
+ // $cond: [ { $gt: [ '$questionFlag', 0 ] }, 1, 0 ],
1866
+ // },
1867
+ },
1868
+ questionCount: {
1869
+ $sum: '$questionCount',
1870
+ // $sum: {
1871
+ // $cond: [ { $gt: [ '$questionCount', 0 ] }, 1, 0 ],
1872
+ // },
1873
+ },
1874
+
1875
+ },
1876
+ },
1877
+ {
1878
+ $project: {
1879
+ totalAssignedStores: 1,
1880
+ flagIncidents: 1,
1881
+ questionCount: 1,
1882
+ correctAnswers: { $subtract: [ '$questionCount', '$questionFlag' ] },
1883
+
1884
+ },
1885
+ },
1886
+ {
1887
+ $project: {
1888
+ totalAssignedStores: 1,
1889
+ flagIncidents: 1,
1890
+ complianceRate: {
1891
+ $cond: {
1892
+ if: { $eq: [ '$questionCount', 0 ] },
1893
+ then: 0,
1894
+ else: {
1895
+ $round: [ { $multiply: [ { $divide: [ '$correctAnswers', '$questionCount' ] }, 100 ] }, 2 ],
1896
+ },
1897
+ },
1898
+ },
1899
+ },
1900
+ },
1901
+ ];
1902
+
1903
+
1904
+ const cardData = await processedchecklistService.aggregate( pipeline );
1905
+
1906
+ if ( !cardData?.[0] ) {
1907
+ return res.sendError( 'No Content', 204 );
1908
+ }
1909
+
1910
+ const resData ={
1911
+ customCards: {
1912
+ totalAssignedStores: {
1913
+ count: cardData?.[0]?.totalAssignedStores,
1914
+ },
1915
+ flagIncidents: {
1916
+ count: cardData?.[0]?.flagIncidents,
1917
+ },
1918
+ complianceRate: {
1919
+ count: cardData?.[0]?.complianceRate,
1920
+ },
1921
+ },
1922
+ };
1923
+
1924
+
1925
+ return res.sendSuccess( resData );
1926
+ } else {
1927
+ const pipeline = [
1928
+ {
1929
+ $match:
1930
+ {
1931
+ date_iso: {
1932
+ $gte: new Date( reqestData.fromDate ),
1933
+ },
1934
+ date_iso: {
1935
+ $lte: dayjs.utc( reqestData.toDate ).endOf( 'day' ).toDate(),
1936
+ },
1937
+ store_id: {
1938
+ $in: reqestData.storeId,
1939
+ },
1940
+ client_id: reqestData.clientId,
1941
+ sourceCheckList_id: new mongoose.Types.ObjectId( reqestData.sourceCheckList_id ),
1942
+ },
1943
+ },
1944
+ {
1945
+ $project: {
1946
+ storeCount: 1,
1947
+ },
1948
+ },
1949
+ {
1950
+ $sort: { storeCount: -1 },
1951
+ },
1952
+ {
1953
+ $limit: 1,
1954
+ },
1955
+ ];
1956
+ const checklist = await aggregate( pipeline );
1957
+ reqestData.storeCount = checklist[0]?.storeCount | 0;
1958
+ let LamdaURL = 'https://k462fpztd3zaucty5ruoks6z540qqgqj.lambda-url.ap-south-1.on.aws/';
1959
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
1960
+ if ( resultData ) {
1961
+ if ( resultData.status_code == '200' ) {
1962
+ return res.sendSuccess( resultData );
1963
+ } else {
1964
+ return res.sendError( 'No Content', 204 );
1965
+ }
1966
+ } else {
1967
+ return res.sendError( 'No Content', 204 );
1968
+ }
1969
+ }
1970
+ } catch ( error ) {
1971
+ console.log( 'error =>', error );
1972
+ logger.error( { error: error, function: 'flagChecklistCardsV1' } );
1973
+ return res.sendError( error, 500 );
1974
+ }
1975
+ };
1976
+
1977
+
1978
+ export const flagChecklistComparisonCardsV1 = async ( req, res ) => {
1979
+ try {
1980
+ let requestData = req.body;
1981
+ let toDate = new Date( requestData.toDate );
1982
+ let userTimezoneOffset = toDate.getTimezoneOffset() * 60000;
1983
+ toDate = new Date( toDate.getTime() - userTimezoneOffset );
1984
+ toDate.setUTCHours( 23, 59, 59, 59 );
1985
+
1986
+ let rangeOneFromDate;
1987
+ let rangeOneToDate;
1988
+ let rangeTwoFromDate;
1989
+ let rangeTwoToDate;
1990
+ if ( requestData.dateType == 'weekly' ) {
1991
+ rangeOneFromDate = new Date( requestData.toDate );
1992
+ rangeOneFromDate.setDate( rangeOneFromDate.getDate() - 6 );
1993
+ rangeOneToDate = new Date( requestData.toDate );
1994
+ rangeOneToDate = new Date( rangeOneToDate.getTime() - userTimezoneOffset );
1995
+ rangeOneToDate.setUTCHours( 23, 59, 59, 59 );
1996
+ rangeTwoToDate = new Date( requestData.toDate );
1997
+ rangeTwoToDate.setDate( rangeTwoToDate.getDate() - 7 );
1998
+ rangeTwoFromDate = new Date( rangeTwoToDate );
1999
+ rangeTwoFromDate.setDate( rangeTwoFromDate.getDate() - 6 );
2000
+ rangeTwoToDate = new Date( rangeTwoToDate.getTime() - userTimezoneOffset );
2001
+ rangeTwoToDate.setUTCHours( 23, 59, 59, 59 );
2002
+ } else if ( requestData.dateType == 'monthly' ) {
2003
+ rangeOneFromDate = new Date( requestData.toDate );
2004
+ rangeOneFromDate.setDate( rangeOneFromDate.getDate() - 30 );
2005
+ rangeOneToDate = new Date( requestData.toDate );
2006
+ rangeOneToDate = new Date( rangeOneToDate.getTime() - userTimezoneOffset );
2007
+ rangeOneToDate.setUTCHours( 23, 59, 59, 59 );
2008
+ rangeTwoToDate = new Date( requestData.toDate );
2009
+ rangeTwoToDate.setDate( rangeTwoToDate.getDate() - 31 );
2010
+ rangeTwoFromDate = new Date( rangeTwoToDate );
2011
+ rangeTwoFromDate.setDate( rangeTwoFromDate.getDate() - 30 );
2012
+ rangeTwoToDate = new Date( rangeTwoToDate.getTime() - userTimezoneOffset );
2013
+ rangeTwoToDate.setUTCHours( 23, 59, 59, 59 );
2014
+ } else {
2015
+ rangeOneFromDate = new Date( requestData.toDate );
2016
+ rangeOneFromDate.setDate( rangeOneFromDate.getDate() - 0 );
2017
+ rangeOneToDate = new Date( requestData.toDate );
2018
+ rangeOneToDate = new Date( rangeOneToDate.getTime() - userTimezoneOffset );
2019
+ rangeOneToDate.setUTCHours( 23, 59, 59, 59 );
2020
+ rangeTwoToDate = new Date( requestData.toDate );
2021
+ rangeTwoToDate.setDate( rangeTwoToDate.getDate() - 1 );
2022
+ rangeTwoFromDate = new Date( rangeTwoToDate );
2023
+ rangeTwoFromDate.setDate( rangeTwoFromDate.getDate() - 0 );
2024
+ rangeTwoToDate = new Date( rangeTwoToDate.getTime() - userTimezoneOffset );
2025
+ rangeTwoToDate.setUTCHours( 23, 59, 59, 59 );
2026
+ }
2027
+
2028
+ let flagComparisonCards = {
2029
+ 'totalAssignedStores': {
2030
+ 'comparisonData': 0,
2031
+ 'ComparisonFlag': '',
2032
+ },
2033
+ 'flagIncidents': {
2034
+ 'comparisonData': 0,
2035
+ 'ComparisonFlag': '',
2036
+ },
2037
+ 'complianceRate': {
2038
+ 'comparisonData': 0,
2039
+ 'ComparisonFlag': '',
2040
+ },
2041
+ };
2042
+
2043
+
2044
+ if ( requestData.ChecklistType == 'custom' ) {
2045
+ const range1pipeline = [
2046
+ {
2047
+ $match: {
2048
+ $and: [
2049
+ { client_id: requestData?.clientId },
2050
+ { store_id: { $in: requestData?.storeId } },
2051
+ { date_iso: { $gte: rangeOneFromDate } },
2052
+ { date_iso: { $lte: rangeOneToDate } },
2053
+ { sourceCheckList_id: new mongoose.Types.ObjectId( requestData.sourceCheckList_id ) },
2054
+ ],
2055
+ },
2056
+ },
2057
+ {
2058
+ $project: {
2059
+ storeCount: 1,
2060
+ sourceCheckList_id: 1,
2061
+ timeFlag: 1,
2062
+ questionFlag: 1,
2063
+ questionCount: 1,
2064
+ },
2065
+ },
2066
+ {
2067
+ $group: {
2068
+ _id: '$sourceCheckList_id',
2069
+ totalAssignedStores: {
2070
+ $max: '$storeCount',
2071
+ },
2072
+ flagIncidents: {
2073
+
2074
+ $sum: {
2075
+ $add: [ '$questionFlag', '$timeFlag' ],
2076
+ // $cond: [ {
2077
+ // $or: [
2078
+ // { $gt: [ '$timeFlag', 0 ] },
2079
+ // { $gt: [ '$questionFlag', 0 ] },
2080
+ // ],
2081
+ // }, 1, 0 ],
2082
+ },
2083
+
2084
+ },
2085
+ questionFlag: {
2086
+ $sum: '$questionFlag',
2087
+ // $sum: {
2088
+ // $cond: [ { $gt: [ '$questionFlag', 0 ] }, 1, 0 ],
2089
+ // },
2090
+ },
2091
+ questionCount: {
2092
+ $sum: '$questionCount',
2093
+ // $sum: {
2094
+ // $cond: [ { $gt: [ '$questionCount', 0 ] }, 1, 0 ],
2095
+ // },
2096
+ },
2097
+
2098
+ },
2099
+ },
2100
+ {
2101
+ $project: {
2102
+ totalAssignedStores: 1,
2103
+ flagIncidents: 1,
2104
+ questionCount: 1,
2105
+ correctAnswers: { $subtract: [ '$questionCount', '$questionFlag' ] },
2106
+
2107
+ },
2108
+ },
2109
+ {
2110
+ $project: {
2111
+ totalAssignedStores: 1,
2112
+ flagIncidents: 1,
2113
+ complianceRate: {
2114
+ $cond: {
2115
+ if: { $eq: [ '$questionCount', 0 ] },
2116
+ then: 0,
2117
+ else: {
2118
+ $round: [ { $multiply: [ { $divide: [ '$correctAnswers', '$questionCount' ] }, 100 ] }, 2 ],
2119
+ },
2120
+ },
2121
+ },
2122
+ },
2123
+ },
2124
+ ];
2125
+
2126
+ const range2pipeline = [
2127
+ {
2128
+ $match: {
2129
+ $and: [
2130
+ { client_id: requestData?.clientId },
2131
+ { store_id: { $in: requestData?.storeId } },
2132
+ { date_iso: { $gte: rangeTwoFromDate } },
2133
+ { date_iso: { $lte: rangeTwoToDate } },
2134
+ { sourceCheckList_id: new mongoose.Types.ObjectId( requestData.sourceCheckList_id ) },
2135
+ ],
2136
+ },
2137
+ },
2138
+ {
2139
+ $project: {
2140
+ storeCount: 1,
2141
+ sourceCheckList_id: 1,
2142
+ timeFlag: 1,
2143
+ questionFlag: 1,
2144
+ questionCount: 1,
2145
+ },
2146
+ },
2147
+ {
2148
+ $group: {
2149
+ _id: '$sourceCheckList_id',
2150
+ totalAssignedStores: {
2151
+ $max: '$storeCount',
2152
+ },
2153
+ flagIncidents: {
2154
+ $sum: {
2155
+ $add: [ '$questionFlag', '$timeFlag' ],
2156
+ // $cond: [ {
2157
+ // $or: [
2158
+ // { $gt: [ '$timeFlag', 0 ] },
2159
+ // { $gt: [ '$questionFlag', 0 ] },
2160
+ // ],
2161
+ // }, 1, 0 ],
2162
+ },
2163
+
2164
+ },
2165
+ questionFlag: {
2166
+ $sum: '$questionFlag',
2167
+ // $sum: {
2168
+ // $cond: [ { $gt: [ '$questionFlag', 0 ] }, 1, 0 ],
2169
+ // },
2170
+ },
2171
+ questionCount: {
2172
+ $sum: '$questionCount',
2173
+ // $sum: {
2174
+ // $cond: [ { $gt: [ '$questionCount', 0 ] }, 1, 0 ],
2175
+ // },
2176
+ },
2177
+
2178
+ },
2179
+ },
2180
+ {
2181
+ $project: {
2182
+ totalAssignedStores: 1,
2183
+ flagIncidents: 1,
2184
+ questionCount: 1,
2185
+ correctAnswers: { $subtract: [ '$questionCount', '$questionFlag' ] },
2186
+
2187
+ },
2188
+ },
2189
+ {
2190
+ $project: {
2191
+ totalAssignedStores: 1,
2192
+ flagIncidents: 1,
2193
+ complianceRate: {
2194
+ $cond: {
2195
+ if: { $eq: [ '$questionCount', 0 ] },
2196
+ then: 0,
2197
+ else: {
2198
+ $round: [ { $multiply: [ { $divide: [ '$correctAnswers', '$questionCount' ] }, 100 ] }, 2 ],
2199
+ },
2200
+ },
2201
+ },
2202
+ },
2203
+ },
2204
+ ];
2205
+
2206
+ const [ rangeOneData, rangeTwoData ] = await Promise.all( [ processedchecklistService.aggregate( range1pipeline ), processedchecklistService.aggregate( range2pipeline ) ] );
2207
+
2208
+
2209
+ if ( rangeOneData.length >0 && rangeTwoData.length >0 ) {
2210
+ flagComparisonCards.totalAssignedStores.comparisonData = ( ( ( rangeOneData[0].totalAssignedStores - rangeTwoData[0].totalAssignedStores )/rangeOneData[0].totalAssignedStores )*100 ).toFixed( 1 );
2211
+ if ( flagComparisonCards.totalAssignedStores.comparisonData > 0 ) {
2212
+ flagComparisonCards.totalAssignedStores.ComparisonFlag = true;
2213
+ } else {
2214
+ flagComparisonCards.totalAssignedStores.ComparisonFlag = false;
2215
+ }
2216
+ flagComparisonCards.flagIncidents.comparisonData = ( ( ( rangeOneData[0].flagIncidents - rangeTwoData[0].flagIncidents )/rangeOneData[0].flagIncidents )*100 ).toFixed( 1 );
2217
+ if ( flagComparisonCards.flagIncidents.comparisonData > 0 ) {
2218
+ flagComparisonCards.flagIncidents.ComparisonFlag = true;
2219
+ } else {
2220
+ flagComparisonCards.flagIncidents.ComparisonFlag = false;
2221
+ }
2222
+ flagComparisonCards.complianceRate.comparisonData = ( ( ( rangeOneData[0].complianceRate - rangeTwoData[0].complianceRate )/rangeOneData[0].complianceRate )*100 ).toFixed( 1 );
2223
+ if ( flagComparisonCards.complianceRate.comparisonData > 0 ) {
2224
+ flagComparisonCards.complianceRate.ComparisonFlag = true;
2225
+ } else {
2226
+ flagComparisonCards.complianceRate.ComparisonFlag = false;
2227
+ }
2228
+
2229
+ flagComparisonCards.totalAssignedStores.comparisonData = Math.abs( flagComparisonCards.totalAssignedStores.comparisonData );
2230
+ flagComparisonCards.flagIncidents.comparisonData = Math.abs( flagComparisonCards.flagIncidents.comparisonData );
2231
+ flagComparisonCards.complianceRate.comparisonData = Math.abs( flagComparisonCards.complianceRate.comparisonData );
2232
+ }
2233
+
2234
+ let result = {
2235
+ 'customCards': flagComparisonCards,
2236
+ };
2237
+
2238
+ return res.sendSuccess( result );
2239
+ } else {
2240
+ const fromPipeline = [
2241
+ {
2242
+ $match:
2243
+ {
2244
+ date_iso: {
2245
+ $gte: rangeOneFromDate,
2246
+ },
2247
+ date_iso: {
2248
+ $lte: rangeOneToDate,
2249
+ },
2250
+ store_id: {
2251
+ $in: requestData.storeId,
2252
+ },
2253
+ client_id: requestData.clientId,
2254
+ sourceCheckList_id: new mongoose.Types.ObjectId( requestData.sourceCheckList_id ),
2255
+ },
2256
+ },
2257
+ {
2258
+ $project: {
2259
+ storeCount: 1,
2260
+ },
2261
+ },
2262
+ {
2263
+ $sort: { storeCount: -1 },
2264
+ },
2265
+ {
2266
+ $limit: 1,
2267
+ },
2268
+ ];
2269
+ const from = await aggregate( fromPipeline );
2270
+ requestData.range1StoreCount = from[0]?.storeCount | 0;
2271
+
2272
+ const toPipeline = [
2273
+ {
2274
+ $match:
2275
+ {
2276
+ date_iso: {
2277
+ $gte: rangeTwoFromDate,
2278
+ },
2279
+ date_iso: {
2280
+ $lte: rangeTwoToDate,
2281
+ },
2282
+ store_id: {
2283
+ $in: requestData.storeId,
2284
+ },
2285
+ client_id: requestData.clientId,
2286
+ sourceCheckList_id: new mongoose.Types.ObjectId( requestData.sourceCheckList_id ),
2287
+ },
2288
+ },
2289
+ {
2290
+ $project: {
2291
+ storeCount: 1,
2292
+ },
2293
+ },
2294
+ {
2295
+ $sort: { storeCount: -1 },
2296
+ },
2297
+ {
2298
+ $limit: 1,
2299
+ },
2300
+ ];
2301
+
2302
+
2303
+ const to = await aggregate( toPipeline );
2304
+ requestData.range2StoreCount = to[0]?.storeCount | 0;
2305
+ let LamdaURL = 'https://5m55vcuecg2hll7jzfppx6h53y0lvcmq.lambda-url.ap-south-1.on.aws/';
2306
+ let resultData = await LamdaServiceCall( LamdaURL, requestData );
2307
+ // console.log( 'resultData =>', resultData );
2308
+ if ( resultData ) {
2309
+ if ( resultData.status_code == '200' ) {
2310
+ return res.sendSuccess( resultData );
2311
+ } else {
2312
+ return res.sendError( 'No Content', 204 );
2313
+ }
2314
+ } else {
2315
+ return res.sendError( 'No Content', 204 );
2316
+ }
2317
+ }
2318
+ } catch ( error ) {
2319
+ console.log( 'error =>', error );
2320
+ logger.error( { error: error, function: 'flagChecklistComparisonCardsV1' } );
2321
+ return res.sendError( error, 500 );
2322
+ }
2323
+ };
2324
+
2325
+
2326
+ export const flagChecklistTableV1 = async ( req, res ) => {
2327
+ try {
2328
+ let reqestData = req.body;
2329
+ if ( reqestData.ChecklistType == 'custom' ) {
2330
+ const match = {
2331
+ $match: {
2332
+ $and: [
2333
+ { client_id: reqestData?.clientId },
2334
+ { store_id: { $in: reqestData?.storeId } },
2335
+ { date_iso: { $gte: new Date( reqestData?.fromDate ) } },
2336
+ { date_iso: { $lte: dayjs.utc( reqestData.toDate ).endOf( 'day' ).toDate() } },
2337
+ { sourceCheckList_id: new mongoose.Types.ObjectId( reqestData.sourceCheckList_id ) },
2338
+ // {
2339
+ // $or: [
2340
+ // { timeFlag: { $gt: 0 } },
2341
+ // { questionFlag: { $gt: 0 } },
2342
+ // ],
2343
+ // },
2344
+ ],
2345
+ },
2346
+ };
2347
+
2348
+ if ( reqestData?.filter === 'question' ) {
2349
+ match.$match.$and.push( { questionFlag: { $gte: 1 } } );
2350
+ } else if ( reqestData?.filter === 'time' ) {
2351
+ match.$match.$and.push( { timeFlag: { $gte: 1 } } );
2352
+ }
2353
+ const pipeline = [
2354
+ match,
2355
+ {
2356
+ $project: {
2357
+ storeSpocEmail: '$userEmail',
2358
+ dateString: '$date_string',
2359
+ storeName: 1,
2360
+ storeId: '$store_id',
2361
+ date_iso: 1,
2362
+ checklistStatus: 1,
2363
+ questionFlagCount: '$questionFlag',
2364
+ timeFlagCount: '$timeFlag',
2365
+ reinitiateStatus: true,
2366
+ // detections: {
2367
+ // $sum: {
2368
+ // $cond: [
2369
+ // {
2370
+ // $or: [
2371
+ // { $gt: [ '$timeFlag', 0 ] },
2372
+ // { $gt: [ '$questionFlag', 0 ] },
2373
+ // ],
2374
+ // },
2375
+ // 1,
2376
+ // 0,
2377
+ // ],
2378
+ // },
2379
+ // },
2380
+ detections: {
2381
+ $sum: {
2382
+ $add: [ '$questionFlag', '$timeFlag' ],
2383
+ },
2384
+ },
2385
+ },
2386
+ },
2387
+ ];
2388
+
2389
+ if ( reqestData.search && reqestData.search != '' ) {
2390
+ pipeline[0].$match.$and.push( { storeName: { $regex: reqestData.search, $options: 'i' } } );
2391
+ }
2392
+
2393
+ const total = await processedchecklistService.aggregate( pipeline );
2394
+
2395
+ if ( !total.length ) {
2396
+ return res.sendError( { error: 'No Data Found' }, 204 );
2397
+ }
2398
+
2399
+ if ( reqestData.sortColumnName && reqestData.sortColumnName != '' && reqestData.sortBy && reqestData.sortBy !='' ) {
2400
+ pipeline.push( { $sort: { [reqestData.sortColumnName]: reqestData.sortBy } } );
2401
+ } else {
2402
+ pipeline.push( { $sort: { ['date_iso']: -1 } } );
2403
+ }
2404
+
2405
+ if ( reqestData.export ) {
2406
+ const exportdata = [];
2407
+ total.forEach( ( element ) => {
2408
+ exportdata.push( {
2409
+ 'Date': dayjs( element.dateString ).format( 'DD MMM, YYYY' ),
2410
+ 'Store Name': element?.storeName,
2411
+ 'Store Id': element?.storeId,
2412
+ 'Store Spoc Email': element?.storeSpocEmail,
2413
+ 'Detections': element?.detections,
2414
+ } );
2415
+ } );
2416
+ return await download( exportdata, res );
2417
+ }
2418
+
2419
+ const limit = parseInt( reqestData?.limit ) || 10;
2420
+ const skip = limit * ( reqestData?.offset ) || 0;
2421
+ pipeline.push( { $skip: skip }, { $limit: limit } );
2422
+
2423
+ const data = await processedchecklistService.aggregate( pipeline );
2424
+ if ( !data.length ) {
2425
+ return res.sendError( { error: 'No Data Found' }, 204 );
2426
+ }
2427
+
2428
+ for ( let index = 0; index < data.length; index++ ) {
2429
+ data[index].date = dayjs( data[index].dateString ).format( 'DD MMM, YYYY' );
2430
+ }
2431
+
2432
+
2433
+ return res.sendSuccess( { customData: data, totalCount: total?.length } );
2434
+ } else {
2435
+ if ( reqestData.export ) {
2436
+ reqestData.limit = 10000;
2437
+ reqestData.offset = 0;
2438
+ let LamdaURL = 'https://vpcejaftccr3jzqf5wrdkks7yy0krqix.lambda-url.ap-south-1.on.aws/';
2439
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
2440
+ if ( resultData ) {
2441
+ if ( resultData.status_code == '200' ) {
2442
+ const exportdata = [];
2443
+ resultData[reqestData.ChecklistType + 'Data'].forEach( ( element ) => {
2444
+ exportdata.push( {
2445
+ 'Date': element?.date,
2446
+ 'Store Name': element?.storeName,
2447
+ 'Store Id': element?.storeId,
2448
+ // 'Store Spoc Email': element?.SpocEmail,
2449
+ 'Detections': element?.detections,
2450
+ } );
2451
+ } );
2452
+ return await download( exportdata, res );
2453
+ } else {
2454
+ return res.sendError( 'No Content', 204 );
2455
+ }
2456
+ } else {
2457
+ return res.sendError( 'No Content', 204 );
2458
+ }
2459
+ }
2460
+
2461
+ let LamdaURL = 'https://vpcejaftccr3jzqf5wrdkks7yy0krqix.lambda-url.ap-south-1.on.aws/';
2462
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
2463
+ // console.log( 'resultData =>', resultData );
2464
+ if ( resultData ) {
2465
+ if ( resultData.status_code == '200' ) {
2466
+ return res.sendSuccess( resultData );
2467
+ } else {
2468
+ return res.sendError( 'No Content', 204 );
2469
+ }
2470
+ } else {
2471
+ return res.sendError( 'No Content', 204 );
2472
+ }
2473
+ }
2474
+ } catch ( error ) {
2475
+ console.log( 'error =>', error );
2476
+ logger.error( { error: error, function: 'flagChecklistTableV1' } );
2477
+ return res.sendError( error, 500 );
2478
+ }
2479
+ };
2480
+
2481
+ export const checklistDropdownSourceChecklist = async ( req, res ) => {
2482
+ try {
2483
+ let requestData = req.body;
2484
+ let fromDate = new Date( requestData.fromDate );
2485
+ let toDate = new Date( requestData.toDate );
2486
+ let userTimezoneOffset = toDate.getTimezoneOffset() * 60000;
2487
+ toDate = new Date( toDate.getTime() - userTimezoneOffset );
2488
+ toDate.setUTCHours( 23, 59, 59, 59 );
2489
+ let result = {};
2490
+
2491
+ let findQuery = [];
2492
+ let findAndQuery = [];
2493
+ findAndQuery.push(
2494
+ { client_id: requestData.clientId },
2495
+ { date_iso: { $gte: fromDate } },
2496
+ { date_iso: { $lte: toDate } },
2497
+ );
2498
+
2499
+ findQuery.push( { $match: { $and: findAndQuery } } );
2500
+
2501
+ findQuery.push( {
2502
+ $project: {
2503
+ sourceCheckList_id: 1,
2504
+ checkListName: 1,
2505
+ checkListType: 1,
2506
+ createdByName: 1,
2507
+ storeCount: 1,
2508
+ scheduleRepeatedType: 1,
2509
+ scheduleStartTime: 1,
2510
+ scheduleEndTime: 1,
2511
+ },
2512
+ } );
2513
+
2514
+ findQuery.push( {
2515
+ $group: {
2516
+ _id: '$sourceCheckList_id',
2517
+ sourceCheckList_id: { $last: '$sourceCheckList_id' },
2518
+ checkListName: { $last: '$checkListName' },
2519
+ checkListType: { $last: '$checkListType' },
2520
+ createdByName: { $last: '$createdByName' },
2521
+ storeCount: { $max: '$storeCount' },
2522
+ scheduleRepeatedType: { $last: '$scheduleRepeatedType' },
2523
+ scheduleStartTime: { $last: '$scheduleStartTime' },
2524
+ scheduleEndTime: { $last: '$scheduleEndTime' },
2525
+ },
2526
+ } );
2527
+
2528
+ findQuery.push( {
2529
+ $lookup: {
2530
+ from: 'checklistconfigs',
2531
+ let: { sourceCheckList_id: '$sourceCheckList_id' },
2532
+ pipeline: [
2533
+ {
2534
+ $match: {
2535
+ $expr: {
2536
+ $and: [
2537
+ { $eq: [ '$_id', '$$sourceCheckList_id' ] },
2538
+ ],
2539
+ },
2540
+ },
2541
+ },
2542
+ {
2543
+ $project: {
2544
+ checkListName: 1,
2545
+ publish: 1,
2546
+ },
2547
+ },
2548
+ ], as: 'checklistconfigs',
2549
+ },
2550
+ } );
2551
+ findQuery.push( { $unwind: { path: '$checklistconfigs', preserveNullAndEmptyArrays: true } } );
2552
+ findQuery.push( {
2553
+ $project: {
2554
+ sourceCheckList_id: 1,
2555
+ checkListName: 1,
2556
+ checkListType: 1,
2557
+ createdByName: 1,
2558
+ storeCount: 1,
2559
+ scheduleRepeatedType: 1,
2560
+ scheduleStartTime: 1,
2561
+ scheduleEndTime: 1,
2562
+ publish: '$checklistconfigs.publish',
2563
+ },
2564
+ } );
2565
+
2566
+ let getTotalCount = await processedchecklistconfigService.aggregate( findQuery );
2567
+ if ( !getTotalCount.length ) {
2568
+ return res.sendError( { error: 'No Data Found' }, 204 );
2569
+ }
2570
+
2571
+ if ( requestData.sortColumnName && requestData.sortColumnName != '' && requestData.sortBy && requestData.sortBy !='' ) {
2572
+ findQuery.push( { $sort: { [requestData.sortColumnName]: requestData.sortBy } } );
2573
+ } else {
2574
+ findQuery.push( { $sort: { ['checkListName']: -1 } } );
2575
+ }
2576
+
2577
+ let getChecklistData = await processedchecklistconfigService.aggregate( findQuery );
2578
+ result.checklistData = getChecklistData;
2579
+ return res.sendSuccess( result );
2580
+ } catch ( error ) {
2581
+ logger.error( { error: error, message: req.query, function: 'checklistDropdownV1' } );
2582
+ return res.sendError( { error: error }, 500 );
2583
+ }
2584
+ };
2585
+
2586
+ export const checklistDropdownV1 = async ( req, res ) => {
2587
+ try {
2588
+ let requestData = req.body;
2589
+ let fromDate = new Date( requestData.fromDate );
2590
+ let toDate = new Date( requestData.toDate );
2591
+ let userTimezoneOffset = toDate.getTimezoneOffset() * 60000;
2592
+ toDate = new Date( toDate.getTime() - userTimezoneOffset );
2593
+ toDate.setUTCHours( 23, 59, 59, 59 );
2594
+ let result = {};
2595
+
2596
+ let findQuery = [
2597
+ { $match: { $and: [
2598
+ { client_id: requestData.clientId },
2599
+ {
2600
+ $or: [
2601
+ { store_id: { $in: requestData.storeId } },
2602
+ { aiStoreList: { $in: requestData.storeId } },
2603
+ ],
2604
+ },
2605
+ { date_iso: { $gte: fromDate } },
2606
+ { date_iso: { $lte: toDate } },
2607
+ {
2608
+ $or: [
2609
+ { questionFlag: { $gte: 1 } },
2610
+ { timeFlag: { $gte: 1 } },
2611
+ { checkListType: { $ne: 'custom' } },
2612
+ ],
2613
+ },
2614
+ ] } },
2615
+ {
2616
+ $project: {
2617
+ sourceCheckList_id: 1,
2618
+ checkListName: 1,
2619
+ },
2620
+ },
2621
+ {
2622
+ $group: {
2623
+ _id: '$sourceCheckList_id',
2624
+ checkListName: { $last: '$checkListName' },
2625
+ },
2626
+ },
2627
+ {
2628
+ $project: {
2629
+ _id: 0,
2630
+ sourceCheckList_id: '$_id',
2631
+ checkListName: 1,
2632
+ },
2633
+ },
2634
+ {
2635
+ $lookup: {
2636
+ from: 'checklistconfigs',
2637
+ let: { sourceId: '$sourceCheckList_id' },
2638
+ pipeline: [
2639
+ {
2640
+ $match: {
2641
+ $expr: {
2642
+ $and: [
2643
+ { $eq: [ '$_id', '$$sourceId' ] },
2644
+ ],
2645
+ },
2646
+ },
2647
+ },
2648
+ {
2649
+ $project: {
2650
+ _id: 1,
2651
+ checkListName: 1,
2652
+ checkListNameLowercase: { $toLower: '$checkListName' },
2653
+ checkListType: 1,
2654
+ createdByName: 1,
2655
+ publish: 1,
2656
+ scheduleEndTime: 1,
2657
+ scheduleRepeatedType: 1,
2658
+ scheduleStartTime: 1,
2659
+ sourceCheckList_id: '$_id',
2660
+ storeCount: 1,
2661
+ },
2662
+ },
2663
+ ], as: 'checklistData',
2664
+ },
2665
+ },
2666
+ { $unwind: { path: '$checklistData', preserveNullAndEmptyArrays: true } },
2667
+ {
2668
+ $project: {
2669
+ _id: '$checklistData._id',
2670
+ checkListName: '$checklistData.checkListName',
2671
+ checkListNameLowercase: { $toLower: '$checkListName' },
2672
+ checkListType: '$checklistData.checkListType',
2673
+ createdByName: '$checklistData.createdByName',
2674
+ publish: '$checklistData.publish',
2675
+ scheduleEndTime: '$checklistData.scheduleEndTime',
2676
+ scheduleRepeatedType: '$checklistData.scheduleRepeatedType',
2677
+ scheduleStartTime: '$checklistData.scheduleStartTime',
2678
+ sourceCheckList_id: '$checklistData._id',
2679
+ storeCount: '$checklistData.storeCount',
2680
+ },
2681
+ },
2682
+ ];
2683
+
2684
+ findQuery.push( { $sort: { checkListName: 1 } } );
2685
+
2686
+ let getChecklistData = await processedchecklistService.aggregate( findQuery );
2687
+
2688
+ if ( !getChecklistData.length ) {
2689
+ return res.sendError( { error: 'No Data Found' }, 204 );
2690
+ }
2691
+ result.totalCount = getChecklistData.length;
2692
+ result.checklistData = getChecklistData;
2693
+ return res.sendSuccess( result );
2694
+ } catch ( error ) {
2695
+ console.log( 'error =>', error );
2696
+ logger.error( { error: error, message: req.query, function: 'checklistDropdown' } );
2697
+ return res.sendError( { error: error }, 500 );
2698
+ }
2699
+ };