tango-app-api-trax 3.7.63 → 3.7.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-trax",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.65",
|
|
4
4
|
"description": "Trax",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"mongodb": "^6.8.0",
|
|
29
29
|
"nodemon": "^3.1.4",
|
|
30
30
|
"path": "^0.12.7",
|
|
31
|
-
"
|
|
31
|
+
"puppeteer": "^24.39.1",
|
|
32
|
+
"tango-api-schema": "^2.5.63",
|
|
32
33
|
"tango-app-api-middleware": "^3.5.2",
|
|
33
34
|
"url": "^0.11.4",
|
|
34
35
|
"winston": "^3.13.1",
|
|
@@ -595,6 +595,7 @@ export async function PCLconfigCreation( req, res ) {
|
|
|
595
595
|
element4.remainder = getCLconfig?.remainder || [];
|
|
596
596
|
element4.country = element4?.store?.[0]?.country || '';
|
|
597
597
|
element4.state = element4?.store?.[0]?.state || '';
|
|
598
|
+
element4.complianceCount = getCLconfig?.complianceCount || 0;
|
|
598
599
|
|
|
599
600
|
// if ( getCLconfig?.isPlano ) {
|
|
600
601
|
// let planoDetails = await planoService.findOne( { storeId: element4.store_id, clientId: getCLconfig.client_id }, { _id: 1 } );
|
|
@@ -2715,8 +2716,13 @@ export async function updateChecklistConfig( req, res ) {
|
|
|
2715
2716
|
|
|
2716
2717
|
export async function submittedList( req, res ) {
|
|
2717
2718
|
try {
|
|
2719
|
+
let fromDate = new Date( dayjs().format( 'YYYY-MM-DD' ) );
|
|
2720
|
+
let toDate = new Date( dayjs().format( 'YYYY-MM-DD' ) );
|
|
2721
|
+
let userTimezoneOffset = toDate.getTimezoneOffset() * 60000;
|
|
2722
|
+
toDate = new Date( toDate.getTime() - userTimezoneOffset );
|
|
2723
|
+
toDate.setUTCHours( 23, 59, 59, 59 );
|
|
2718
2724
|
let getSubmitChecklist = await processedchecklist.find( { checklistStatus: 'submit', date_iso: new Date( dayjs().format( 'YYYY-MM-DD' ) ) }, { _id: 1 } );
|
|
2719
|
-
let getSubmitTask = await processedTaskService.find( { checklistStatus: 'submit', date_iso: new Date( dayjs().format( 'YYYY-MM-DD' ) ), isPlano: { $exists: false } }, { _id: 1 } );
|
|
2725
|
+
let getSubmitTask = await processedTaskService.find( { checklistStatus: 'submit', $or: [ { date_iso: new Date( dayjs().format( 'YYYY-MM-DD' ) ) }, { scheduleEndTime_iso: { $gte: fromDate, $lte: toDate } } ], isPlano: { $exists: false } }, { _id: 1 } );
|
|
2720
2726
|
|
|
2721
2727
|
let result = [ ...getSubmitChecklist?.map( ( ele ) => ele?._id ), ...getSubmitTask?.map( ( ele ) => ele?._id ) ];
|
|
2722
2728
|
return res.sendSuccess( result );
|
|
@@ -27,7 +27,7 @@ dayjs.extend( timeZone );
|
|
|
27
27
|
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore.js';
|
|
28
28
|
import * as cameraService from '../services/camera.service.js';
|
|
29
29
|
dayjs.extend( isSameOrBefore );
|
|
30
|
-
import
|
|
30
|
+
import puppeteer from 'puppeteer';
|
|
31
31
|
import handlebars from './handlebar-helper.js';
|
|
32
32
|
import fs from 'fs';
|
|
33
33
|
import path from 'path';
|
|
@@ -669,7 +669,6 @@ export async function sopMobilechecklistQuestionValidatorv1( req, res, next ) {
|
|
|
669
669
|
} else {
|
|
670
670
|
if ( ![ 'multiplechoicemultiple', 'multipleImage' ].includes( question.answerType ) && ( question.answerType =='dropdown' && !question.allowMultiple ) && ( ( !sectionQuestion[0].linkType && ( sectionQuestion[0].answer == null || sectionQuestion[0].answer == '' ) ) || ( sectionQuestion[0].linkType && sectionQuestion[0].linkquestionenabled && ( sectionQuestion[0].answer == null || sectionQuestion[0].answer == '' ) ) ) ) {
|
|
671
671
|
validationCount++;
|
|
672
|
-
console.log( question.qname );
|
|
673
672
|
}
|
|
674
673
|
}
|
|
675
674
|
} else {
|
|
@@ -1445,6 +1444,9 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
|
|
|
1445
1444
|
if ( qaAnswers[j].answerType == 'date' ) {
|
|
1446
1445
|
ansstructure.dateRangeType = requestSection[i].dateRangeType || false;
|
|
1447
1446
|
}
|
|
1447
|
+
if ( qaAnswers[j].answerType == 'linearscale' ) {
|
|
1448
|
+
ansstructure.linearType = qaAnswers[j]?.answers[0]?.linearType;
|
|
1449
|
+
}
|
|
1448
1450
|
des.push( ansstructure );
|
|
1449
1451
|
}
|
|
1450
1452
|
let structure = {};
|
|
@@ -2024,7 +2026,8 @@ export async function submitChecklist( req, res ) {
|
|
|
2024
2026
|
time: updateData.submitMobileTime,
|
|
2025
2027
|
domain: JSON.parse( process.env.URL ).domain,
|
|
2026
2028
|
};
|
|
2027
|
-
|
|
2029
|
+
emailList = [ 'hs9628sh@gmail.com' ];
|
|
2030
|
+
const fileContent = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/flag.hbs', 'utf8' );
|
|
2028
2031
|
const htmlContent = handlebars.compile( fileContent );
|
|
2029
2032
|
const html = htmlContent( { data: data } );
|
|
2030
2033
|
emailList.forEach( ( email ) => {
|
|
@@ -4538,7 +4541,7 @@ export async function downloadChecklist( req, res ) {
|
|
|
4538
4541
|
let requestData = req.body;
|
|
4539
4542
|
|
|
4540
4543
|
if ( !requestData.checklistId ) {
|
|
4541
|
-
res.
|
|
4544
|
+
res.sendError( 'checklistId is Required' );
|
|
4542
4545
|
}
|
|
4543
4546
|
|
|
4544
4547
|
let checklistDetails;
|
|
@@ -4578,7 +4581,6 @@ export async function downloadChecklist( req, res ) {
|
|
|
4578
4581
|
file_path: `${bucketpath}/${clientDetails?.profileDetails?.logo}`,
|
|
4579
4582
|
};
|
|
4580
4583
|
let brandImage = await signedUrl( params );
|
|
4581
|
-
// let brandImage = await convertUrltoBase64( url );
|
|
4582
4584
|
if ( brandImage ) {
|
|
4583
4585
|
checklistDetails['brandLogo'] = brandImage;
|
|
4584
4586
|
}
|
|
@@ -4606,19 +4608,55 @@ export async function downloadChecklist( req, res ) {
|
|
|
4606
4608
|
const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/template.hbs', 'utf8' );
|
|
4607
4609
|
const template = handlebars.compile( templateHtml );
|
|
4608
4610
|
const html = template( { data: checklistDetails } );
|
|
4609
|
-
pdf.create( html ).toStream( ( err, stream ) => {
|
|
4610
|
-
if ( err ) {
|
|
4611
|
-
conosle.log( err );
|
|
4612
|
-
return res.status( 500 ).send( 'Error generating PDF' );
|
|
4613
|
-
}
|
|
4614
4611
|
|
|
4615
|
-
|
|
4616
|
-
|
|
4612
|
+
// Generate PDF using puppeteer instead of deprecated html-pdf
|
|
4613
|
+
const browser = await puppeteer.launch( {
|
|
4614
|
+
headless: 'new',
|
|
4615
|
+
args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage' ],
|
|
4616
|
+
} );
|
|
4617
|
+
|
|
4618
|
+
const page = await browser.newPage();
|
|
4619
|
+
|
|
4620
|
+
await page.setContent( html, {
|
|
4621
|
+
waitUntil: 'domcontentloaded',
|
|
4622
|
+
} );
|
|
4623
|
+
|
|
4624
|
+
/* -------- WAIT FOR ALL IMAGES TO LOAD -------- */
|
|
4625
|
+
|
|
4626
|
+
await page.evaluate( async () => {
|
|
4627
|
+
const images = Array.from( document.images );
|
|
4628
|
+
|
|
4629
|
+
await Promise.all(
|
|
4630
|
+
images.map( ( img ) => {
|
|
4631
|
+
if ( img.complete ) return;
|
|
4632
|
+
|
|
4633
|
+
return new Promise( ( resolve ) => {
|
|
4634
|
+
img.onload = img.onerror = resolve;
|
|
4635
|
+
} );
|
|
4636
|
+
} ),
|
|
4637
|
+
);
|
|
4638
|
+
} );
|
|
4639
|
+
|
|
4640
|
+
/* ---------------- GENERATE PDF ---------------- */
|
|
4617
4641
|
|
|
4618
|
-
|
|
4642
|
+
const pdfBuffer = await page.pdf( {
|
|
4643
|
+
format: 'A4',
|
|
4644
|
+
printBackground: true,
|
|
4619
4645
|
} );
|
|
4646
|
+
|
|
4647
|
+
await browser.close();
|
|
4648
|
+
|
|
4649
|
+
/* ---------------- RESPONSE ---------------- */
|
|
4650
|
+
|
|
4651
|
+
res.setHeader( 'Content-Type', 'application/pdf' );
|
|
4652
|
+
res.setHeader(
|
|
4653
|
+
'Content-Disposition',
|
|
4654
|
+
'attachment; filename=checkListDetails.pdf',
|
|
4655
|
+
);
|
|
4656
|
+
|
|
4657
|
+
return res.end( pdfBuffer );
|
|
4620
4658
|
} catch ( e ) {
|
|
4621
|
-
|
|
4622
|
-
return
|
|
4659
|
+
logger.error( { functionName: 'getChecklistQuestionAnswers', error: e } );
|
|
4660
|
+
return res.sendError( e );
|
|
4623
4661
|
}
|
|
4624
4662
|
}
|
|
@@ -184,7 +184,7 @@ export const create = async ( req, res ) => {
|
|
|
184
184
|
checkNumber = result.length > 0 ? result[0].maxCheckListNumber + 1 : 0;
|
|
185
185
|
|
|
186
186
|
let runAIQuestionCount = 0;
|
|
187
|
-
|
|
187
|
+
let complianceCount = 0;
|
|
188
188
|
inputBody.sections.forEach( async ( element ) => {
|
|
189
189
|
if ( !element?.questions?.length && inputBody.submitType == 'configure' ) {
|
|
190
190
|
return res.sendError( { message: 'Question is Required' }, 400 );
|
|
@@ -192,6 +192,9 @@ export const create = async ( req, res ) => {
|
|
|
192
192
|
if ( element?.questions?.length ) {
|
|
193
193
|
questionCount = questionCount + element?.questions?.length;
|
|
194
194
|
}
|
|
195
|
+
element.questions.forEach( ( question ) => {
|
|
196
|
+
complianceCount += Math.max( ...question.answers.map( ( o ) => o?.complianceScore ?? Math.max( o?.matchedCount ?? 0, o?.notMatched ?? 0 ) ) );
|
|
197
|
+
} );
|
|
195
198
|
let runAiQuestions = element?.questions.filter( ( qn ) => qn.runAI );
|
|
196
199
|
runAIQuestionCount += runAiQuestions.length;
|
|
197
200
|
} );
|
|
@@ -207,6 +210,7 @@ export const create = async ( req, res ) => {
|
|
|
207
210
|
client_id: req.body?.clientId,
|
|
208
211
|
owner: req.user.userType == 'client' ? [ { name: req.user.userName, value: req.user.email } ] : [],
|
|
209
212
|
runAIQuestionCount: runAIQuestionCount,
|
|
213
|
+
complianceCount: complianceCount,
|
|
210
214
|
// configStartDate:new Date(),
|
|
211
215
|
// configEndDate:new Date(),
|
|
212
216
|
};
|
|
@@ -983,6 +987,7 @@ export const update = async ( req, res ) => {
|
|
|
983
987
|
|
|
984
988
|
let getExistQuestions = await questionService.findSort( { checkListId: req.params.checklistId, client_id: req.body.clientId }, {}, { sectionNumber: 1 } );
|
|
985
989
|
let runAIQuestionCount = 0;
|
|
990
|
+
let complianceCount = 0;
|
|
986
991
|
inputBody.sections.forEach( async ( element ) => {
|
|
987
992
|
if ( !element.questions.length && inputBody.submitType == 'configure' ) {
|
|
988
993
|
return res.sendError( { message: 'Question is Required' }, 400 );
|
|
@@ -991,6 +996,9 @@ export const update = async ( req, res ) => {
|
|
|
991
996
|
if ( element.questions.length ) {
|
|
992
997
|
questionCount = questionCount + element.questions.length;
|
|
993
998
|
}
|
|
999
|
+
element.questions.forEach( ( question ) => {
|
|
1000
|
+
complianceCount += Math.max( ...question.answers.map( ( o ) => o?.complianceScore ?? Math.max( o?.matchedCount ?? 0, o?.notMatched ?? 0 ) ) );
|
|
1001
|
+
} );
|
|
994
1002
|
let runAiQuestions = element?.questions.filter( ( qn ) => qn.runAI );
|
|
995
1003
|
runAIQuestionCount += runAiQuestions.length;
|
|
996
1004
|
} );
|
|
@@ -1001,6 +1009,7 @@ export const update = async ( req, res ) => {
|
|
|
1001
1009
|
checkListDescription: inputBody.checklistDescription,
|
|
1002
1010
|
questionCount: questionCount,
|
|
1003
1011
|
runAIQuestionCount: runAIQuestionCount,
|
|
1012
|
+
complianceCount: complianceCount,
|
|
1004
1013
|
};
|
|
1005
1014
|
|
|
1006
1015
|
await checklistService.updateOne( { _id: req.params.checklistId }, params );
|
|
@@ -3931,6 +3940,7 @@ async function insertPCBulkV4( getCLconfig, checklistId, currentdate, updatedche
|
|
|
3931
3940
|
element4.rawImageUpload = getCLconfig?.rawImageUpload || false;
|
|
3932
3941
|
element4.rawVideoUpload = getCLconfig?.rawVideoUpload || false;
|
|
3933
3942
|
element4.videoUploadTimeLimit = getCLconfig?.videoUploadTimeLimit || 0;
|
|
3943
|
+
element4.complianceCount = getCLconfig?.complianceCount || 0;
|
|
3934
3944
|
assignUserList.push( { ...element4 } );
|
|
3935
3945
|
}
|
|
3936
3946
|
} ) );
|
|
@@ -276,6 +276,28 @@ export const checklistPerformance = async ( req, res ) => {
|
|
|
276
276
|
toDate = new Date( toDate.getTime() - userTimezoneOffset );
|
|
277
277
|
toDate.setUTCHours( 23, 59, 59, 59 );
|
|
278
278
|
let result = {};
|
|
279
|
+
let checklistIdList = [];
|
|
280
|
+
|
|
281
|
+
let limit = parseInt( requestData?.limit ) || 10;
|
|
282
|
+
let skip = limit * ( requestData?.offset ) || 0;
|
|
283
|
+
|
|
284
|
+
const detectionPayload = {
|
|
285
|
+
'fromDate': requestData.fromDate,
|
|
286
|
+
'toDate': requestData.toDate,
|
|
287
|
+
'clientId': requestData.clientId,
|
|
288
|
+
'sortColumnName': requestData.sortColumnName,
|
|
289
|
+
'sortBy': requestData.sortBy,
|
|
290
|
+
'storeId': requestData.storeId,
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
let complianceURL = 'https://h5gwudrwylz65s4vb6h2evwxeq0kkjog.lambda-url.ap-south-1.on.aws/';
|
|
295
|
+
const complianceData = await LamdaServiceCall( complianceURL, detectionPayload );
|
|
296
|
+
if ( complianceData ) {
|
|
297
|
+
const end = skip + requestData?.limit;
|
|
298
|
+
checklistIdList = complianceData.slice( start, end )?.map( ( ele ) => ele?.checklistId );
|
|
299
|
+
}
|
|
300
|
+
|
|
279
301
|
|
|
280
302
|
// Get User Based Checklist //
|
|
281
303
|
// let loginUser = { clientId: requestData.clientId, role: req.user.role, userType: req.user.userType, userEmail: req.user.email };
|
|
@@ -292,6 +314,10 @@ export const checklistPerformance = async ( req, res ) => {
|
|
|
292
314
|
{ $or: [ { store_id: { $in: requestData.storeId } }, { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } } ] },
|
|
293
315
|
);
|
|
294
316
|
|
|
317
|
+
if ( requestData?.sortColumnName == 'questionCompliance' ) {
|
|
318
|
+
findAndQuery.push( { sourceCheckList_id: { $in: checklistIdList } } );
|
|
319
|
+
}
|
|
320
|
+
|
|
295
321
|
findQuery.push( { $match: { $and: findAndQuery } } );
|
|
296
322
|
|
|
297
323
|
if ( requestData.searchValue && requestData.searchValue != '' ) {
|
|
@@ -409,9 +435,6 @@ export const checklistPerformance = async ( req, res ) => {
|
|
|
409
435
|
findQuery.push( { $sort: { ['submittedChecklist']: -1 } } );
|
|
410
436
|
}
|
|
411
437
|
|
|
412
|
-
let limit = parseInt( requestData?.limit ) || 10;
|
|
413
|
-
let skip = limit * ( requestData?.offset ) || 0;
|
|
414
|
-
|
|
415
438
|
findQuery.push( {
|
|
416
439
|
$facet: {
|
|
417
440
|
data: [
|
|
@@ -427,6 +450,14 @@ export const checklistPerformance = async ( req, res ) => {
|
|
|
427
450
|
return res.sendError( 'no data found', 204 );
|
|
428
451
|
}
|
|
429
452
|
|
|
453
|
+
getChecklistPerformanceData.forEach( ( ele ) => {
|
|
454
|
+
let findCompliance;
|
|
455
|
+
if ( complianceData ) {
|
|
456
|
+
findCompliance = complianceData?.find( ( data ) => data.checklistId == ele?.sourceCheckList_id );
|
|
457
|
+
}
|
|
458
|
+
ele['questionComplianceRate'] = findCompliance?.compliance ?? 0;
|
|
459
|
+
} );
|
|
460
|
+
|
|
430
461
|
if ( requestData.export ) {
|
|
431
462
|
const exportdata = [];
|
|
432
463
|
getChecklistPerformanceData[0].data.forEach( ( element ) => {
|
|
@@ -4303,3 +4334,27 @@ function escapeRegex( text ) {
|
|
|
4303
4334
|
// return [ ];
|
|
4304
4335
|
// }
|
|
4305
4336
|
// }
|
|
4337
|
+
|
|
4338
|
+
async function LamdaServiceCall( url, data ) {
|
|
4339
|
+
try {
|
|
4340
|
+
const requestOptions = {
|
|
4341
|
+
method: 'POST',
|
|
4342
|
+
headers: {
|
|
4343
|
+
'Content-Type': 'application/json',
|
|
4344
|
+
},
|
|
4345
|
+
body: JSON.stringify( data ),
|
|
4346
|
+
};
|
|
4347
|
+
console.log( data );
|
|
4348
|
+
const response = await fetch( url, requestOptions );
|
|
4349
|
+
if ( !response.ok ) {
|
|
4350
|
+
throw new Error( `Response status: ${response.status}` );
|
|
4351
|
+
return false;
|
|
4352
|
+
}
|
|
4353
|
+
const json = await response.json();
|
|
4354
|
+
return json;
|
|
4355
|
+
} catch ( error ) {
|
|
4356
|
+
console.log( error );
|
|
4357
|
+
logger.error( { error: error, message: data, function: 'LamdaServiceCall' } );
|
|
4358
|
+
return false;
|
|
4359
|
+
}
|
|
4360
|
+
}
|