tango-app-api-trax 3.7.56 → 3.7.57

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.56",
3
+ "version": "3.7.57",
4
4
  "description": "Trax",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -23,11 +23,12 @@
23
23
  "firebase-admin": "^13.0.0",
24
24
  "fs": "^0.0.1-security",
25
25
  "handlebars": "^4.7.8",
26
+ "html-pdf": "^3.0.1",
26
27
  "lodash": "^4.17.21",
27
28
  "mongodb": "^6.8.0",
28
29
  "nodemon": "^3.1.4",
29
30
  "path": "^0.12.7",
30
- "tango-api-schema": "^2.5.59",
31
+ "tango-api-schema": "^2.5.61",
31
32
  "tango-app-api-middleware": "^3.5.2",
32
33
  "url": "^0.11.4",
33
34
  "winston": "^3.13.1",
@@ -0,0 +1,11 @@
1
+ import Handlebars from 'handlebars';
2
+
3
+ Handlebars.registerHelper( 'eq', function( arg1, arg2, options ) {
4
+ return ( arg1 == arg2 ) ? options.fn( this ) : options.inverse( this );
5
+ } );
6
+
7
+ Handlebars.registerHelper( 'neq', function( a, b, options ) {
8
+ return a !== b ? options.fn( this ) : options.inverse( this );
9
+ } );
10
+
11
+ export default Handlebars;
@@ -3203,9 +3203,37 @@ export async function checklistTaskSubmissionDetails( req, res ) {
3203
3203
  }
3204
3204
  let details = [];
3205
3205
  if ( req.body.type == 'checklist' ) {
3206
- details = await processedchecklist.find( { sourceCheckList_id: req.body.checklistId, date_iso: new Date( dayjs( req.body.date ).format( 'YYYY-MM-DD' ) ) }, { submitTime: '$submitTime_string', status: '$checklistStatus', approvalStatus: '$approvalStatus', approvalTime: '$approvalTime_string', _id: 0 } );
3206
+ details = await processedchecklist.find( { sourceCheckList_id: req.body.checklistId, checklistStatus: 'submit', date_iso: new Date( dayjs( req.body.date ).format( 'YYYY-MM-DD' ) ) }, {
3207
+ date_string: 1,
3208
+ checkListName: 1,
3209
+ createdByName: 1,
3210
+ store_id: 1,
3211
+ storeName: 1,
3212
+ submmitedBy: '$userName',
3213
+ submmitedByEmail: '$userEmail',
3214
+ checklistStatus: 1,
3215
+ submitTime: 1,
3216
+ approvalTime: 1,
3217
+ approvalTime_string: 1,
3218
+ approvalByName: 1,
3219
+ approvalByEmail: 1,
3220
+ } );
3207
3221
  } else {
3208
- details = await processedTaskService.find( { sourceCheckList_id: req.body.checklistId, date_iso: new Date( dayjs( req.body.date ).format( 'YYYY-MM-DD' ) ) }, { submitTime: '$submitTime_string', status: '$checklistStatus', approvalStatus: '$approvalStatus', approvalTime: '$approvalTime_string', _id: 0 } );
3222
+ details = await processedTaskService.find( { sourceCheckList_id: req.body.checklistId, checklistStatus: 'submit', date_iso: new Date( dayjs( req.body.date ).format( 'YYYY-MM-DD' ) ) }, {
3223
+ date_string: 1,
3224
+ checkListName: 1,
3225
+ createdByName: 1,
3226
+ store_id: 1,
3227
+ storeName: 1,
3228
+ submmitedBy: '$userName',
3229
+ submmitedByEmail: '$userEmail',
3230
+ checklistStatus: 1,
3231
+ submitTime: 1,
3232
+ approvalTime: 1,
3233
+ approvalTime_string: 1,
3234
+ approvalByName: 1,
3235
+ approvalByEmail: 1,
3236
+ } );
3209
3237
  }
3210
3238
  return res.sendSuccess( details );
3211
3239
  } catch ( e ) {
@@ -21,12 +21,19 @@ import * as clientService from '../services/clients.services.js';
21
21
  import { create } from '../services/authentication.service.js';
22
22
  import { readFileSync } from 'fs';
23
23
  import { join } from 'path';
24
- import handlebars from 'handlebars';
24
+ // import handlebars from 'handlebars';
25
25
  dayjs.extend( customParseFormat );
26
26
  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 * as pdf from 'html-pdf';
31
+ import handlebars from './handlebar-helper.js';
32
+ import fs from 'fs';
33
+ import { fileURLToPath } from 'url';
34
+ import path from 'path';
35
+ const __filename = fileURLToPath( import.meta.url );
36
+ const __dirname = path.dirname( __filename );
30
37
 
31
38
  export async function storeList( req, res ) {
32
39
  try {
@@ -1082,7 +1089,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1082
1089
 
1083
1090
  if ( requestData.submittype == 'submit' ) {
1084
1091
  reqAnswers.forEach( ( reqA ) => {
1085
- if ( ![ 'multiplechoicemultiple', 'multipleImage' ].includes( reqA?.answerType ) ) {
1092
+ if ( ![ 'multiplechoicemultiple', 'multipleImage', 'image/video' ].includes( reqA?.answerType ) && ( reqA.answerType == 'dropDown' && !reqA.allowMultiple ) ) {
1086
1093
  if ( ( !reqA.linkType && ( reqA.answer == null || reqA.answer == '' ) ) || ( reqA.linkType && reqA.linkquestionenabled && ( reqA.answer == null || reqA.answer == '' ) ) ) {
1087
1094
  return res.sendError( 'Please Fill All Fields', 400 );
1088
1095
  }
@@ -1220,7 +1227,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1220
1227
  structure.redoComment = qaAnswers[j]?.redoComment;
1221
1228
  };
1222
1229
  newArray.push( structure );
1223
- } else if ( qaAnswers[j].answerType == 'multiplechoicesingle' ) {
1230
+ } else if ( qaAnswers[j].answerType == 'multiplechoicesingle' || ( qaAnswers[j].answerType == 'dropdown' && !qaAnswers[j].allowMultiple ) ) {
1224
1231
  let qaans = qaAnswers[j].answers;
1225
1232
  let ms = [];
1226
1233
  for ( let k = 0; k < qaans.length; k++ ) {
@@ -1276,7 +1283,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1276
1283
  structure.redoComment = qaAnswers[j]?.redoComment;
1277
1284
  };
1278
1285
  newArray.push( structure );
1279
- } else if ( qaAnswers[j].answerType == 'multiplechoicemultiple' ) {
1286
+ } else if ( qaAnswers[j].answerType == 'multiplechoicemultiple' || ( qaAnswers[j].answerType == 'dropdown' && qaAnswers[j].allowMultiple ) ) {
1280
1287
  let qaans = qaAnswers[j].answers;
1281
1288
  let mcmo = [];
1282
1289
  for ( let k = 0; k < qaans.length; k++ ) {
@@ -1336,7 +1343,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1336
1343
  structure.redoComment = qaAnswers[j]?.redoComment;
1337
1344
  };
1338
1345
  newArray.push( structure );
1339
- } else if ( qaAnswers[j].answerType == 'multipleImage' ) {
1346
+ } else if ( [ 'image/video', 'multipleImage' ].includes( qaAnswers[j].answerType ) ) {
1340
1347
  let separatedArray = typeof requestSection[i].Multianswer == 'string' ? JSON.parse( requestSection[i].Multianswer ) : requestSection[i].Multianswer;
1341
1348
  let mcmi = [];
1342
1349
  // for (let k = 0; k < qaans.length; k++) {
@@ -1366,6 +1373,9 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1366
1373
  newAnswer.runAI = qaAnswers[j].answers[0]?.runAI || false;
1367
1374
  newAnswer.runAIFeatures = qaAnswers[j].answers[0]?.runAIFeatures || [];
1368
1375
  newAnswer.runAIDescription = qaAnswers[j].answers[0]?.runAIDescription || '';
1376
+ if ( qaAnswers[j].answerType == 'image/video' ) {
1377
+ newAnswer.answerType = separatedArray[s].answerType;
1378
+ }
1369
1379
  mcmi.push( newAnswer );
1370
1380
  }
1371
1381
  }
@@ -2002,6 +2012,32 @@ export async function submitChecklist( req, res ) {
2002
2012
  };
2003
2013
  console.log( 'inserttraxlogs =>', inserttraxlogs );
2004
2014
  insertOpenSearchData( openSearch.traxActivityLog, inserttraxlogs );
2015
+ let checklistDetails = await checklistService.findOne( { _id: getchecklist[0].sourceCheckList_id }, { notifyFlags: 1, approver: 1 } );
2016
+ if ( checklistDetails?.notifyFlags?.notifyType?.length ) {
2017
+ let emailList = checklistDetails?.notifyFlags?.notifyType.includes( 'approver' ) ? checklistDetails.approver.flatMap( ( ele ) => ele?.value ): [];
2018
+ emailList = [ ...emailList, ...checklistDetails?.notifyFlags?.notifyType?.users.flatMap( ( ele ) => ele?.value ) ];
2019
+ let data = {
2020
+ storeName: getchecklist[0].storeName,
2021
+ flagCount: updateData.questionFlag,
2022
+ checklistName: getchecklist[0].checkListName,
2023
+ submittedBy: getchecklist[0].userName,
2024
+ time: updateData.submitMobileTime,
2025
+ domain: JSON.parse( process.env.URL ).domain,
2026
+ };
2027
+ const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialExtentionEmail.hbs', 'utf8' );
2028
+ const template = Handlebars.compile( templateHtml );
2029
+ const html = template( { data: data } );
2030
+ emailList.forEach( ( email ) => {
2031
+ let params = {
2032
+ toEmail: email,
2033
+ mailSubject: 'TangoEye | Checklist Flag',
2034
+ htmlBody: html,
2035
+ attachment: '',
2036
+ sourceEmail: JSON.parse( process.env.SES ).adminEmail,
2037
+ };
2038
+ sendEmailWithSES( params.toEmail, params.mailSubject, params.htmlBody, params.attachment, params.sourceEmail );
2039
+ } );
2040
+ }
2005
2041
  }
2006
2042
 
2007
2043
  return res.sendSuccess( 'Checklist Updated Successfully' );
@@ -3230,6 +3266,7 @@ export async function questionList( req, res ) {
3230
3266
  startTime: { $ifNull: [ '$startTime', '' ] },
3231
3267
  submitTime: { $ifNull: [ '$submitTime', '' ] },
3232
3268
  allowedOverTime: { $ifNull: [ '$allowedOverTime', '' ] },
3269
+ sourceCheckList_id: 1,
3233
3270
  // allowedStoreLocation: { $ifNull: [ '$allowedStoreLocation', '' ] },
3234
3271
  allowedStoreLocation: {
3235
3272
  $cond: {
@@ -3285,7 +3322,7 @@ export async function questionList( req, res ) {
3285
3322
  }
3286
3323
 
3287
3324
  for ( let [ ansIndex, answer ] of question.answers.entries() ) {
3288
- if ( question.answerType == 'multiplechoicemultiple' ) {
3325
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
3289
3326
  let checkvalidation = null;
3290
3327
  if ( answer.validationAnswer && answer.validationAnswer !='' ) {
3291
3328
  if ( answer.validationType != 'Descriptive Answer' ) {
@@ -3339,24 +3376,24 @@ export async function questionList( req, res ) {
3339
3376
  getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].multiReferenceImage = userAns.multiReferenceImage;
3340
3377
  }
3341
3378
 
3342
- if ( question.answerType == 'multiplechoicemultiple' ) {
3379
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
3343
3380
  let ansIndex = Multianswer.findIndex( ( item ) => item.answer == userAns.answer );
3344
3381
  if ( ansIndex ) {
3345
3382
  Multianswer[ansIndex].validationAnswer = userAns.validationAnswer;
3346
3383
  }
3347
3384
  }
3348
- if ( question.answerType == 'multipleImage' ) {
3385
+ if ( [ 'image/video', 'multipleImage' ].includes( question.answerType ) ) {
3349
3386
  if ( userAns && userAns.answer && userAns.answer !='' ) {
3350
3387
  // let manswer = await signedUrl( { file_path: decodeURIComponent( userAns.answer ), Bucket: bucket.sop } );
3351
3388
  let manswer = `${cdnurl.TraxAnswerCDN}${userAns.answer}`;
3352
- Multianswer.push( { 'answer': manswer, 'no': userAnsIndex, 'validationAnswer': '' } );
3389
+ Multianswer.push( { 'answer': manswer, 'no': userAnsIndex, 'validationAnswer': '', ...( question.answerType == 'image/video' && { answerType: userAns?.answerType } ) } );
3353
3390
  } else {
3354
3391
 
3355
3392
  }
3356
3393
  }
3357
3394
  }
3358
3395
  }
3359
- if ( question.answerType == 'multiplechoicemultiple' ) {
3396
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
3360
3397
  Multianswer.forEach( ( item ) => {
3361
3398
  if ( item.validationAnswer == null ) {
3362
3399
  item.answer = null;
@@ -3368,11 +3405,11 @@ export async function questionList( req, res ) {
3368
3405
  question.Multianswer = Multianswer;
3369
3406
  }
3370
3407
  }
3371
- if ( question.answerType == 'multipleImage' ) {
3408
+ if ( [ 'image/video', 'multipleImage' ].includes( question.answerType ) ) {
3372
3409
  if ( Multianswer.length ) {
3373
3410
  question.Multianswer = Multianswer;
3374
3411
  } else {
3375
- Multianswer.push( { 'answer': null, 'no': 0, 'validationAnswer': null } );
3412
+ Multianswer.push( { 'answer': null, 'no': 0, 'validationAnswer': null, ...( question.answerType == 'image/video' && { answerType: null } ) } );
3376
3413
  question.Multianswer = Multianswer;
3377
3414
  }
3378
3415
  }
@@ -3417,6 +3454,11 @@ export async function questionList( req, res ) {
3417
3454
  }
3418
3455
  }
3419
3456
 
3457
+ let checklisDetails = await checklistService.findOne( { _id: getchecklist?.[0]?.sourceCheckList_id }, { export: 1 } );
3458
+ if ( checklisDetails ) {
3459
+ getchecklist[0]['export'] = checklisDetails.export;
3460
+ }
3461
+
3420
3462
  return res.sendSuccess( getchecklist );
3421
3463
  }
3422
3464
  } catch ( e ) {
@@ -4238,6 +4280,7 @@ export async function questionListV1( req, res ) {
4238
4280
  startTime: { $ifNull: [ '$startTime', '' ] },
4239
4281
  submitTime: { $ifNull: [ '$submitTime', '' ] },
4240
4282
  allowedOverTime: { $ifNull: [ '$allowedOverTime', '' ] },
4283
+ sourceCheckList_id: { $ifNull: [ '$sourceCheckList_id', '' ] },
4241
4284
  // allowedStoreLocation: { $ifNull: [ '$allowedStoreLocation', '' ] },
4242
4285
  allowedStoreLocation: {
4243
4286
  $cond: {
@@ -4293,7 +4336,7 @@ export async function questionListV1( req, res ) {
4293
4336
  }
4294
4337
 
4295
4338
  for ( let [ ansIndex, answer ] of question.answers.entries() ) {
4296
- if ( question.answerType == 'multiplechoicemultiple' ) {
4339
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
4297
4340
  let checkvalidation = null;
4298
4341
  if ( answer.validationAnswer && answer.validationAnswer !='' ) {
4299
4342
  if ( answer.validationType != 'Descriptive Answer' ) {
@@ -4345,13 +4388,13 @@ export async function questionListV1( req, res ) {
4345
4388
 
4346
4389
  getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].multiReferenceImage = userAns.multiReferenceImage;
4347
4390
  }
4348
- if ( question.answerType == 'multiplechoicemultiple' ) {
4391
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
4349
4392
  let ansIndex = Multianswer.findIndex( ( item ) => item.answer == userAns.answer );
4350
4393
  if ( ansIndex ) {
4351
4394
  Multianswer[ansIndex].validationAnswer = userAns.validationAnswer;
4352
4395
  }
4353
4396
  }
4354
- if ( question.answerType == 'multipleImage' ) {
4397
+ if ( question.answerType == 'multipleImage' || question.answerType == 'image/video' ) {
4355
4398
  if ( userAns && userAns.answer && userAns.answer !='' ) {
4356
4399
  let manswer = `${cdnurl.TraxAnswerCDN}${userAns.answer}`;
4357
4400
  Multianswer.push( { 'answer': manswer, 'no': userAnsIndex, 'validationAnswer': '' } );
@@ -4361,7 +4404,7 @@ export async function questionListV1( req, res ) {
4361
4404
  }
4362
4405
  }
4363
4406
  }
4364
- if ( question.answerType == 'multiplechoicemultiple' ) {
4407
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
4365
4408
  Multianswer.forEach( ( item ) => {
4366
4409
  if ( item.validationAnswer == null ) {
4367
4410
  item.answer = null;
@@ -4373,7 +4416,7 @@ export async function questionListV1( req, res ) {
4373
4416
  question.Multianswer = Multianswer;
4374
4417
  }
4375
4418
  }
4376
- if ( question.answerType == 'multipleImage' ) {
4419
+ if ( question.answerType == 'multipleImage' || question.answerType == 'image/video' ) {
4377
4420
  if ( Multianswer.length ) {
4378
4421
  question.Multianswer = Multianswer;
4379
4422
  } else {
@@ -4422,6 +4465,11 @@ export async function questionListV1( req, res ) {
4422
4465
  }
4423
4466
  }
4424
4467
 
4468
+ let checklisDetails = await checklistService.findOne( { _id: getchecklist?.[0]?.sourceCheckList_id }, { export: 1 } );
4469
+ if ( checklisDetails ) {
4470
+ getchecklist[0]['export'] = checklisDetails.export;
4471
+ }
4472
+
4425
4473
  return res.sendSuccess( getchecklist );
4426
4474
  }
4427
4475
  } catch ( e ) {
@@ -4484,3 +4532,135 @@ export async function chunkUpload( req, res ) {
4484
4532
  return res.sendError( e, 500 );
4485
4533
  }
4486
4534
  }
4535
+
4536
+ export async function downloadChecklist( req, res ) {
4537
+ try {
4538
+ let requestData = req.body;
4539
+
4540
+ if ( !requestData.checklistId ) {
4541
+ res.sendBadRequest( 'checklistId is Required' );
4542
+ }
4543
+
4544
+ let checklistDetails;
4545
+
4546
+ if ( requestData.type == 'checklist' ) {
4547
+ checklistDetails = await processedchecklist.findOne( { _id: requestData.checklistId, checklistStatus: 'submit' } );
4548
+ } else {
4549
+ checklistDetails = await processedTask.findOne( { _id: requestData.checklistId, checklistStatus: 'submit' } );
4550
+ }
4551
+
4552
+ if ( !checklistDetails ) {
4553
+ return res.sendError( 'No data found', 204 );
4554
+ }
4555
+
4556
+ let storeDetails = await storeService.findOne( { storeId: checklistDetails.store_id }, { storeProfile: 1 } );
4557
+ if ( !storeDetails ) {
4558
+ return res.sendError( 'No data found', 204 );
4559
+ }
4560
+
4561
+ let clientDetails = await clientService.findOne( { clientId: checklistDetails.client_id } );
4562
+
4563
+ if ( !clientDetails ) {
4564
+ return res.sendError( 'No client found', 204 );
4565
+ }
4566
+
4567
+ checklistDetails = { ...checklistDetails.toObject(), ...storeDetails?.toObject()?.storeProfile };
4568
+
4569
+
4570
+ let scheduleDateTime = dayjs( checklistDetails.submitTime );
4571
+ checklistDetails.submitDate = scheduleDateTime.format( 'DD MMM, YYYY' );
4572
+ checklistDetails.submitTime = scheduleDateTime.format( 'hh:mm A' );
4573
+ if ( clientDetails?.profileDetails?.logo ) {
4574
+ let bucketpath = checklistDetails.client_id + '/logo';
4575
+
4576
+ let params = {
4577
+ Bucket: JSON.parse( process.env.BUCKET )?.assets,
4578
+ file_path: `${bucketpath}/${clientDetails?.profileDetails?.logo}`,
4579
+ };
4580
+ let url = await signedUrl( params );
4581
+ let brandImage = await convertUrltoBase64( url );
4582
+ if ( brandImage ) {
4583
+ checklistDetails['brandLogo'] = brandImage;
4584
+ }
4585
+ }
4586
+ checklistDetails['brandName'] = clientDetails?.clientName;
4587
+ for ( let section of checklistDetails.questionAnswers ) {
4588
+ for ( let question of section.questions ) {
4589
+ question.remarks = question.remarks == null || question.remarks == 'null' ? '' : question.remarks;
4590
+ for ( let answer of question.userAnswer ) {
4591
+ if ( answer?.referenceImage?.trim() ) {
4592
+ let inputData = {
4593
+ Bucket: JSON.parse( process.env.BUCKET )?.sop,
4594
+ file_path: answer.referenceImage,
4595
+ };
4596
+ let url = await signedUrl( inputData );
4597
+ const base64Image = await convertUrltoBase64( url );
4598
+ if ( base64Image ) {
4599
+ answer.referenceImage = base64Image;
4600
+ }
4601
+ }
4602
+ if ( answer.validationType == 'Capture Image' && answer?.validationAnswer?.trim() ) {
4603
+ let inputData = {
4604
+ Bucket: JSON.parse( process.env.BUCKET )?.sop,
4605
+ file_path: answer.validationAnswer,
4606
+ };
4607
+ let url = await signedUrl( inputData );
4608
+ const base64Image = await convertUrltoBase64( url );
4609
+ if ( base64Image ) {
4610
+ answer.validationAnswer = base64Image;
4611
+ }
4612
+ }
4613
+ if ( answer?.answer?.trim() && [ 'image', 'descriptiveImage', 'multipleImage', 'image/video' ].includes( question.answerType ) ) {
4614
+ let inputData = {
4615
+ Bucket: JSON.parse( process.env.BUCKET )?.sop,
4616
+ file_path: answer.answer,
4617
+ };
4618
+ let url = await signedUrl( inputData );
4619
+ const base64Image = await convertUrltoBase64( url );
4620
+ if ( base64Image ) {
4621
+ answer.answer = base64Image;
4622
+ }
4623
+ }
4624
+ }
4625
+ }
4626
+ }
4627
+ const targetFolder = path.join( __dirname, '..', '/hbs/template.hbs' );
4628
+ const templateHtml = fs.readFileSync( targetFolder, 'utf8' );
4629
+ const template = handlebars.compile( templateHtml );
4630
+ const html = template( { data: checklistDetails } );
4631
+ pdf.create( html ).toBuffer( ( err, buffer ) => {
4632
+ if ( err ) {
4633
+ res.status( 500 ).send( 'Error Generating PDF' );
4634
+ } else {
4635
+ res.setHeader( 'Content-Disposition', 'attachment; filename=checkListDetails.pdf' );
4636
+ res.contentType( 'application/pdf' );
4637
+ res.send( buffer );
4638
+ }
4639
+ } );
4640
+ } catch ( e ) {
4641
+ console.log( 'getChecklistQuestionAnswers =>', e );
4642
+ return false;
4643
+ }
4644
+ }
4645
+
4646
+ async function convertUrltoBase64( url ) {
4647
+ try {
4648
+ const response = await fetch( url );
4649
+
4650
+ if ( !response.ok ) {
4651
+ throw new Error( 'Failed to fetch image' );
4652
+ }
4653
+
4654
+ const contentType = response.headers.get( 'content-type' );
4655
+ const arrayBuffer = await response.arrayBuffer();
4656
+
4657
+ const base64Image =
4658
+ `data:${contentType};base64,` +
4659
+ Buffer.from( arrayBuffer ).toString( 'base64' );
4660
+
4661
+ return base64Image;
4662
+ } catch ( error ) {
4663
+ // console.error( 'Error fetching image:', error.message );
4664
+ return false;
4665
+ }
4666
+ }