tango-app-api-audit 3.4.68 → 3.5.0
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/README.md +28 -28
- package/index.js +3 -1
- package/package.json +3 -3
- package/src/controllers/audit.controllers.js +334 -347
- package/src/controllers/eyeTestAudit.controllers.js +889 -0
- package/src/docs/eyeTestAudit.docs.js +163 -0
- package/src/dtos/eyeTestAudit.dtos.js +97 -0
- package/src/routes/eyeTestAudit.routes.js +18 -0
|
@@ -0,0 +1,889 @@
|
|
|
1
|
+
import { getOpenSearchData, getOpenSearchById, logger, insertOpenSearchData, updateOpenSearchData, download, chunkArray } from 'tango-app-api-middleware';
|
|
2
|
+
import { findOneUser } from '../service/user.service.js';
|
|
3
|
+
import mongoose from 'mongoose';
|
|
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 );
|
|
11
|
+
|
|
12
|
+
export async function getList( req, res ) {
|
|
13
|
+
try {
|
|
14
|
+
const inputData = req.body;
|
|
15
|
+
if ( inputData.clientId !== '11' ) {
|
|
16
|
+
return res.sendError( 'No data found', 204 );
|
|
17
|
+
}
|
|
18
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
19
|
+
const limit = inputData.limit || 10;
|
|
20
|
+
const offset = inputData.offset ? ( inputData.offset - 1 ) * limit : 0;
|
|
21
|
+
|
|
22
|
+
const sortBy = inputData?.sortBy ? inputData.sortBy === 'coveredStepsAI'||inputData.sortBy==='updatedAt' ? inputData.sortBy :`${inputData.sortBy}.keyword` : 'storeName.keyword';
|
|
23
|
+
const order = inputData?.sortOrder || -1;
|
|
24
|
+
let filter= [
|
|
25
|
+
{
|
|
26
|
+
'range': {
|
|
27
|
+
'date': {
|
|
28
|
+
'gte': new Date( inputData.fromDate ),
|
|
29
|
+
'lte': new Date( inputData.toDate ),
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
if ( inputData.demographics && inputData.demographics.length > 0 ) {
|
|
38
|
+
filter.push( {
|
|
39
|
+
'terms': {
|
|
40
|
+
'visitorsType.keyword': inputData.demographics,
|
|
41
|
+
},
|
|
42
|
+
} );
|
|
43
|
+
}
|
|
44
|
+
if ( inputData.type && inputData.type!='' ) {
|
|
45
|
+
filter.push( {
|
|
46
|
+
'term': {
|
|
47
|
+
'type.keyword': inputData.type,
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
} );
|
|
51
|
+
}
|
|
52
|
+
if ( inputData.storeId && inputData.storeId.length > 0 ) {
|
|
53
|
+
filter.push( {
|
|
54
|
+
|
|
55
|
+
'terms': {
|
|
56
|
+
'storeId.keyword': inputData.storeId,
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
} );
|
|
60
|
+
} else {
|
|
61
|
+
return res.sendError( 'No data found', 204 );
|
|
62
|
+
}
|
|
63
|
+
let search ={
|
|
64
|
+
'must': filter,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
if ( inputData.searchValue && inputData.searchValue !== '' ) {
|
|
68
|
+
if ( inputData.type&&inputData.type==='remote' ) {
|
|
69
|
+
search ={
|
|
70
|
+
'must': filter,
|
|
71
|
+
'should': [
|
|
72
|
+
{
|
|
73
|
+
'wildcard': {
|
|
74
|
+
'storeName.keyword': {
|
|
75
|
+
'value': `*${inputData.searchValue}*`,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
'wildcard': {
|
|
81
|
+
'storeId.keyword': {
|
|
82
|
+
'value': `*${inputData.searchValue}*`,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
'wildcard': {
|
|
88
|
+
'engagementId.keyword': {
|
|
89
|
+
'value': `*${inputData.searchValue}*`,
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
{
|
|
95
|
+
'wildcard': {
|
|
96
|
+
'auditStatus.keyword': {
|
|
97
|
+
'value': `*${inputData.searchValue}*`,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
'minimum_should_match': 1,
|
|
103
|
+
};
|
|
104
|
+
} else {
|
|
105
|
+
search ={
|
|
106
|
+
'must': filter,
|
|
107
|
+
'should': [
|
|
108
|
+
{
|
|
109
|
+
'wildcard': {
|
|
110
|
+
'storeName.keyword': {
|
|
111
|
+
'value': `*${inputData.searchValue}*`,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
'wildcard': {
|
|
117
|
+
'storeId.keyword': {
|
|
118
|
+
'value': `*${inputData.searchValue}*`,
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
'wildcard': {
|
|
124
|
+
'engagementId.keyword': {
|
|
125
|
+
'value': `*${inputData.searchValue}*`,
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
'wildcard': {
|
|
131
|
+
'queueId.keyword': {
|
|
132
|
+
'value': `*${inputData.searchValue}*`,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
'wildcard': {
|
|
138
|
+
'optumId.keyword': {
|
|
139
|
+
'value': `*${inputData.searchValue}*`,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
'wildcard': {
|
|
145
|
+
'visitorsType.keyword': {
|
|
146
|
+
'value': `*${inputData.searchValue}*`,
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
{
|
|
152
|
+
'wildcard': {
|
|
153
|
+
'auditStatus.keyword': {
|
|
154
|
+
'value': `*${inputData.searchValue}*`,
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
'minimum_should_match': 1,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
let searchQuery={
|
|
164
|
+
'from': offset,
|
|
165
|
+
'size': limit,
|
|
166
|
+
'query': {
|
|
167
|
+
'bool': search,
|
|
168
|
+
},
|
|
169
|
+
'sort': [
|
|
170
|
+
{ date: { order: 'desc' } },
|
|
171
|
+
],
|
|
172
|
+
};
|
|
173
|
+
if ( sortBy && sortBy !== '' ) {
|
|
174
|
+
searchQuery={
|
|
175
|
+
'from': offset,
|
|
176
|
+
'size': limit,
|
|
177
|
+
'query': {
|
|
178
|
+
'bool': search,
|
|
179
|
+
},
|
|
180
|
+
'sort': [
|
|
181
|
+
{ [sortBy]: { order: order === -1 ?'desc':'asc' } },
|
|
182
|
+
],
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if ( inputData.isExport==true ) {
|
|
187
|
+
searchQuery={
|
|
188
|
+
'from': 0,
|
|
189
|
+
'size': 10000,
|
|
190
|
+
'query': {
|
|
191
|
+
'bool': search,
|
|
192
|
+
},
|
|
193
|
+
'sort': [
|
|
194
|
+
{ 'storeName.keyword': { order: 'desc' } },
|
|
195
|
+
],
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
const result = await getOpenSearchData( openSearch.EyeTestInput, searchQuery );
|
|
199
|
+
const count = result?.body?.hits?.total?.value;
|
|
200
|
+
if ( !count || count == 0 ) {
|
|
201
|
+
return res.sendError( 'No data found', 204 );
|
|
202
|
+
}
|
|
203
|
+
const searchValue = result?.body?.hits?.hits;
|
|
204
|
+
if ( !searchValue || searchValue?.length == 0 ) {
|
|
205
|
+
return res.sendError( 'No data found', 204 );
|
|
206
|
+
}
|
|
207
|
+
if ( inputData.isExport == true ) {
|
|
208
|
+
const chunkedMappingData = await chunkArray( searchValue, 10 );
|
|
209
|
+
const promises = chunkedMappingData.map( async ( chunk ) => {
|
|
210
|
+
const exportData = [];
|
|
211
|
+
for ( const element of chunk ) {
|
|
212
|
+
const testDuration = element?._source?.testDuration;
|
|
213
|
+
const minutes = Math.floor( testDuration / 60 );
|
|
214
|
+
const seconds = testDuration % 60;
|
|
215
|
+
const minutes1 =minutes> 1? `${minutes} mins` : `${minutes} min`;
|
|
216
|
+
const seconds1 = seconds > 1? `${minutes} secs`: seconds == 1? `${minutes} sec` : '';
|
|
217
|
+
const duration =`${minutes1} ${seconds1}`;
|
|
218
|
+
let userName = '';
|
|
219
|
+
if ( element?._source?.userId&&element?._source?.userId!='' ) {
|
|
220
|
+
userName = await findOneUser( { _id: element?._source?.userId }, { _id: 0, userName: 1 } );
|
|
221
|
+
}
|
|
222
|
+
if ( element?._source?.type == 'physical' ) {
|
|
223
|
+
exportData.push( {
|
|
224
|
+
'Date': dayjs( element?._source?.date ).format( 'D MMM, YYYY' ),
|
|
225
|
+
'Store Name': element?._source?.storeName,
|
|
226
|
+
'Store ID': element?._source?.storeId || 'Un Assigned',
|
|
227
|
+
'Store Name': element?._source?.storeName ||'Un Assigned',
|
|
228
|
+
'Optum ID': element?._source?.optumId,
|
|
229
|
+
'Queue ID': element?._source?.queueId,
|
|
230
|
+
'Compliance Score': element?._source?.totalSteps>0 ? Math.round( ( element?._source?.coveredStepsAI/ element?._source?.totalSteps )*100 ): 0,
|
|
231
|
+
'Steps Covered By AI': element?._source?.coveredStepsAI || 0,
|
|
232
|
+
'Visitor Type': element?._source?.visitorsType,
|
|
233
|
+
'Test Duration': duration || '',
|
|
234
|
+
'Audit Status': element?._source?.auditStatus || '',
|
|
235
|
+
'Audited By': userName?.userName || '',
|
|
236
|
+
|
|
237
|
+
} );
|
|
238
|
+
} else {
|
|
239
|
+
exportData.push( {
|
|
240
|
+
'Date': dayjs( element?._source?.date ).format( 'D MMM, YYYY' ),
|
|
241
|
+
'Store Name': element?._source?.storeName,
|
|
242
|
+
'Store ID': element?._source?.storeId || 'Un Assigned',
|
|
243
|
+
'Store Name': element?._source?.storeName ||'Un Assigned',
|
|
244
|
+
'Engagement ID': element?._source?.engagementId,
|
|
245
|
+
'Compliance Score': element?._source?.complianceScore || 0,
|
|
246
|
+
'Steps Covered By AI': element?._source?.coveredStepsAI || 0,
|
|
247
|
+
'Test Duration': duration || '',
|
|
248
|
+
'Audit Status': element?._source?.auditStatus || '',
|
|
249
|
+
'Audited By': userName?.userName || '',
|
|
250
|
+
|
|
251
|
+
} );
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return exportData;
|
|
255
|
+
} );
|
|
256
|
+
const mappedArrays = await Promise.all( promises );
|
|
257
|
+
const result = mappedArrays.flat();
|
|
258
|
+
await download( result, res );
|
|
259
|
+
return;
|
|
260
|
+
} else {
|
|
261
|
+
for ( const [ i, item ] of searchValue.entries() ) {
|
|
262
|
+
let userName='';
|
|
263
|
+
if ( item?._source?.userId&&item?._source?.userId!='' ) {
|
|
264
|
+
userName = await findOneUser( { _id: item?._source?.userId }, { _id: 0, userName: 1 } );
|
|
265
|
+
}
|
|
266
|
+
const testDuration = searchValue[i]?._source?.testDuration;
|
|
267
|
+
const minutes = Math.floor( testDuration / 60 );
|
|
268
|
+
const seconds = testDuration % 60;
|
|
269
|
+
searchValue[i]._source.complianceScore = searchValue[i]?._source?.totalSteps>0 ? Math.round( ( searchValue[i]?._source?.coveredStepsAI/ searchValue[i]?._source?.totalSteps )*100 ): 0;
|
|
270
|
+
searchValue[i]._source.min = minutes;
|
|
271
|
+
searchValue[i]._source.sec = seconds;
|
|
272
|
+
searchValue[i]._source.auditedBy = userName?.userName || '';
|
|
273
|
+
searchValue[i]._source.date = dayjs( searchValue[i]?._source?.date ).format( 'D MMM, YYYY' );
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return res.sendSuccess( { result: searchValue, count: count } );
|
|
278
|
+
} catch ( error ) {
|
|
279
|
+
const err = error.message || 'Internal Server Error';
|
|
280
|
+
logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-getList' } );
|
|
281
|
+
return res.sendError( err, 500 );
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export async function viewFile( req, res ) {
|
|
286
|
+
try {
|
|
287
|
+
const inputData = req.params;
|
|
288
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
289
|
+
const url = JSON.parse( process.env.URL );
|
|
290
|
+
let isEnable =true;
|
|
291
|
+
|
|
292
|
+
const getInput = await getOpenSearchById( openSearch.EyeTestInput, inputData.id );
|
|
293
|
+
if ( !getInput || !getInput?.body ) {
|
|
294
|
+
return res.sendError( 'No Data Found', 204 );
|
|
295
|
+
}
|
|
296
|
+
const getData =getInput?.body?._source;
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
let searchFilter =[
|
|
300
|
+
{
|
|
301
|
+
'term': {
|
|
302
|
+
'queueId.keyword': getData?.queueId,
|
|
303
|
+
},
|
|
304
|
+
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
'term': {
|
|
308
|
+
'type.keyword': getData?.type,
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
'terms': {
|
|
313
|
+
'auditStatus.keyword': [ 'Audited', 'Re-Audited' ],
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
];
|
|
317
|
+
if ( getData?.type == 'remote' ) {
|
|
318
|
+
searchFilter =[
|
|
319
|
+
{
|
|
320
|
+
'term': {
|
|
321
|
+
'engagementId.keyword': getData?.engagementId,
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
'term': {
|
|
327
|
+
'type.keyword': getData?.type,
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
'terms': {
|
|
332
|
+
'auditStatus.keyword': [ 'Audited', 'Re-Audited' ],
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
];
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
let searchQuery={
|
|
339
|
+
'size': 1,
|
|
340
|
+
'query': {
|
|
341
|
+
'bool': {
|
|
342
|
+
'must': searchFilter,
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
'sort': [
|
|
346
|
+
{ createdAt: { order: 'desc' } },
|
|
347
|
+
],
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
const searchRes= await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
|
|
351
|
+
|
|
352
|
+
const temp = searchRes?.body?.hits?.hits?.length > 0? searchRes?.body?.hits?.hits[0] : [];
|
|
353
|
+
|
|
354
|
+
const getUserName = await findOneUser( { _id: new mongoose.Types.ObjectId( temp?._source?.userId ) }, { userName: 1 } );
|
|
355
|
+
|
|
356
|
+
const searchData = temp?
|
|
357
|
+
getData['lastAuditedDetails']= {
|
|
358
|
+
'auditedBy': getUserName?.userName || '',
|
|
359
|
+
'completionTime': temp?._source?.endTime? dayjs.utc( temp?._source?.endTime ).tz( 'Asia/Kolkata' ).format( 'HH:mm:ss' ): '',
|
|
360
|
+
'timeZone': temp?.timeZone || '',
|
|
361
|
+
} : null;
|
|
362
|
+
getData['complianceScore'] = getData.complianceScore || getData?.totalSteps>0 ? Math.round( ( getData?.coveredStepsAI/ getData?.totalSteps )*100 ): 0;
|
|
363
|
+
getData['trustScore'] = getData?.trustScore || 0;
|
|
364
|
+
getData['testDuration'] = Math.round( getData?.testDuration/60 ) || 0;
|
|
365
|
+
getData['filePath'] = `${url[getData?.type]}${getData?.filePath}`;
|
|
366
|
+
getData['auditType'] = getData.auditType || 'Audit';
|
|
367
|
+
const response = getData;
|
|
368
|
+
|
|
369
|
+
switch ( getData?.auditStatus ) {
|
|
370
|
+
case 'Yet-to-Audit':
|
|
371
|
+
isEnable=true;
|
|
372
|
+
break;
|
|
373
|
+
case 'In-Progress':
|
|
374
|
+
if ( searchData.lenght ==0 ) {
|
|
375
|
+
return res.sendError( 'No saved records found', 400 );
|
|
376
|
+
}
|
|
377
|
+
if ( searchData.userId !== req.user._id ) {
|
|
378
|
+
isEnable=false;
|
|
379
|
+
}
|
|
380
|
+
break;
|
|
381
|
+
case 'Audited':
|
|
382
|
+
response['steps']= temp._source?.steps;
|
|
383
|
+
isEnable=true;
|
|
384
|
+
case 'Re-Audited':
|
|
385
|
+
response['steps']= temp._source?.steps;
|
|
386
|
+
isEnable=true;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return res.sendSuccess( { result: response, isEnable: isEnable } );
|
|
390
|
+
} catch ( error ) {
|
|
391
|
+
const err = error.message || 'Internal Server Error';
|
|
392
|
+
logger.error( { message: error, data: req.params, function: 'eyetestAudit-controller-viewFile' } );
|
|
393
|
+
return res.sendError( err, 500 );
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export async function getFile( req, res ) {
|
|
398
|
+
try {
|
|
399
|
+
const inputData = req.params;
|
|
400
|
+
const url = JSON.parse( process.env.URL );
|
|
401
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
402
|
+
|
|
403
|
+
const getInput = await getOpenSearchById( openSearch.EyeTestInput, inputData.id );
|
|
404
|
+
if ( !getInput || !getInput?.body ) {
|
|
405
|
+
return res.sendError( 'No Data Found', 204 );
|
|
406
|
+
}
|
|
407
|
+
const getData =getInput?.body?._source;
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
let searchFilter =[
|
|
411
|
+
{
|
|
412
|
+
'terms': {
|
|
413
|
+
'queueId.keyword': getData?.queueId,
|
|
414
|
+
},
|
|
415
|
+
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
'terms': {
|
|
419
|
+
'type.keyword': getData?.type,
|
|
420
|
+
},
|
|
421
|
+
|
|
422
|
+
},
|
|
423
|
+
];
|
|
424
|
+
if ( getData?.type == 'remote' ) {
|
|
425
|
+
searchFilter =[
|
|
426
|
+
{
|
|
427
|
+
'terms': {
|
|
428
|
+
'engagementId.keyword': getData?.engagementId,
|
|
429
|
+
},
|
|
430
|
+
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
'terms': {
|
|
434
|
+
'type.keyword': getData?.type,
|
|
435
|
+
},
|
|
436
|
+
|
|
437
|
+
},
|
|
438
|
+
];
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
let searchQuery={
|
|
442
|
+
'size': 1,
|
|
443
|
+
'query': {
|
|
444
|
+
'bool': {
|
|
445
|
+
'must': searchFilter,
|
|
446
|
+
},
|
|
447
|
+
},
|
|
448
|
+
'sort': [
|
|
449
|
+
{ createdAt: { order: 'desc' } },
|
|
450
|
+
],
|
|
451
|
+
};
|
|
452
|
+
const searchRes= await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
|
|
453
|
+
const searchData = searchRes?.body?.hits?.hits?.lenght > 0? searchRes?.body?.hits?.hits[0] : null;
|
|
454
|
+
logger.info( { searchData: searchData, getData: getData, messahe: '...........3' } );
|
|
455
|
+
switch ( getData?.auditStatus ) {
|
|
456
|
+
case 'Yet-to-Audit':
|
|
457
|
+
const record= {
|
|
458
|
+
'date': getData?.date,
|
|
459
|
+
'fileDate': getData?.fileDate,
|
|
460
|
+
'storeName': getData?.storeName,
|
|
461
|
+
'storeId': getData?.storeId,
|
|
462
|
+
'userId': req?.user?._id,
|
|
463
|
+
'type': getData?.type,
|
|
464
|
+
'engagementId': getData?.engagementId,
|
|
465
|
+
'queueId': getData?.queueId,
|
|
466
|
+
'optumId': getData?.optumId,
|
|
467
|
+
'displayName': getData?.displayName,
|
|
468
|
+
'complianceScore': getData?.totalSteps>0 ? Math.round( ( getData?.coveredStepsAI/ getData?.totalSteps )*100 ): 0,
|
|
469
|
+
'coveredStepsAI': getData?.coveredStepsAI,
|
|
470
|
+
'auditedSteps': 0,
|
|
471
|
+
'overRides': 0,
|
|
472
|
+
'trustScore': 0,
|
|
473
|
+
'visitorsType': getData?.visitorsType,
|
|
474
|
+
'testDuration': Math.round( getData?.testDuration/60 ) || 0,
|
|
475
|
+
'testStartTime': getData?.testStartTime,
|
|
476
|
+
'testEndTime': getData?.testEndTime,
|
|
477
|
+
'timeZone': 'IST',
|
|
478
|
+
'spokenLanguage': '',
|
|
479
|
+
'auditStatus': 'In-Progress',
|
|
480
|
+
'totalSteps': getData?.totalSteps,
|
|
481
|
+
'inputBucketName': getData?.inputBucketName,
|
|
482
|
+
'filePath': `${url[getData?.type]}${getData?.filePath}`,
|
|
483
|
+
'steps': getData?.steps,
|
|
484
|
+
'startTime': dayjs().tz( 'Asia/Kolkata' ),
|
|
485
|
+
'createdAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
486
|
+
'updatedAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
487
|
+
'auditType': 'Audit',
|
|
488
|
+
|
|
489
|
+
};
|
|
490
|
+
record?.steps?.map( ( item, i ) => {
|
|
491
|
+
record.steps[i]['auditedStatus']= null, record.steps[i]['reason'] = '', record.steps[i]['startTime'] = '', record.steps[i]['endTime'] = '';
|
|
492
|
+
} );
|
|
493
|
+
if ( !searchData ) {
|
|
494
|
+
const data1 = await insertOpenSearchData( openSearch.EyeTestOutput, record );
|
|
495
|
+
logger.info( { data1: data1 } );
|
|
496
|
+
await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: { 'auditStatus': 'In-Progress', 'auditType': 'Audit', 'userId': req?.user?._id, 'updatedAt': dayjs().tz( 'Asia/Kolkata' ) } } );
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
break;
|
|
500
|
+
case 'In-Progress':
|
|
501
|
+
|
|
502
|
+
if ( !searchData ) {
|
|
503
|
+
return res.sendError( 'No saved records found', 400 );
|
|
504
|
+
}
|
|
505
|
+
if ( searchData?.userId !== req.user._id ) {
|
|
506
|
+
return res.sendError( 'Forbidden to this action', 403 );
|
|
507
|
+
}
|
|
508
|
+
break;
|
|
509
|
+
case 'Audited':
|
|
510
|
+
case 'Re-Audited':
|
|
511
|
+
const newRecord= {
|
|
512
|
+
'date': getData?.date,
|
|
513
|
+
'fileDate': getData?.fileDate,
|
|
514
|
+
'storeName': getData?.storeName,
|
|
515
|
+
'storeId': getData?.storeId,
|
|
516
|
+
'userId': req?.user?._id,
|
|
517
|
+
'type': getData?.type,
|
|
518
|
+
'engagementId': getData?.engagementId,
|
|
519
|
+
'queueId': getData?.queueId,
|
|
520
|
+
'optumId': getData?.optumId,
|
|
521
|
+
'displayName': getData?.displayName,
|
|
522
|
+
'complianceScore': getData?.totalSteps>0 ? Math.round( ( getData?.coveredStepsAI/ getData?.totalSteps )*100 ): 0,
|
|
523
|
+
'coveredStepsAI': getData?.coveredStepsAI,
|
|
524
|
+
'auditedSteps': getData?.auditedSteps || 0,
|
|
525
|
+
'overRides': getData?.overRides || 0,
|
|
526
|
+
'trustScore': getData?.trustScore || 0,
|
|
527
|
+
'visitorsType': getData?.visitorsType,
|
|
528
|
+
'testDuration': getData?.testDuration,
|
|
529
|
+
'testStartTime': getData?.testStartTime,
|
|
530
|
+
'testEndTime': getData?.testEndTime,
|
|
531
|
+
'timeZone': getData?.timeZone,
|
|
532
|
+
'spokenLanguage': getData?.spokenLanguage || '',
|
|
533
|
+
'auditStatus': 'In-Progress',
|
|
534
|
+
'totalSteps': getData?.totalSteps,
|
|
535
|
+
'filePath': `${url[getData?.type]}${getData?.filePath}`,
|
|
536
|
+
'steps': getData?.steps,
|
|
537
|
+
'auditType': 'Re-Audit',
|
|
538
|
+
'startTime': dayjs().tz( 'Asia/Kolkata' ),
|
|
539
|
+
'createdAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
540
|
+
'updatedAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
541
|
+
|
|
542
|
+
};
|
|
543
|
+
await insertOpenSearchData( openSearch.EyeTestOutput, newRecord );
|
|
544
|
+
await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: { auditStatus: 'In-Progress', auditType: 'Re-Audit', userId: req?.user?._id } } );
|
|
545
|
+
|
|
546
|
+
break;
|
|
547
|
+
default:
|
|
548
|
+
return res.sendError( 'Status must be valid', 400 );
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
return res.sendSuccess( 'The status has been updated' );
|
|
552
|
+
} catch ( error ) {
|
|
553
|
+
const err = error.message || 'Internal Server Error';
|
|
554
|
+
logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-getFile' } );
|
|
555
|
+
return res.sendError( err, 500 );
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
export async function save( req, res ) {
|
|
559
|
+
try {
|
|
560
|
+
const inputData = req.body;
|
|
561
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
562
|
+
|
|
563
|
+
let searchFilter =[
|
|
564
|
+
{
|
|
565
|
+
'term': {
|
|
566
|
+
'queueId.keyword': inputData?.fileId,
|
|
567
|
+
},
|
|
568
|
+
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
'term': {
|
|
572
|
+
'type.keyword': inputData?.type,
|
|
573
|
+
},
|
|
574
|
+
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
'term': {
|
|
578
|
+
'userId.keyword': req?.user?._id,
|
|
579
|
+
},
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
'term': {
|
|
583
|
+
'auditStatus.keyword': 'In-Progress',
|
|
584
|
+
},
|
|
585
|
+
},
|
|
586
|
+
];
|
|
587
|
+
if ( inputData?.type == 'remote' ) {
|
|
588
|
+
searchFilter =[
|
|
589
|
+
{
|
|
590
|
+
'term': {
|
|
591
|
+
'engagementId.keyword': inputData?.fileId,
|
|
592
|
+
},
|
|
593
|
+
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
'term': {
|
|
597
|
+
'type.keyword': inputData?.type,
|
|
598
|
+
},
|
|
599
|
+
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
'term': {
|
|
603
|
+
'userId.keyword': req?.user?._id,
|
|
604
|
+
},
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
'term': {
|
|
608
|
+
'auditStatus.keyword': 'In-Progress',
|
|
609
|
+
},
|
|
610
|
+
},
|
|
611
|
+
];
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
let searchQuery={
|
|
615
|
+
'size': 1,
|
|
616
|
+
'query': {
|
|
617
|
+
'bool': {
|
|
618
|
+
'must': searchFilter,
|
|
619
|
+
},
|
|
620
|
+
},
|
|
621
|
+
};
|
|
622
|
+
const getOutput = await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
|
|
623
|
+
logger.info( { getOutput: getOutput } );
|
|
624
|
+
const output = getOutput?.body?.hits?.hits?.length > 0 ? getOutput?.body?.hits?.hits[0] : null;
|
|
625
|
+
if ( !output ) {
|
|
626
|
+
return res.sendError( 'This file is currently being audited by another user. Any actions you perform will not be saved.', 400 );
|
|
627
|
+
}
|
|
628
|
+
const record ={
|
|
629
|
+
'steps': inputData?.steps,
|
|
630
|
+
'auditStatus': inputData?.auditStatus,
|
|
631
|
+
'auditedSteps': inputData?.auditedSteps,
|
|
632
|
+
'overRides': inputData?.overRides,
|
|
633
|
+
'trustScore': Math.round( 100-( ( inputData?.overRides / inputData?.steps?.length ) * 100 ) ),
|
|
634
|
+
'spokenLanguage': inputData?.spokenLanguage,
|
|
635
|
+
'endTime': dayjs().tz( 'Asia/Kolkata' ),
|
|
636
|
+
'updatedAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
637
|
+
};
|
|
638
|
+
const inputrecord ={
|
|
639
|
+
|
|
640
|
+
'auditStatus': inputData?.auditStatus,
|
|
641
|
+
'auditedSteps': inputData?.auditedSteps,
|
|
642
|
+
'overRides': inputData?.overRides,
|
|
643
|
+
'trustScore': Math.round( 100-( ( inputData?.overRides / inputData?.steps?.length ) * 100 ) ),
|
|
644
|
+
'spokenLanguage': inputData?.spokenLanguage,
|
|
645
|
+
'endTime': dayjs().tz( 'Asia/Kolkata' ),
|
|
646
|
+
'updatedAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
647
|
+
|
|
648
|
+
};
|
|
649
|
+
await updateOpenSearchData( openSearch.EyeTestOutput, output?._id, { doc: record } );
|
|
650
|
+
await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: inputrecord } );
|
|
651
|
+
return res.sendSuccess( 'The file has been submited successfully' );
|
|
652
|
+
} catch ( error ) {
|
|
653
|
+
const err = error.message || 'Internal Server Error';
|
|
654
|
+
logger.error( { message: error, data: req.params, function: 'eyetestAudit-controller-save' } );
|
|
655
|
+
return res.sendError( err, 500 );
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
export async function cancel( req, res ) {
|
|
660
|
+
try {
|
|
661
|
+
const inputData = req.body;
|
|
662
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
663
|
+
let searchFilterhistory=[
|
|
664
|
+
{
|
|
665
|
+
'term': {
|
|
666
|
+
'queueId.keyword': inputData?.fileId,
|
|
667
|
+
},
|
|
668
|
+
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
'term': {
|
|
672
|
+
'type.keyword': inputData?.type,
|
|
673
|
+
},
|
|
674
|
+
|
|
675
|
+
},
|
|
676
|
+
];
|
|
677
|
+
let searchFilter =[
|
|
678
|
+
{
|
|
679
|
+
'term': {
|
|
680
|
+
'queueId.keyword': inputData?.fileId,
|
|
681
|
+
},
|
|
682
|
+
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
'term': {
|
|
686
|
+
'type.keyword': inputData?.type,
|
|
687
|
+
},
|
|
688
|
+
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
'term': {
|
|
692
|
+
'userId.keyword': req?.user?._id,
|
|
693
|
+
},
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
'term': {
|
|
697
|
+
'auditStatus.keyword': 'In-Progress',
|
|
698
|
+
},
|
|
699
|
+
},
|
|
700
|
+
];
|
|
701
|
+
if ( inputData?.type == 'remote' ) {
|
|
702
|
+
searchFilter =[
|
|
703
|
+
{
|
|
704
|
+
'term': {
|
|
705
|
+
'engagementId.keyword': inputData?.fileId,
|
|
706
|
+
},
|
|
707
|
+
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
'term': {
|
|
711
|
+
'type.keyword': inputData?.type,
|
|
712
|
+
},
|
|
713
|
+
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
'term': {
|
|
717
|
+
'userId.keyword': req?.user?._id,
|
|
718
|
+
},
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
'term': {
|
|
722
|
+
'auditStatus.keyword': 'In-Progress',
|
|
723
|
+
},
|
|
724
|
+
},
|
|
725
|
+
];
|
|
726
|
+
searchFilterhistory=[
|
|
727
|
+
{
|
|
728
|
+
'term': {
|
|
729
|
+
'engagementId.keyword': inputData?.fileId,
|
|
730
|
+
},
|
|
731
|
+
|
|
732
|
+
},
|
|
733
|
+
{
|
|
734
|
+
'term': {
|
|
735
|
+
'type.keyword': inputData?.type,
|
|
736
|
+
},
|
|
737
|
+
|
|
738
|
+
},
|
|
739
|
+
];
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
let searchQuery={
|
|
743
|
+
'size': 1,
|
|
744
|
+
'query': {
|
|
745
|
+
'bool': {
|
|
746
|
+
'must': searchFilter,
|
|
747
|
+
},
|
|
748
|
+
},
|
|
749
|
+
};
|
|
750
|
+
let searchQueryHistory={
|
|
751
|
+
'size': 100,
|
|
752
|
+
'query': {
|
|
753
|
+
'bool': {
|
|
754
|
+
'must': searchFilterhistory,
|
|
755
|
+
},
|
|
756
|
+
},
|
|
757
|
+
};
|
|
758
|
+
const getOutput = await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
|
|
759
|
+
const getOutputHistory = await getOpenSearchData( openSearch.EyeTestOutput, searchQueryHistory );
|
|
760
|
+
logger.info( { getOutput: getOutput } );
|
|
761
|
+
const output = getOutput?.body?.hits?.hits?.length > 0 ? getOutput?.body?.hits?.hits[0] : null;
|
|
762
|
+
let checkReaudited = getOutput?.body?.hits?.hits?.length > 0 ? getOutputHistory?.body?.hits?.hits.filter( ( data ) => data._source.auditType==='Re-Audit'&&data._source.auditStatus==='Re-Audited' ).length:0;
|
|
763
|
+
let checkReauditedData = getOutput?.body?.hits?.hits?.length > 0 ? getOutputHistory?.body?.hits?.hits.filter( ( data ) => data._source.auditType==='Re-Audit'&&data._source.auditStatus==='Re-Audited' ):[];
|
|
764
|
+
let checkaudited = getOutput?.body?.hits?.hits?.length > 0 ? getOutputHistory?.body?.hits?.hits.filter( ( data ) => data._source.auditType==='Audit'&&data._source.auditStatus==='Audited' ).length:0;
|
|
765
|
+
let checkauditedData = getOutput?.body?.hits?.hits?.length > 0 ? getOutputHistory?.body?.hits?.hits.filter( ( data ) => data._source.auditType==='Audit'&&data._source.auditStatus==='Audited' ):[];
|
|
766
|
+
|
|
767
|
+
if ( !output ) {
|
|
768
|
+
return res.sendError( 'No saved records found', 400 );
|
|
769
|
+
}
|
|
770
|
+
const record1 ={
|
|
771
|
+
|
|
772
|
+
auditStatus: 'Skipped',
|
|
773
|
+
auditType: checkReaudited>0?'Re-Audit':'Audit',
|
|
774
|
+
endTime: dayjs().tz( 'Asia/Kolkata' ),
|
|
775
|
+
|
|
776
|
+
};
|
|
777
|
+
const record2 ={
|
|
778
|
+
auditStatus: checkReaudited>0?'Re-Audited':checkaudited>0?'Audited':'Yet-to-Audit',
|
|
779
|
+
auditType: checkReaudited>0?'Re-Audit':'Audit',
|
|
780
|
+
endTime: dayjs().tz( 'Asia/Kolkata' ),
|
|
781
|
+
userId: checkaudited>0?checkauditedData[0]?._source?.userId:checkReaudited>0?checkReauditedData[0]?._source?.userId:'',
|
|
782
|
+
};
|
|
783
|
+
await updateOpenSearchData( openSearch.EyeTestOutput, output?._id, { doc: record1 } );
|
|
784
|
+
await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: record2 } );
|
|
785
|
+
return res.sendSuccess( 'The file has canceled ' );
|
|
786
|
+
} catch ( error ) {
|
|
787
|
+
const err = error.message || 'Internal Server Error';
|
|
788
|
+
logger.error( { message: error, data: req.params, function: 'eyetestAudit-controller-cancel' } );
|
|
789
|
+
return res.sendError( err, 500 );
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
export async function getFileHistory( req, res ) {
|
|
794
|
+
try {
|
|
795
|
+
const parsedOpenSearch = JSON.parse( process.env.OPENSEARCH );
|
|
796
|
+
const inputData = req.params;
|
|
797
|
+
let Query = {};
|
|
798
|
+
if ( inputData.type==='physical' ) {
|
|
799
|
+
Query = {
|
|
800
|
+
'size': 100,
|
|
801
|
+
'query': {
|
|
802
|
+
'bool': {
|
|
803
|
+
'must': [
|
|
804
|
+
{
|
|
805
|
+
'term': {
|
|
806
|
+
'queueId.keyword': inputData.id,
|
|
807
|
+
},
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
'terms': {
|
|
811
|
+
'auditStatus.keyword': [ 'Audited', 'Re-Audited' ],
|
|
812
|
+
},
|
|
813
|
+
},
|
|
814
|
+
],
|
|
815
|
+
},
|
|
816
|
+
},
|
|
817
|
+
'sort': [
|
|
818
|
+
{ updatedAt: { order: 'desc' } },
|
|
819
|
+
],
|
|
820
|
+
};
|
|
821
|
+
} else {
|
|
822
|
+
Query = {
|
|
823
|
+
'size': 100,
|
|
824
|
+
'query': {
|
|
825
|
+
'bool': {
|
|
826
|
+
'must': [
|
|
827
|
+
{
|
|
828
|
+
'term': {
|
|
829
|
+
'engagementId.keyword': inputData.id,
|
|
830
|
+
},
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
'terms': {
|
|
834
|
+
'auditStatus.keyword': [ 'Audited', 'Re-Audited' ],
|
|
835
|
+
},
|
|
836
|
+
},
|
|
837
|
+
],
|
|
838
|
+
},
|
|
839
|
+
},
|
|
840
|
+
'sort': [
|
|
841
|
+
{ updatedAt: { order: 'desc' } },
|
|
842
|
+
],
|
|
843
|
+
};
|
|
844
|
+
};
|
|
845
|
+
|
|
846
|
+
const resposnse = await getOpenSearchData( parsedOpenSearch.EyeTestOutput, Query );
|
|
847
|
+
if ( resposnse.body.hits.hits.length > 0 ) {
|
|
848
|
+
let sourcesArray = resposnse.body.hits.hits.map( ( hit ) => hit );
|
|
849
|
+
let outputData=[];
|
|
850
|
+
for ( let data of sourcesArray ) {
|
|
851
|
+
let findUser= await findOneUser( { _id: new mongoose.Types.ObjectId( data._source.userId ) } );
|
|
852
|
+
outputData.push( {
|
|
853
|
+
_id: data._id,
|
|
854
|
+
userId: data._source.userId,
|
|
855
|
+
userName: findUser.userName,
|
|
856
|
+
Date: dayjs( data._source.endTime ).format( 'DD/MM/YYYY' ),
|
|
857
|
+
Time: dayjs.utc( data._source.endTime ).tz( 'Asia/Kolkata' ).format( 'HH:mm:ss' ),
|
|
858
|
+
} );
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
return res.sendSuccess( { result: outputData } );
|
|
862
|
+
} else {
|
|
863
|
+
return res.sendError( 'No data found', 204 );
|
|
864
|
+
}
|
|
865
|
+
} catch ( error ) {
|
|
866
|
+
const err = error.message || 'Internal Server Error';
|
|
867
|
+
logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-getFileHistory' } );
|
|
868
|
+
return res.sendError( err, 500 );
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
export async function userAuditedData( req, res ) {
|
|
873
|
+
try {
|
|
874
|
+
const parsedOpenSearch = JSON.parse( process.env.OPENSEARCH );
|
|
875
|
+
const inputData = req.params;
|
|
876
|
+
|
|
877
|
+
const resposnse = await getOpenSearchById( parsedOpenSearch.EyeTestOutput, inputData.id );
|
|
878
|
+
|
|
879
|
+
if ( resposnse.body&&resposnse.body._source ) {
|
|
880
|
+
return res.sendSuccess( { result: resposnse.body._source.steps } );
|
|
881
|
+
} else {
|
|
882
|
+
return res.sendError( 'No data found', 204 );
|
|
883
|
+
}
|
|
884
|
+
} catch ( error ) {
|
|
885
|
+
const err = error.message || 'Internal Server Error';
|
|
886
|
+
logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-userAuditedData' } );
|
|
887
|
+
return res.sendError( err, 500 );
|
|
888
|
+
}
|
|
889
|
+
}
|