tango-app-api-audit 1.0.1 → 1.0.3

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,744 @@
1
+ import { chunkArray, getJsonFileData, getUTC, listFileByPath, listFileWithoutLimit, signedUrl } from 'tango-app-api-middleware';
2
+ import { aggregateUserAudit, createUserAudit } from '../service/userAudit.service.js';
3
+ import { aggregateAssignAudit, updateOneAssignAudit } from '../service/assignAudit.service.js';
4
+ import { findOneUser } from '../service/user.service.js';
5
+ import dayjs from 'dayjs';
6
+ import { aggregateClient } from '../service/client.service.js';
7
+ import { logger } from 'tango-app-api-middleware';
8
+ import { sqsReceive } from 'tango-app-api-middleware/src/utils/aws/sqs.js';
9
+ import { createStoreAudit } from '../service/storeAudit.service.js';
10
+
11
+ export async function getAuditFile( req, res ) {
12
+ try {
13
+ const bucket = JSON.parse( process.env.BUCKET );
14
+ const inputData = req.query;
15
+ const data = await getUTC( new Date(), new Date() );
16
+ const start = data.start;
17
+ const end = data.end;
18
+ const fetchData = {};
19
+ let msg = {};
20
+ const userQuery = [
21
+ {
22
+ $match: {
23
+ $and: [
24
+ { userId: req.user._id },
25
+ { queueName: inputData.queueName },
26
+ { auditStatus: { $nin: [ 'completed', 'skipped' ] } },
27
+ { createdAt: { $gte: start } },
28
+ { createdAt: { $lte: end } },
29
+ ],
30
+
31
+ },
32
+
33
+ },
34
+ {
35
+ $sort: { createdAt: -1 },
36
+ },
37
+ {
38
+ $limit: 1,
39
+ },
40
+ ];
41
+
42
+ const userDetails = await aggregateUserAudit( userQuery );
43
+ const auditStatus = userDetails && userDetails.length > 0 ? userDetails[0].auditStatus : null;
44
+
45
+ switch ( auditStatus ) {
46
+ case null:
47
+ const query = [
48
+ {
49
+ $match: {
50
+ $and: [
51
+ { userId: { $eq: req.user._id } },
52
+ { isCompleted: { $eq: false } },
53
+ { queueName: inputData.queueName },
54
+ ],
55
+ },
56
+ },
57
+ ];
58
+ const userAssign = await aggregateAssignAudit( query );
59
+ if ( userAssign.length > 0 ) {
60
+ logger.info( 'Hit in user assign', { inputData } );
61
+ userAssign[0].fileType == 'Audit' ?
62
+ msg = {
63
+ store_id: userAssign[0].storeId,
64
+ curr_date: userAssign[0].fileDate,
65
+ total_count: userAssign[0].fileCount,
66
+ } : msg = {
67
+ store_id: userAssign[0].storeId,
68
+ curr_date: userAssign[0].fileDate,
69
+ audit_type: userAssign[0].fileType,
70
+ total_count: userAssign[0].fileCount,
71
+ };
72
+ await updateOneAssignAudit( { _id: userAssign[0]._id }, { isCompleted: true } );
73
+ logger.info( 'Hit in auditUserAssignModel updateOne', { _id: userAssign[0]._id, isCompleted: true } );
74
+ } else {
75
+ logger.info( 'Hit in new file', { inputData } );
76
+ const consumer = await sqsReceive( inputData.queueName );
77
+ if ( !consumer ) {
78
+ logger.error( { error: consumer, function: 'getAuditFile', message: 'SQS Receive queue is empty' } );
79
+ return res.sendError( `${inputData.queueName} is Empty`, 204 );
80
+ }
81
+ msg = JSON.parse( consumer );
82
+ }
83
+ break;
84
+
85
+ // case 'drafted':
86
+ // logger.info( 'userDetails drafted', { inputData } );
87
+ // const log = await findOneUser( {
88
+ // userId: userDetails[0].userId,
89
+ // fileDate: userDetails[0].fileDate,
90
+ // storeId: userDetails[0].storeId,
91
+ // totalCount: userDetails[0].beforeCount,
92
+ // }, {}, { createdAt: -1 } );
93
+ // if ( log.length == 0 ) {
94
+ // await audit.updateOne( { _id: userDetails[0]._id }, { $set: { isDraft: false, auditStatus: 'skipped' } } );
95
+ // logger.info( 'audit update in drafted', { _id: userDetails[0]._id, isDraft: false, auditStatus: 'skipped' } );
96
+ // return res.sendError( 'User saved data has been deleted', 204 );
97
+ // }
98
+ // const file = {
99
+ // auditId: userDetails[0]._id,
100
+ // store_id: userDetails[0].storeId,
101
+ // file_date: userDetails[0].fileDate,
102
+ // type: userDetails[0].auditType,
103
+ // queueName: log[0].queueName,
104
+ // userId: log[0].userId,
105
+ // };
106
+ // const result = {
107
+ // junk: log[0].junk,
108
+ // junk_count: log[0].junkCount,
109
+ // employee: log[0].employee,
110
+ // employee_count: log[0].employeeCount,
111
+ // customer: log[0].customer,
112
+ // customer_count: log[0].customerCount,
113
+ // retag_image: log[0].retagImage,
114
+ // retag_count: log[0].retagCount,
115
+ // total_count: log[0].totalCount,
116
+ // };
117
+
118
+ // const userdata = await findOneUser( { _id: log[0].userId } );
119
+ // if ( !inputData.nextId || inputData.nextId === '' || inputData.nextId == null ) {
120
+ // const logData = {
121
+ // userId: log[0].userId,
122
+ // userName: userdata.name,
123
+ // logType: 'audit',
124
+ // logSubType: 'auditStart',
125
+ // logData: {
126
+ // file_date: userDetails[0].fileDate,
127
+ // auditType: userDetails[0].auditType,
128
+ // storeId: userDetails[0].storeId,
129
+ // clientName: log[0].queueName,
130
+ // auditId: userDetails[0]._id ,
131
+ // },
132
+ // };
133
+ // logger.info( { logData: logData } );
134
+ // // await savelogs( logData ); Note : insert to os
135
+ // }
136
+ // return res.sendSuccess( {
137
+ // result: result,
138
+ // count: log[0].totalCount,
139
+ // file: file,
140
+ // isDraft: userDetails[0].isDraft,
141
+ // } );
142
+ // break;
143
+
144
+ default:
145
+ msg = {
146
+ store_id: userDetails[0].storeId,
147
+ curr_date: userDetails[0].fileDate,
148
+ audit_type: userDetails[0].auditType,
149
+ total_count: userDetails[0].beforeCount,
150
+ };
151
+ break;
152
+ }
153
+ if ( msg.audit_type === 'ReAudit' ) {
154
+ logger.info(
155
+ 'Hit in user ReAudit'
156
+ , { inputData },
157
+ );
158
+ let reauditInsert = {};
159
+ const [ filterData, auditImage ] = await Promise.all( [
160
+ getFilterData( msg ),
161
+ getAuditImage( msg ),
162
+ ] );
163
+ if ( filterData.statusCode == 404 || auditImage.statusCode == 404 ) {
164
+ return res.sendError( 'No Data found', 204 );
165
+ }
166
+ const reauditImg = await getReauditImg( filterData, auditImage );
167
+ if ( userDetails.length === 0 ) {
168
+ const [ day, month, year ] = msg.curr_date.split( '-' );
169
+ const temp = `${year}-${month}-${day}`;
170
+ let start = new Date( temp );
171
+ const userTimezoneOffset = start.getTimezoneOffset() * 60000;
172
+ start = new Date( start.getTime() - userTimezoneOffset );
173
+ start.setUTCHours( 0, 0, 0, 0 );
174
+ const record = {
175
+ userId: req.user._id,
176
+ storeId: msg.store_id,
177
+ clientId: msg.store_id.split( '-' )[0],
178
+ auditType: msg.audit_type || 'ReAudit',
179
+ fileDate: msg.curr_date,
180
+ queueName: inputData.queueName,
181
+ beforeCount: reauditImg.length,
182
+ auditStatus: 'inprogress',
183
+ fileDateISO: start,
184
+ timeSpent: 0,
185
+ startTime: new Date(),
186
+ };
187
+ const storeRecord = {
188
+ userId: req.user._id,
189
+ storeId: msg.store_id,
190
+ clientId: msg.store_id.split( '-' )[0],
191
+ auditType: msg.audit_type || 'ReAudit',
192
+ fileDate: msg.curr_date,
193
+ queueName: inputData.queueName,
194
+ beforeCount: reauditImg.length,
195
+ status: 'inprogress',
196
+ fileDateISO: start,
197
+ timeSpent: 0,
198
+ };
199
+ reauditInsert = await createUserAudit( record );
200
+ await createStoreAudit( storeRecord );
201
+ } else {
202
+ reauditInsert = userDetails[0];
203
+ }
204
+ const userdata = await findOneUser( { _id: req.user._id } );
205
+ if ( inputData.nextId ) {
206
+ const logData = {
207
+ userId: req.user._id,
208
+ userName: userdata.name,
209
+ logType: 'audit',
210
+ logSubType: 'auditStart',
211
+ logData: {
212
+ fileDate: msg.curr_date,
213
+ auditType: msg.audit_type,
214
+ storeId: msg.store_id,
215
+ clientName: inputData.queueName,
216
+ auditId: reauditInsert._id,
217
+ },
218
+ };
219
+ logger.info( { logData: logData } );
220
+ // await savelogs( logData ); need to change
221
+ }
222
+
223
+ return res.sendSuccess(
224
+ {
225
+ result: reauditImg,
226
+ count: reauditImg.length,
227
+ file: {
228
+ store_id: msg.store_id,
229
+ file_date: msg.curr_date,
230
+ type: msg.audit_type || 'ReAudit',
231
+ queueName: inputData.queueName,
232
+ auditId: reauditInsert._id,
233
+ userId: reauditInsert.userId,
234
+ },
235
+ isDraft: reauditInsert.isDraft,
236
+ },
237
+ );
238
+ }
239
+ const storeId = msg.store_id;
240
+ const fileDate = msg.curr_date;
241
+ const files = [];
242
+ let insertData = {};
243
+ fetchData.Bucket = bucket.auditInput; // need to change
244
+ fetchData.file_path = `${fileDate}/${storeId}/`;
245
+ if ( inputData.limit ) {
246
+ fetchData.MaxKeys = inputData.limit;
247
+ }
248
+ if ( inputData.nextId ) {
249
+ fetchData.ContinuationToken = decodeURIComponent( inputData.nextId );
250
+ }
251
+ const [ folderPath, nextQuery ] = await listFileByPath( fetchData );
252
+ logger.info( { nextQuery: nextQuery } );
253
+ if ( folderPath?.length > 0 ) {
254
+ for ( let i = 0; i < folderPath.length; i++ ) {
255
+ const img = folderPath[i].Key.split( '/' );
256
+ const image = img[2].split( '.' );
257
+ const indexes = image[0].split( '_' );
258
+ fetchData.file_path = folderPath[i].Key;
259
+ const data = await signedUrl( fetchData );
260
+ const mapimg = {
261
+ img_path: data,
262
+ img_name: indexes[1],
263
+ img_id: image[0],
264
+ };
265
+ files.push( {
266
+ img_path: data,
267
+ img_name: indexes[1],
268
+ img_id: image[0],
269
+ selected: false,
270
+ dropped: false,
271
+ count: 1,
272
+ mappedid: [ mapimg ],
273
+ } );
274
+ }
275
+ if ( userDetails.length === 0 ) {
276
+ const [ day, month, year ] = msg.curr_date.split( '-' );
277
+ const temp = `${year}-${month}-${day}`;
278
+ let start = new Date( temp );
279
+ logger.info( { start: start, date: msg.curr_date } );
280
+ const userTimezoneOffset = start.getTimezoneOffset() * 60000;
281
+ start = new Date( start.getTime() - userTimezoneOffset );
282
+ start.setUTCHours( 0, 0, 0, 0 );
283
+ const record = {
284
+ userId: req.user._id,
285
+ storeId: msg.store_id,
286
+ clientId: msg.store_id.split( '-' )[0],
287
+ auditType: 'Audit',
288
+ fileDate: msg.curr_date,
289
+ queueName: inputData.queueName,
290
+ beforeCount: msg.total_count || files.length,
291
+ auditStatus: 'inprogress',
292
+ fileDateISO: start,
293
+ timeSpent: 0,
294
+ startTime: new Date(),
295
+ };
296
+ const storeRecord = {
297
+ userId: req.user._id,
298
+ storeId: msg.store_id,
299
+ clientId: msg.store_id.split( '-' )[0],
300
+ auditType: 'Audit',
301
+ fileDate: msg.curr_date,
302
+ queueName: inputData.queueName,
303
+ beforeCount: msg.total_count || files.length,
304
+ status: 'inprogress',
305
+ fileDateISO: start,
306
+ timeSpent: 0,
307
+ };
308
+
309
+ insertData = await createUserAudit( record );
310
+ await createStoreAudit( storeRecord );
311
+ } else {
312
+ insertData = userDetails[0];
313
+ }
314
+ } else {
315
+ logger.error( { error: { folderPath: folderPath, nextQuery: nextQuery }, function: 'getAuditFile', message: 'Bucket image data not availale' } );
316
+ return res.sendError( 'Bucket is Empty', 204 );
317
+ }
318
+ const userdata = await findOneUser( { _id: insertData.userId } );
319
+ if ( inputData.nextId ) {
320
+ const logData = {
321
+ userId: insertData.userId,
322
+ userName: userdata.name,
323
+ logType: 'audit',
324
+ logSubType: 'auditStart',
325
+ logData: {
326
+ fileDate: insertData.fileDate,
327
+ auditType: insertData.auditType,
328
+ storeId: storeId,
329
+ clientName: inputData.queueName,
330
+ auditId: insertData._id,
331
+ },
332
+ };
333
+ logger.info( logData );
334
+ // await savelogs( logData );
335
+ }
336
+
337
+ return res.sendSuccess( {
338
+ result: files,
339
+ count: msg.total_count,
340
+ file: {
341
+ queueName: inputData.queueName,
342
+ store_id: storeId,
343
+ file_date: fileDate,
344
+ type: 'Audit',
345
+ auditId: insertData._id,
346
+ userId: insertData.userId,
347
+ nextToken: nextQuery ? encodeURIComponent( nextQuery ) : null,
348
+ },
349
+ isDraft: insertData.isDraft,
350
+ } );
351
+ } catch ( error ) {
352
+ logger.error( { error: error, message: req.query, function: 'getAuditFile' } );
353
+ return res.sendError( error, 500 );
354
+ }
355
+ }
356
+
357
+ export async function getFilterData( msg ) {
358
+ try {
359
+ const bucket = JSON.parse( process.env.BUCKET );
360
+ const params = {
361
+ Bucket: `${bucket.auditOutput}`,
362
+ Key: `${msg.store_id}/${msg.curr_date}/${bucketName.masterJsonFile}`,
363
+ };
364
+ const mappingFile = await getJsonFileData( params );
365
+ if ( mappingFile.statusCode ) {
366
+ return mappingFile;
367
+ } else {
368
+ const mappingData = await JSON.parse( mappingFile.toString( 'utf-8' ) );
369
+ const filterData = await mappingData.person_data.filter( ( item ) => item.temp_ids < 20000 && item.temp_ids > 0 && item.person_status === '' );
370
+ const finalResult = await filterData.map( ( i ) => {
371
+ return { ...i, img: i.index.concat( '_', i.temp_ids ) };
372
+ } );
373
+ return finalResult;
374
+ }
375
+ } catch ( error ) {
376
+ logger.error( { error: error, type: 'MAPPING JSON getFilterData', function: 'getFilterData' } );
377
+ return error;
378
+ }
379
+ };
380
+
381
+ export async function getAuditImage( msg ) {
382
+ try {
383
+ const bucket = JSON.parse( process.env.BUCKET );
384
+ const storeId = msg.store_id;
385
+ const fileDate = msg.curr_date;
386
+ const files = [];
387
+ const fetchData = {};
388
+ fetchData.Bucket = `${bucket.auditInput}`;
389
+ fetchData.filePath = `${fileDate}/${storeId}/`;
390
+ const folderPath = await listFileWithoutLimit( fetchData );
391
+ if ( folderPath.statusCode == 404 ) {
392
+ return folderPath;
393
+ }
394
+ const auditImages = folderPath;
395
+ if ( auditImages && auditImages?.length > 0 ) {
396
+ for ( let i = 0; i < auditImages.length; i++ ) {
397
+ const img = auditImages[i].Key.split( '/' );
398
+ const image = img[2].split( '.' );
399
+ const indexes = image[0].split( '_' );
400
+ const params = {
401
+ file_path: auditImages[i].Key,
402
+ Bucket: fetchData.Bucket,
403
+ };
404
+ const data = await signedUrl( params );
405
+ const mapimg = {
406
+ img_path: data,
407
+ img_name: indexes[1],
408
+ img_id: image[0],
409
+ };
410
+ files.push( {
411
+ img_path: data,
412
+ img_name: indexes[1],
413
+ img_id: image[0],
414
+ selected: false,
415
+ dropped: false,
416
+ count: 1,
417
+ mappedid: [ mapimg ],
418
+ } );
419
+ }
420
+ return files;
421
+ }
422
+ } catch ( error ) {
423
+ logger.error( { error: error, type: 'GCP BUCKET --getAuditImage' } );
424
+ return error;
425
+ }
426
+ };
427
+
428
+ export const getReauditImg = async ( filter, image ) => {
429
+ const chunkedMappingData = await chunkArray( image, 10 );
430
+ const promises = chunkedMappingData.map( async ( chunk ) => {
431
+ return mapFunction( chunk, filter );
432
+ } );
433
+ const mappedArrays = await Promise.all( promises );
434
+ return mappedArrays.flat();
435
+ };
436
+
437
+ export const mapFunction = async ( chunk, filter ) => {
438
+ const temp = [];
439
+ for ( let i = 0; i < chunk.length; i++ ) {
440
+ filter.some( ( item ) => {
441
+ if ( chunk[i].img_name === item.temp_ids ) {
442
+ return temp.push( chunk[i] );
443
+ }
444
+ } );
445
+ }
446
+ return temp;
447
+ };
448
+
449
+ export async function getQueueDetailList( req, res ) {
450
+ try {
451
+ const inputData = req.query;
452
+ const data = await getUTC( new Date(), new Date() );
453
+
454
+ const temp = [];
455
+ const clientQuery = [
456
+ {
457
+ $match: {
458
+ $and: [
459
+ { active: { $in: [ 'active', 'hold' ] } },
460
+ { 'auditConfigs.audit': { $eq: true } },
461
+ ],
462
+ },
463
+ },
464
+ {
465
+ $project: {
466
+ clientName: '$clientName',
467
+ clientId: '$clientId',
468
+ },
469
+ },
470
+ ];
471
+
472
+ if ( inputData.searchValue ) {
473
+ clientQuery.push( {
474
+ $match: {
475
+ $or: [
476
+ { clientName: { $regex: inputData.searchValue, $options: 'i' } },
477
+ { clientId: { $regex: inputData.searchValue, $options: 'i' } },
478
+ ],
479
+ },
480
+ } );
481
+ }
482
+ const count = await aggregateClient( clientQuery );
483
+ if ( inputData.limit && inputData.offset && !inputData.export ) {
484
+ const skip = ( inputData.offset - 1 ) * inputData.limit;
485
+ clientQuery.push( { $skip: skip }, { $limit: inputData.limit } );
486
+ }
487
+
488
+ const clientDetails = await aggregateClient( clientQuery );
489
+ if ( clientDetails && clientDetails.length === 0 ) {
490
+ return res.sendError( 'No Data Found', 204 );
491
+ }
492
+
493
+ const clientList = clientDetails.map( ( i ) => i.clientId );
494
+ const query = [
495
+ {
496
+ $match: {
497
+ clientId: { $in: clientList },
498
+ },
499
+ },
500
+ {
501
+ $group: {
502
+ _id: '$clientId',
503
+ clientId: { $last: '$clientId' },
504
+ totalFilesCount: { $last: '$totalFilesCount' },
505
+ clientName: { $last: '$clientName' },
506
+ queueName: { $last: '$queueName' },
507
+
508
+ },
509
+ },
510
+ {
511
+ $project: {
512
+ clientId: 1,
513
+ totalFilesCount: 1,
514
+ clientName: 1,
515
+ queueName: 1,
516
+ },
517
+ },
518
+ ];
519
+
520
+ const fileDate = dayjs( data.start ).subtract( 1, 'days' );
521
+
522
+ const completedFiles = [
523
+ {
524
+ $match: {
525
+ $and: [
526
+ { clientId: { $in: clientList } },
527
+ { fileDateISO: { $eq: new Date( fileDate ) } },
528
+ ],
529
+ },
530
+ },
531
+ {
532
+ $project: {
533
+ clientId: 1,
534
+ completed: {
535
+ $cond: [ { $eq: [ '$storeStatus', 'completed' ] }, 1, 0 ],
536
+ },
537
+ },
538
+ },
539
+ {
540
+ $group: {
541
+ _id: { clientId: '$clientId', storeId: '$storeId' },
542
+ clientId: { $first: '$clientId' },
543
+ completedCount: { $sum: '$completed' },
544
+
545
+ },
546
+ },
547
+ {
548
+ $group: {
549
+ _id: '$clientId',
550
+ clientId: { $first: '$clientId' },
551
+ completedCount: { $first: '$completedCount' },
552
+ },
553
+ },
554
+ ];
555
+
556
+ const auditFiles = [
557
+ {
558
+ $match: {
559
+ $and: [
560
+ { clientId: { $in: clientList } },
561
+ { createdAt: { $gte: data.start } },
562
+ { createdAt: { $lte: data.end } },
563
+ ],
564
+ },
565
+ },
566
+ {
567
+ $project: {
568
+ clientId: 1,
569
+ pending: {
570
+ $cond: [ { $or: [ { $in: [ '$auditStatus', [ 'inprogress', 'drafted' ] ] }, { $in: [ '$storeStatus', [ 'skipped' ] ] } ] }, 1, 0 ],
571
+ },
572
+ },
573
+ },
574
+ {
575
+ $group: {
576
+ _id: { clientId: '$clientId', storeId: '$storeId' },
577
+ clientId: { $first: '$clientId' },
578
+ pendingCount: { $sum: '$pending' },
579
+ totalCount: { $sum: 1 },
580
+
581
+ },
582
+ },
583
+ {
584
+ $group: {
585
+ _id: '$clientId',
586
+ clientId: { $first: '$clientId' },
587
+ pendingCount: { $first: { $ifNull: [ '$pendingCount', 0 ] } },
588
+ totalCount: { $first: '$totalCount' },
589
+ },
590
+ },
591
+
592
+ ];
593
+
594
+ const draftedFiles = [
595
+ {
596
+ $match: {
597
+ $and: [
598
+ { clientId: { $in: clientList } },
599
+ { userId: { $eq: inputData.userId } },
600
+ { createdAt: { $gte: data.start } },
601
+ { createdAt: { $lte: data.end } },
602
+ ],
603
+ },
604
+ },
605
+ {
606
+ $sort: {
607
+ updatedAt: -1,
608
+ },
609
+ },
610
+ {
611
+ $project: {
612
+ clientId: 1,
613
+ isDraft: 1,
614
+ draft: {
615
+ $cond: [ { $eq: [ '$auditStatus', 'drafted' ] }, 1, 0 ],
616
+ },
617
+ inprogress: {
618
+ $cond: [ { $eq: [ '$auditStatus', 'inprogress' ] }, 1, 0 ],
619
+ },
620
+ },
621
+ },
622
+ {
623
+ $group: {
624
+ _id: '$clientId',
625
+ clientId: { $first: '$clientId' },
626
+ isDrafted: { $first: '$isDraft' },
627
+ draftCount: { $sum: '$draft' },
628
+ inprogressCount: { $sum: '$inprogress' },
629
+ },
630
+ },
631
+ ];
632
+
633
+ const userAsign = [
634
+ {
635
+ $match: {
636
+ $and: [
637
+ { userId: { $eq: req.user._id } },
638
+ { isCompleted: false },
639
+ { clientId: { $in: clientList } },
640
+ ],
641
+ },
642
+
643
+ },
644
+ {
645
+ $group: {
646
+ _id: '$clientId',
647
+ clientId: { $first: '$clientId' },
648
+ asignedCount: { $sum: 1 },
649
+ },
650
+ },
651
+ {
652
+ $project: {
653
+ _id: 0,
654
+ clientId: 1,
655
+ asignedCount: 1,
656
+ },
657
+ },
658
+ ];
659
+
660
+ const clientAssign = [
661
+ {
662
+ $match: {
663
+ $and: [
664
+
665
+ { isCompleted: false },
666
+ { clientId: { $in: clientList } },
667
+ ],
668
+ },
669
+
670
+ },
671
+ {
672
+ $group: {
673
+ _id: '$clientId',
674
+ clientId: { $first: '$clientId' },
675
+ ClientAsignedCount: { $sum: 1 },
676
+ },
677
+ },
678
+ {
679
+ $project: {
680
+ _id: 0,
681
+ clientId: 1,
682
+ ClientAsignedCount: { $ifNull: [ '$ClientAsignedCount', 0 ] },
683
+ },
684
+ },
685
+ ];
686
+
687
+ const auditDetails = await AuditFilesModel.aggregate( query );
688
+ const auditCount = await audit.aggregate( auditFiles );
689
+ const draftedCount = await audit.aggregate( draftedFiles );
690
+ const CompletedCount = await audit.aggregate( completedFiles );
691
+
692
+ const clientAssignresult = await auditUserAssignModel.aggregate( clientAssign );
693
+
694
+ const userAsignCount = await auditUserAssignModel.aggregate( userAsign );
695
+ const mergeAll = _.merge( _.keyBy( clientDetails, 'clientId' ), _.keyBy( auditCount, 'clientId' ), _.keyBy( draftedCount, 'clientId' ), _.keyBy( clientAssignresult, 'clientId' ) );
696
+ const finalResult = _.values( mergeAll );
697
+ const merge = _.values( _.merge( _.keyBy( finalResult, 'clientId' ), _.keyBy( auditDetails, 'clientId' ), _.keyBy( userAsignCount, 'clientId' ), _.keyBy( CompletedCount, 'clientId' ) ) );
698
+
699
+ let totalStores = 0;
700
+ for ( let i = 0; i < merge.length; i++ ) {
701
+ totalStores = totalStores + merge[i].totalFilesCount;
702
+
703
+ const pending = await listQueue( merge[i].queueName );
704
+ if ( !pending.statusCode ) {
705
+ temp.push( {
706
+ client_id: merge[i].clientId,
707
+ client_name: merge[i].clientName,
708
+ completedCount: merge[i].completedCount ? Number( merge[i].completedCount ) : 0,
709
+ pendingByQueue: Number( pending ),
710
+ pendingByUser: ( merge[i].pendingCount >= 0 ) ? Number( merge[i].pendingCount )+( merge[i].ClientAsignedCount ? Number( merge[i].ClientAsignedCount ) : 0 ) : 0,
711
+ totalCount: merge[i].totalFilesCount,
712
+ queue_name: merge[i].queueName,
713
+ isDraft: merge[i].isDrafted ? merge[i].isDrafted : false,
714
+ isEnable: Number( pending ) > 0 || merge[i].isDrafted || ( merge[i].asignedCount && merge[i].asignedCount > 0 ) || ( merge[i].inprogressCount && merge[i].inprogressCount > 0 ) ? true : false,
715
+ completedRatio: merge[i].totalFilesCount ? merge[i].completedCount ? Math.round( ( Number( merge[i].completedCount ) / Number( merge[i].totalFilesCount ) ) * 100 ) : 0 : 0,
716
+ isAssigned: merge[i].asignedCount && merge[i].asignedCount > 0 ? true : false,
717
+ Assignedcount: merge[i].asignedCount && merge[i].asignedCount > 0 ? merge[i].asignedCount : 0,
718
+ } );
719
+ }
720
+ }
721
+
722
+ if ( inputData.export == 'true' ) {
723
+ const exportdata = [];
724
+ temp.forEach( ( element ) => {
725
+ exportdata.push( {
726
+ 'Client Name': element.client_name,
727
+ 'Client Id': element.client_id,
728
+ 'Completed Percentage': element.completedRatio + ' %',
729
+ 'Pending Queue': element.pendingByQueue,
730
+ 'Pending User': element.pendingByUser,
731
+ 'Completed': element.completedCount,
732
+ 'Draft': element.isDraft ? 1 : 0,
733
+ 'Assigned': element.Assignedcount,
734
+ } );
735
+ } );
736
+ await download( exportdata, res );
737
+ return;
738
+ } else {
739
+ return res.sendSuccess( { result: temp, count: count.length, totalStores: totalStores } );
740
+ }
741
+ } catch ( error ) {
742
+ return res.sendError( error );
743
+ }
744
+ }