tango-app-api-audit 3.4.68-beta.0 → 3.4.68-beta.10
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,7 +1,13 @@
|
|
|
1
|
-
import { getOpenSearchData, insertOpenSearchData,
|
|
1
|
+
import { getOpenSearchData, getOpenSearchById, logger, insertOpenSearchData, updateOpenSearchData, download, chunkArray } from 'tango-app-api-middleware';
|
|
2
2
|
import { findOneUser } from '../service/user.service.js';
|
|
3
3
|
import mongoose from 'mongoose';
|
|
4
4
|
import dayjs from 'dayjs';
|
|
5
|
+
import utc from 'dayjs/plugin/utc.js';
|
|
6
|
+
import timezone from 'dayjs/plugin/timezone.js';
|
|
7
|
+
import 'dayjs/locale/en.js';
|
|
8
|
+
|
|
9
|
+
dayjs.extend( utc );
|
|
10
|
+
dayjs.extend( timezone );
|
|
5
11
|
|
|
6
12
|
export async function getList( req, res ) {
|
|
7
13
|
try {
|
|
@@ -10,7 +16,8 @@ export async function getList( req, res ) {
|
|
|
10
16
|
const limit = inputData.limit || 10;
|
|
11
17
|
const offset = inputData.offset ? ( inputData.offset - 1 ) * limit : 0;
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
const sortBy = inputData?.sortBy ? `${inputData.sortBy}.keyword` : 'storeName.keyword';
|
|
20
|
+
const order = inputData?.sortOrder || -1;
|
|
14
21
|
let filter= [
|
|
15
22
|
{
|
|
16
23
|
'range': {
|
|
@@ -22,21 +29,24 @@ export async function getList( req, res ) {
|
|
|
22
29
|
},
|
|
23
30
|
|
|
24
31
|
];
|
|
25
|
-
let search ={
|
|
26
|
-
'must': filter,
|
|
27
|
-
};
|
|
28
32
|
|
|
29
|
-
if ( inputData.visitorsType && inputData.visitorsType.lenght > 0 ) {
|
|
30
|
-
filter.push( {
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
// if ( inputData.demographics && inputData.demographics.length > 0 ) {
|
|
35
|
+
// filter.push( {
|
|
36
|
+
// 'terms': {
|
|
37
|
+
// 'visitorsType.keyword': inputData.demographics,
|
|
38
|
+
// },
|
|
39
|
+
// } );
|
|
40
|
+
// }
|
|
41
|
+
if ( inputData.type && inputData.type!='' ) {
|
|
42
|
+
filter.push( {
|
|
43
|
+
'term': {
|
|
44
|
+
'type.keyword': inputData.type,
|
|
34
45
|
},
|
|
35
46
|
|
|
36
47
|
} );
|
|
37
48
|
}
|
|
38
|
-
|
|
39
|
-
if ( inputData.storeId && inputData.storeId.lenght > 0 ) {
|
|
49
|
+
if ( inputData.storeId && inputData.storeId.length > 0 ) {
|
|
40
50
|
filter.push( {
|
|
41
51
|
|
|
42
52
|
'terms': {
|
|
@@ -45,6 +55,9 @@ export async function getList( req, res ) {
|
|
|
45
55
|
|
|
46
56
|
} );
|
|
47
57
|
}
|
|
58
|
+
let search ={
|
|
59
|
+
'must': filter,
|
|
60
|
+
};
|
|
48
61
|
|
|
49
62
|
if ( inputData.searchValue && inputData.searchValue !== '' ) {
|
|
50
63
|
search ={
|
|
@@ -103,14 +116,41 @@ export async function getList( req, res ) {
|
|
|
103
116
|
'minimum_should_match': 1,
|
|
104
117
|
};
|
|
105
118
|
}
|
|
106
|
-
|
|
107
119
|
let searchQuery={
|
|
108
120
|
'from': offset,
|
|
109
121
|
'size': limit,
|
|
110
122
|
'query': {
|
|
111
123
|
'bool': search,
|
|
112
124
|
},
|
|
125
|
+
'sort': [
|
|
126
|
+
{ date: { order: 'desc' } },
|
|
127
|
+
],
|
|
113
128
|
};
|
|
129
|
+
if ( sortBy && sortBy !== '' ) {
|
|
130
|
+
searchQuery={
|
|
131
|
+
'from': offset,
|
|
132
|
+
'size': limit,
|
|
133
|
+
'query': {
|
|
134
|
+
'bool': search,
|
|
135
|
+
},
|
|
136
|
+
'sort': [
|
|
137
|
+
{ [sortBy]: { order: order === -1 ?'desc':'asc' } },
|
|
138
|
+
],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if ( inputData.isExport==true ) {
|
|
143
|
+
searchQuery={
|
|
144
|
+
'from': 0,
|
|
145
|
+
'size': 10000,
|
|
146
|
+
'query': {
|
|
147
|
+
'bool': search,
|
|
148
|
+
},
|
|
149
|
+
'sort': [
|
|
150
|
+
{ 'storeName.keyword': { order: 'desc' } },
|
|
151
|
+
],
|
|
152
|
+
};
|
|
153
|
+
}
|
|
114
154
|
const result = await getOpenSearchData( openSearch.EyeTestInput, searchQuery );
|
|
115
155
|
const count = result?.body?.hits?.total?.value;
|
|
116
156
|
if ( !count || count == 0 ) {
|
|
@@ -120,6 +160,70 @@ export async function getList( req, res ) {
|
|
|
120
160
|
if ( !searchValue || searchValue?.length == 0 ) {
|
|
121
161
|
return res.sendError( 'No data found', 204 );
|
|
122
162
|
}
|
|
163
|
+
if ( inputData.isExport == true ) {
|
|
164
|
+
const chunkedMappingData = await chunkArray( searchValue, 10 );
|
|
165
|
+
const promises = chunkedMappingData.map( async ( chunk ) => {
|
|
166
|
+
const exportData = [];
|
|
167
|
+
for ( const element of chunk ) {
|
|
168
|
+
const testDuration = element?._source?.testDuration;
|
|
169
|
+
const minutes = Math.floor( testDuration / 60 );
|
|
170
|
+
const seconds = testDuration % 60;
|
|
171
|
+
const minutes1 =minutes> 1? `${minutes} mins` : `${minutes} min`;
|
|
172
|
+
const seconds1 = seconds > 1? `${minutes} secs`: seconds == 1? `${minutes} sec` : '';
|
|
173
|
+
const duration =`${minutes1} ${seconds1}`;
|
|
174
|
+
const userName = await findOneUser( { _id: element?._source?.userId }, { _id: 0, userName: 1 } );
|
|
175
|
+
if ( element?._source?.type == 'physical' ) {
|
|
176
|
+
exportData.push( {
|
|
177
|
+
'Date': dayjs( element?._source?.date ).format( 'YYYY,MMM D' ),
|
|
178
|
+
'Store Name': element?._source?.storeName,
|
|
179
|
+
'Store ID': element?._source?.storeId || 'Un Assigned',
|
|
180
|
+
'Store Name': element?._source?.storeName ||'Un Assigned',
|
|
181
|
+
'Optum ID': element?._source?.optumId,
|
|
182
|
+
'Queue ID': element?._source?.queueId,
|
|
183
|
+
'Compliance Score': element?._source?.totalSteps>0 ? Math.round( ( element?._source?.coveredStepsAI/ element?._source?.totalSteps )*100 ): 0,
|
|
184
|
+
'Steps Covered By AI': element?._source?.coveredStepsAI || 0,
|
|
185
|
+
'Visitor Type': element?._source?.visitorsType,
|
|
186
|
+
'Test Duration': duration || '',
|
|
187
|
+
'Audit Status': element?._source?.auditStatus || '',
|
|
188
|
+
'Audited By': userName?.userName || '',
|
|
189
|
+
|
|
190
|
+
} );
|
|
191
|
+
} else {
|
|
192
|
+
exportData.push( {
|
|
193
|
+
'Date': dayjs( element?._source?.date ).format( 'YYYY,MMM D' ),
|
|
194
|
+
'Store Name': element?._source?.storeName,
|
|
195
|
+
'Store ID': element?._source?.storeId || 'Un Assigned',
|
|
196
|
+
'Store Name': element?._source?.storeName ||'Un Assigned',
|
|
197
|
+
'Engagement ID': element?._source?.engagementId,
|
|
198
|
+
'Compliance Score': element?._source?.complianceScore || 0,
|
|
199
|
+
'Steps Covered By AI': element?._source?.coveredStepsAI || 0,
|
|
200
|
+
'Visitor Type': element?._source?.visitorsType,
|
|
201
|
+
'Test Duration': duration || '',
|
|
202
|
+
'Audit Status': element?._source?.auditStatus || '',
|
|
203
|
+
'Audited By': userName?.userName || '',
|
|
204
|
+
|
|
205
|
+
} );
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return exportData;
|
|
209
|
+
} );
|
|
210
|
+
const mappedArrays = await Promise.all( promises );
|
|
211
|
+
const result = mappedArrays.flat();
|
|
212
|
+
await download( result, res );
|
|
213
|
+
return;
|
|
214
|
+
} else {
|
|
215
|
+
for ( const [ i, item ] of searchValue.entries() ) {
|
|
216
|
+
const userName = await findOneUser( { _id: item?._source?.userId }, { _id: 0, userName: 1 } );
|
|
217
|
+
const testDuration = searchValue[i]?._source?.testDuration;
|
|
218
|
+
const minutes = Math.floor( testDuration / 60 );
|
|
219
|
+
const seconds = testDuration % 60;
|
|
220
|
+
searchValue[i]._source.complianceScore = searchValue[i]?._source?.totalSteps>0 ? Math.round( ( searchValue[i]?._source?.coveredStepsAI/ searchValue[i]?._source?.totalSteps )*100 ): 0;
|
|
221
|
+
searchValue[i]._source.min = minutes;
|
|
222
|
+
searchValue[i]._source.sec = seconds;
|
|
223
|
+
searchValue[i]._source.auditedBy = userName?.userName || '';
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
123
227
|
return res.sendSuccess( { result: searchValue, count: count } );
|
|
124
228
|
} catch ( error ) {
|
|
125
229
|
const err = error.message || 'Internal Server Error';
|
|
@@ -128,18 +232,453 @@ export async function getList( req, res ) {
|
|
|
128
232
|
}
|
|
129
233
|
}
|
|
130
234
|
|
|
235
|
+
export async function viewFile( req, res ) {
|
|
236
|
+
try {
|
|
237
|
+
const inputData = req.params;
|
|
238
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
239
|
+
const url = JSON.parse( process.env.URL );
|
|
240
|
+
let isEnable =true;
|
|
241
|
+
|
|
242
|
+
const getInput = await getOpenSearchById( openSearch.EyeTestInput, inputData.id );
|
|
243
|
+
if ( !getInput || !getInput?.body ) {
|
|
244
|
+
return res.sendError( 'No Data Found', 204 );
|
|
245
|
+
}
|
|
246
|
+
const getData =getInput?.body?._source;
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
let searchFilter =[
|
|
250
|
+
{
|
|
251
|
+
'term': {
|
|
252
|
+
'queueId.keyword': getData?.queueId,
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
'term': {
|
|
258
|
+
'type.keyword': getData?.type,
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
},
|
|
262
|
+
];
|
|
263
|
+
if ( getData?.type == 'remote' ) {
|
|
264
|
+
searchFilter =[
|
|
265
|
+
{
|
|
266
|
+
'term': {
|
|
267
|
+
'engagementId.keyword': getData?.engagementId,
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
'term': {
|
|
273
|
+
'type.keyword': getData?.type,
|
|
274
|
+
},
|
|
275
|
+
|
|
276
|
+
},
|
|
277
|
+
];
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
let searchQuery={
|
|
281
|
+
'size': 1,
|
|
282
|
+
'query': {
|
|
283
|
+
'bool': {
|
|
284
|
+
'must': searchFilter,
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
'sort': [
|
|
288
|
+
{ createdAt: { order: 'desc' } },
|
|
289
|
+
],
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const searchRes= await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
|
|
293
|
+
const temp = searchRes?.body?.hits?.hits?.length > 0? searchRes?.body?.hits?.hits[0] : [];
|
|
294
|
+
|
|
295
|
+
const getUserName = await findOneUser( { _id: new mongoose.Types.ObjectId( temp?._source?.userId ) }, { userName: 1 } );
|
|
296
|
+
|
|
297
|
+
const searchData = temp?
|
|
298
|
+
getData['lastAuditedDetails']= {
|
|
299
|
+
'auditedBy': getUserName?.userName || '',
|
|
300
|
+
'completionTime': temp?._source?.startTime? dayjs.utc( temp?._source?.startTime ).tz( 'Asia/Kolkata' ).format( 'HH:ss:mm' ): '',
|
|
301
|
+
'timeZone': temp?.timeZone || '',
|
|
302
|
+
} : null;
|
|
303
|
+
getData['complianceScore'] = getData.complianceScore || getData?.totalSteps>0 ? Math.round( ( getData?.coveredStepsAI/ getData?.totalSteps )*100 ): 0;
|
|
304
|
+
getData['trustScore'] = getData?.trustScore || 0;
|
|
305
|
+
getData['testDuration'] = Math.round( getData?.testDuration/60 ) || 0;
|
|
306
|
+
getData['filePath'] = `${url[getData?.type]}${getData?.filePath}`;
|
|
307
|
+
getData['auditType'] = getData.auditType || 'Audit';
|
|
308
|
+
const response = getData;
|
|
309
|
+
|
|
310
|
+
switch ( getData?.auditStatus ) {
|
|
311
|
+
case 'Yet-to-Audit':
|
|
312
|
+
isEnable=true;
|
|
313
|
+
break;
|
|
314
|
+
case 'In-Progress':
|
|
315
|
+
if ( searchData.lenght ==0 ) {
|
|
316
|
+
return res.sendError( 'No saved records found', 400 );
|
|
317
|
+
}
|
|
318
|
+
if ( searchData.userId !== req.user._id ) {
|
|
319
|
+
isEnable=false;
|
|
320
|
+
}
|
|
321
|
+
break;
|
|
322
|
+
case 'Audited':
|
|
323
|
+
response['steps']= temp._source?.steps;
|
|
324
|
+
isEnable=true;
|
|
325
|
+
case 'Re-Audited':
|
|
326
|
+
response['steps']= temp._source?.steps;
|
|
327
|
+
isEnable=true;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return res.sendSuccess( { result: response, isEnable: isEnable } );
|
|
331
|
+
} catch ( error ) {
|
|
332
|
+
const err = error.message || 'Internal Server Error';
|
|
333
|
+
logger.error( { message: error, data: req.params, function: 'eyetestAudit-controller-viewFile' } );
|
|
334
|
+
return res.sendError( err, 500 );
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
131
338
|
export async function getFile( req, res ) {
|
|
132
339
|
try {
|
|
133
340
|
const inputData = req.params;
|
|
341
|
+
const url = JSON.parse( process.env.URL );
|
|
134
342
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
135
|
-
|
|
136
|
-
|
|
343
|
+
|
|
344
|
+
const getInput = await getOpenSearchById( openSearch.EyeTestInput, inputData.id );
|
|
345
|
+
if ( !getInput || !getInput?.body ) {
|
|
346
|
+
return res.sendError( 'No Data Found', 204 );
|
|
347
|
+
}
|
|
348
|
+
const getData =getInput?.body?._source;
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
let searchFilter =[
|
|
352
|
+
{
|
|
353
|
+
'terms': {
|
|
354
|
+
'queueId.keyword': getData?.queueId,
|
|
355
|
+
},
|
|
356
|
+
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
'terms': {
|
|
360
|
+
'type.keyword': getData?.type,
|
|
361
|
+
},
|
|
362
|
+
|
|
363
|
+
},
|
|
364
|
+
];
|
|
365
|
+
if ( getData?.type == 'remote' ) {
|
|
366
|
+
searchFilter =[
|
|
367
|
+
{
|
|
368
|
+
'terms': {
|
|
369
|
+
'engagementId.keyword': getData?.engagementId,
|
|
370
|
+
},
|
|
371
|
+
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
'terms': {
|
|
375
|
+
'type.keyword': getData?.type,
|
|
376
|
+
},
|
|
377
|
+
|
|
378
|
+
},
|
|
379
|
+
];
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
let searchQuery={
|
|
383
|
+
'size': 1,
|
|
384
|
+
'query': {
|
|
385
|
+
'bool': {
|
|
386
|
+
'must': searchFilter,
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
'sort': [
|
|
390
|
+
{ createdAt: { order: 'desc' } },
|
|
391
|
+
],
|
|
392
|
+
};
|
|
393
|
+
const searchRes= await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
|
|
394
|
+
const searchData = searchRes?.body?.hits?.hits?.lenght > 0? searchRes?.body?.hits?.hits[0] : null;
|
|
395
|
+
logger.info( { searchData: searchData, getData: getData, messahe: '...........3' } );
|
|
396
|
+
switch ( getData?.auditStatus ) {
|
|
397
|
+
case 'Yet-to-Audit':
|
|
398
|
+
const record= {
|
|
399
|
+
'date': getData?.date,
|
|
400
|
+
'fileDate': getData?.fileDate,
|
|
401
|
+
'storeName': getData?.storeName,
|
|
402
|
+
'storeId': getData?.storeId,
|
|
403
|
+
'userId': req?.user?._id,
|
|
404
|
+
'type': getData?.type,
|
|
405
|
+
'engagementId': getData?.engagementId,
|
|
406
|
+
'queueId': getData?.queueId,
|
|
407
|
+
'optumId': getData?.optumId,
|
|
408
|
+
'displayName': getData?.displayName,
|
|
409
|
+
'complianceScore': getData?.totalSteps>0 ? Math.round( ( getData?.coveredStepsAI/ getData?.totalSteps )*100 ): 0,
|
|
410
|
+
'coveredStepsAI': getData?.coveredStepsAI,
|
|
411
|
+
'auditedSteps': 0,
|
|
412
|
+
'overRides': 0,
|
|
413
|
+
'trustScore': 0,
|
|
414
|
+
'visitorsType': getData?.visitorsType,
|
|
415
|
+
'testDuration': Math.round( getData?.testDuration/60 ) || 0,
|
|
416
|
+
'testStartTime': getData?.testStartTime,
|
|
417
|
+
'testEndTime': getData?.testEndTime,
|
|
418
|
+
'timeZone': 'IST',
|
|
419
|
+
'spokenLanguage': '',
|
|
420
|
+
'auditStatus': 'In-Progress',
|
|
421
|
+
'totalSteps': getData?.totalSteps,
|
|
422
|
+
'inputBucketName': getData?.inputBucketName,
|
|
423
|
+
'filePath': `${url[getData?.type]}${getData?.filePath}`,
|
|
424
|
+
'steps': getData?.steps,
|
|
425
|
+
'startTime': dayjs().tz( 'Asia/Kolkata' ),
|
|
426
|
+
'createdAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
427
|
+
'updatedAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
428
|
+
'auditType': 'Audit',
|
|
429
|
+
|
|
430
|
+
};
|
|
431
|
+
record?.steps?.map( ( item, i ) => {
|
|
432
|
+
record.steps[i]['auditedStatus']= null, record.steps[i]['reason'] = '', record.steps[i]['startTime'] = '', record.steps[i]['endTime'] = '';
|
|
433
|
+
} );
|
|
434
|
+
if ( !searchData ) {
|
|
435
|
+
const data1 = await insertOpenSearchData( openSearch.EyeTestOutput, record );
|
|
436
|
+
logger.info( { data1: data1 } );
|
|
437
|
+
await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: { auditStatus: 'In-Progress', auditType: 'Audit', userId: req?.user?._id } } );
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
break;
|
|
441
|
+
case 'In-Progress':
|
|
442
|
+
|
|
443
|
+
if ( !searchData ) {
|
|
444
|
+
return res.sendError( 'No saved records found', 400 );
|
|
445
|
+
}
|
|
446
|
+
if ( searchData?.userId !== req.user._id ) {
|
|
447
|
+
return res.sendError( 'Forbidden to this action', 403 );
|
|
448
|
+
}
|
|
449
|
+
break;
|
|
450
|
+
case 'Audited':
|
|
451
|
+
case 'Re-Audited':
|
|
452
|
+
const newRecord= {
|
|
453
|
+
'date': getData?.date,
|
|
454
|
+
'fileDate': getData?.fileDate,
|
|
455
|
+
'storeName': getData?.storeName,
|
|
456
|
+
'storeId': getData?.storeId,
|
|
457
|
+
'userId': req?.user?._id,
|
|
458
|
+
'type': getData?.type,
|
|
459
|
+
'engagementId': getData?.engagementId,
|
|
460
|
+
'queueId': getData?.queueId,
|
|
461
|
+
'optumId': getData?.optumId,
|
|
462
|
+
'displayName': getData?.displayName,
|
|
463
|
+
'complianceScore': getData?.totalSteps>0 ? Math.round( ( getData?.coveredStepsAI/ getData?.totalSteps )*100 ): 0,
|
|
464
|
+
'coveredStepsAI': getData?.coveredStepsAI,
|
|
465
|
+
'auditedSteps': getData?.auditedSteps || 0,
|
|
466
|
+
'overRides': getData?.overRides || 0,
|
|
467
|
+
'trustScore': getData?.trustScore || 0,
|
|
468
|
+
'visitorsType': getData?.visitorsType,
|
|
469
|
+
'testDuration': getData?.testDuration,
|
|
470
|
+
'testStartTime': getData?.testStartTime,
|
|
471
|
+
'testEndTime': getData?.testEndTime,
|
|
472
|
+
'timeZone': getData?.timeZone,
|
|
473
|
+
'spokenLanguage': getData?.spokenLanguage || '',
|
|
474
|
+
'auditStatus': 'In-Progress',
|
|
475
|
+
'totalSteps': getData?.totalSteps,
|
|
476
|
+
'filePath': `${url[getData?.type]}${getData?.filePath}`,
|
|
477
|
+
'steps': getData?.steps,
|
|
478
|
+
'auditType': 'Re-Audit',
|
|
479
|
+
'startTime': dayjs().tz( 'Asia/Kolkata' ),
|
|
480
|
+
'createdAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
481
|
+
'updatedAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
482
|
+
|
|
483
|
+
};
|
|
484
|
+
await insertOpenSearchData( openSearch.EyeTestOutput, newRecord );
|
|
485
|
+
await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: { auditStatus: 'In-Progress', auditType: 'Re-Audit' } } );
|
|
486
|
+
|
|
487
|
+
break;
|
|
488
|
+
default:
|
|
489
|
+
return res.sendError( 'Status must be valid', 400 );
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
return res.sendSuccess( 'The status has been updated' );
|
|
137
493
|
} catch ( error ) {
|
|
138
494
|
const err = error.message || 'Internal Server Error';
|
|
139
495
|
logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-getFile' } );
|
|
140
496
|
return res.sendError( err, 500 );
|
|
141
497
|
}
|
|
142
498
|
}
|
|
499
|
+
export async function save( req, res ) {
|
|
500
|
+
try {
|
|
501
|
+
const inputData = req.body;
|
|
502
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
503
|
+
|
|
504
|
+
let searchFilter =[
|
|
505
|
+
{
|
|
506
|
+
'term': {
|
|
507
|
+
'queueId.keyword': inputData?.fileId,
|
|
508
|
+
},
|
|
509
|
+
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
'term': {
|
|
513
|
+
'type.keyword': inputData?.type,
|
|
514
|
+
},
|
|
515
|
+
|
|
516
|
+
},
|
|
517
|
+
|
|
518
|
+
{
|
|
519
|
+
'term': {
|
|
520
|
+
'auditStatus.keyword': 'In-Progress',
|
|
521
|
+
},
|
|
522
|
+
},
|
|
523
|
+
];
|
|
524
|
+
if ( inputData?.type == 'remote' ) {
|
|
525
|
+
searchFilter =[
|
|
526
|
+
{
|
|
527
|
+
'term': {
|
|
528
|
+
'engagementId.keyword': inputData?.fileId,
|
|
529
|
+
},
|
|
530
|
+
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
'term': {
|
|
534
|
+
'type.keyword': inputData?.type,
|
|
535
|
+
},
|
|
536
|
+
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
'term': {
|
|
540
|
+
'userId.keyword': req?.user?._id,
|
|
541
|
+
},
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
'term': {
|
|
545
|
+
'auditStatus.keyword': 'In-Progress',
|
|
546
|
+
},
|
|
547
|
+
},
|
|
548
|
+
];
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
let searchQuery={
|
|
552
|
+
'size': 1,
|
|
553
|
+
'query': {
|
|
554
|
+
'bool': {
|
|
555
|
+
'must': searchFilter,
|
|
556
|
+
},
|
|
557
|
+
},
|
|
558
|
+
};
|
|
559
|
+
const getOutput = await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
|
|
560
|
+
logger.info( { getOutput: getOutput } );
|
|
561
|
+
const output = getOutput?.body?.hits?.hits?.length > 0 ? getOutput?.body?.hits?.hits[0] : null;
|
|
562
|
+
if ( !output ) {
|
|
563
|
+
return res.sendError( 'No saved records found', 400 );
|
|
564
|
+
}
|
|
565
|
+
const record ={
|
|
566
|
+
steps: inputData?.steps,
|
|
567
|
+
auditStatus: inputData?.auditStatus,
|
|
568
|
+
auditedSteps: inputData?.auditedSteps,
|
|
569
|
+
overRides: inputData?.overRides,
|
|
570
|
+
trustScore: Math.round( 100-( ( inputData?.overRides / inputData?.steps?.length ) * 100 ) ),
|
|
571
|
+
spokenLanguage: inputData?.spokenLanguage,
|
|
572
|
+
endTime: dayjs().tz( 'Asia/Kolkata' ),
|
|
573
|
+
|
|
574
|
+
};
|
|
575
|
+
const inputrecord ={
|
|
576
|
+
|
|
577
|
+
auditStatus: inputData?.auditStatus,
|
|
578
|
+
auditedSteps: inputData?.auditedSteps,
|
|
579
|
+
overRides: inputData?.overRides,
|
|
580
|
+
trustScore: Math.round( 100-( ( inputData?.overRides / inputData?.steps?.length ) * 100 ) ),
|
|
581
|
+
spokenLanguage: inputData?.spokenLanguage,
|
|
582
|
+
endTime: dayjs().tz( 'Asia/Kolkata' ),
|
|
583
|
+
|
|
584
|
+
};
|
|
585
|
+
await updateOpenSearchData( openSearch.EyeTestOutput, output?._id, { doc: record } );
|
|
586
|
+
await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: inputrecord } );
|
|
587
|
+
return res.sendSuccess( 'The file has been submited successfully' );
|
|
588
|
+
} catch ( error ) {
|
|
589
|
+
const err = error.message || 'Internal Server Error';
|
|
590
|
+
logger.error( { message: error, data: req.params, function: 'eyetestAudit-controller-save' } );
|
|
591
|
+
return res.sendError( err, 500 );
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
export async function cancel( req, res ) {
|
|
596
|
+
try {
|
|
597
|
+
const inputData = req.body;
|
|
598
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
599
|
+
|
|
600
|
+
let searchFilter =[
|
|
601
|
+
{
|
|
602
|
+
'term': {
|
|
603
|
+
'queueId.keyword': inputData?.fileId,
|
|
604
|
+
},
|
|
605
|
+
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
'term': {
|
|
609
|
+
'type.keyword': inputData?.type,
|
|
610
|
+
},
|
|
611
|
+
|
|
612
|
+
},
|
|
613
|
+
|
|
614
|
+
{
|
|
615
|
+
'term': {
|
|
616
|
+
'auditStatus.keyword': 'In-Progress',
|
|
617
|
+
},
|
|
618
|
+
},
|
|
619
|
+
];
|
|
620
|
+
if ( inputData?.type == 'remote' ) {
|
|
621
|
+
searchFilter =[
|
|
622
|
+
{
|
|
623
|
+
'term': {
|
|
624
|
+
'engagementId.keyword': inputData?.fileId,
|
|
625
|
+
},
|
|
626
|
+
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
'term': {
|
|
630
|
+
'type.keyword': inputData?.type,
|
|
631
|
+
},
|
|
632
|
+
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
'term': {
|
|
636
|
+
'userId.keyword': req?.user?._id,
|
|
637
|
+
},
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
'term': {
|
|
641
|
+
'auditStatus.keyword': 'In-Progress',
|
|
642
|
+
},
|
|
643
|
+
},
|
|
644
|
+
];
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
let searchQuery={
|
|
648
|
+
'size': 1,
|
|
649
|
+
'query': {
|
|
650
|
+
'bool': {
|
|
651
|
+
'must': searchFilter,
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
};
|
|
655
|
+
const getOutput = await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
|
|
656
|
+
logger.info( { getOutput: getOutput } );
|
|
657
|
+
const output = getOutput?.body?.hits?.hits?.length > 0 ? getOutput?.body?.hits?.hits[0] : null;
|
|
658
|
+
if ( !output ) {
|
|
659
|
+
return res.sendError( 'No saved records found', 400 );
|
|
660
|
+
}
|
|
661
|
+
const record1 ={
|
|
662
|
+
|
|
663
|
+
auditStatus: 'Skipped',
|
|
664
|
+
endTime: dayjs().tz( 'Asia/Kolkata' ),
|
|
665
|
+
|
|
666
|
+
};
|
|
667
|
+
const record2 ={
|
|
668
|
+
|
|
669
|
+
auditStatus: 'Yet-to-Audit',
|
|
670
|
+
endTime: dayjs().tz( 'Asia/Kolkata' ),
|
|
671
|
+
|
|
672
|
+
};
|
|
673
|
+
await updateOpenSearchData( openSearch.EyeTestOutput, output?._id, { doc: record1 } );
|
|
674
|
+
await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: record2 } );
|
|
675
|
+
return res.sendSuccess( 'The file has canceled ' );
|
|
676
|
+
} catch ( error ) {
|
|
677
|
+
const err = error.message || 'Internal Server Error';
|
|
678
|
+
logger.error( { message: error, data: req.params, function: 'eyetestAudit-controller-cancel' } );
|
|
679
|
+
return res.sendError( err, 500 );
|
|
680
|
+
}
|
|
681
|
+
}
|
|
143
682
|
|
|
144
683
|
export async function getFileHistory( req, res ) {
|
|
145
684
|
try {
|
|
@@ -157,7 +696,11 @@ export async function getFileHistory( req, res ) {
|
|
|
157
696
|
'queueId.keyword': inputData.id,
|
|
158
697
|
},
|
|
159
698
|
},
|
|
160
|
-
|
|
699
|
+
{
|
|
700
|
+
'terms': {
|
|
701
|
+
'auditStatus.keyword': [ 'Audited', 'Re-Audited' ],
|
|
702
|
+
},
|
|
703
|
+
},
|
|
161
704
|
],
|
|
162
705
|
},
|
|
163
706
|
},
|
|
@@ -173,7 +716,11 @@ export async function getFileHistory( req, res ) {
|
|
|
173
716
|
'engagementId.keyword': inputData.id,
|
|
174
717
|
},
|
|
175
718
|
},
|
|
176
|
-
|
|
719
|
+
{
|
|
720
|
+
'terms': {
|
|
721
|
+
'auditStatus.keyword': [ 'Audited', 'Re-Audited' ],
|
|
722
|
+
},
|
|
723
|
+
},
|
|
177
724
|
],
|
|
178
725
|
},
|
|
179
726
|
},
|
|
@@ -185,13 +732,14 @@ export async function getFileHistory( req, res ) {
|
|
|
185
732
|
let sourcesArray = resposnse.body.hits.hits.map( ( hit ) => hit );
|
|
186
733
|
let outputData=[];
|
|
187
734
|
for ( let data of sourcesArray ) {
|
|
735
|
+
// console.log( data._source.endTime );
|
|
188
736
|
let findUser= await findOneUser( { _id: new mongoose.Types.ObjectId( data._source.userId ) } );
|
|
189
737
|
outputData.push( {
|
|
190
738
|
_id: data._id,
|
|
191
739
|
userId: data._source.userId,
|
|
192
740
|
userName: findUser.userName,
|
|
193
741
|
Date: dayjs( data._source.endTime ).format( 'DD/MM/YYYY' ),
|
|
194
|
-
Time: dayjs( data._source.endTime ).format( 'HH:
|
|
742
|
+
Time: dayjs.utc( data._source.endTime ).tz( 'Asia/Kolkata' ).format( 'HH:ss:mm' ),
|
|
195
743
|
} );
|
|
196
744
|
}
|
|
197
745
|
|
|
@@ -210,7 +758,9 @@ export async function userAuditedData( req, res ) {
|
|
|
210
758
|
try {
|
|
211
759
|
const parsedOpenSearch = JSON.parse( process.env.OPENSEARCH );
|
|
212
760
|
const inputData = req.params;
|
|
761
|
+
|
|
213
762
|
const resposnse = await getOpenSearchById( parsedOpenSearch.EyeTestOutput, inputData.id );
|
|
763
|
+
|
|
214
764
|
if ( resposnse.body&&resposnse.body._source ) {
|
|
215
765
|
return res.sendSuccess( { result: resposnse.body._source.steps } );
|
|
216
766
|
} else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import j2s from 'joi-to-swagger';
|
|
2
|
-
import { getListSchema, getFileSchema, getFileHistorySchema, userAuditedDataSchema } from '../dtos/eyeTestAudit.dtos.js';
|
|
2
|
+
import { getListSchema, getFileSchema, getFileHistorySchema, userAuditedDataSchema, viewFileSchema, saveSchema, cancelSchema } from '../dtos/eyeTestAudit.dtos.js';
|
|
3
3
|
|
|
4
4
|
export const eyeTestAuditDocs = {
|
|
5
5
|
|
|
@@ -25,21 +25,38 @@ export const eyeTestAuditDocs = {
|
|
|
25
25
|
},
|
|
26
26
|
},
|
|
27
27
|
|
|
28
|
-
'/v3/eye-test-audit/
|
|
28
|
+
'/v3/eye-test-audit/view-file/{id}': {
|
|
29
29
|
get: {
|
|
30
30
|
tags: [ 'Eye Test Audit' ],
|
|
31
|
-
description: '
|
|
32
|
-
operationId: '
|
|
31
|
+
description: 'View a file via Open Serach',
|
|
32
|
+
operationId: 'view-file',
|
|
33
33
|
parameters: [
|
|
34
34
|
{
|
|
35
35
|
in: 'path',
|
|
36
36
|
name: 'id',
|
|
37
|
-
scema: j2s(
|
|
37
|
+
scema: j2s( viewFileSchema ).swagger,
|
|
38
38
|
require: true,
|
|
39
39
|
},
|
|
40
|
+
],
|
|
41
|
+
responses: {
|
|
42
|
+
200: { description: 'Successful' },
|
|
43
|
+
401: { description: 'Unauthorized User' },
|
|
44
|
+
422: { description: 'Field Error' },
|
|
45
|
+
500: { description: 'Server Error' },
|
|
46
|
+
204: { description: 'Not Found' },
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
'/v3/eye-test-audit/get-file/{id}': {
|
|
52
|
+
get: {
|
|
53
|
+
tags: [ 'Eye Test Audit' ],
|
|
54
|
+
description: 'Get a file via Open Serach',
|
|
55
|
+
operationId: 'get-file',
|
|
56
|
+
parameters: [
|
|
40
57
|
{
|
|
41
58
|
in: 'path',
|
|
42
|
-
name: '
|
|
59
|
+
name: 'id',
|
|
43
60
|
scema: j2s( getFileSchema ).swagger,
|
|
44
61
|
require: true,
|
|
45
62
|
},
|
|
@@ -54,6 +71,50 @@ export const eyeTestAuditDocs = {
|
|
|
54
71
|
},
|
|
55
72
|
},
|
|
56
73
|
|
|
74
|
+
'/v3/eye-test-audit/save': {
|
|
75
|
+
post: {
|
|
76
|
+
tags: [ 'Eye Test Audit' ],
|
|
77
|
+
description: 'submit eytest audit',
|
|
78
|
+
operationId: 'save',
|
|
79
|
+
requestBody: {
|
|
80
|
+
content: {
|
|
81
|
+
'application/json': {
|
|
82
|
+
schema: j2s( saveSchema ).swagger,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
responses: {
|
|
87
|
+
200: { description: 'Successful' },
|
|
88
|
+
401: { description: 'Unauthorized User' },
|
|
89
|
+
422: { description: 'Field Error' },
|
|
90
|
+
500: { description: 'Server Error' },
|
|
91
|
+
204: { description: 'Not Found' },
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
'/v3/eye-test-audit/cancel': {
|
|
97
|
+
post: {
|
|
98
|
+
tags: [ 'Eye Test Audit' ],
|
|
99
|
+
description: 'cancel eytest audit',
|
|
100
|
+
operationId: 'cancel',
|
|
101
|
+
requestBody: {
|
|
102
|
+
content: {
|
|
103
|
+
'application/json': {
|
|
104
|
+
schema: j2s( cancelSchema ).swagger,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
responses: {
|
|
109
|
+
200: { description: 'Successful' },
|
|
110
|
+
401: { description: 'Unauthorized User' },
|
|
111
|
+
422: { description: 'Field Error' },
|
|
112
|
+
500: { description: 'Server Error' },
|
|
113
|
+
204: { description: 'Not Found' },
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
|
|
57
118
|
'/v3/eye-test-audit/get-file-history/{id}': {
|
|
58
119
|
get: {
|
|
59
120
|
tags: [ 'Eye Test Audit' ],
|
|
@@ -11,6 +11,8 @@ export const getListSchema = joi.object(
|
|
|
11
11
|
offset: joi.number().optional(),
|
|
12
12
|
searchValue: joi.string().optional().allow( '' ),
|
|
13
13
|
isExport: joi.boolean().optional(),
|
|
14
|
+
sortBy: joi.string().optional(),
|
|
15
|
+
sortOrder: joi.number().optional(),
|
|
14
16
|
},
|
|
15
17
|
);
|
|
16
18
|
|
|
@@ -18,16 +20,50 @@ export const getListValid = {
|
|
|
18
20
|
body: getListSchema,
|
|
19
21
|
};
|
|
20
22
|
|
|
23
|
+
export const viewFileSchema = joi.object( {
|
|
24
|
+
id: joi.string().required(),
|
|
25
|
+
} );
|
|
26
|
+
|
|
27
|
+
export const viewFileValid = {
|
|
28
|
+
params: viewFileSchema,
|
|
29
|
+
};
|
|
30
|
+
|
|
21
31
|
|
|
22
32
|
export const getFileSchema = joi.object( {
|
|
23
33
|
id: joi.string().required(),
|
|
24
|
-
type: joi.string().required(),
|
|
25
34
|
} );
|
|
26
35
|
|
|
27
36
|
export const getFileValid = {
|
|
28
37
|
params: getFileSchema,
|
|
29
38
|
};
|
|
30
39
|
|
|
40
|
+
export const saveSchema = joi.object( {
|
|
41
|
+
type: joi.string().required(),
|
|
42
|
+
fileId: joi.string().required(),
|
|
43
|
+
id: joi.string().required(),
|
|
44
|
+
steps: joi.array().required(),
|
|
45
|
+
auditedSteps: joi.number().required(),
|
|
46
|
+
auditStatus: joi.string().required(),
|
|
47
|
+
overRides: joi.number().required(),
|
|
48
|
+
spokenLanguage: joi.string().optional(),
|
|
49
|
+
} );
|
|
50
|
+
|
|
51
|
+
export const saveValid = {
|
|
52
|
+
body: saveSchema,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
export const cancelSchema = joi.object( {
|
|
57
|
+
type: joi.string().required(),
|
|
58
|
+
fileId: joi.string().required(),
|
|
59
|
+
id: joi.string().required(),
|
|
60
|
+
} );
|
|
61
|
+
|
|
62
|
+
export const cancelValid = {
|
|
63
|
+
body: cancelSchema,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
|
|
31
67
|
export const getFileHistorySchema = joi.object( {
|
|
32
68
|
id: joi.string().required(),
|
|
33
69
|
type: joi.string().required(),
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
|
|
3
3
|
import { accessVerification } from 'tango-app-api-middleware';
|
|
4
|
-
import { getFileHistoryValid, getFileValid, getListValid, userAuditedDataValid } from '../dtos/eyeTestAudit.dtos.js';
|
|
5
|
-
import { getFile, getFileHistory, getList, userAuditedData } from '../controllers/eyeTestAudit.controllers.js';
|
|
4
|
+
import { cancelValid, getFileHistoryValid, getFileValid, getListValid, saveValid, userAuditedDataValid, viewFileValid } from '../dtos/eyeTestAudit.dtos.js';
|
|
5
|
+
import { cancel, getFile, getFileHistory, getList, save, userAuditedData, viewFile } from '../controllers/eyeTestAudit.controllers.js';
|
|
6
6
|
|
|
7
7
|
export const eyeTestAuditRouter = Router();
|
|
8
8
|
|
|
9
9
|
eyeTestAuditRouter.post( '/get-list', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( getListValid ), getList );
|
|
10
|
-
eyeTestAuditRouter.get( '/
|
|
10
|
+
eyeTestAuditRouter.get( '/view-file/:id', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( viewFileValid ), viewFile );
|
|
11
|
+
eyeTestAuditRouter.get( '/get-file/:id', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( getFileValid ), getFile );
|
|
12
|
+
eyeTestAuditRouter.post( '/save', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( saveValid ), save );
|
|
13
|
+
eyeTestAuditRouter.post( '/cancel', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( cancelValid ), cancel );
|
|
11
14
|
eyeTestAuditRouter.get( '/get-file-history/:id/:type', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( getFileHistoryValid ), getFileHistory );
|
|
12
15
|
eyeTestAuditRouter.get( '/user-audited-data/:id', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( userAuditedDataValid ), userAuditedData );
|
|
13
16
|
|