tango-app-api-audit 3.4.0-alpha.0 → 3.4.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +3 -1
- package/package.json +2 -2
- package/src/controllers/traxAudit.controllers.js +750 -5
- package/src/docs/traxAudit.docs.js +69 -1
- package/src/dtos/traxAudit.dtos.js +29 -11
- package/src/routes/traxAudit.routes.js +17 -6
- package/src/service/binaryAudit.service.js +9 -1
- package/src/service/storeEmpDetection.service.js +6 -0
- package/src/service/traxAuditData.service.js +10 -0
- package/src/service/userEmpDetection.service.js +9 -1
- package/src/validation/traxAuditValidation.js +39 -0
package/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
3
|
import { auditRouter } from './src/routes/audit.routes.js';
|
|
4
|
+
import { traxAuditRouter } from './src/routes/traxAudit.routes.js';
|
|
4
5
|
import { auditDocs } from './src/docs/audit.docs.js';
|
|
6
|
+
import { traxAuditDocs } from './src/docs/traxAudit.docs.js';
|
|
5
7
|
|
|
6
|
-
export { auditRouter, auditDocs };
|
|
8
|
+
export { auditRouter, auditDocs, traxAuditRouter, traxAuditDocs };
|
|
7
9
|
|
|
8
10
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-audit",
|
|
3
|
-
"version": "3.4.0-alpha.
|
|
3
|
+
"version": "3.4.0-alpha.2",
|
|
4
4
|
"description": "audit & audit metrics apis",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"mongodb": "^6.7.0",
|
|
25
25
|
"nodemon": "^3.1.3",
|
|
26
26
|
"swagger-ui-express": "^5.0.1",
|
|
27
|
-
"tango-api-schema": "^2.1.
|
|
27
|
+
"tango-api-schema": "^2.1.6",
|
|
28
28
|
"tango-app-api-middleware": "^3.1.33",
|
|
29
29
|
"winston": "^3.13.0",
|
|
30
30
|
"winston-daily-rotate-file": "^5.0.0"
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import { checkFileExist, getDate, insertOpenSearchData, listFileByPath, logger, signedUrl, sqsReceive } from 'tango-app-api-middleware';
|
|
2
|
-
import {
|
|
1
|
+
import { checkFileExist, download, getDate, getDateWithCustomizeTime, getUTC, insertOpenSearchData, listFileByPath, logger, signedUrl, sqsReceive } from 'tango-app-api-middleware';
|
|
2
|
+
import { aggregateBinaryAudit, createBinaryAudit, updateOneBinaryAuditModel } from '../service/binaryAudit.service.js';
|
|
3
3
|
import { findOneStore } from '../service/store.service.js';
|
|
4
4
|
import { findOneUser } from '../service/user.service.js';
|
|
5
|
+
import { aggregateUserEmpDetection, createUserEmpDetection } from '../service/userEmpDetection.service.js';
|
|
6
|
+
import { aggregateTraxAuditData, findOneTraxAuditData } from '../service/traxAuditData.service.js';
|
|
7
|
+
import { aggregateClient } from '../service/client.service.js';
|
|
8
|
+
import dayjs from 'dayjs';
|
|
9
|
+
import { aggregateAssignAudit } from '../service/assignAudit.service.js';
|
|
10
|
+
import { aggregateStoreEmpDetection } from '../service/storeEmpDetection.service.js';
|
|
11
|
+
import { listQueue } from 'tango-app-api-middleware/src/utils/aws/sqs.js';
|
|
12
|
+
import _ from 'lodash';
|
|
5
13
|
|
|
6
14
|
|
|
7
15
|
export async function getDetectionAuditFile( req, res ) {
|
|
@@ -37,7 +45,7 @@ export async function getDetectionAuditFile( req, res ) {
|
|
|
37
45
|
},
|
|
38
46
|
];
|
|
39
47
|
|
|
40
|
-
const userDetails = await
|
|
48
|
+
const userDetails = await aggregateUserEmpDetection( userQuery );
|
|
41
49
|
logger.info( { userDetails: userDetails, function: 'userDetails' } );
|
|
42
50
|
const auditStatus =
|
|
43
51
|
userDetails && userDetails.length > 0 ? userDetails[0].auditStatus : null;
|
|
@@ -380,7 +388,7 @@ export async function getDetectionAuditFile( req, res ) {
|
|
|
380
388
|
moduleType: inputData.moduleType,
|
|
381
389
|
};
|
|
382
390
|
|
|
383
|
-
insertData = await
|
|
391
|
+
insertData = await createUserEmpDetection( record );
|
|
384
392
|
await updateManyStoreAudit( query, storeRecord );
|
|
385
393
|
} else {
|
|
386
394
|
insertData = userDetails[0];
|
|
@@ -451,6 +459,403 @@ export async function getDetectionAuditFile( req, res ) {
|
|
|
451
459
|
}
|
|
452
460
|
}
|
|
453
461
|
|
|
462
|
+
export async function workSpace( req, res ) {
|
|
463
|
+
try {
|
|
464
|
+
const inputData = req.body;
|
|
465
|
+
const limit = inputData.limit || 10;
|
|
466
|
+
const offset = inputData.offset ?
|
|
467
|
+
( inputData.offset - 1 ) * limit :
|
|
468
|
+
0;
|
|
469
|
+
const dateRange = await getDate( new Date(), new Date() );
|
|
470
|
+
const filter =[
|
|
471
|
+
{ status: { $in: [ 'active', 'hold' ] } },
|
|
472
|
+
{ 'auditConfigs.audit': { $eq: true } },
|
|
473
|
+
];
|
|
474
|
+
if ( inputData?.clientId?.length > 0 ) {
|
|
475
|
+
filter.push( { clientId: { $in: inputData.clientId } } );
|
|
476
|
+
}
|
|
477
|
+
const temp = [];
|
|
478
|
+
const clientQuery = [
|
|
479
|
+
{
|
|
480
|
+
$match: {
|
|
481
|
+
$and: filter,
|
|
482
|
+
},
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
$project: {
|
|
486
|
+
clientName: 1,
|
|
487
|
+
clientId: 1,
|
|
488
|
+
queueName: {
|
|
489
|
+
$cond: [
|
|
490
|
+
{ $eq: [ inputData.moduleType, 'unattended-customer' ] }, '$auditConfigs.traxQueueName.unattendedCustomer',
|
|
491
|
+
{ $cond: [
|
|
492
|
+
{ $eq: [ inputData.moduleType, 'left-in-middle' ] }, '$auditConfigs.traxQueueName.leftInMiddle',
|
|
493
|
+
{
|
|
494
|
+
$cond: [
|
|
495
|
+
{ $eq: [ inputData.moduleType, 'uniform-detection' ] }, '$auditConfigs.traxQueueName.uniformDetection',
|
|
496
|
+
{
|
|
497
|
+
$cond: [
|
|
498
|
+
{ $eq: [ inputData.moduleType, 'mobile-detection' ] }, '$auditConfigs.traxQueueName.mobileDetection', '$auditConfigs.traxQueueName.cameraAngleChange',
|
|
499
|
+
],
|
|
500
|
+
},
|
|
501
|
+
],
|
|
502
|
+
},
|
|
503
|
+
],
|
|
504
|
+
},
|
|
505
|
+
],
|
|
506
|
+
},
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
];
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
if ( inputData.searchValue && inputData.searchValue !== '' ) {
|
|
513
|
+
clientQuery.push( {
|
|
514
|
+
$match: {
|
|
515
|
+
$or: [
|
|
516
|
+
{ clientName: { $regex: inputData.searchValue, $options: 'i' } },
|
|
517
|
+
{ clientId: { $regex: inputData.searchValue, $options: 'i' } },
|
|
518
|
+
],
|
|
519
|
+
},
|
|
520
|
+
} );
|
|
521
|
+
}
|
|
522
|
+
if ( inputData.sortColumnName ) {
|
|
523
|
+
const sortBy = inputData.sortBy || -1;
|
|
524
|
+
const sortColumn = inputData.sortColumnName;
|
|
525
|
+
clientQuery.push( {
|
|
526
|
+
$sort: { [sortColumn]: sortBy },
|
|
527
|
+
},
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
const count = await aggregateClient( clientQuery );
|
|
532
|
+
if ( count?.length == 0 ) {
|
|
533
|
+
return res.sendError( 'No Data Found', 204 );
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
if ( !inputData.isExport ) {
|
|
537
|
+
clientQuery.push( { $skip: offset }, { $limit: limit } );
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
const clientDetails = await aggregateClient( clientQuery );
|
|
541
|
+
const clientList = clientDetails.map( ( i ) => i.clientId );
|
|
542
|
+
const fileDate = dayjs( dateRange.start ).subtract( 1, 'days' );
|
|
543
|
+
const getStoreData = await findOneTraxAuditData(
|
|
544
|
+
{},
|
|
545
|
+
{ fileDate: 1 },
|
|
546
|
+
{ createdAt: -1 },
|
|
547
|
+
);
|
|
548
|
+
const latestDate = getStoreData?.fileDate || dayjs( fileDate ).format( 'DD-MM-YYYY' );
|
|
549
|
+
const auditStoreDataQuery = [
|
|
550
|
+
{
|
|
551
|
+
$match: {
|
|
552
|
+
clientId: { $in: clientList },
|
|
553
|
+
moduleType: { $eq: inputData.moduleType },
|
|
554
|
+
fileDate: { $eq: latestDate },
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
$group: {
|
|
559
|
+
_id: '$clientId',
|
|
560
|
+
clientId: { $last: '$clientId' },
|
|
561
|
+
clientName: { $last: '$clientName' },
|
|
562
|
+
installedStore: { $last: '$installedStore' },
|
|
563
|
+
// queueName: { $last: '$queueName' },
|
|
564
|
+
totalCount: { $sum: 1 },
|
|
565
|
+
},
|
|
566
|
+
},
|
|
567
|
+
{
|
|
568
|
+
$project: {
|
|
569
|
+
_id: 0,
|
|
570
|
+
clientId: 1,
|
|
571
|
+
clientName: 1,
|
|
572
|
+
installedStore: 1,
|
|
573
|
+
queueName: 1,
|
|
574
|
+
totalCount: 1,
|
|
575
|
+
},
|
|
576
|
+
},
|
|
577
|
+
];
|
|
578
|
+
|
|
579
|
+
const completedStores = [
|
|
580
|
+
{
|
|
581
|
+
$match: {
|
|
582
|
+
$and: [
|
|
583
|
+
{ clientId: { $in: clientList } },
|
|
584
|
+
{ fileDate: { $eq: latestDate } },
|
|
585
|
+
{ moduleType: { $eq: inputData.moduleType } },
|
|
586
|
+
],
|
|
587
|
+
},
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
$project: {
|
|
591
|
+
clientId: 1,
|
|
592
|
+
completed: {
|
|
593
|
+
$cond: [ { $eq: [ '$status', 'completed' ] }, 1, 0 ],
|
|
594
|
+
},
|
|
595
|
+
},
|
|
596
|
+
},
|
|
597
|
+
// {
|
|
598
|
+
// $group: {
|
|
599
|
+
// _id: { clientId: '$clientId', storeId: '$storeId' },
|
|
600
|
+
// clientId: { $first: '$clientId' },
|
|
601
|
+
// completedStoresCount: { $sum: '$completed' },
|
|
602
|
+
// },
|
|
603
|
+
// },
|
|
604
|
+
{
|
|
605
|
+
$group: {
|
|
606
|
+
_id: '$clientId',
|
|
607
|
+
clientId: { $first: '$clientId' },
|
|
608
|
+
// completedStoresCount: { $first: '$completedStoresCount' },
|
|
609
|
+
completedStoresCount: { $sum: '$completed' },
|
|
610
|
+
},
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
$project: {
|
|
614
|
+
_id: 0,
|
|
615
|
+
clientId: 1,
|
|
616
|
+
completedStoresCount: 1,
|
|
617
|
+
},
|
|
618
|
+
},
|
|
619
|
+
];
|
|
620
|
+
|
|
621
|
+
const auditFiles = [
|
|
622
|
+
{
|
|
623
|
+
$match: {
|
|
624
|
+
$and: [
|
|
625
|
+
{ clientId: { $in: clientList } },
|
|
626
|
+
{ createdAt: { $gte: dateRange.start } },
|
|
627
|
+
{ createdAt: { $lte: dateRange.end } },
|
|
628
|
+
{ moduleType: { $eq: inputData.moduleType } },
|
|
629
|
+
],
|
|
630
|
+
},
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
$project: {
|
|
634
|
+
clientId: 1,
|
|
635
|
+
pending: {
|
|
636
|
+
$cond: [
|
|
637
|
+
{ $or: [ { $in: [ '$auditStatus', [ 'inprogress', 'drafted' ] ] } ] },
|
|
638
|
+
1,
|
|
639
|
+
0,
|
|
640
|
+
],
|
|
641
|
+
},
|
|
642
|
+
},
|
|
643
|
+
},
|
|
644
|
+
{
|
|
645
|
+
$group: {
|
|
646
|
+
_id: { clientId: '$clientId', storeId: '$storeId' },
|
|
647
|
+
clientId: { $first: '$clientId' },
|
|
648
|
+
pendingCount: { $sum: '$pending' },
|
|
649
|
+
totalFilesCount: { $sum: 1 },
|
|
650
|
+
},
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
$group: {
|
|
654
|
+
_id: '$clientId',
|
|
655
|
+
clientId: { $first: '$clientId' },
|
|
656
|
+
pendingCount: { $first: { $ifNull: [ '$pendingCount', 0 ] } },
|
|
657
|
+
totalFilesCount: { $first: '$totalFilesCount' },
|
|
658
|
+
},
|
|
659
|
+
},
|
|
660
|
+
];
|
|
661
|
+
const userIncompleteFiles = [
|
|
662
|
+
{
|
|
663
|
+
$match: {
|
|
664
|
+
$and: [
|
|
665
|
+
{ clientId: { $in: clientList } },
|
|
666
|
+
{ userId: { $eq: req.user._id } },
|
|
667
|
+
{ moduleType: { $eq: inputData.moduleType } },
|
|
668
|
+
{ createdAt: { $gte: dateRange.start } },
|
|
669
|
+
{ createdAt: { $lte: dateRange.end } },
|
|
670
|
+
],
|
|
671
|
+
},
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
$sort: {
|
|
675
|
+
updatedAt: -1,
|
|
676
|
+
},
|
|
677
|
+
},
|
|
678
|
+
{
|
|
679
|
+
$project: {
|
|
680
|
+
clientId: 1,
|
|
681
|
+
isDraft: 1,
|
|
682
|
+
draft: {
|
|
683
|
+
$cond: [ { $eq: [ '$auditStatus', 'drafted' ] }, 1, 0 ],
|
|
684
|
+
},
|
|
685
|
+
inprogress: {
|
|
686
|
+
$cond: [ { $eq: [ '$auditStatus', 'inprogress' ] }, 1, 0 ],
|
|
687
|
+
},
|
|
688
|
+
},
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
$group: {
|
|
692
|
+
_id: '$clientId',
|
|
693
|
+
clientId: { $first: '$clientId' },
|
|
694
|
+
isDrafted: { $first: '$isDraft' },
|
|
695
|
+
userDraftCount: { $sum: '$draft' },
|
|
696
|
+
userInprogressCount: { $sum: '$inprogress' },
|
|
697
|
+
},
|
|
698
|
+
},
|
|
699
|
+
];
|
|
700
|
+
|
|
701
|
+
const userAsignAudit = [
|
|
702
|
+
{
|
|
703
|
+
$match: {
|
|
704
|
+
$and: [
|
|
705
|
+
{ userId: { $eq: req.user._id } },
|
|
706
|
+
{ isCompleted: false },
|
|
707
|
+
{ clientId: { $in: clientList } },
|
|
708
|
+
{ moduleType: { $eq: inputData.moduleType } },
|
|
709
|
+
],
|
|
710
|
+
},
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
$group: {
|
|
714
|
+
_id: '$clientId',
|
|
715
|
+
clientId: { $first: '$clientId' },
|
|
716
|
+
userAsignedCount: { $sum: 1 },
|
|
717
|
+
},
|
|
718
|
+
},
|
|
719
|
+
{
|
|
720
|
+
$project: {
|
|
721
|
+
_id: 0,
|
|
722
|
+
clientId: 1,
|
|
723
|
+
userAsignedCount: 1,
|
|
724
|
+
},
|
|
725
|
+
},
|
|
726
|
+
];
|
|
727
|
+
|
|
728
|
+
const clientAssign = [
|
|
729
|
+
{
|
|
730
|
+
$match: {
|
|
731
|
+
$and: [ { isCompleted: false },
|
|
732
|
+
{ clientId: { $in: clientList } },
|
|
733
|
+
{ moduleType: { $eq: inputData.moduleType } },
|
|
734
|
+
],
|
|
735
|
+
},
|
|
736
|
+
},
|
|
737
|
+
{
|
|
738
|
+
$group: {
|
|
739
|
+
_id: '$clientId',
|
|
740
|
+
clientId: { $first: '$clientId' },
|
|
741
|
+
clientAsignedCount: { $sum: 1 },
|
|
742
|
+
},
|
|
743
|
+
},
|
|
744
|
+
{
|
|
745
|
+
$project: {
|
|
746
|
+
_id: 0,
|
|
747
|
+
clientId: 1,
|
|
748
|
+
clientAsignedCount: { $ifNull: [ '$clientAsignedCount', 0 ] },
|
|
749
|
+
},
|
|
750
|
+
},
|
|
751
|
+
];
|
|
752
|
+
|
|
753
|
+
const auditUserCount = inputData.moduleType.includes( [ 'uniform-detection', 'mobile-detection' ] )?await aggregateUserEmpDetection( auditFiles ) : await aggregateBinaryAudit( auditFiles );
|
|
754
|
+
const userIncompleteFilesCount = inputData.moduleType.includes( [ 'uniform-detection', 'mobile-detection' ] )?await aggregateUserEmpDetection( userIncompleteFiles ) : await aggregateBinaryAudit( userIncompleteFiles );
|
|
755
|
+
const userAsignAuditCount = await aggregateAssignAudit( userAsignAudit );
|
|
756
|
+
const completedStoresCount = inputData.moduleType.includes( [ 'uniform-detection', 'mobile-detection' ] )? await aggregateStoreEmpDetection( completedStores ) : await aggregateBinaryAudit( completedStores );
|
|
757
|
+
const clientAssignedCount = await aggregateAssignAudit( clientAssign );
|
|
758
|
+
const auditStoreData = await aggregateTraxAuditData(
|
|
759
|
+
auditStoreDataQuery,
|
|
760
|
+
);
|
|
761
|
+
|
|
762
|
+
const mergeAll = _.merge(
|
|
763
|
+
_.keyBy( clientDetails, 'clientId' ),
|
|
764
|
+
_.keyBy( auditUserCount, 'clientId' ),
|
|
765
|
+
_.keyBy( userIncompleteFilesCount, 'clientId' ),
|
|
766
|
+
_.keyBy( clientAssignedCount, 'clientId' ),
|
|
767
|
+
);
|
|
768
|
+
const finalResult = _.values( mergeAll );
|
|
769
|
+
const merge = _.values(
|
|
770
|
+
_.merge(
|
|
771
|
+
_.keyBy( finalResult, 'clientId' ),
|
|
772
|
+
_.keyBy( auditStoreData, 'clientId' ),
|
|
773
|
+
_.keyBy( userAsignAuditCount, 'clientId' ),
|
|
774
|
+
_.keyBy( completedStoresCount, 'clientId' ),
|
|
775
|
+
),
|
|
776
|
+
);
|
|
777
|
+
let totalStores = 0;
|
|
778
|
+
for ( let i = 0; i < merge.length; i++ ) {
|
|
779
|
+
totalStores = merge[i]?.totalCount || 0;
|
|
780
|
+
|
|
781
|
+
const pending = await listQueue( merge[i].queueName );
|
|
782
|
+
|
|
783
|
+
if ( !pending.statusCode ) {
|
|
784
|
+
temp.push( {
|
|
785
|
+
clientId: merge[i].clientId,
|
|
786
|
+
clientName: merge[i].clientName,
|
|
787
|
+
completedStoresCount: merge[i].completedStoresCount ?
|
|
788
|
+
Number( merge[i].completedStoresCount ) :
|
|
789
|
+
0,
|
|
790
|
+
pendingByQueue: Number( pending ),
|
|
791
|
+
pendingByUser:
|
|
792
|
+
merge[i].pendingCount >= 0 ?
|
|
793
|
+
Number( merge[i].pendingCount ) +
|
|
794
|
+
( merge[i].clientAsignedCount ?
|
|
795
|
+
Number( merge[i].clientAsignedCount ) :
|
|
796
|
+
0 ) :
|
|
797
|
+
0,
|
|
798
|
+
totalCount: merge[i].totalCount,
|
|
799
|
+
queueName: merge[i].queueName,
|
|
800
|
+
isDraft: merge[i]?.isDrafted || false,
|
|
801
|
+
isEnable:
|
|
802
|
+
Number( pending ) > 0 ||
|
|
803
|
+
merge[i].isDrafted ||
|
|
804
|
+
( merge[i].userAsignedCount && merge[i].userAsignedCount > 0 ) ||
|
|
805
|
+
( merge[i].userInprogressCount && merge[i].userInprogressCount > 0 ) ?
|
|
806
|
+
1 :
|
|
807
|
+
0,
|
|
808
|
+
completedRatio: merge[i].totalCount ?
|
|
809
|
+
merge[i].completedStoresCount ?
|
|
810
|
+
Math.round(
|
|
811
|
+
( Number( merge[i].completedStoresCount ) /
|
|
812
|
+
Number( merge[i].totalCount ) ) *
|
|
813
|
+
100,
|
|
814
|
+
) :
|
|
815
|
+
0 :
|
|
816
|
+
0,
|
|
817
|
+
isAssigned:
|
|
818
|
+
merge[i].userAsignedCount && merge[i].userAsignedCount > 0 ?
|
|
819
|
+
true :
|
|
820
|
+
false,
|
|
821
|
+
Assignedcount:
|
|
822
|
+
merge[i].userAsignedCount && merge[i].userAsignedCount > 0 ?
|
|
823
|
+
merge[i].userAsignedCount :
|
|
824
|
+
0,
|
|
825
|
+
} );
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
if ( inputData.isExport ) {
|
|
830
|
+
const exportdata = [];
|
|
831
|
+
temp.forEach( ( element ) => {
|
|
832
|
+
exportdata.push( {
|
|
833
|
+
'Client Name': element.clientName,
|
|
834
|
+
'Client Id': element.clientId,
|
|
835
|
+
'Completed stores Count': element.completedStoresCount,
|
|
836
|
+
'Completed Percentage': element.completedRatio + ' %',
|
|
837
|
+
'Pending Queue': element.pendingByQueue,
|
|
838
|
+
'Pending User': element.pendingByUser,
|
|
839
|
+
'Draft': element.isDraft ? 1 : 0,
|
|
840
|
+
'Assigned': element.Assignedcount,
|
|
841
|
+
} );
|
|
842
|
+
} );
|
|
843
|
+
await download( exportdata, res );
|
|
844
|
+
return;
|
|
845
|
+
} else {
|
|
846
|
+
return res.sendSuccess( {
|
|
847
|
+
result: temp,
|
|
848
|
+
count: count.length,
|
|
849
|
+
totalStores: totalStores,
|
|
850
|
+
} );
|
|
851
|
+
}
|
|
852
|
+
} catch ( error ) {
|
|
853
|
+
const err = error.message || 'Internal Server Error';
|
|
854
|
+
logger.info( { error: error, message: req.query, function: 'workSpace' } );
|
|
855
|
+
return res.sendError( err, 500 );
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
454
859
|
export async function getAuditFile( req, res ) {
|
|
455
860
|
try {
|
|
456
861
|
const inputData = req.query;
|
|
@@ -480,7 +885,7 @@ export async function getAuditFile( req, res ) {
|
|
|
480
885
|
},
|
|
481
886
|
];
|
|
482
887
|
|
|
483
|
-
const userDetails = await
|
|
888
|
+
const userDetails = await aggregateBinaryAudit( userQuery );
|
|
484
889
|
logger.info( { userDetails: userDetails, function: 'userDetails' } );
|
|
485
890
|
const auditStatus = userDetails && userDetails.length > 0 ? userDetails[0].auditStatus : null;
|
|
486
891
|
|
|
@@ -728,6 +1133,7 @@ export async function getAuditFile( req, res ) {
|
|
|
728
1133
|
question: msg.question,
|
|
729
1134
|
questionType: msg.questionType,
|
|
730
1135
|
streamName: msg.streamName,
|
|
1136
|
+
auditId: insertData._id,
|
|
731
1137
|
} );
|
|
732
1138
|
} catch ( error ) {
|
|
733
1139
|
const err = error.message || 'Internal Server Error';
|
|
@@ -735,3 +1141,342 @@ export async function getAuditFile( req, res ) {
|
|
|
735
1141
|
return res.sendError( err, 500 );
|
|
736
1142
|
}
|
|
737
1143
|
}
|
|
1144
|
+
|
|
1145
|
+
export async function saveBinary( req, res ) {
|
|
1146
|
+
try {
|
|
1147
|
+
const inputData = req.body;
|
|
1148
|
+
|
|
1149
|
+
switch ( inputData.moduleType ) {
|
|
1150
|
+
case 'unattended-customer':
|
|
1151
|
+
let unattendedquery ={
|
|
1152
|
+
_id: inputData.auditId,
|
|
1153
|
+
storeId: inputData.storeId,
|
|
1154
|
+
fileDate: inputData.fileDate,
|
|
1155
|
+
tempId: inputData.tempId,
|
|
1156
|
+
moduleType: inputData.moduleType,
|
|
1157
|
+
};
|
|
1158
|
+
|
|
1159
|
+
let update={
|
|
1160
|
+
auditStatus: 'completed',
|
|
1161
|
+
answer: inputData.answer,
|
|
1162
|
+
};
|
|
1163
|
+
let updatDataunattended= await updateOneBinaryAuditModel( unattendedquery, update );
|
|
1164
|
+
if ( updatDataunattended.modifiedCount==0 ) {
|
|
1165
|
+
return res.sendError( updatDataunattended, 204 );
|
|
1166
|
+
}
|
|
1167
|
+
logger.info( 'update in binary data', { query: unattendedquery, update: update } );
|
|
1168
|
+
res.sendSuccess( `Successfully update in ${inputData.moduleType} ` );
|
|
1169
|
+
|
|
1170
|
+
break;
|
|
1171
|
+
|
|
1172
|
+
case 'left-in-middle':
|
|
1173
|
+
let leftquery ={
|
|
1174
|
+
_id: inputData.auditId,
|
|
1175
|
+
storeId: inputData.storeId,
|
|
1176
|
+
fileDate: inputData.fileDate,
|
|
1177
|
+
question: inputData.question,
|
|
1178
|
+
moduleType: inputData.moduleType,
|
|
1179
|
+
};
|
|
1180
|
+
let leftupdate={
|
|
1181
|
+
auditStatus: 'completed',
|
|
1182
|
+
answer: inputData.answer,
|
|
1183
|
+
};
|
|
1184
|
+
let updatDataleft= await updateOneBinaryAuditModel( leftquery, leftupdate );
|
|
1185
|
+
if ( updatDataleft.modifiedCount==0 ) {
|
|
1186
|
+
return res.sendError( updatDataleft, 204 );
|
|
1187
|
+
}
|
|
1188
|
+
logger.info( 'update in binary data', { query: leftquery, update: leftupdate } );
|
|
1189
|
+
res.sendSuccess( `Successfully update in ${inputData.moduleType} ` );
|
|
1190
|
+
|
|
1191
|
+
break;
|
|
1192
|
+
|
|
1193
|
+
case 'camera-angle-change':
|
|
1194
|
+
let cameraquery ={
|
|
1195
|
+
_id: inputData.auditId,
|
|
1196
|
+
storeId: inputData.storeId,
|
|
1197
|
+
fileDate: inputData.fileDate,
|
|
1198
|
+
streamName: inputData.streamName,
|
|
1199
|
+
moduleType: inputData.moduleType,
|
|
1200
|
+
};
|
|
1201
|
+
let cameraupdate={
|
|
1202
|
+
auditStatus: 'completed',
|
|
1203
|
+
answer: inputData.answer,
|
|
1204
|
+
};
|
|
1205
|
+
let updatDatacamera= await updateOneBinaryAuditModel( cameraquery, cameraupdate );
|
|
1206
|
+
if ( updatDatacamera.modifiedCount==0 ) {
|
|
1207
|
+
return res.sendError( updatDatacamera, 204 );
|
|
1208
|
+
}
|
|
1209
|
+
logger.info( 'update in binary data', { query: cameraquery, update: cameraupdate } );
|
|
1210
|
+
res.sendSuccess( `Successfully update in ${inputData.moduleType} ` );
|
|
1211
|
+
|
|
1212
|
+
break;
|
|
1213
|
+
|
|
1214
|
+
default:
|
|
1215
|
+
res.sendError( 'no data', 204 );
|
|
1216
|
+
break
|
|
1217
|
+
;
|
|
1218
|
+
}
|
|
1219
|
+
} catch ( error ) {
|
|
1220
|
+
const err = error.mesage || 'Internal Server Error';
|
|
1221
|
+
logger.error( { error: error, data: req.body, function: 'saveBinary' } );
|
|
1222
|
+
return res.sendError( err, 500 );
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
export async function userAuditHistory( req, res ) {
|
|
1227
|
+
try {
|
|
1228
|
+
const inputData = req.body;
|
|
1229
|
+
const userId = inputData.userId? new mongoose.Types.ObjectId( inputData.userId ) : req.user._id;
|
|
1230
|
+
const limit = inputData.limit || 10;
|
|
1231
|
+
const offset = inputData.offset ? ( inputData.offset - 1 ) * limit : 0;
|
|
1232
|
+
const dateRange = await getUTC( new Date( inputData.fromDate ), new Date( inputData.toDate ) );
|
|
1233
|
+
const dateRangeCreatedAt = await getDateWithCustomizeTime( new Date( inputData.fromDate ), new Date( inputData.toDate ) );
|
|
1234
|
+
let filter = [
|
|
1235
|
+
{ userId: { $eq: userId } },
|
|
1236
|
+
{ moduleType: { $eq: inputData.moduleType } },
|
|
1237
|
+
];
|
|
1238
|
+
|
|
1239
|
+
if ( inputData.dateType == 'fileDate' ) {
|
|
1240
|
+
filter.push(
|
|
1241
|
+
{ fileDateISO: { $gte: dateRange.start } },
|
|
1242
|
+
{ fileDateISO: { $lte: dateRange.end } },
|
|
1243
|
+
);
|
|
1244
|
+
} else {
|
|
1245
|
+
filter.push(
|
|
1246
|
+
{ createdAt: { $gte: dateRangeCreatedAt.start } },
|
|
1247
|
+
{ createdAt: { $lte: dateRangeCreatedAt.end } },
|
|
1248
|
+
);
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
|
|
1252
|
+
if ( inputData.filterByAuditType?.length > 0 ) {
|
|
1253
|
+
filter.push( {
|
|
1254
|
+
auditType: { $in: inputData.filterByAuditType },
|
|
1255
|
+
} );
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
if ( inputData.filterByStoreId?.length > 0 ) {
|
|
1259
|
+
filter.push( {
|
|
1260
|
+
storeId: { $in: inputData.filterByStoreId },
|
|
1261
|
+
} );
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
if ( inputData.filterByStatus?.length > 0 ) {
|
|
1265
|
+
filter.push( {
|
|
1266
|
+
auditStatus: { $in: inputData.filterByStatus },
|
|
1267
|
+
} );
|
|
1268
|
+
}
|
|
1269
|
+
if ( inputData?.clientId?.length > 0 ) {
|
|
1270
|
+
filter.push( { clientId: { $in: inputData.clientId } } );
|
|
1271
|
+
}
|
|
1272
|
+
const query = [
|
|
1273
|
+
{
|
|
1274
|
+
$match: {
|
|
1275
|
+
$and: filter,
|
|
1276
|
+
},
|
|
1277
|
+
},
|
|
1278
|
+
{
|
|
1279
|
+
$lookup: {
|
|
1280
|
+
from: 'stores',
|
|
1281
|
+
let: { storeId: '$storeId' },
|
|
1282
|
+
pipeline: [
|
|
1283
|
+
{
|
|
1284
|
+
$match: {
|
|
1285
|
+
$expr: {
|
|
1286
|
+
$eq: [ '$storeId', '$$storeId' ],
|
|
1287
|
+
},
|
|
1288
|
+
},
|
|
1289
|
+
},
|
|
1290
|
+
{
|
|
1291
|
+
$project: {
|
|
1292
|
+
storeName: 1,
|
|
1293
|
+
},
|
|
1294
|
+
},
|
|
1295
|
+
], as: 'store',
|
|
1296
|
+
},
|
|
1297
|
+
},
|
|
1298
|
+
{
|
|
1299
|
+
$unwind: {
|
|
1300
|
+
path: '$store', preserveNullAndEmptyArrays: true,
|
|
1301
|
+
},
|
|
1302
|
+
},
|
|
1303
|
+
{
|
|
1304
|
+
$lookup: {
|
|
1305
|
+
from: 'clients',
|
|
1306
|
+
let: { clientId: '$clientId' },
|
|
1307
|
+
pipeline: [
|
|
1308
|
+
{
|
|
1309
|
+
$match: {
|
|
1310
|
+
$expr: {
|
|
1311
|
+
$eq: [ '$clientId', '$$clientId' ],
|
|
1312
|
+
},
|
|
1313
|
+
},
|
|
1314
|
+
},
|
|
1315
|
+
{
|
|
1316
|
+
$project: {
|
|
1317
|
+
clientName: 1,
|
|
1318
|
+
},
|
|
1319
|
+
},
|
|
1320
|
+
], as: 'client',
|
|
1321
|
+
},
|
|
1322
|
+
|
|
1323
|
+
},
|
|
1324
|
+
{
|
|
1325
|
+
$unwind: {
|
|
1326
|
+
path: '$client', preserveNullAndEmptyArrays: true,
|
|
1327
|
+
},
|
|
1328
|
+
},
|
|
1329
|
+
{
|
|
1330
|
+
$project: {
|
|
1331
|
+
storeId: 1,
|
|
1332
|
+
userId: 1,
|
|
1333
|
+
tempId: 1,
|
|
1334
|
+
streamName: 1,
|
|
1335
|
+
question: 1,
|
|
1336
|
+
answer: 1,
|
|
1337
|
+
storeName: '$store.storeName',
|
|
1338
|
+
clientId: 1,
|
|
1339
|
+
clientName: '$client.clientName',
|
|
1340
|
+
fileDate: 1,
|
|
1341
|
+
auditType: 1,
|
|
1342
|
+
zoneName: 1,
|
|
1343
|
+
moduleType: 1,
|
|
1344
|
+
beforeCount: 1,
|
|
1345
|
+
afterCount: 1,
|
|
1346
|
+
accuracy: { $cond: [ { $eq: [ '$auditStatus', 'completed' ] }, { $round: [
|
|
1347
|
+
{
|
|
1348
|
+
$multiply: [ { $divide: [ '$afterCount', '$beforeCount' ] }, 100 ],
|
|
1349
|
+
}, 1,
|
|
1350
|
+
],
|
|
1351
|
+
}, null ] },
|
|
1352
|
+
|
|
1353
|
+
startTime: {
|
|
1354
|
+
$dateToString: {
|
|
1355
|
+
format: '%Y-%m-%d %H:%M:%S',
|
|
1356
|
+
date: '$startTime',
|
|
1357
|
+
timezone: 'Asia/Kolkata',
|
|
1358
|
+
},
|
|
1359
|
+
},
|
|
1360
|
+
endTime: {
|
|
1361
|
+
$dateToString: {
|
|
1362
|
+
format: '%Y-%m-%d %H:%M:%S',
|
|
1363
|
+
date: '$endTime',
|
|
1364
|
+
timezone: 'Asia/Kolkata',
|
|
1365
|
+
},
|
|
1366
|
+
},
|
|
1367
|
+
// timeSpent: { $round: [
|
|
1368
|
+
// { $divide: [ '$timeSpent', 60 ] }, 2,
|
|
1369
|
+
// ] },
|
|
1370
|
+
timeSpent: {
|
|
1371
|
+
|
|
1372
|
+
$cond: [
|
|
1373
|
+
{ $lt: [ '$timeSpent', 60 ] }, // Case 1: If less than 60 seconds
|
|
1374
|
+
{ $concat: [ { $toString: '$timeSpent' }, ' sec' ] },
|
|
1375
|
+
{
|
|
1376
|
+
$cond: [
|
|
1377
|
+
{ $lt: [ '$timeSpent', 3600 ] }, // Case 2: If less than 60 minutes (3600 seconds)
|
|
1378
|
+
{
|
|
1379
|
+
$concat: [
|
|
1380
|
+
{ $toString: { $round: [ { $divide: [ '$timeSpent', 60 ] }, 1 ] } }, // Convert to minutes
|
|
1381
|
+
' min',
|
|
1382
|
+
],
|
|
1383
|
+
},
|
|
1384
|
+
{
|
|
1385
|
+
$concat: [
|
|
1386
|
+
{ $toString: { $round: [ { $divide: [ '$timeSpent', 3600 ] }, 1 ] } }, // Convert to hours
|
|
1387
|
+
' hr',
|
|
1388
|
+
],
|
|
1389
|
+
},
|
|
1390
|
+
],
|
|
1391
|
+
},
|
|
1392
|
+
],
|
|
1393
|
+
|
|
1394
|
+
},
|
|
1395
|
+
auditStatus: 1,
|
|
1396
|
+
createdAt: 1,
|
|
1397
|
+
},
|
|
1398
|
+
},
|
|
1399
|
+
];
|
|
1400
|
+
|
|
1401
|
+
if ( inputData.searchValue && inputData.searchValue!== '' ) {
|
|
1402
|
+
query.push( {
|
|
1403
|
+
$match: {
|
|
1404
|
+
$or: [
|
|
1405
|
+
{ clientName: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1406
|
+
{ clientId: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1407
|
+
{ storeId: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1408
|
+
{ storeName: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1409
|
+
{ streamName: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1410
|
+
{ moduleType: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1411
|
+
{ auditType: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1412
|
+
{ auditStatus: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1413
|
+
{ tempId: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1414
|
+
{ question: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1415
|
+
],
|
|
1416
|
+
|
|
1417
|
+
},
|
|
1418
|
+
} );
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
if ( inputData.sortColumnName ) {
|
|
1422
|
+
const sortBy = inputData.sortBy || -1;
|
|
1423
|
+
const sortColumn = inputData.sortColumnName;
|
|
1424
|
+
query.push( {
|
|
1425
|
+
$sort: { [sortColumn]: sortBy },
|
|
1426
|
+
},
|
|
1427
|
+
);
|
|
1428
|
+
}
|
|
1429
|
+
const count = inputData.moduleType.includes( [ 'uniform-detection', 'mobile-detection' ] )? await aggregateUserEmpDetection( query ) : await aggregateBinaryAudit( query );
|
|
1430
|
+
if ( count.length == 0 ) {
|
|
1431
|
+
return res.sendError( 'No Data Found', 204 );
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
if ( inputData.isExport ) {
|
|
1435
|
+
const chunkedMappingData = await chunkArray( count, 10 );
|
|
1436
|
+
const promises = chunkedMappingData.map( async ( chunk ) => {
|
|
1437
|
+
const exportData = [];
|
|
1438
|
+
chunk.forEach( ( element ) => {
|
|
1439
|
+
exportData.push( {
|
|
1440
|
+
'File Date': element.fileDate,
|
|
1441
|
+
'Brand ID': element.clientId,
|
|
1442
|
+
'Brand Name': element.clientName,
|
|
1443
|
+
'Store ID': element.storeId,
|
|
1444
|
+
'Store Name': element.storeName,
|
|
1445
|
+
'Stream Name': element.moduleType == 'camera-angle-change'? element.zoneName : '',
|
|
1446
|
+
'Audit Type': element.auditType,
|
|
1447
|
+
'Product Type': element.moduleType,
|
|
1448
|
+
'Before Count': element.beforeCount,
|
|
1449
|
+
'After Count': element.afterCount || '',
|
|
1450
|
+
'Accuracy': element.accuracy || '',
|
|
1451
|
+
'Start Time': element.startTime,
|
|
1452
|
+
'End Time': element.endTime || '',
|
|
1453
|
+
'Time Spent': element.timeSpent,
|
|
1454
|
+
'Audit Status': element.auditStatus,
|
|
1455
|
+
'Audited Date': dayjs( element.createdAt ).format( 'YYYY,MMM D' ),
|
|
1456
|
+
|
|
1457
|
+
} );
|
|
1458
|
+
} );
|
|
1459
|
+
return exportData;
|
|
1460
|
+
} );
|
|
1461
|
+
const mappedArrays = await Promise.all( promises );
|
|
1462
|
+
mappedArrays.flat();
|
|
1463
|
+
logger.info( { mappedArrays: mappedArrays[0] } );
|
|
1464
|
+
await download( mappedArrays[0], res );
|
|
1465
|
+
return;
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
query.push( {
|
|
1469
|
+
$skip: offset,
|
|
1470
|
+
},
|
|
1471
|
+
{
|
|
1472
|
+
$limit: limit,
|
|
1473
|
+
} );
|
|
1474
|
+
const result = inputData.moduleType.includes( [ 'uniform-detection', 'mobile-detection' ] )? await aggregateUserEmpDetection( query ) : await aggregateBinaryAudit( query );
|
|
1475
|
+
|
|
1476
|
+
return res.sendSuccess( { result: result, count: count.length } );
|
|
1477
|
+
} catch ( error ) {
|
|
1478
|
+
const err = error.message || 'Internal Server Error';
|
|
1479
|
+
logger.info( { error: error, message: req.body, function: 'userAuditHistory' } );
|
|
1480
|
+
return res.sendError( err, 500 );
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import j2s from 'joi-to-swagger';
|
|
2
|
-
import { getFileSchema } from '../dtos/traxAudit.dtos.js';
|
|
2
|
+
import { getFileSchema, userAuditHistorySchema, workSpaceSchema, saveSchema } from '../dtos/traxAudit.dtos.js';
|
|
3
3
|
|
|
4
4
|
export const traxAuditDocs = {
|
|
5
5
|
|
|
@@ -43,4 +43,72 @@ export const traxAuditDocs = {
|
|
|
43
43
|
},
|
|
44
44
|
},
|
|
45
45
|
},
|
|
46
|
+
|
|
47
|
+
'/v3/trax-audit/work-space': {
|
|
48
|
+
post: {
|
|
49
|
+
tags: [ 'Trax Audit' ],
|
|
50
|
+
description: 'queue wise info of audit files ',
|
|
51
|
+
operationId: 'work-space',
|
|
52
|
+
requestBody: {
|
|
53
|
+
content: {
|
|
54
|
+
'application/json': {
|
|
55
|
+
schema: j2s( workSpaceSchema ).swagger,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
responses: {
|
|
60
|
+
200: { description: 'Successful' },
|
|
61
|
+
401: { description: 'Unauthorized User' },
|
|
62
|
+
422: { description: 'Field Error' },
|
|
63
|
+
500: { description: 'Server Error' },
|
|
64
|
+
204: { description: 'Not Found' },
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
'/v3/trax-audit/save-binary-audit': {
|
|
70
|
+
post: {
|
|
71
|
+
tags: [ 'Trax Audit' ],
|
|
72
|
+
description: 'Save binay data type',
|
|
73
|
+
operationId: 'save-binary-audit',
|
|
74
|
+
parameters: {},
|
|
75
|
+
requestBody: {
|
|
76
|
+
content: {
|
|
77
|
+
'application/json': {
|
|
78
|
+
schema: j2s( saveSchema ).swagger,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
responses: {
|
|
83
|
+
200: { description: 'Successful' },
|
|
84
|
+
401: { description: 'Unauthorized User' },
|
|
85
|
+
422: { description: 'Field Error' },
|
|
86
|
+
500: { description: 'Server Error' },
|
|
87
|
+
204: { description: 'Not Found' },
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
'/v3/trax-audit/metrics/user-audit-history': {
|
|
93
|
+
post: {
|
|
94
|
+
tags: [ 'Trax Audit' ],
|
|
95
|
+
description: `Get list of user wise audit user details with date range`,
|
|
96
|
+
operationId: 'metrics/user-audit-history',
|
|
97
|
+
parameters: {},
|
|
98
|
+
requestBody: {
|
|
99
|
+
content: {
|
|
100
|
+
'application/json': {
|
|
101
|
+
schema: j2s( userAuditHistorySchema ).swagger,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
responses: {
|
|
106
|
+
200: { description: 'Successful' },
|
|
107
|
+
401: { description: 'Unauthorized User' },
|
|
108
|
+
422: { description: 'Field Error' },
|
|
109
|
+
500: { description: 'Server Error' },
|
|
110
|
+
204: { description: 'Not Found' },
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
46
114
|
};
|
|
@@ -68,18 +68,11 @@ export const saveSchema = joi.object(
|
|
|
68
68
|
auditId: joi.string().required(),
|
|
69
69
|
storeId: joi.string().required(),
|
|
70
70
|
fileDate: joi.string().required(),
|
|
71
|
-
|
|
72
|
-
moduleType: joi.string().required(),
|
|
73
|
-
zoneName: joi.string().required(),
|
|
74
|
-
beforeCount: joi.number().required(),
|
|
75
|
-
junkCount: joi.number().required(),
|
|
76
|
-
junk: joi.array().required(),
|
|
77
|
-
employeeCount: joi.number().required(),
|
|
78
|
-
employee: joi.array().required(),
|
|
79
|
-
customerCount: joi.number().required(),
|
|
80
|
-
customer: joi.array().required(),
|
|
71
|
+
tempId: joi.number().optional(),
|
|
81
72
|
moduleType: joi.string().required(),
|
|
82
|
-
|
|
73
|
+
question: joi.string().optional(),
|
|
74
|
+
streamName: joi.string().optional(),
|
|
75
|
+
answer: joi.string().required(),
|
|
83
76
|
},
|
|
84
77
|
);
|
|
85
78
|
|
|
@@ -103,3 +96,28 @@ export const workSpaceSchema = joi.object(
|
|
|
103
96
|
export const workSpaceValid = {
|
|
104
97
|
body: workSpaceSchema,
|
|
105
98
|
};
|
|
99
|
+
|
|
100
|
+
export const userAuditHistorySchema = joi.object(
|
|
101
|
+
{
|
|
102
|
+
userId: joi.string().optional(),
|
|
103
|
+
fromDate: joi.string().required(),
|
|
104
|
+
toDate: joi.string().required(),
|
|
105
|
+
dateType: joi.string().required(),
|
|
106
|
+
clientId: joi.array().optional(),
|
|
107
|
+
filterByStoreId: joi.array().required(),
|
|
108
|
+
moduleType: joi.string().required(),
|
|
109
|
+
filterByAuditType: joi.array().optional(),
|
|
110
|
+
filterByStatus: joi.array().optional(),
|
|
111
|
+
searchValue: joi.string().optional().allow( '' ),
|
|
112
|
+
limit: joi.number().optional(),
|
|
113
|
+
offset: joi.number().optional(),
|
|
114
|
+
sortColumnName: joi.string().optional(),
|
|
115
|
+
sortBy: joi.number().optional(),
|
|
116
|
+
isExport: joi.boolean().optional(),
|
|
117
|
+
|
|
118
|
+
},
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
export const userAuditHistoryValid = {
|
|
122
|
+
body: userAuditHistorySchema,
|
|
123
|
+
};
|
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
|
|
3
|
-
import { getDetectionFileValid, getFileValid } from '../dtos/traxAudit.dtos.js';
|
|
3
|
+
import { getDetectionFileValid, getFileValid, userAuditHistoryValid, workSpaceValid, saveValid } from '../dtos/traxAudit.dtos.js';
|
|
4
4
|
import { isExistsQueue } from '../validation/audit.validation.js';
|
|
5
|
-
import { getAuditFile, getDetectionAuditFile } from '../controllers/traxAudit.controllers.js';
|
|
5
|
+
import { getAuditFile, getDetectionAuditFile, saveBinary, userAuditHistory, workSpace } from '../controllers/traxAudit.controllers.js';
|
|
6
|
+
import { validateBinaryAudit } from '../validation/traxAuditValidation.js';
|
|
6
7
|
|
|
7
8
|
export const traxAuditRouter = Router();
|
|
8
9
|
|
|
9
10
|
// Audit Mapping
|
|
10
|
-
|
|
11
|
-
traxAuditRouter.get( '/get-file', isAllowedSessionHandler, validate( getDetectionFileValid ), isExistsQueue, getDetectionAuditFile );
|
|
11
|
+
|
|
12
|
+
traxAuditRouter.get( '/get-file-detection', isAllowedSessionHandler, validate( getDetectionFileValid ), isExistsQueue, getDetectionAuditFile );
|
|
12
13
|
// traxAuditRouter.post( '/save-draft', isAllowedSessionHandler, validate( saveDraftValid ), saveDraft );
|
|
13
14
|
// traxAuditRouter.get( '/get-drafted-data', isAllowedSessionHandler, validate( getDraftedDataValid ), getDraftedData );
|
|
14
|
-
// traxAuditRouter.post( '/save', isAllowedSessionHandler, validate( saveValid ),
|
|
15
|
-
|
|
15
|
+
// traxAuditRouter.post( '/save', isAllowedSessionHandler, validate( saveValid ), validateUserEmpDetection, save ); use this validateuserEMpDetection
|
|
16
|
+
traxAuditRouter.post( '/work-space', isAllowedSessionHandler, validate( workSpaceValid ), workSpace );
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
// Y/n
|
|
20
|
+
traxAuditRouter.get( '/get-file', isAllowedSessionHandler, validate( getFileValid ), isExistsQueue, getAuditFile ); // remove the reaudit concept
|
|
21
|
+
traxAuditRouter.post( '/save-binary-audit', isAllowedSessionHandler, validate( saveValid ), validateBinaryAudit, saveBinary ); // need to add valid joi function, saveBinary function
|
|
22
|
+
|
|
23
|
+
export default traxAuditRouter;
|
|
24
|
+
|
|
25
|
+
// metrcis
|
|
26
|
+
traxAuditRouter.post( '/metrics/user-audit-history', isAllowedSessionHandler, validate( userAuditHistoryValid ), userAuditHistory );
|
|
@@ -5,6 +5,14 @@ export function createBinaryAudit( record ) {
|
|
|
5
5
|
return binaryAuditModel.create( record );
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
export function
|
|
8
|
+
export function aggregateBinaryAudit( query ) {
|
|
9
9
|
return binaryAuditModel.aggregate( query, { collation: { locale: 'en', strength: 2 } } );
|
|
10
10
|
}
|
|
11
|
+
|
|
12
|
+
export function findOneBinaryAudit( query ) {
|
|
13
|
+
return binaryAuditModel.findOne( query );
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function updateOneBinaryAuditModel( query, record ) {
|
|
17
|
+
return binaryAuditModel.updateOne( query, { $set: record } );
|
|
18
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
|
|
2
|
+
import traxAuditDataModel from 'tango-api-schema/schema/traxAuditData.model.js';
|
|
3
|
+
|
|
4
|
+
export function findOneTraxAuditData( query, fields, sort ) {
|
|
5
|
+
return traxAuditDataModel.findOne( query, fields ).sort( sort );
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function aggregateTraxAuditData( query ) {
|
|
9
|
+
return traxAuditDataModel.aggregate( query, { collation: { locale: 'en', strength: 2 } } );
|
|
10
|
+
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import userEmpDetectionModel from 'tango-api-schema/schema/userEmpDetection.model.js';
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
export function
|
|
4
|
+
export function aggregateUserEmpDetection( query ) {
|
|
5
5
|
return userEmpDetectionModel.aggregate( query, { collation: { locale: 'en', strength: 2 } } );
|
|
6
6
|
}
|
|
7
|
+
|
|
8
|
+
export function createUserEmpDetection( record ) {
|
|
9
|
+
return userEmpDetectionModel.create( record );
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function findOneUserEmpDetection( query, fields ) {
|
|
13
|
+
return userEmpDetectionModel.findOne( query, fields );
|
|
14
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { findOneBinaryAudit } from '../service/binaryAudit.service.js';
|
|
2
|
+
import { findOneUserEmpDetection } from '../service/userEmpDetection.service.js';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export async function validateUserEmpDetection( req, res, next ) {
|
|
6
|
+
try {
|
|
7
|
+
const inputData = req.body;
|
|
8
|
+
const userAuditDetails =await findOneUserEmpDetection( { _id: inputData.auditId } );
|
|
9
|
+
if ( !userAuditDetails ) {
|
|
10
|
+
return res.sendError( 'No Data Available' );
|
|
11
|
+
} else if ( userAuditDetails && userAuditDetails.auditStatus == 'skipped' ) {
|
|
12
|
+
return res.sendError( 'The Audit file Assigned to some one else', 203 );
|
|
13
|
+
}
|
|
14
|
+
req.userAudit = userAuditDetails;
|
|
15
|
+
next();
|
|
16
|
+
} catch ( error ) {
|
|
17
|
+
const err = error.message || 'Internal Server Error';
|
|
18
|
+
logger.error( { error: error, message: req.query, function: 'validateUserEmpDetection' } );
|
|
19
|
+
return res.sendError( err, 500 );
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function validateBinaryAudit( req, res, next ) {
|
|
24
|
+
try {
|
|
25
|
+
const inputData = req.body;
|
|
26
|
+
const userAuditDetails =await findOneBinaryAudit( { _id: inputData.auditId } );
|
|
27
|
+
if ( !userAuditDetails ) {
|
|
28
|
+
return res.sendError( 'No Data Available' );
|
|
29
|
+
} else if ( userAuditDetails && userAuditDetails.auditStatus == 'completed' ) {
|
|
30
|
+
return res.sendError( 'Forbidden to this action', 203 );
|
|
31
|
+
}
|
|
32
|
+
req.userAudit = userAuditDetails;
|
|
33
|
+
next();
|
|
34
|
+
} catch ( error ) {
|
|
35
|
+
const err = error.message || 'Internal Server Error';
|
|
36
|
+
logger.error( { error: error, message: req.query, function: 'validateBinaryAudit' } );
|
|
37
|
+
return res.sendError( err, 500 );
|
|
38
|
+
}
|
|
39
|
+
}
|