tango-app-api-trax 3.7.62 → 3.7.64
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.64",
|
|
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';
|
|
@@ -664,7 +664,7 @@ export async function sopMobilechecklistQuestionValidatorv1( req, res, next ) {
|
|
|
664
664
|
// question.answers.forEach( ( answer ) => {
|
|
665
665
|
let sectionQuestion = requestSection.filter( ( secQuestion ) => secQuestion.qname == question.oldQname || secQuestion.qname == question.qname );
|
|
666
666
|
if ( sectionQuestion.length ) {
|
|
667
|
-
if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType =='dropdown' && question.allowMultiple ) && ( sectionQuestion[0].Multianswer == null || sectionQuestion[0].Multianswer == '' || !sectionQuestion[0].Multianswer.length ) ) {
|
|
667
|
+
if ( ( question.answerType == 'multiplechoicemultiple' || ( question.answerType =='dropdown' && question.allowMultiple ) ) && ( sectionQuestion[0].Multianswer == null || sectionQuestion[0].Multianswer == '' || !sectionQuestion[0].Multianswer.length ) ) {
|
|
668
668
|
validationCount++;
|
|
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 == '' ) ) ) ) {
|
|
@@ -1444,6 +1444,9 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
|
|
|
1444
1444
|
if ( qaAnswers[j].answerType == 'date' ) {
|
|
1445
1445
|
ansstructure.dateRangeType = requestSection[i].dateRangeType || false;
|
|
1446
1446
|
}
|
|
1447
|
+
if ( qaAnswers[j].answerType == 'linearscale' ) {
|
|
1448
|
+
ansstructure.linearType = qaAnswers[j]?.answers[0]?.linearType;
|
|
1449
|
+
}
|
|
1447
1450
|
des.push( ansstructure );
|
|
1448
1451
|
}
|
|
1449
1452
|
let structure = {};
|
|
@@ -4577,7 +4580,6 @@ export async function downloadChecklist( req, res ) {
|
|
|
4577
4580
|
file_path: `${bucketpath}/${clientDetails?.profileDetails?.logo}`,
|
|
4578
4581
|
};
|
|
4579
4582
|
let brandImage = await signedUrl( params );
|
|
4580
|
-
// let brandImage = await convertUrltoBase64( url );
|
|
4581
4583
|
if ( brandImage ) {
|
|
4582
4584
|
checklistDetails['brandLogo'] = brandImage;
|
|
4583
4585
|
}
|
|
@@ -4605,18 +4607,55 @@ export async function downloadChecklist( req, res ) {
|
|
|
4605
4607
|
const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/template.hbs', 'utf8' );
|
|
4606
4608
|
const template = handlebars.compile( templateHtml );
|
|
4607
4609
|
const html = template( { data: checklistDetails } );
|
|
4608
|
-
pdf.create( html ).toStream( ( err, stream ) => {
|
|
4609
|
-
if ( err ) {
|
|
4610
|
-
return res.status( 500 ).send( 'Error generating PDF' );
|
|
4611
|
-
}
|
|
4612
4610
|
|
|
4613
|
-
|
|
4614
|
-
|
|
4611
|
+
// Generate PDF using puppeteer instead of deprecated html-pdf
|
|
4612
|
+
const browser = await puppeteer.launch( {
|
|
4613
|
+
headless: 'new',
|
|
4614
|
+
args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage' ],
|
|
4615
|
+
} );
|
|
4616
|
+
|
|
4617
|
+
const page = await browser.newPage();
|
|
4618
|
+
|
|
4619
|
+
await page.setContent( html, {
|
|
4620
|
+
waitUntil: 'domcontentloaded',
|
|
4621
|
+
} );
|
|
4622
|
+
|
|
4623
|
+
/* -------- WAIT FOR ALL IMAGES TO LOAD -------- */
|
|
4624
|
+
|
|
4625
|
+
await page.evaluate( async () => {
|
|
4626
|
+
const images = Array.from( document.images );
|
|
4627
|
+
|
|
4628
|
+
await Promise.all(
|
|
4629
|
+
images.map( ( img ) => {
|
|
4630
|
+
if ( img.complete ) return;
|
|
4631
|
+
|
|
4632
|
+
return new Promise( ( resolve ) => {
|
|
4633
|
+
img.onload = img.onerror = resolve;
|
|
4634
|
+
} );
|
|
4635
|
+
} ),
|
|
4636
|
+
);
|
|
4637
|
+
} );
|
|
4638
|
+
|
|
4639
|
+
/* ---------------- GENERATE PDF ---------------- */
|
|
4615
4640
|
|
|
4616
|
-
|
|
4641
|
+
const pdfBuffer = await page.pdf( {
|
|
4642
|
+
format: 'A4',
|
|
4643
|
+
printBackground: true,
|
|
4617
4644
|
} );
|
|
4645
|
+
|
|
4646
|
+
await browser.close();
|
|
4647
|
+
|
|
4648
|
+
/* ---------------- RESPONSE ---------------- */
|
|
4649
|
+
|
|
4650
|
+
res.setHeader( 'Content-Type', 'application/pdf' );
|
|
4651
|
+
res.setHeader(
|
|
4652
|
+
'Content-Disposition',
|
|
4653
|
+
'attachment; filename=checkListDetails.pdf',
|
|
4654
|
+
);
|
|
4655
|
+
|
|
4656
|
+
return res.end( pdfBuffer );
|
|
4618
4657
|
} catch ( e ) {
|
|
4619
|
-
|
|
4620
|
-
return
|
|
4658
|
+
logger.error( { functionName: 'getChecklistQuestionAnswers', error: e } );
|
|
4659
|
+
return e;
|
|
4621
4660
|
}
|
|
4622
4661
|
}
|
|
@@ -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 };
|
|
@@ -290,8 +312,13 @@ export const checklistPerformance = async ( req, res ) => {
|
|
|
290
312
|
{ client_id: requestData.clientId },
|
|
291
313
|
// { store_id: { $in: requestData.storeId } },
|
|
292
314
|
{ $or: [ { store_id: { $in: requestData.storeId } }, { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } } ] },
|
|
315
|
+
|
|
293
316
|
);
|
|
294
317
|
|
|
318
|
+
if ( requestData?.sortColumnName == 'questionCompliance' ) {
|
|
319
|
+
findAndQuery.push( { sourceCheckList_id: { $in: checklistIdList } } );
|
|
320
|
+
}
|
|
321
|
+
|
|
295
322
|
findQuery.push( { $match: { $and: findAndQuery } } );
|
|
296
323
|
|
|
297
324
|
if ( requestData.searchValue && requestData.searchValue != '' ) {
|
|
@@ -409,9 +436,6 @@ export const checklistPerformance = async ( req, res ) => {
|
|
|
409
436
|
findQuery.push( { $sort: { ['submittedChecklist']: -1 } } );
|
|
410
437
|
}
|
|
411
438
|
|
|
412
|
-
let limit = parseInt( requestData?.limit ) || 10;
|
|
413
|
-
let skip = limit * ( requestData?.offset ) || 0;
|
|
414
|
-
|
|
415
439
|
findQuery.push( {
|
|
416
440
|
$facet: {
|
|
417
441
|
data: [
|
|
@@ -427,6 +451,11 @@ export const checklistPerformance = async ( req, res ) => {
|
|
|
427
451
|
return res.sendError( 'no data found', 204 );
|
|
428
452
|
}
|
|
429
453
|
|
|
454
|
+
getChecklistPerformanceData.forEach( ( ele ) => {
|
|
455
|
+
let findCompliance = complianceData?.find( ( data ) => data.checklistId == ele?.sourceCheckList_id );
|
|
456
|
+
ele['questionComplianceRate'] = findCompliance?.compliance ?? 0;
|
|
457
|
+
} );
|
|
458
|
+
|
|
430
459
|
if ( requestData.export ) {
|
|
431
460
|
const exportdata = [];
|
|
432
461
|
getChecklistPerformanceData[0].data.forEach( ( element ) => {
|
|
@@ -4303,3 +4332,27 @@ function escapeRegex( text ) {
|
|
|
4303
4332
|
// return [ ];
|
|
4304
4333
|
// }
|
|
4305
4334
|
// }
|
|
4335
|
+
|
|
4336
|
+
async function LamdaServiceCall( url, data ) {
|
|
4337
|
+
try {
|
|
4338
|
+
const requestOptions = {
|
|
4339
|
+
method: 'POST',
|
|
4340
|
+
headers: {
|
|
4341
|
+
'Content-Type': 'application/json',
|
|
4342
|
+
},
|
|
4343
|
+
body: JSON.stringify( data ),
|
|
4344
|
+
};
|
|
4345
|
+
console.log( data );
|
|
4346
|
+
const response = await fetch( url, requestOptions );
|
|
4347
|
+
if ( !response.ok ) {
|
|
4348
|
+
throw new Error( `Response status: ${response.status}` );
|
|
4349
|
+
return false;
|
|
4350
|
+
}
|
|
4351
|
+
const json = await response.json();
|
|
4352
|
+
return json;
|
|
4353
|
+
} catch ( error ) {
|
|
4354
|
+
console.log( error );
|
|
4355
|
+
logger.error( { error: error, message: data, function: 'LamdaServiceCall' } );
|
|
4356
|
+
return false;
|
|
4357
|
+
}
|
|
4358
|
+
}
|