tango-app-api-audit 3.6.22 → 3.6.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-audit",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.23",
|
|
4
4
|
"description": "audit & audit metrics apis",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
"author": "praveenraj",
|
|
14
14
|
"license": "ISC",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@aws-sdk/client-ses": "^3.918.0",
|
|
17
16
|
"adm-zip": "^0.5.15",
|
|
18
17
|
"aws-sdk": "^2.1643.0",
|
|
19
18
|
"axios": "^1.7.9",
|
|
@@ -25,7 +24,6 @@
|
|
|
25
24
|
"joi-to-swagger": "^6.2.0",
|
|
26
25
|
"lodash": "^4.17.21",
|
|
27
26
|
"mongodb": "^6.7.0",
|
|
28
|
-
"nodemailer": "^7.0.10",
|
|
29
27
|
"nodemon": "^3.1.3",
|
|
30
28
|
"swagger-ui-express": "^5.0.1",
|
|
31
29
|
"tango-api-schema": "^2.3.28",
|
|
@@ -609,7 +609,7 @@ export async function getAuditFile( req, res ) {
|
|
|
609
609
|
const getQuery = msg.audit_type =='ReAudit'?
|
|
610
610
|
{
|
|
611
611
|
size: inputData?.limit || 500,
|
|
612
|
-
_source: [ 'module', 'status', 'date', 'store_id', 'outputCluster', 'personPath', 'REIDCluster', 'isEmployee', 'isJunk', 'EmployeeStatusFinal' ], // Only fetch necessary fields
|
|
612
|
+
_source: [ 'module', 'status', 'date', 'store_id', 'outputCluster', 'personPath', 'REIDCluster', 'isEmployee', 'isJunk', 'EmployeeStatusFinal', 'status_time' ], // Only fetch necessary fields
|
|
613
613
|
|
|
614
614
|
query: {
|
|
615
615
|
bool: {
|
|
@@ -638,13 +638,13 @@ export async function getAuditFile( req, res ) {
|
|
|
638
638
|
},
|
|
639
639
|
},
|
|
640
640
|
sort: [
|
|
641
|
-
{
|
|
641
|
+
{ status_time: { order: 'desc' } },
|
|
642
642
|
],
|
|
643
643
|
|
|
644
644
|
}:
|
|
645
645
|
{
|
|
646
646
|
size: inputData?.limit || 500,
|
|
647
|
-
_source: [ 'module', 'status', 'date', 'store_id', 'personPath', 'REIDCluster', 'EmployeeStatusProposed', 'isJunk', 'EmployeeStatusFinal' ], // Only fetch necessary fields
|
|
647
|
+
_source: [ 'module', 'status', 'date', 'store_id', 'personPath', 'REIDCluster', 'EmployeeStatusProposed', 'isJunk', 'EmployeeStatusFinal', 'status_time' ], // Only fetch necessary fields
|
|
648
648
|
|
|
649
649
|
query: {
|
|
650
650
|
bool: {
|
|
@@ -668,7 +668,7 @@ export async function getAuditFile( req, res ) {
|
|
|
668
668
|
},
|
|
669
669
|
},
|
|
670
670
|
sort: [
|
|
671
|
-
{
|
|
671
|
+
{ status_time: { order: 'desc' } },
|
|
672
672
|
],
|
|
673
673
|
|
|
674
674
|
};
|
|
@@ -4490,7 +4490,7 @@ export async function auditImages( req, res ) {
|
|
|
4490
4490
|
case 'BC':
|
|
4491
4491
|
const getQuery = {
|
|
4492
4492
|
size: 10000,
|
|
4493
|
-
_source: [ 'module', 'status', 'date', 'store_id', 'personPath', 'REIDCluster', 'EmployeeStatusProposed', 'isJunk', 'EmployeeStatusFinal' ], // Only fetch necessary fields
|
|
4493
|
+
_source: [ 'module', 'status', 'date', 'store_id', 'personPath', 'REIDCluster', 'EmployeeStatusProposed', 'isJunk', 'EmployeeStatusFinal', 'status_time' ], // Only fetch necessary fields
|
|
4494
4494
|
|
|
4495
4495
|
query: {
|
|
4496
4496
|
bool: {
|
|
@@ -4515,7 +4515,7 @@ export async function auditImages( req, res ) {
|
|
|
4515
4515
|
},
|
|
4516
4516
|
|
|
4517
4517
|
sort: [
|
|
4518
|
-
{
|
|
4518
|
+
{ status_time: { order: 'desc' } },
|
|
4519
4519
|
],
|
|
4520
4520
|
};
|
|
4521
4521
|
const files = [];
|
|
@@ -4565,7 +4565,7 @@ export async function auditImages( req, res ) {
|
|
|
4565
4565
|
|
|
4566
4566
|
const getACQuery = {
|
|
4567
4567
|
size: 10000,
|
|
4568
|
-
_source: [ 'module', 'status', 'date', 'store_id', 'outputCluster', 'personPath', 'REIDCluster', 'isEmployee', 'isJunk', 'EmployeeStatusFinal' ], // Only fetch necessary fields
|
|
4568
|
+
_source: [ 'module', 'status', 'date', 'store_id', 'outputCluster', 'personPath', 'REIDCluster', 'isEmployee', 'isJunk', 'EmployeeStatusFinal', 'status_time' ], // Only fetch necessary fields
|
|
4569
4569
|
|
|
4570
4570
|
query: {
|
|
4571
4571
|
bool: {
|
|
@@ -4594,7 +4594,7 @@ export async function auditImages( req, res ) {
|
|
|
4594
4594
|
},
|
|
4595
4595
|
},
|
|
4596
4596
|
sort: [
|
|
4597
|
-
{
|
|
4597
|
+
{ status_time: { order: 'desc' } },
|
|
4598
4598
|
],
|
|
4599
4599
|
|
|
4600
4600
|
};
|
|
@@ -811,6 +811,7 @@ export async function save( req, res ) {
|
|
|
811
811
|
},
|
|
812
812
|
};
|
|
813
813
|
const getOutput = await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
|
|
814
|
+
logger.info( { getOutput: getOutput } );
|
|
814
815
|
const output = getOutput?.body?.hits?.hits?.length > 0 ? getOutput?.body?.hits?.hits[0] : null;
|
|
815
816
|
if ( !output ) {
|
|
816
817
|
return res.sendError( 'This file is currently being audited by another user. Any actions you perform will not be saved.', 400 );
|
|
@@ -844,27 +845,19 @@ export async function save( req, res ) {
|
|
|
844
845
|
|
|
845
846
|
const getEyetestConfig = await findOneEyeTestConfig( { clientId: req?.user.userType == 'tango'? inputData?.clientId : req.user.clientId, configureType: 'email' }, { complianceThreshold: 1 } );
|
|
846
847
|
|
|
847
|
-
if ( getEyetestConfig &&
|
|
848
|
+
if ( getEyetestConfig && inputData.auditStatus == 'Audited' && inputUpdatedData ) {
|
|
848
849
|
const trustScore = Math.round( 100-( ( inputData?.overRides / inputData?.steps?.length ) * 100 ) );
|
|
849
850
|
const value = Number( getEyetestConfig?.complianceThreshold?.value?.split( '%' )[0] );
|
|
850
851
|
const condition = getEyetestConfig?.complianceThreshold?.condition;
|
|
851
|
-
const id=
|
|
852
|
-
const humanScore = Math.round( ( inputUpdatedData?._source?.auditedSteps /inputUpdatedData?._source?.totalSteps ) * 100 );
|
|
853
|
-
const userName = await findOneUser( { _id: new mongoose.Types.ObjectId( inputUpdatedData?._source?.userId ) }, { userName: 1 } );
|
|
854
|
-
|
|
855
|
-
|
|
852
|
+
const id= `${inputData?.RMEmail}_${inputData?.cluster}_${inputUpdatedData?._source?.optumId}_${inputData?.fileId}`;
|
|
856
853
|
switch ( condition ) {
|
|
857
854
|
case '>': if ( trustScore > value ) {
|
|
858
855
|
const record1 = {
|
|
859
856
|
RMEmail: inputData.RMEmail,
|
|
860
|
-
RMName: inputData.RMEmail,
|
|
861
857
|
cluster: inputData.cluster,
|
|
862
858
|
optumId: inputUpdatedData?._source?.optumId,
|
|
863
|
-
optomEmailId: inputUpdatedData?._source?.salesmanEmailId,
|
|
864
859
|
storeName: inputUpdatedData?._source?.storeName,
|
|
865
860
|
complianceScore: inputUpdatedData?._source?.ComplianceScore,
|
|
866
|
-
humanScore: humanScore,
|
|
867
|
-
auditedBy: userName?.userName || '',
|
|
868
861
|
trustScore: inputUpdatedData?._source?.trustScore,
|
|
869
862
|
auditedId: inputUpdatedData?._id,
|
|
870
863
|
queueId: inputUpdatedData?._source?.queueId,
|
|
@@ -878,14 +871,10 @@ export async function save( req, res ) {
|
|
|
878
871
|
case '<': if ( trustScore < value ) {
|
|
879
872
|
const record2 = {
|
|
880
873
|
RMEmail: inputData.RMEmail,
|
|
881
|
-
RMName: inputData.RMEmail,
|
|
882
874
|
cluster: inputData.cluster,
|
|
883
875
|
optumId: inputUpdatedData?._source?.optumId,
|
|
884
|
-
optomEmailId: inputUpdatedData?._source?.salesmanEmailId,
|
|
885
876
|
storeName: inputUpdatedData?._source?.storeName,
|
|
886
877
|
complianceScore: inputUpdatedData?._source?.ComplianceScore,
|
|
887
|
-
humanScore: humanScore,
|
|
888
|
-
auditedBy: userName?.userName || '',
|
|
889
878
|
trustScore: inputUpdatedData?._source?.trustScore,
|
|
890
879
|
auditedId: inputUpdatedData?._id,
|
|
891
880
|
queueId: inputUpdatedData?._source?.queueId,
|
|
@@ -899,14 +888,10 @@ export async function save( req, res ) {
|
|
|
899
888
|
case '>=': if ( trustScore >= value ) {
|
|
900
889
|
const record3 = {
|
|
901
890
|
RMEmail: inputData.RMEmail,
|
|
902
|
-
RMName: inputData.RMEmail,
|
|
903
891
|
cluster: inputData.cluster,
|
|
904
892
|
optumId: inputUpdatedData?._source?.optumId,
|
|
905
|
-
optomEmailId: inputUpdatedData?._source?.salesmanEmailId,
|
|
906
893
|
storeName: inputUpdatedData?._source?.storeName,
|
|
907
894
|
complianceScore: inputUpdatedData?._source?.ComplianceScore,
|
|
908
|
-
humanScore: humanScore,
|
|
909
|
-
auditedBy: userName?.userName || '',
|
|
910
895
|
trustScore: inputUpdatedData?._source?.trustScore,
|
|
911
896
|
auditedId: inputUpdatedData?._id,
|
|
912
897
|
queueId: inputUpdatedData?._source?.queueId,
|
|
@@ -920,14 +905,10 @@ export async function save( req, res ) {
|
|
|
920
905
|
case '<=': if ( trustScore <= value ) {
|
|
921
906
|
const record4 = {
|
|
922
907
|
RMEmail: inputData.RMEmail,
|
|
923
|
-
RMName: inputData.RMEmail,
|
|
924
908
|
cluster: inputData.cluster,
|
|
925
909
|
optumId: inputUpdatedData?._source?.optumId,
|
|
926
|
-
optomEmailId: inputUpdatedData?._source?.salesmanEmailId,
|
|
927
910
|
storeName: inputUpdatedData?._source?.storeName,
|
|
928
911
|
complianceScore: inputUpdatedData?._source?.ComplianceScore,
|
|
929
|
-
humanScore: humanScore,
|
|
930
|
-
auditedBy: userName?.userName || '',
|
|
931
912
|
trustScore: inputUpdatedData?._source?.trustScore,
|
|
932
913
|
auditedId: inputUpdatedData?._id,
|
|
933
914
|
queueId: inputUpdatedData?._source?.queueId,
|
|
@@ -942,14 +923,10 @@ export async function save( req, res ) {
|
|
|
942
923
|
case '==': if ( trustScore == value ) {
|
|
943
924
|
const record5 = {
|
|
944
925
|
RMEmail: inputData.RMEmail,
|
|
945
|
-
RMName: inputData.RMEmail,
|
|
946
926
|
cluster: inputData.cluster,
|
|
947
927
|
optumId: inputUpdatedData?._source?.optumId,
|
|
948
|
-
optomEmailId: inputUpdatedData?._source?.salesmanEmailId,
|
|
949
928
|
storeName: inputUpdatedData?._source?.storeName,
|
|
950
929
|
complianceScore: inputUpdatedData?._source?.ComplianceScore,
|
|
951
|
-
humanScore: humanScore,
|
|
952
|
-
auditedBy: userName?.userName || '',
|
|
953
930
|
trustScore: inputUpdatedData?._source?.trustScore,
|
|
954
931
|
auditedId: inputUpdatedData?._id,
|
|
955
932
|
queueId: inputUpdatedData?._source?.queueId,
|
|
@@ -963,14 +940,10 @@ export async function save( req, res ) {
|
|
|
963
940
|
case '===': if ( trustScore === value ) {
|
|
964
941
|
const record6 = {
|
|
965
942
|
RMEmail: inputData.RMEmail,
|
|
966
|
-
RMName: inputData.RMEmail,
|
|
967
943
|
cluster: inputData.cluster,
|
|
968
944
|
optumId: inputUpdatedData?._source?.optumId,
|
|
969
|
-
optomEmailId: inputUpdatedData?._source?.salesmanEmailId,
|
|
970
945
|
storeName: inputUpdatedData?._source?.storeName,
|
|
971
946
|
complianceScore: inputUpdatedData?._source?.ComplianceScore,
|
|
972
|
-
humanScore: humanScore,
|
|
973
|
-
auditedBy: userName?.userName || '',
|
|
974
947
|
trustScore: inputUpdatedData?._source?.trustScore,
|
|
975
948
|
auditedId: inputUpdatedData?._id,
|
|
976
949
|
queueId: inputUpdatedData?._source?.queueId,
|
|
@@ -983,7 +956,7 @@ export async function save( req, res ) {
|
|
|
983
956
|
default: throw new Error( `Unknown condition: ${condition}` );
|
|
984
957
|
}
|
|
985
958
|
}
|
|
986
|
-
return res.sendSuccess( 'The file has been
|
|
959
|
+
return res.sendSuccess( 'The file has been submited successfully' );
|
|
987
960
|
} catch ( error ) {
|
|
988
961
|
const err = error.message || 'Internal Server Error';
|
|
989
962
|
logger.error( { message: error, data: req.params, function: 'eyetestAudit-controller-save' } );
|
|
@@ -1225,25 +1198,18 @@ export async function userAuditedData( req, res ) {
|
|
|
1225
1198
|
|
|
1226
1199
|
export async function summaryList( req, res ) {
|
|
1227
1200
|
try {
|
|
1228
|
-
// declare inputData and get request body
|
|
1229
1201
|
const inputData = req.body;
|
|
1230
|
-
|
|
1231
|
-
// throw 204 if client id is not 11
|
|
1232
1202
|
if ( inputData.clientId !== '11' ) {
|
|
1233
1203
|
return res.sendError( 'No data found', 204 );
|
|
1234
1204
|
}
|
|
1235
1205
|
|
|
1236
|
-
// declare openSearch and get data form the .env/secret manager
|
|
1237
1206
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
1238
|
-
|
|
1239
|
-
// set limit, offset, sortBy, sortOrder value if not set default value
|
|
1240
1207
|
const limit = inputData.limit || 10;
|
|
1241
1208
|
const offset = inputData.offset ? ( inputData.offset - 1 ) * limit : 0;
|
|
1242
1209
|
|
|
1243
1210
|
const sortBy = inputData?.sortBy ? [ 'coveredStepsAI', 'trustScore', 'date', 'ComplianceScore', 'auditedSteps' ].includes( inputData.sortBy ) ? inputData.sortBy :`${inputData.sortBy}.keyword` : 'storeName.keyword';
|
|
1244
1211
|
const order = inputData?.sortOrder || -1;
|
|
1245
1212
|
|
|
1246
|
-
// declare filter and assign range values from inputData
|
|
1247
1213
|
let filter= [
|
|
1248
1214
|
{
|
|
1249
1215
|
'range': {
|
|
@@ -1256,7 +1222,6 @@ export async function summaryList( req, res ) {
|
|
|
1256
1222
|
|
|
1257
1223
|
];
|
|
1258
1224
|
|
|
1259
|
-
// filter by Audit Status if key has minimum one element
|
|
1260
1225
|
if ( inputData?.auditStatus && inputData?.auditStatus?.length > 0 ) {
|
|
1261
1226
|
filter.push( {
|
|
1262
1227
|
'terms': {
|
|
@@ -1264,8 +1229,6 @@ export async function summaryList( req, res ) {
|
|
|
1264
1229
|
},
|
|
1265
1230
|
} );
|
|
1266
1231
|
}
|
|
1267
|
-
|
|
1268
|
-
// filter by Visitors Type if key has minimum one element
|
|
1269
1232
|
if ( inputData?.demographics && inputData?.demographics?.length > 0 ) {
|
|
1270
1233
|
filter.push( {
|
|
1271
1234
|
'terms': {
|
|
@@ -1273,8 +1236,6 @@ export async function summaryList( req, res ) {
|
|
|
1273
1236
|
},
|
|
1274
1237
|
} );
|
|
1275
1238
|
}
|
|
1276
|
-
|
|
1277
|
-
// filter by Eye test Type if key has string value one element
|
|
1278
1239
|
if ( inputData.type && inputData.type!='' ) {
|
|
1279
1240
|
filter.push( {
|
|
1280
1241
|
'term': {
|
|
@@ -1284,17 +1245,6 @@ export async function summaryList( req, res ) {
|
|
|
1284
1245
|
} );
|
|
1285
1246
|
}
|
|
1286
1247
|
|
|
1287
|
-
// filter by near addition if value != "" and eye test must be a physical
|
|
1288
|
-
if ( inputData.nearAddition && inputData.nearAddition!='' && inputData.type ==='physical' ) {
|
|
1289
|
-
filter.push( {
|
|
1290
|
-
'term': {
|
|
1291
|
-
'nearAddition.keyword': inputData.nearAddition,
|
|
1292
|
-
},
|
|
1293
|
-
|
|
1294
|
-
} );
|
|
1295
|
-
}
|
|
1296
|
-
|
|
1297
|
-
// filter by stores if key has minimum one element else throw an error
|
|
1298
1248
|
if ( inputData.storeId && inputData.storeId.length > 0 ) {
|
|
1299
1249
|
filter.push( {
|
|
1300
1250
|
|
|
@@ -1307,14 +1257,11 @@ export async function summaryList( req, res ) {
|
|
|
1307
1257
|
return res.sendError( 'No data found', 204 );
|
|
1308
1258
|
}
|
|
1309
1259
|
|
|
1310
|
-
// Declare mustQuery as an array and include all elements from the filter array
|
|
1311
1260
|
let mustQuery = [
|
|
1312
1261
|
...filter,
|
|
1313
1262
|
];
|
|
1314
1263
|
|
|
1315
|
-
|
|
1316
|
-
if ( inputData.complianceScore && inputData.complianceScore?.length > 0 ) {
|
|
1317
|
-
// If the key type is not 'store', split the compliance score ranges
|
|
1264
|
+
if ( inputData.complianceScore && inputData.complianceScore?.length > null ) {
|
|
1318
1265
|
if ( inputData.keyType !== 'store' ) {
|
|
1319
1266
|
const rangeShould = inputData?.complianceScore?.map( ( r ) => {
|
|
1320
1267
|
const [ gte, lte ] = r.split( '-' ).map( Number );
|
|
@@ -1324,7 +1271,7 @@ export async function summaryList( req, res ) {
|
|
|
1324
1271
|
},
|
|
1325
1272
|
};
|
|
1326
1273
|
} );
|
|
1327
|
-
|
|
1274
|
+
|
|
1328
1275
|
mustQuery.push(
|
|
1329
1276
|
{
|
|
1330
1277
|
bool: {
|
|
@@ -1333,7 +1280,7 @@ export async function summaryList( req, res ) {
|
|
|
1333
1280
|
},
|
|
1334
1281
|
},
|
|
1335
1282
|
);
|
|
1336
|
-
} else {
|
|
1283
|
+
} else {
|
|
1337
1284
|
const values = Array.isArray( inputData.complianceScore ) ?
|
|
1338
1285
|
inputData.complianceScore.map( Number ) :
|
|
1339
1286
|
[ Number( inputData.complianceScore ) ];
|
|
@@ -1346,7 +1293,6 @@ export async function summaryList( req, res ) {
|
|
|
1346
1293
|
}
|
|
1347
1294
|
}
|
|
1348
1295
|
|
|
1349
|
-
// filter by category if key exist allow "fake, genuine" else throw valid category
|
|
1350
1296
|
if ( inputData?.category ) {
|
|
1351
1297
|
switch ( inputData?.category ) {
|
|
1352
1298
|
case 'fake':
|
|
@@ -2172,15 +2118,6 @@ export async function summaryCard( req, res ) {
|
|
|
2172
2118
|
},
|
|
2173
2119
|
} );
|
|
2174
2120
|
}
|
|
2175
|
-
|
|
2176
|
-
if ( inputData.nearAddition && inputData.nearAddition!='' && inputData.type ==='physical' ) {
|
|
2177
|
-
filter.push( {
|
|
2178
|
-
'term': {
|
|
2179
|
-
'nearAddition.keyword': inputData.nearAddition,
|
|
2180
|
-
},
|
|
2181
|
-
|
|
2182
|
-
} );
|
|
2183
|
-
}
|
|
2184
2121
|
let mustQuery = [
|
|
2185
2122
|
...filter,
|
|
2186
2123
|
];
|
|
@@ -2449,7 +2386,7 @@ export async function emailAlertLog( req, res ) {
|
|
|
2449
2386
|
inputData.clientId = req.user.userType == 'tango'? inputData?.clientId : req?.user?.clientId;
|
|
2450
2387
|
// get openserach name form the env file
|
|
2451
2388
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
2452
|
-
|
|
2389
|
+
|
|
2453
2390
|
|
|
2454
2391
|
let filter =[
|
|
2455
2392
|
{
|
|
@@ -2462,7 +2399,7 @@ export async function emailAlertLog( req, res ) {
|
|
|
2462
2399
|
},
|
|
2463
2400
|
];
|
|
2464
2401
|
let sort =[
|
|
2465
|
-
{ [sortBy]: { order: inputData.sortOrder === 1 ? 'asc' : 'desc' } },
|
|
2402
|
+
{ [inputData?.sortBy]: { order: inputData.sortOrder === 1 ? 'asc' : 'desc' } },
|
|
2466
2403
|
];
|
|
2467
2404
|
if ( inputData.RmList && inputData.RmList?.lenght > 0 ) {
|
|
2468
2405
|
filter.push( {
|
|
@@ -2479,86 +2416,19 @@ export async function emailAlertLog( req, res ) {
|
|
|
2479
2416
|
},
|
|
2480
2417
|
} );
|
|
2481
2418
|
}
|
|
2482
|
-
let search = {
|
|
2483
|
-
must: filter,
|
|
2484
|
-
};
|
|
2485
|
-
if ( inputData.searchValue && inputData.searchValue !== '' ) {
|
|
2486
|
-
search ={
|
|
2487
|
-
'must': filter,
|
|
2488
|
-
'should': [
|
|
2489
|
-
{
|
|
2490
|
-
'wildcard': {
|
|
2491
|
-
'RMEmail.keyword': {
|
|
2492
|
-
'value': `*${inputData.searchValue}*`,
|
|
2493
|
-
},
|
|
2494
|
-
},
|
|
2495
|
-
},
|
|
2496
|
-
{
|
|
2497
|
-
'wildcard': {
|
|
2498
|
-
'RMName.keyword': {
|
|
2499
|
-
'value': `*${inputData.searchValue}*`,
|
|
2500
|
-
},
|
|
2501
|
-
},
|
|
2502
|
-
},
|
|
2503
|
-
{
|
|
2504
|
-
'wildcard': {
|
|
2505
|
-
'cluster.keyword': {
|
|
2506
|
-
'value': `*${inputData.searchValue}*`,
|
|
2507
|
-
},
|
|
2508
|
-
},
|
|
2509
|
-
},
|
|
2510
|
-
{
|
|
2511
|
-
'wildcard': {
|
|
2512
|
-
'optumId.keyword': {
|
|
2513
|
-
'value': `*${inputData.searchValue}*`,
|
|
2514
|
-
},
|
|
2515
|
-
},
|
|
2516
|
-
},
|
|
2517
|
-
{
|
|
2518
|
-
'wildcard': {
|
|
2519
|
-
'queueId.keyword': {
|
|
2520
|
-
'value': `*${inputData.searchValue}*`,
|
|
2521
|
-
},
|
|
2522
|
-
},
|
|
2523
|
-
},
|
|
2524
|
-
{
|
|
2525
|
-
'wildcard': {
|
|
2526
|
-
'storeName.keyword': {
|
|
2527
|
-
'value': `*${inputData.searchValue}*`,
|
|
2528
|
-
},
|
|
2529
|
-
},
|
|
2530
|
-
},
|
|
2531
|
-
{
|
|
2532
|
-
'wildcard': {
|
|
2533
|
-
'auditedBy.keyword': {
|
|
2534
|
-
'value': `*${inputData.searchValue}*`,
|
|
2535
|
-
},
|
|
2536
|
-
},
|
|
2537
|
-
},
|
|
2538
|
-
{
|
|
2539
|
-
'wildcard': {
|
|
2540
|
-
'optomEmailId.keyword': {
|
|
2541
|
-
'value': `*${inputData.searchValue}*`,
|
|
2542
|
-
},
|
|
2543
|
-
},
|
|
2544
|
-
},
|
|
2545
|
-
],
|
|
2546
|
-
'minimum_should_match': 1,
|
|
2547
|
-
};
|
|
2548
|
-
}
|
|
2549
2419
|
const getQuery = {
|
|
2550
2420
|
'size': inputData.isExport == true? 50000 : inputData?.limit || 10,
|
|
2551
2421
|
'from': offset || 0,
|
|
2552
2422
|
'query': {
|
|
2553
|
-
'bool':
|
|
2423
|
+
'bool': {
|
|
2424
|
+
'must': filter,
|
|
2425
|
+
},
|
|
2554
2426
|
},
|
|
2555
2427
|
'sort': sort,
|
|
2556
2428
|
};
|
|
2557
2429
|
|
|
2558
|
-
|
|
2559
2430
|
// get query result from the open saerch
|
|
2560
2431
|
const getData= await getOpenSearchData( openSearch.eyeTestEmailAlert, getQuery );
|
|
2561
|
-
const count = getData?.body?.hits?.total?.value;
|
|
2562
2432
|
// throw error if got null or empty array
|
|
2563
2433
|
if ( !getData || getData?.body?.hits?.hits?.length == 0 ) {
|
|
2564
2434
|
return res.sendError( 'No records found', 204 );
|
|
@@ -2566,18 +2436,14 @@ export async function emailAlertLog( req, res ) {
|
|
|
2566
2436
|
let response =[];
|
|
2567
2437
|
for ( let item of getData?.body?.hits?.hits ) {
|
|
2568
2438
|
response.push( {
|
|
2569
|
-
RMEmail: item?._source?.RMEmail
|
|
2570
|
-
RMName: item?._source?.RMName || '',
|
|
2439
|
+
RMEmail: item?._source?.RMEmail,
|
|
2571
2440
|
cluster: item?._source?.cluster,
|
|
2572
2441
|
optumId: item?._source?.optumId,
|
|
2573
|
-
optomEmailId: item?._source?.optomEmailId,
|
|
2574
2442
|
storeName: item?._source?.storeName,
|
|
2575
2443
|
complianceScore: item?._source?.complianceScore,
|
|
2576
|
-
humanScore: item?._source?.humanScore,
|
|
2577
2444
|
trustScore: item?._source?.trustScore,
|
|
2578
2445
|
auditedId: item?._source?.auditedId,
|
|
2579
2446
|
queueId: item?._source?.queueId,
|
|
2580
|
-
auditedBy: item?._source?.auditedBy,
|
|
2581
2447
|
|
|
2582
2448
|
} );
|
|
2583
2449
|
}
|
|
@@ -2611,7 +2477,7 @@ export async function emailAlertLog( req, res ) {
|
|
|
2611
2477
|
|
|
2612
2478
|
|
|
2613
2479
|
logger.info( { inputData: inputData, getData: response } );
|
|
2614
|
-
return res.sendSuccess( { result: response, count:
|
|
2480
|
+
return res.sendSuccess( { result: response, count: response.length } );
|
|
2615
2481
|
} catch ( error ) {
|
|
2616
2482
|
const err = error.message || 'Internal Server Error';
|
|
2617
2483
|
logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-emailAlertLog' } );
|
|
@@ -2771,6 +2637,10 @@ export async function getEmailConfig( req, res ) {
|
|
|
2771
2637
|
configureType: 'email',
|
|
2772
2638
|
};
|
|
2773
2639
|
const getOne = await findOneEyeTestConfig( query, { complianceThreshold: 1, _id: 1 } );
|
|
2640
|
+
logger.info( { getOne: getOne, message: 'getEmailConfig' } );
|
|
2641
|
+
// if ( !getOne?.complianceThreshold ) {
|
|
2642
|
+
// return res.sendError( 'No data found', 204 );
|
|
2643
|
+
// }
|
|
2774
2644
|
if ( !getOne ) {
|
|
2775
2645
|
return res.sendError( ' No data found', 204 );
|
|
2776
2646
|
}
|
|
@@ -64,7 +64,6 @@ export const saveSchema = joi.object( {
|
|
|
64
64
|
spokenLanguage: joi.string().optional(),
|
|
65
65
|
cluster: joi.string().required().allow( '' ),
|
|
66
66
|
RMEmail: joi.string().required().allow( '' ),
|
|
67
|
-
isReSend: joi.boolean().optional(),
|
|
68
67
|
} );
|
|
69
68
|
|
|
70
69
|
export const saveValid = {
|
|
@@ -157,7 +156,7 @@ export const summaryListSchema = joi.object( {
|
|
|
157
156
|
).optional(),
|
|
158
157
|
storeId: joi.array().items( joi.string().required() ).required(),
|
|
159
158
|
complianceScore: joi.array().items( joi.string().required() ).optional(),
|
|
160
|
-
nearAddition: joi.string().optional().allow( ''
|
|
159
|
+
nearAddition: joi.string().optional().allow( '' ),
|
|
161
160
|
isExport: joi.boolean().optional(),
|
|
162
161
|
searchValue: joi.string().optional().allow( '' ),
|
|
163
162
|
sortBy: joi.string().optional(),
|
|
@@ -235,7 +234,7 @@ export const summaryCardSchema = joi.object( {
|
|
|
235
234
|
).optional(),
|
|
236
235
|
storeId: joi.array().items( joi.string().required() ).required(),
|
|
237
236
|
complianceScore: joi.array().items( joi.string().required() ).optional(),
|
|
238
|
-
nearAddition: joi.string().optional().allow( ''
|
|
237
|
+
nearAddition: joi.string().optional().allow( '' ),
|
|
239
238
|
category: joi.string().optional() .valid( 'fake', 'genuine' ),
|
|
240
239
|
} );
|
|
241
240
|
|
|
@@ -280,8 +279,12 @@ export const emailAlertLogSchema = joi.object( {
|
|
|
280
279
|
|
|
281
280
|
return value;
|
|
282
281
|
} ),
|
|
282
|
+
type: joi.string().required().messages( {
|
|
283
|
+
'any.required': 'Type is required',
|
|
284
|
+
'string.empty': 'Type cannot be empty',
|
|
285
|
+
} ),
|
|
283
286
|
RMList: joi.array().items(
|
|
284
|
-
joi.string().
|
|
287
|
+
joi.string().optional(),
|
|
285
288
|
).optional(),
|
|
286
289
|
clientId: joi.string().when( '$userType', {
|
|
287
290
|
is: 'tango',
|
|
@@ -291,7 +294,7 @@ export const emailAlertLogSchema = joi.object( {
|
|
|
291
294
|
} ),
|
|
292
295
|
otherwise: joi.optional(),
|
|
293
296
|
} ),
|
|
294
|
-
cluster: joi.array().items( joi.string().required() ).
|
|
297
|
+
cluster: joi.array().items( joi.string().required() ).required(),
|
|
295
298
|
isExport: joi.boolean().optional(),
|
|
296
299
|
searchValue: joi.string().optional().allow( '' ),
|
|
297
300
|
sortBy: joi.string().optional(),
|
|
@@ -410,7 +413,6 @@ export const getEmailConfigSchema = joi.object( {
|
|
|
410
413
|
} ),
|
|
411
414
|
otherwise: joi.optional(),
|
|
412
415
|
} ),
|
|
413
|
-
|
|
414
416
|
} );
|
|
415
417
|
|
|
416
418
|
export const getEmailConfigValid = {
|
|
@@ -3,14 +3,14 @@ import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
|
|
|
3
3
|
import { accessVerification } from 'tango-app-api-middleware';
|
|
4
4
|
import { cancelValid, clusterListValid, emailAlertLogValid, getEmailConfigValid, getFileHistoryValid, getFileValid, getListValid, getUserConfigValid, rmListValid, saveValid, summaryCardValid, summaryListValid, updateEmailConfigValid, updateUserConfigValid, userAuditedDataValid, viewFileValid } from '../dtos/eyeTestAudit.dtos.js';
|
|
5
5
|
import { addUserConfig, cancel, clusterList, emailAlertLog, getEmailConfig, getFile, getFileHistory, getList, getUserConfig, rmList, save, summaryCard, summaryList, updateEmailConfig, updateEmailConfig1, updateUserConfig, userAuditedData, viewFile } from '../controllers/eyeTestAudit.controllers.js';
|
|
6
|
-
import { isSuperAdmin, roleValidation
|
|
6
|
+
import { isSuperAdmin, roleValidation } from '../validation/eyeTest.validation.js';
|
|
7
7
|
|
|
8
8
|
export const eyeTestAuditRouter = Router();
|
|
9
9
|
|
|
10
10
|
eyeTestAuditRouter.post( '/get-list', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( getListValid ), getList );
|
|
11
11
|
eyeTestAuditRouter.get( '/view-file/:id', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( viewFileValid ), viewFile );
|
|
12
12
|
eyeTestAuditRouter.get( '/get-file/:id', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( getFileValid ), getFile );
|
|
13
|
-
eyeTestAuditRouter.post( '/save', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( saveValid ),
|
|
13
|
+
eyeTestAuditRouter.post( '/save', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( saveValid ), save );
|
|
14
14
|
eyeTestAuditRouter.post( '/cancel', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( cancelValid ), cancel );
|
|
15
15
|
eyeTestAuditRouter.get( '/get-file-history/:id/:type', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( getFileHistoryValid ), getFileHistory );
|
|
16
16
|
eyeTestAuditRouter.get( '/user-audited-data/:id', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( userAuditedDataValid ), userAuditedData );
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { SESClient, SendEmailCommand } from '@aws-sdk/client-ses';
|
|
1
|
+
import { logger } from 'tango-app-api-middleware';
|
|
3
2
|
|
|
4
3
|
export async function roleValidation( req, res, next ) {
|
|
5
4
|
try {
|
|
@@ -40,118 +39,3 @@ export async function isSuperAdmin( req, res, next ) {
|
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
export async function sendAlert( req, res, next ) {
|
|
44
|
-
try {
|
|
45
|
-
const inputData = req.body;
|
|
46
|
-
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
47
|
-
if ( inputData.auditStatus == 'ReAudited' && inputData.type == 'physical' && inputData?.isReSend == undefined ) {
|
|
48
|
-
const getOne = await getOpenSearchById( openSearch.EyeTestInput, inputData.id );
|
|
49
|
-
const id = `${inputData.id}_${getOne?.body?._source?.optumId}_${inputData.fileId}`;
|
|
50
|
-
const getId = await getOpenSearchById( openSearch.eyeTestEmailAlert, id );
|
|
51
|
-
const inputUpdatedData = getId?.body;
|
|
52
|
-
if ( inputUpdatedData ) {
|
|
53
|
-
return res.sendError( 'Do you want resend mail?', 202 );
|
|
54
|
-
} else {
|
|
55
|
-
return next();
|
|
56
|
-
}
|
|
57
|
-
} else {
|
|
58
|
-
return next();
|
|
59
|
-
}
|
|
60
|
-
} catch ( error ) {
|
|
61
|
-
const err = error.message;
|
|
62
|
-
return res.sendError( err, 500 );
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Send HTML Email using AWS SES
|
|
68
|
-
* @param {Object} params
|
|
69
|
-
* @param {string} params.toEmail - Recipient email address
|
|
70
|
-
* @param {string} params.userName - Recipient name
|
|
71
|
-
* @param {number} params.compliancePercentage - Compliance score
|
|
72
|
-
*/
|
|
73
|
-
export async function sendComplianceEmail( {
|
|
74
|
-
toEmail,
|
|
75
|
-
fromEmail, // sender email added here
|
|
76
|
-
userName,
|
|
77
|
-
compliancePercentage,
|
|
78
|
-
} ) {
|
|
79
|
-
// Initialize AWS SES client
|
|
80
|
-
const sesClient = new SESClient( {
|
|
81
|
-
region: 'ap-south-1', // Change to your AWS region
|
|
82
|
-
credentials: {
|
|
83
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
84
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
85
|
-
},
|
|
86
|
-
} );
|
|
87
|
-
const htmlBody = `
|
|
88
|
-
<!DOCTYPE html>
|
|
89
|
-
<html>
|
|
90
|
-
<head>
|
|
91
|
-
<meta charset="UTF-8" />
|
|
92
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
93
|
-
<title>Non Compliance Report</title>
|
|
94
|
-
<style>
|
|
95
|
-
body { font-family: 'Inter', sans-serif; margin: 0; padding: 24px; background: #f9fafb; color: #121a26; }
|
|
96
|
-
.container { max-width: 700px; background: #fff; padding: 24px; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
|
|
97
|
-
.title { font-size: 24px; font-weight: 700; color: #121a26; }
|
|
98
|
-
.subtitle { font-size: 16px; color: #384860; line-height: 1.5; margin-top: 8px; }
|
|
99
|
-
.table { width: 100%; border-collapse: collapse; margin-top: 16px; }
|
|
100
|
-
.table th, .table td { text-align: left; padding: 12px 16px; border-bottom: 1px solid #eaeef0; color: #667085; }
|
|
101
|
-
.footer { margin-top: 32px; font-size: 14px; color: #384860; }
|
|
102
|
-
.compliance { font-size: 18px; font-weight: 700; color: #f04438; margin-top: 16px; }
|
|
103
|
-
</style>
|
|
104
|
-
</head>
|
|
105
|
-
<body>
|
|
106
|
-
<div class="container">
|
|
107
|
-
<p class="title">Non Compliance on Eye Test Procedures</p>
|
|
108
|
-
<p class="subtitle">
|
|
109
|
-
Dear ${userName},<br><br>
|
|
110
|
-
Please ensure that all conducted eye tests meet the required compliance standards.<br>
|
|
111
|
-
Your prompt attention to this matter will help us maintain the highest standards and avoid any discrepancies.<br>
|
|
112
|
-
Please take a look at the below findings.
|
|
113
|
-
</p>
|
|
114
|
-
|
|
115
|
-
<table class="table">
|
|
116
|
-
<thead>
|
|
117
|
-
<tr>
|
|
118
|
-
<th>RM Name</th>
|
|
119
|
-
<th>Comments</th>
|
|
120
|
-
</tr>
|
|
121
|
-
</thead>
|
|
122
|
-
<tbody>
|
|
123
|
-
<tr><td>JCC (Jackson Cross Cylinder)</td><td>Lorem ipsum dolor sit amet consectetur.</td></tr>
|
|
124
|
-
<tr><td>DuoChrome Test</td><td>Lorem ipsum dolor sit amet consectetur.</td></tr>
|
|
125
|
-
<tr><td>Prescription Verification</td><td>Lorem ipsum dolor sit amet consectetur.</td></tr>
|
|
126
|
-
<tr><td>Distance-VA-Check</td><td>Lorem ipsum dolor sit amet consectetur.</td></tr>
|
|
127
|
-
</tbody>
|
|
128
|
-
</table>
|
|
129
|
-
|
|
130
|
-
<p class="compliance">Compliance Percentage: ${compliancePercentage}%</p>
|
|
131
|
-
<p class="footer">Regards,<br>Team Tango</p>
|
|
132
|
-
</div>
|
|
133
|
-
</body>
|
|
134
|
-
</html>`;
|
|
135
|
-
|
|
136
|
-
const params = {
|
|
137
|
-
Source: fromEmail, // sender email (must be verified in SES)
|
|
138
|
-
Destination: {
|
|
139
|
-
ToAddresses: [ toEmail ],
|
|
140
|
-
},
|
|
141
|
-
Message: {
|
|
142
|
-
Subject: { Data: 'Non Compliance on Eye Test Procedures' },
|
|
143
|
-
Body: { Html: { Data: htmlBody } },
|
|
144
|
-
},
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
try {
|
|
148
|
-
const response = await sesClient.send( new SendEmailCommand( params ) );
|
|
149
|
-
// console.log( 'Email sent successfully:', response.MessageId );
|
|
150
|
-
return response;
|
|
151
|
-
} catch ( error ) {
|
|
152
|
-
// console.error( 'Error sending email:', error );
|
|
153
|
-
throw error;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
|