tango-app-api-audit 3.4.68-beta.0 → 3.4.68-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
# README #
|
|
2
|
-
|
|
3
|
-
This README would normally document whatever steps are necessary to get your application up and running.
|
|
4
|
-
|
|
5
|
-
### What is this repository for? ###
|
|
6
|
-
|
|
7
|
-
* Quick summary
|
|
8
|
-
* Version
|
|
9
|
-
* [Learn Markdown](https://bitbucket.org/tutorials/markdowndemo)
|
|
10
|
-
|
|
11
|
-
### How do I get set up? ###
|
|
12
|
-
|
|
13
|
-
* Summary of set up
|
|
14
|
-
* Configuration
|
|
15
|
-
* Dependencies
|
|
16
|
-
* Database configuration
|
|
17
|
-
* How to run tests
|
|
18
|
-
* Deployment instructions
|
|
19
|
-
|
|
20
|
-
### Contribution guidelines ###
|
|
21
|
-
|
|
22
|
-
* Writing tests
|
|
23
|
-
* Code review
|
|
24
|
-
* Other guidelines
|
|
25
|
-
|
|
26
|
-
### Who do I talk to? ###
|
|
27
|
-
|
|
28
|
-
* Repo owner or admin
|
|
1
|
+
# README #
|
|
2
|
+
|
|
3
|
+
This README would normally document whatever steps are necessary to get your application up and running.
|
|
4
|
+
|
|
5
|
+
### What is this repository for? ###
|
|
6
|
+
|
|
7
|
+
* Quick summary
|
|
8
|
+
* Version
|
|
9
|
+
* [Learn Markdown](https://bitbucket.org/tutorials/markdowndemo)
|
|
10
|
+
|
|
11
|
+
### How do I get set up? ###
|
|
12
|
+
|
|
13
|
+
* Summary of set up
|
|
14
|
+
* Configuration
|
|
15
|
+
* Dependencies
|
|
16
|
+
* Database configuration
|
|
17
|
+
* How to run tests
|
|
18
|
+
* Deployment instructions
|
|
19
|
+
|
|
20
|
+
### Contribution guidelines ###
|
|
21
|
+
|
|
22
|
+
* Writing tests
|
|
23
|
+
* Code review
|
|
24
|
+
* Other guidelines
|
|
25
|
+
|
|
26
|
+
### Who do I talk to? ###
|
|
27
|
+
|
|
28
|
+
* Repo owner or admin
|
|
29
29
|
* Other community or team contact
|
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 {
|
|
@@ -22,21 +28,24 @@ export async function getList( req, res ) {
|
|
|
22
28
|
},
|
|
23
29
|
|
|
24
30
|
];
|
|
25
|
-
let search ={
|
|
26
|
-
'must': filter,
|
|
27
|
-
};
|
|
28
31
|
|
|
29
|
-
if ( inputData.visitorsType && inputData.visitorsType.lenght > 0 ) {
|
|
30
|
-
filter.push( {
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
// if ( inputData.demographics && inputData.demographics.length > 0 ) {
|
|
34
|
+
// filter.push( {
|
|
35
|
+
// 'terms': {
|
|
36
|
+
// 'visitorsType.keyword': inputData.demographics,
|
|
37
|
+
// },
|
|
38
|
+
// } );
|
|
39
|
+
// }
|
|
40
|
+
if ( inputData.type && inputData.type!='' ) {
|
|
41
|
+
filter.push( {
|
|
42
|
+
'term': {
|
|
43
|
+
'type.keyword': inputData.type,
|
|
34
44
|
},
|
|
35
45
|
|
|
36
46
|
} );
|
|
37
47
|
}
|
|
38
|
-
|
|
39
|
-
if ( inputData.storeId && inputData.storeId.lenght > 0 ) {
|
|
48
|
+
if ( inputData.storeId && inputData.storeId.length > 0 ) {
|
|
40
49
|
filter.push( {
|
|
41
50
|
|
|
42
51
|
'terms': {
|
|
@@ -45,6 +54,9 @@ export async function getList( req, res ) {
|
|
|
45
54
|
|
|
46
55
|
} );
|
|
47
56
|
}
|
|
57
|
+
let search ={
|
|
58
|
+
'must': filter,
|
|
59
|
+
};
|
|
48
60
|
|
|
49
61
|
if ( inputData.searchValue && inputData.searchValue !== '' ) {
|
|
50
62
|
search ={
|
|
@@ -103,14 +115,43 @@ export async function getList( req, res ) {
|
|
|
103
115
|
'minimum_should_match': 1,
|
|
104
116
|
};
|
|
105
117
|
}
|
|
106
|
-
|
|
107
118
|
let searchQuery={
|
|
108
119
|
'from': offset,
|
|
109
120
|
'size': limit,
|
|
110
121
|
'query': {
|
|
111
122
|
'bool': search,
|
|
112
123
|
},
|
|
124
|
+
'sort': [
|
|
125
|
+
{ date: { order: 'desc' } },
|
|
126
|
+
],
|
|
113
127
|
};
|
|
128
|
+
if ( inputData.sortBy && inputData.sortBy !== '' ) {
|
|
129
|
+
const sortBy = inputData.sortBy;
|
|
130
|
+
const order = inputData.sortOrder || -1;
|
|
131
|
+
searchQuery={
|
|
132
|
+
'from': offset,
|
|
133
|
+
'size': limit,
|
|
134
|
+
'query': {
|
|
135
|
+
'bool': search,
|
|
136
|
+
},
|
|
137
|
+
'sort': [
|
|
138
|
+
{ [sortBy]: { order: order === -1 ?'desc':'asc' } },
|
|
139
|
+
],
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if ( inputData.isExport==true ) {
|
|
144
|
+
searchQuery={
|
|
145
|
+
'from': 0,
|
|
146
|
+
'size': 10000,
|
|
147
|
+
'query': {
|
|
148
|
+
'bool': search,
|
|
149
|
+
},
|
|
150
|
+
'sort': [
|
|
151
|
+
{ createdAt: { order: 'desc' } },
|
|
152
|
+
],
|
|
153
|
+
};
|
|
154
|
+
}
|
|
114
155
|
const result = await getOpenSearchData( openSearch.EyeTestInput, searchQuery );
|
|
115
156
|
const count = result?.body?.hits?.total?.value;
|
|
116
157
|
if ( !count || count == 0 ) {
|
|
@@ -120,6 +161,70 @@ export async function getList( req, res ) {
|
|
|
120
161
|
if ( !searchValue || searchValue?.length == 0 ) {
|
|
121
162
|
return res.sendError( 'No data found', 204 );
|
|
122
163
|
}
|
|
164
|
+
if ( inputData.isExport == true ) {
|
|
165
|
+
const chunkedMappingData = await chunkArray( searchValue, 10 );
|
|
166
|
+
const promises = chunkedMappingData.map( async ( chunk ) => {
|
|
167
|
+
const exportData = [];
|
|
168
|
+
chunk.forEach( async ( element ) => {
|
|
169
|
+
const testDuration = element?._source?.testDuration;
|
|
170
|
+
const minutes = Math.floor( testDuration / 60 );
|
|
171
|
+
const seconds = testDuration % 60;
|
|
172
|
+
const minutes1 =minutes> 1? `${minutes} mins` : `${minutes} min`;
|
|
173
|
+
const seconds1 = seconds > 1? `${minutes} secs`: seconds == 1? `${minutes} sec` : '';
|
|
174
|
+
const duration =`${minutes1} ${seconds1}`;
|
|
175
|
+
const userName = await findOneUser( { _id: element?._source?.userId }, { _id: 0, userName: 1 } );
|
|
176
|
+
if ( element?._source?.type == 'physical' ) {
|
|
177
|
+
exportData.push( {
|
|
178
|
+
'Date': dayjs( element?._source?.date ).format( 'YYYY,MMM D' ),
|
|
179
|
+
'Store Name': element?._source?.storeName,
|
|
180
|
+
'Store ID': element?._source?.storeId || 'Un Assigned',
|
|
181
|
+
'Store Name': element?._source?.storeName ||'Un Assigned',
|
|
182
|
+
'Optum ID': element?._source?.optumId,
|
|
183
|
+
'Queue ID': element?._source?.queueId,
|
|
184
|
+
'Compliance Score': element?._source?.complianceScore || 0,
|
|
185
|
+
'Steps Covered By AI': element?._source?.coveredStepsAI || 0,
|
|
186
|
+
'Visitor Type': element?._source?.visitorsType,
|
|
187
|
+
'Test Duration': duration || '',
|
|
188
|
+
'Audit Status': element?._source?.auditStatus || '',
|
|
189
|
+
'Audited By': userName?.userName || '',
|
|
190
|
+
|
|
191
|
+
} );
|
|
192
|
+
} else {
|
|
193
|
+
exportData.push( {
|
|
194
|
+
'Date': dayjs( element?._source?.date ).format( 'YYYY,MMM D' ),
|
|
195
|
+
'Store Name': element?._source?.storeName,
|
|
196
|
+
'Store ID': element?._source?.storeId || 'Un Assigned',
|
|
197
|
+
'Store Name': element?._source?.storeName ||'Un Assigned',
|
|
198
|
+
'Engagement ID': element?._source?.engagementId,
|
|
199
|
+
'Compliance Score': element?._source?.complianceScore || 0,
|
|
200
|
+
'Steps Covered By AI': element?._source?.coveredStepsAI || 0,
|
|
201
|
+
'Visitor Type': element?._source?.visitorsType,
|
|
202
|
+
'Test Duration': duration || '',
|
|
203
|
+
'Audit Status': element?._source?.auditStatus || '',
|
|
204
|
+
'Audited By': userName.userName || '',
|
|
205
|
+
|
|
206
|
+
} );
|
|
207
|
+
}
|
|
208
|
+
} );
|
|
209
|
+
return exportData;
|
|
210
|
+
} );
|
|
211
|
+
const mappedArrays = await Promise.all( promises );
|
|
212
|
+
const result = mappedArrays.flat();
|
|
213
|
+
await download( result, res );
|
|
214
|
+
return;
|
|
215
|
+
} else {
|
|
216
|
+
for ( const [ i, item ] of searchValue.entries() ) {
|
|
217
|
+
const userName = await findOneUser( { _id: item?._source?.userId }, { _id: 0, userName: 1 } );
|
|
218
|
+
const testDuration = searchValue[i]?._source?.testDuration;
|
|
219
|
+
const minutes = Math.floor( testDuration / 60 );
|
|
220
|
+
const seconds = testDuration % 60;
|
|
221
|
+
|
|
222
|
+
searchValue[i]._source.min = minutes;
|
|
223
|
+
searchValue[i]._source.sec = seconds;
|
|
224
|
+
searchValue[i]._source.auditedBy = userName?.userName || '';
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
123
228
|
return res.sendSuccess( { result: searchValue, count: count } );
|
|
124
229
|
} catch ( error ) {
|
|
125
230
|
const err = error.message || 'Internal Server Error';
|
|
@@ -128,18 +233,363 @@ export async function getList( req, res ) {
|
|
|
128
233
|
}
|
|
129
234
|
}
|
|
130
235
|
|
|
236
|
+
export async function viewFile( req, res ) {
|
|
237
|
+
try {
|
|
238
|
+
const inputData = req.params;
|
|
239
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
240
|
+
const url = JSON.parse( process.env.URL );
|
|
241
|
+
let isEnable =true;
|
|
242
|
+
|
|
243
|
+
const getInput = await getOpenSearchById( openSearch.EyeTestInput, inputData.id );
|
|
244
|
+
if ( !getInput || !getInput?.body ) {
|
|
245
|
+
return res.sendError( 'No Data Found', 204 );
|
|
246
|
+
}
|
|
247
|
+
const getData =getInput?.body?._source;
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
let searchFilter =[
|
|
251
|
+
{
|
|
252
|
+
'term': {
|
|
253
|
+
'queueId.keyword': getData?.queueId,
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
'term': {
|
|
259
|
+
'type.keyword': getData?.type,
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
},
|
|
263
|
+
];
|
|
264
|
+
if ( getData?.type == 'remote' ) {
|
|
265
|
+
searchFilter =[
|
|
266
|
+
{
|
|
267
|
+
'term': {
|
|
268
|
+
'engagementId.keyword': getData?.engagementId,
|
|
269
|
+
},
|
|
270
|
+
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
'term': {
|
|
274
|
+
'type.keyword': getData?.type,
|
|
275
|
+
},
|
|
276
|
+
|
|
277
|
+
},
|
|
278
|
+
];
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
let searchQuery={
|
|
282
|
+
'size': 1,
|
|
283
|
+
'query': {
|
|
284
|
+
'bool': {
|
|
285
|
+
'must': searchFilter,
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
'sort': [
|
|
289
|
+
{ createdAt: { order: 'desc' } },
|
|
290
|
+
],
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
const searchRes= await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
|
|
294
|
+
const temp = searchRes?.body?.hits?.hits?.length > 0? searchRes?.body?.hits?.hits[0] : [];
|
|
295
|
+
|
|
296
|
+
const getUserName = await findOneUser( { _id: new mongoose.Types.ObjectId( temp?._source?.userId ) }, { userName: 1 } );
|
|
297
|
+
|
|
298
|
+
const searchData = temp?
|
|
299
|
+
getData['lastAuditedDetails']= {
|
|
300
|
+
'auditedBy': getUserName?.userName || '',
|
|
301
|
+
'completionTime': temp?._source?.startTime? new Date( temp?._source?.startTime ).toLocaleTimeString( 'en-IN', { hour12: false } ): '',
|
|
302
|
+
'timeZone': temp?.timeZone || '',
|
|
303
|
+
} : null;
|
|
304
|
+
getData['complianceScore'] = getData.complianceScore || getData?.totalSteps>0 ? Math.round( ( getData?.coveredStepsAI/ getData?.totalSteps )*100 ): 0;
|
|
305
|
+
getData['trustScore'] = getData?.trustScore || 0;
|
|
306
|
+
getData['testDuration'] = Math.round( getData?.testDuration/60 ) || 0;
|
|
307
|
+
getData['filePath'] = `${url[getData?.type]}${getData?.filePath}`;
|
|
308
|
+
getData['auditType'] = getData.auditType || 'Audit';
|
|
309
|
+
const response = getData;
|
|
310
|
+
|
|
311
|
+
switch ( getData?.auditStatus ) {
|
|
312
|
+
case 'Yet-to-Audit':
|
|
313
|
+
isEnable=true;
|
|
314
|
+
break;
|
|
315
|
+
case 'In-Progress':
|
|
316
|
+
if ( searchData.lenght ==0 ) {
|
|
317
|
+
return res.sendError( 'No saved records found', 400 );
|
|
318
|
+
}
|
|
319
|
+
if ( searchData.userId !== req.user._id ) {
|
|
320
|
+
isEnable=false;
|
|
321
|
+
}
|
|
322
|
+
break;
|
|
323
|
+
case 'Audited':
|
|
324
|
+
response['steps']= temp._source?.steps;
|
|
325
|
+
case 'Re-Audited':
|
|
326
|
+
isEnable=true;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return res.sendSuccess( { result: response, isEnable: isEnable } );
|
|
330
|
+
} catch ( error ) {
|
|
331
|
+
const err = error.message || 'Internal Server Error';
|
|
332
|
+
logger.error( { message: error, data: req.params, function: 'eyetestAudit-controller-viewFile' } );
|
|
333
|
+
return res.sendError( err, 500 );
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
131
337
|
export async function getFile( req, res ) {
|
|
132
338
|
try {
|
|
133
339
|
const inputData = req.params;
|
|
340
|
+
const url = JSON.parse( process.env.URL );
|
|
134
341
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
135
|
-
|
|
136
|
-
|
|
342
|
+
|
|
343
|
+
const getInput = await getOpenSearchById( openSearch.EyeTestInput, inputData.id );
|
|
344
|
+
if ( !getInput || !getInput?.body ) {
|
|
345
|
+
return res.sendError( 'No Data Found', 204 );
|
|
346
|
+
}
|
|
347
|
+
const getData =getInput?.body?._source;
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
let searchFilter =[
|
|
351
|
+
{
|
|
352
|
+
'terms': {
|
|
353
|
+
'queueId.keyword': getData?.queueId,
|
|
354
|
+
},
|
|
355
|
+
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
'terms': {
|
|
359
|
+
'type.keyword': getData?.type,
|
|
360
|
+
},
|
|
361
|
+
|
|
362
|
+
},
|
|
363
|
+
];
|
|
364
|
+
if ( getData?.type == 'remote' ) {
|
|
365
|
+
searchFilter =[
|
|
366
|
+
{
|
|
367
|
+
'terms': {
|
|
368
|
+
'engagementId.keyword': getData?.engagementId,
|
|
369
|
+
},
|
|
370
|
+
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
'terms': {
|
|
374
|
+
'type.keyword': getData?.type,
|
|
375
|
+
},
|
|
376
|
+
|
|
377
|
+
},
|
|
378
|
+
];
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
let searchQuery={
|
|
382
|
+
'size': 1,
|
|
383
|
+
'query': {
|
|
384
|
+
'bool': {
|
|
385
|
+
'must': searchFilter,
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
'sort': [
|
|
389
|
+
{ createdAt: { order: 'desc' } },
|
|
390
|
+
],
|
|
391
|
+
};
|
|
392
|
+
const searchRes= await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
|
|
393
|
+
const searchData = searchRes?.body?.hits?.hits?.lenght > 0? searchRes?.body?.hits?.hits[0] : null;
|
|
394
|
+
logger.info( { searchData: searchData, getData: getData, messahe: '...........3' } );
|
|
395
|
+
switch ( getData?.auditStatus ) {
|
|
396
|
+
case 'Yet-to-Audit':
|
|
397
|
+
const record= {
|
|
398
|
+
'date': getData?.date,
|
|
399
|
+
'fileDate': getData?.fileDate,
|
|
400
|
+
'storeName': getData?.storeName,
|
|
401
|
+
'storeId': getData?.storeId,
|
|
402
|
+
'userId': req?.user?._id,
|
|
403
|
+
'type': getData?.type,
|
|
404
|
+
'engagementId': getData?.engagementId,
|
|
405
|
+
'queueId': getData?.queueId,
|
|
406
|
+
'optumId': getData?.optumId,
|
|
407
|
+
'displayName': getData?.displayName,
|
|
408
|
+
'complianceScore': getData?.totalSteps>0 ? Math.round( ( getData?.coveredStepsAI/ getData?.totalSteps )*100 ): 0,
|
|
409
|
+
'coveredStepsAI': getData?.coveredStepsAI,
|
|
410
|
+
'auditedSteps': 0,
|
|
411
|
+
'overRides': 0,
|
|
412
|
+
'trustScore': 0,
|
|
413
|
+
'visitorsType': getData?.visitorsType,
|
|
414
|
+
'testDuration': Math.round( getData?.testDuration/60 ) || 0,
|
|
415
|
+
'testStartTime': getData?.testStartTime,
|
|
416
|
+
'testEndTime': getData?.testEndTime,
|
|
417
|
+
'timeZone': 'IST',
|
|
418
|
+
'spokenLanguage': '',
|
|
419
|
+
'auditStatus': 'In-Progress',
|
|
420
|
+
'totalSteps': getData?.totalSteps,
|
|
421
|
+
'inputBucketName': getData?.inputBucketName,
|
|
422
|
+
'filePath': `${url[getData?.type]}${getData?.filePath}`,
|
|
423
|
+
'steps': getData?.steps,
|
|
424
|
+
'startTime': dayjs().tz( 'Asia/Kolkata' ),
|
|
425
|
+
'createdAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
426
|
+
'updatedAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
427
|
+
'auditType': 'Audit',
|
|
428
|
+
|
|
429
|
+
};
|
|
430
|
+
record?.steps?.map( ( item, i ) => {
|
|
431
|
+
record.steps[i]['auditedStatus']= null, record.steps[i]['reason'] = '', record.steps[i]['startTime'] = '', record.steps[i]['endTime'] = '';
|
|
432
|
+
} );
|
|
433
|
+
if ( !searchData ) {
|
|
434
|
+
const data1 = await insertOpenSearchData( openSearch.EyeTestOutput, record );
|
|
435
|
+
logger.info( { data1: data1 } );
|
|
436
|
+
await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: { auditStatus: 'In-Progress', auditType: 'Audit', userId: req?.user?._id } } );
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
break;
|
|
440
|
+
case 'In-Progress':
|
|
441
|
+
|
|
442
|
+
if ( !searchData ) {
|
|
443
|
+
return res.sendError( 'No saved records found', 400 );
|
|
444
|
+
}
|
|
445
|
+
if ( searchData?.userId !== req.user._id ) {
|
|
446
|
+
return res.sendError( 'Forbidden to this action', 403 );
|
|
447
|
+
}
|
|
448
|
+
break;
|
|
449
|
+
case 'Audited':
|
|
450
|
+
case 'Re-Audited':
|
|
451
|
+
const newRecord= {
|
|
452
|
+
'date': getData?.date,
|
|
453
|
+
'fileDate': getData?.fileDate,
|
|
454
|
+
'storeName': getData?.storeName,
|
|
455
|
+
'storeId': getData?.storeId,
|
|
456
|
+
'userId': req?.user?._id,
|
|
457
|
+
'type': getData?.type,
|
|
458
|
+
'engagementId': getData?.engagementId,
|
|
459
|
+
'queueId': getData?.queueId,
|
|
460
|
+
'optumId': getData?.optumId,
|
|
461
|
+
'displayName': getData?.displayName,
|
|
462
|
+
'complianceScore': getData?.totalSteps>0 ? Math.round( ( getData?.coveredStepsAI/ getData?.totalSteps )*100 ): 0,
|
|
463
|
+
'coveredStepsAI': getData?.coveredStepsAI,
|
|
464
|
+
'auditedSteps': getData?.auditedSteps || 0,
|
|
465
|
+
'overRides': getData?.overRides || 0,
|
|
466
|
+
'trustScore': getData?.trustScore || 0,
|
|
467
|
+
'visitorsType': getData?.visitorsType,
|
|
468
|
+
'testDuration': getData?.testDuration,
|
|
469
|
+
'testStartTime': getData?.testStartTime,
|
|
470
|
+
'testEndTime': getData?.testEndTime,
|
|
471
|
+
'timeZone': getData?.timeZone,
|
|
472
|
+
'spokenLanguage': getData?.spokenLanguage || '',
|
|
473
|
+
'auditStatus': 'In-Progress',
|
|
474
|
+
'totalSteps': getData?.totalSteps,
|
|
475
|
+
'filePath': `${url[getData?.type]}${getData?.filePath}`,
|
|
476
|
+
'steps': getData?.steps,
|
|
477
|
+
'auditType': 'Re-Audit',
|
|
478
|
+
'startTime': dayjs().tz( 'Asia/Kolkata' ),
|
|
479
|
+
'createdAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
480
|
+
'updatedAt': dayjs().tz( 'Asia/Kolkata' ),
|
|
481
|
+
|
|
482
|
+
};
|
|
483
|
+
await insertOpenSearchData( openSearch.EyeTestOutput, newRecord );
|
|
484
|
+
await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: { auditStatus: 'In-Progress', auditType: 'Re-Audit' } } );
|
|
485
|
+
|
|
486
|
+
break;
|
|
487
|
+
default:
|
|
488
|
+
return res.sendError( 'Status must be valid', 400 );
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
return res.sendSuccess( 'The status has been updated' );
|
|
137
492
|
} catch ( error ) {
|
|
138
493
|
const err = error.message || 'Internal Server Error';
|
|
139
494
|
logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-getFile' } );
|
|
140
495
|
return res.sendError( err, 500 );
|
|
141
496
|
}
|
|
142
497
|
}
|
|
498
|
+
export async function save( req, res ) {
|
|
499
|
+
try {
|
|
500
|
+
const inputData = req.body;
|
|
501
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
502
|
+
|
|
503
|
+
let searchFilter =[
|
|
504
|
+
{
|
|
505
|
+
'term': {
|
|
506
|
+
'queueId.keyword': inputData?.fileId,
|
|
507
|
+
},
|
|
508
|
+
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
'term': {
|
|
512
|
+
'type.keyword': inputData?.type,
|
|
513
|
+
},
|
|
514
|
+
|
|
515
|
+
},
|
|
516
|
+
|
|
517
|
+
{
|
|
518
|
+
'term': {
|
|
519
|
+
'auditStatus.keyword': 'In-Progress',
|
|
520
|
+
},
|
|
521
|
+
},
|
|
522
|
+
];
|
|
523
|
+
if ( inputData?.type == 'remote' ) {
|
|
524
|
+
searchFilter =[
|
|
525
|
+
{
|
|
526
|
+
'term': {
|
|
527
|
+
'engagementId.keyword': inputData?.fileId,
|
|
528
|
+
},
|
|
529
|
+
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
'term': {
|
|
533
|
+
'type.keyword': inputData?.type,
|
|
534
|
+
},
|
|
535
|
+
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
'term': {
|
|
539
|
+
'userId.keyword': req?.user?._id,
|
|
540
|
+
},
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
'term': {
|
|
544
|
+
'auditStatus.keyword': 'In-Progress',
|
|
545
|
+
},
|
|
546
|
+
},
|
|
547
|
+
];
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
let searchQuery={
|
|
551
|
+
'size': 1,
|
|
552
|
+
'query': {
|
|
553
|
+
'bool': {
|
|
554
|
+
'must': searchFilter,
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
};
|
|
558
|
+
const getOutput = await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
|
|
559
|
+
logger.info( { getOutput: getOutput } );
|
|
560
|
+
const output = getOutput?.body?.hits?.hits?.length > 0 ? getOutput?.body?.hits?.hits[0] : null;
|
|
561
|
+
if ( !output ) {
|
|
562
|
+
return res.sendError( 'No saved records found', 400 );
|
|
563
|
+
}
|
|
564
|
+
const record ={
|
|
565
|
+
steps: inputData?.steps,
|
|
566
|
+
auditStatus: inputData?.auditStatus,
|
|
567
|
+
auditedSteps: inputData?.auditedSteps,
|
|
568
|
+
overRides: inputData?.overRides,
|
|
569
|
+
trustScore: Math.round( 100-( ( inputData?.overRides / inputData?.steps?.length ) * 100 ) ),
|
|
570
|
+
spokenLanguage: inputData?.spokenLanguage,
|
|
571
|
+
endTime: dayjs().tz( 'Asia/Kolkata' ),
|
|
572
|
+
|
|
573
|
+
};
|
|
574
|
+
const inputrecord ={
|
|
575
|
+
|
|
576
|
+
auditStatus: inputData?.auditStatus,
|
|
577
|
+
auditedSteps: inputData?.auditedSteps,
|
|
578
|
+
overRides: inputData?.overRides,
|
|
579
|
+
trustScore: Math.round( 100-( ( inputData?.overRides / inputData?.steps?.length ) * 100 ) ),
|
|
580
|
+
spokenLanguage: inputData?.spokenLanguage,
|
|
581
|
+
endTime: dayjs().tz( 'Asia/Kolkata' ),
|
|
582
|
+
|
|
583
|
+
};
|
|
584
|
+
await updateOpenSearchData( openSearch.EyeTestOutput, output?._id, { doc: record } );
|
|
585
|
+
await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: inputrecord } );
|
|
586
|
+
return res.sendSuccess( 'The file has been submited successfully' );
|
|
587
|
+
} catch ( error ) {
|
|
588
|
+
const err = error.message || 'Internal Server Error';
|
|
589
|
+
logger.error( { message: error, data: req.params, function: 'eyetestAudit-controller-save' } );
|
|
590
|
+
return res.sendError( err, 500 );
|
|
591
|
+
}
|
|
592
|
+
}
|
|
143
593
|
|
|
144
594
|
export async function getFileHistory( req, res ) {
|
|
145
595
|
try {
|
|
@@ -210,7 +660,9 @@ export async function userAuditedData( req, res ) {
|
|
|
210
660
|
try {
|
|
211
661
|
const parsedOpenSearch = JSON.parse( process.env.OPENSEARCH );
|
|
212
662
|
const inputData = req.params;
|
|
663
|
+
|
|
213
664
|
const resposnse = await getOpenSearchById( parsedOpenSearch.EyeTestOutput, inputData.id );
|
|
665
|
+
|
|
214
666
|
if ( resposnse.body&&resposnse.body._source ) {
|
|
215
667
|
return res.sendSuccess( { result: resposnse.body._source.steps } );
|
|
216
668
|
} 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 } 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,28 @@ 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
|
+
|
|
57
96
|
'/v3/eye-test-audit/get-file-history/{id}': {
|
|
58
97
|
get: {
|
|
59
98
|
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,39 @@ 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
|
+
|
|
31
56
|
export const getFileHistorySchema = joi.object( {
|
|
32
57
|
id: joi.string().required(),
|
|
33
58
|
type: joi.string().required(),
|
|
@@ -1,13 +1,15 @@
|
|
|
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 { getFileHistoryValid, getFileValid, getListValid, saveValid, userAuditedDataValid, viewFileValid } from '../dtos/eyeTestAudit.dtos.js';
|
|
5
|
+
import { 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 );
|
|
11
13
|
eyeTestAuditRouter.get( '/get-file-history/:id/:type', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( getFileHistoryValid ), getFileHistory );
|
|
12
14
|
eyeTestAuditRouter.get( '/user-audited-data/:id', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( userAuditedDataValid ), userAuditedData );
|
|
13
15
|
|