tango-app-api-trax 3.7.75 → 3.7.76

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.
@@ -21,12 +21,16 @@ 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 puppeteer from 'puppeteer';
31
+ import handlebars from './handlebar-helper.js';
32
+ import fs from 'fs';
33
+ import path from 'path';
30
34
 
31
35
  export async function storeList( req, res ) {
32
36
  try {
@@ -225,6 +229,7 @@ export async function startChecklist( req, res ) {
225
229
  },
226
230
  questionAnswers: { $ifNull: [ '$questionAnswers', '' ] },
227
231
  redoStatus: { $ifNull: [ '$redoStatus', '' ] },
232
+ export: { $ifNull: [ '$export', '' ] },
228
233
  },
229
234
  } );
230
235
  let getupdatedchecklist = await processedchecklist.aggregate( findQuery );
@@ -645,7 +650,7 @@ export async function sopMobilechecklistQuestionValidatorv1( req, res, next ) {
645
650
  return res.sendError( 'Please Fill all Required Fields', 400 );
646
651
  }
647
652
 
648
- if ( requestData.submittype == 'submit' ) {
653
+ if ( !requestData?.editSubmit || requestData?.editSubmit == 'false' ) {
649
654
  let reqAnswers = requestData.questionAnswers;
650
655
  logger.error( { functionName: 'payload', message: reqAnswers } );
651
656
  let CLQAnswers = getChecklistQA.questionAnswers;
@@ -659,11 +664,11 @@ export async function sopMobilechecklistQuestionValidatorv1( req, res, next ) {
659
664
  section.questions.forEach( ( question ) => {
660
665
  // question.answers.forEach( ( answer ) => {
661
666
  let sectionQuestion = requestSection.filter( ( secQuestion ) => secQuestion.qname == question.oldQname || secQuestion.qname == question.qname );
662
- if ( sectionQuestion.length ) {
663
- if ( question.answerType == 'multiplechoicemultiple' && ( sectionQuestion[0].Multianswer == null || sectionQuestion[0].Multianswer == '' || !sectionQuestion[0].Multianswer.length ) ) {
667
+ if ( sectionQuestion.length && requestData.submittype == 'submit' ) {
668
+ if ( ( question.answerType == 'multiplechoicemultiple' || ( question.answerType =='dropdown' && question.allowMultiple ) ) && ( sectionQuestion[0].Multianswer == null || sectionQuestion[0].Multianswer == '' || !sectionQuestion[0].Multianswer.length ) ) {
664
669
  validationCount++;
665
670
  } else {
666
- if ( ![ 'multiplechoicemultiple', 'multipleImage' ].includes( question.answerType ) && ( ( !sectionQuestion[0].linkType && ( sectionQuestion[0].answer == null || sectionQuestion[0].answer == '' ) ) || ( sectionQuestion[0].linkType && sectionQuestion[0].linkquestionenabled && ( sectionQuestion[0].answer == null || sectionQuestion[0].answer == '' ) ) ) ) {
671
+ 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 == '' ) ) ) ) {
667
672
  validationCount++;
668
673
  }
669
674
  }
@@ -709,10 +714,13 @@ export async function sopMobileTaskQuestionValidator( req, res, next ) {
709
714
  section.questions.forEach( ( question ) => {
710
715
  question.answers.forEach( ( answer ) => {
711
716
  let sectionQuestion = requestSection.filter( ( secQuestion ) => secQuestion.qno == question.qno );
712
- if ( question.answerType == 'multiplechoicemultiple' && ( sectionQuestion[0].Multianswer == null || sectionQuestion[0].Multianswer == '' || !sectionQuestion[0].Multianswer.length ) ) {
713
- validationCount++;
714
- } else {
715
- if ( ![ 'multiplechoicemultiple', 'multipleImage' ].includes( question.answerType ) && ( ( !sectionQuestion[0].linkType && ( sectionQuestion[0].answer == null || sectionQuestion[0].answer == '' ) ) || ( sectionQuestion[0].linkType && sectionQuestion[0].linkquestionenabled && ( sectionQuestion[0].answer == null || sectionQuestion[0].answer == '' ) ) ) ) {
717
+ if ( sectionQuestion[0] ) {
718
+ const multianswerEmpty = sectionQuestion[0].Multianswer == null || sectionQuestion[0].Multianswer == '' || !sectionQuestion[0].Multianswer?.length;
719
+ const answerEmpty = ( !sectionQuestion[0].linkType && ( sectionQuestion[0].answer == null || sectionQuestion[0].answer == '' ) ) || ( sectionQuestion[0].linkType && sectionQuestion[0].linkquestionenabled && ( sectionQuestion[0].answer == null || sectionQuestion[0].answer == '' ) );
720
+ const usesMultianswer = [ 'multiplechoicemultiple', 'multipleImage', 'image/video' ].includes( question.answerType ) || ( question.answerType == 'dropdown' && question.allowMultiple );
721
+ if ( usesMultianswer && multianswerEmpty ) {
722
+ validationCount++;
723
+ } else if ( !usesMultianswer && answerEmpty ) {
716
724
  validationCount++;
717
725
  }
718
726
  }
@@ -1082,7 +1090,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1082
1090
 
1083
1091
  if ( requestData.submittype == 'submit' ) {
1084
1092
  reqAnswers.forEach( ( reqA ) => {
1085
- if ( ![ 'multiplechoicemultiple', 'multipleImage' ].includes( reqA?.answerType ) ) {
1093
+ if ( ![ 'multiplechoicemultiple', 'multipleImage', 'image/video' ].includes( reqA?.answerType ) && ( reqA.answerType == 'dropDown' && !reqA.allowMultiple ) ) {
1086
1094
  if ( ( !reqA.linkType && ( reqA.answer == null || reqA.answer == '' ) ) || ( reqA.linkType && reqA.linkquestionenabled && ( reqA.answer == null || reqA.answer == '' ) ) ) {
1087
1095
  return res.sendError( 'Please Fill All Fields', 400 );
1088
1096
  }
@@ -1205,6 +1213,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1205
1213
  structure.questionReferenceImage = qaAnswers[j].questionReferenceImage || '';
1206
1214
  structure.multiQuestionReferenceImage = qaAnswers[j].multiQuestionReferenceImage || [];
1207
1215
  structure.descriptivetype = qaAnswers[j].descriptivetype;
1216
+ structure.compliance = qaAnswers[j]?.compliance;
1208
1217
  // structure.parentQuestion = requestSection[i]?.parentQuestion || qaAnswers[j].qno;
1209
1218
  structure.oldQname = qaAnswers[j]?.oldQname || qaAnswers[j].qname;
1210
1219
  if ( qaAnswers[j]?.taskId ) {
@@ -1220,7 +1229,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1220
1229
  structure.redoComment = qaAnswers[j]?.redoComment;
1221
1230
  };
1222
1231
  newArray.push( structure );
1223
- } else if ( qaAnswers[j].answerType == 'multiplechoicesingle' ) {
1232
+ } else if ( qaAnswers[j].answerType == 'multiplechoicesingle' || ( qaAnswers[j].answerType == 'dropdown' && !qaAnswers[j].allowMultiple ) ) {
1224
1233
  let qaans = qaAnswers[j].answers;
1225
1234
  let ms = [];
1226
1235
  for ( let k = 0; k < qaans.length; k++ ) {
@@ -1261,6 +1270,8 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1261
1270
  structure.questionReferenceImage = qaAnswers[j].questionReferenceImage || '';
1262
1271
  structure.multiQuestionReferenceImage = qaAnswers[j].multiQuestionReferenceImage || [];
1263
1272
  structure.descriptivetype = qaAnswers[j].descriptivetype;
1273
+ structure.allowMultiple = qaAnswers[j].allowMultiple;
1274
+ structure.compliance = qaAnswers[j]?.compliance;
1264
1275
  // structure.parentQuestion = requestSection[i]?.parentQuestion || qaAnswers[j].qno;
1265
1276
  structure.oldQname = qaAnswers[j]?.oldQname || qaAnswers[j].qname;
1266
1277
  if ( qaAnswers[j]?.taskId ) {
@@ -1276,7 +1287,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1276
1287
  structure.redoComment = qaAnswers[j]?.redoComment;
1277
1288
  };
1278
1289
  newArray.push( structure );
1279
- } else if ( qaAnswers[j].answerType == 'multiplechoicemultiple' ) {
1290
+ } else if ( qaAnswers[j].answerType == 'multiplechoicemultiple' || ( qaAnswers[j].answerType == 'dropdown' && qaAnswers[j].allowMultiple ) ) {
1280
1291
  let qaans = qaAnswers[j].answers;
1281
1292
  let mcmo = [];
1282
1293
  for ( let k = 0; k < qaans.length; k++ ) {
@@ -1321,6 +1332,8 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1321
1332
  structure.questionReferenceImage = qaAnswers[j].questionReferenceImage || '';
1322
1333
  structure.multiQuestionReferenceImage = qaAnswers[j].multiQuestionReferenceImage || [];
1323
1334
  structure.descriptivetype = qaAnswers[j].descriptivetype;
1335
+ structure.allowMultiple = qaAnswers[j].allowMultiple;
1336
+ structure.compliance = qaAnswers[j]?.compliance;
1324
1337
  // structure.parentQuestion = requestSection[i]?.parentQuestion || qaAnswers[j].qno;
1325
1338
  structure.oldQname = qaAnswers[j]?.oldQname || qaAnswers[j].qname;
1326
1339
  if ( qaAnswers[j]?.taskId ) {
@@ -1336,7 +1349,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1336
1349
  structure.redoComment = qaAnswers[j]?.redoComment;
1337
1350
  };
1338
1351
  newArray.push( structure );
1339
- } else if ( qaAnswers[j].answerType == 'multipleImage' ) {
1352
+ } else if ( [ 'image/video', 'multipleImage' ].includes( qaAnswers[j].answerType ) ) {
1340
1353
  let separatedArray = typeof requestSection[i].Multianswer == 'string' ? JSON.parse( requestSection[i].Multianswer ) : requestSection[i].Multianswer;
1341
1354
  let mcmi = [];
1342
1355
  // for (let k = 0; k < qaans.length; k++) {
@@ -1366,6 +1379,9 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1366
1379
  newAnswer.runAI = qaAnswers[j].answers[0]?.runAI || false;
1367
1380
  newAnswer.runAIFeatures = qaAnswers[j].answers[0]?.runAIFeatures || [];
1368
1381
  newAnswer.runAIDescription = qaAnswers[j].answers[0]?.runAIDescription || '';
1382
+ if ( qaAnswers[j].answerType == 'image/video' ) {
1383
+ newAnswer.answerType = separatedArray[s].answerType;
1384
+ }
1369
1385
  mcmi.push( newAnswer );
1370
1386
  }
1371
1387
  }
@@ -1388,6 +1404,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1388
1404
  structure.questionReferenceImage = qaAnswers[j].questionReferenceImage || '';
1389
1405
  structure.multiQuestionReferenceImage = qaAnswers[j].multiQuestionReferenceImage || [];
1390
1406
  structure.descriptivetype = qaAnswers[j].descriptivetype;
1407
+ structure.compliance = qaAnswers[j]?.compliance;
1391
1408
  // structure.parentQuestion = requestSection[i]?.parentQuestion || qaAnswers[j].qno;
1392
1409
  structure.oldQname = qaAnswers[j]?.oldQname || qaAnswers[j].qname;
1393
1410
  if ( qaAnswers[j]?.taskId ) {
@@ -1434,6 +1451,40 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1434
1451
  };
1435
1452
  if ( qaAnswers[j].answerType == 'date' ) {
1436
1453
  ansstructure.dateRangeType = requestSection[i].dateRangeType || false;
1454
+ if ( qaAnswers[j].compliance ) {
1455
+ if ( qaAnswers[j].compliance ) {
1456
+ let ansArray = requestSection[i].answer.split( ',' );
1457
+ if ( ansArray.includes( '-' ) ) {
1458
+ ansArray = requestSection[i].answer.split( '-' );
1459
+ }
1460
+ if ( ansArray.length > 1 && ansArray.some( ( date ) => dayjs( date, 'DD MMM YYYY' ).format( 'DD-MM-YYYY' ) >= qaAnswers[j]?.answers[0]?.startDate || dayjs( date, 'DD MMM YYYY' ) <= qaAnswers[j]?.answers[0]?.endDate ) ) {
1461
+ ansstructure.complianceScore = qaAnswers[j]?.answers[0]?.matchedCount;
1462
+ } else if ( ansArray.length > 1 && ( dayjs( ansArray?.[0], 'DD MMM YYYY' ).format( 'DD-MM-YYYY' ) >= qaAnswers[j]?.answers[0]?.startDate || dayjs( ansArray?.[1], 'DD MMM YYYY' ).format( 'DD-MM-YYYY' ) <= qaAnswers[j]?.answers[0]?.endDate ) ) {
1463
+ ansstructure.complianceScore = qaAnswers[j]?.answers[0]?.matchedCount;
1464
+ } else if ( dayjs( requestSection[i].answer, 'DD MMM YYYY' ) >= qaAnswers[j]?.answers[0]?.startDate || dayjs( requestSection[i].answer, 'DD MMM YYYY' ) <= qaAnswers[j]?.answers[0]?.startDate ) {
1465
+ ansstructure.complianceScore = qaAnswers[j]?.answers[0]?.matchedCount;
1466
+ } else {
1467
+ ansstructure.complianceScore = qaAnswers[j]?.answers[0]?.notMatchedCount;
1468
+ }
1469
+ }
1470
+ }
1471
+ }
1472
+ if ( qaAnswers[j].answerType == 'linearscale' ) {
1473
+ if ( qaAnswers[j].compliance ) {
1474
+ let linearAnswer = requestSection[i].answer.split( 'to' );
1475
+ if ( parseInt( linearAnswer?.[0] ) >= qaAnswers[j]?.answers[0]?.minValue || parseInt( linearAnswer?.[1] ) <= qaAnswers[j]?.answers[0]?.maxValue ) {
1476
+ ansstructure.complianceScore = qaAnswers[j]?.answers[0]?.matchedCount;
1477
+ } else {
1478
+ ansstructure.complianceScore = qaAnswers[j]?.answers[0]?.notMatchedCount;
1479
+ }
1480
+ }
1481
+ ansstructure.linearType = qaAnswers[j]?.answers[0]?.linearType;
1482
+ ansstructure.matchedCount = qaAnswers[j]?.answers[0]?.matchedCount;
1483
+ ansstructure.notMatchedCount = qaAnswers[j]?.answers[0]?.notMatchedCount;
1484
+ }
1485
+ if ( qaAnswers[j].answerType == 'image' ) {
1486
+ ansstructure.matchedCount = qaAnswers[j]?.answers[0]?.matchedCount;
1487
+ ansstructure.notMatchedCount = qaAnswers[j]?.answers[0]?.notMatchedCount;
1437
1488
  }
1438
1489
  des.push( ansstructure );
1439
1490
  }
@@ -1457,6 +1508,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1457
1508
  structure.descriptivetype = qaAnswers[j].descriptivetype;
1458
1509
  // structure.parentQuestion = requestSection[i]?.parentQuestion || qaAnswers[j].qno;
1459
1510
  structure.oldQname = qaAnswers[j]?.oldQname || qaAnswers[j].qname;
1511
+ structure.compliance = qaAnswers[j]?.compliance;
1460
1512
  if ( qaAnswers[j]?.taskId ) {
1461
1513
  structure.taskId = qaAnswers[j]?.taskId;
1462
1514
  structure.task = true;
@@ -1503,7 +1555,7 @@ export async function sopMobileTaskMultiSectionFormatter( req, res, next ) {
1503
1555
 
1504
1556
  if ( requestData.submittype == 'submit' ) {
1505
1557
  reqAnswers.forEach( ( reqA ) => {
1506
- if ( ![ 'multiplechoicemultiple', 'multipleImage' ].includes( reqA?.answerType ) ) {
1558
+ if ( ![ 'multiplechoicemultiple', 'multipleImage', 'image/video' ].includes( reqA?.answerType ) && ( reqA?.answerType == 'dropdown' && !reqA?.Multianswer?.length ) ) {
1507
1559
  if ( ( !reqA.linkType && ( reqA.answer == null || reqA.answer == '' ) ) || ( reqA.linkType && reqA.linkquestionenabled && ( reqA.answer == null || reqA.answer == '' ) ) ) {
1508
1560
  return res.sendError( 'Please Fill All Fields', 400 );
1509
1561
  }
@@ -1684,8 +1736,64 @@ export async function sopMobileTaskMultiSectionFormatter( req, res, next ) {
1684
1736
  structure.redoComment = qaAnswers[j]?.redoComment;
1685
1737
  };
1686
1738
  newArray.push( structure );
1739
+ } else if ( qaAnswers[j].answerType == 'dropdown' && qaAnswers[j].allowMultiple ) {
1740
+ let qaans = qaAnswers[j].answers;
1741
+ let mcmo = [];
1742
+ for ( let k = 0; k < qaans.length; k++ ) {
1743
+ let separatedArray = typeof requestSection[i].Multianswer == 'string' ? JSON.parse( requestSection[i].Multianswer ) : requestSection[i].Multianswer;
1744
+ if ( separatedArray && separatedArray.length ) {
1745
+ for ( let s = 0; s < separatedArray.length; s++ ) {
1746
+ if ( separatedArray[s].answer == qaans[k].answer ) {
1747
+ if ( qaans[k].validationType == 'Capture Image' || qaans[k].validationType == 'Capture Video' ) {
1748
+ if ( separatedArray[s].validationAnswer ) {
1749
+ let validationAnswer = decodeURIComponent( separatedArray[s].validationAnswer.split( '?' )[0] );
1750
+ if ( validationAnswer.length ) {
1751
+ let splitImgUrl = validationAnswer.split( '/' );
1752
+ if ( splitImgUrl.length > 1 ) {
1753
+ splitImgUrl.splice( 0, 3 );
1754
+ qaans[k].validationAnswer = splitImgUrl.join( '/' ) || '';
1755
+ }
1756
+ }
1757
+ }
1758
+ } else {
1759
+ qaans[k].descriptivetype = qaAnswers[j].descriptivetype || '';
1760
+ qaans[k].validationAnswer = separatedArray[s].validationAnswer || '';
1761
+ }
1762
+ mcmo.push( qaans[k] );
1763
+ }
1764
+ }
1765
+ }
1766
+ }
1767
+ let structure = {};
1768
+ structure.qno = qaAnswers[j].qno;
1769
+ structure.qname = qaAnswers[j].qname;
1770
+ if ( qaAnswers[j].qcomment && qaAnswers[j].qcomment!='' ) {
1771
+ structure.qcomment = qaAnswers[j].qcomment;
1772
+ }
1773
+ structure.answerType = qaAnswers[j].answerType;
1774
+ structure.runAI = qaAnswers[j].runAI;
1775
+ structure.runAIDescription = qaAnswers[j].runAIDescription;
1776
+ structure.allowUploadfromGallery = qaAnswers[j].allowUploadfromGallery;
1777
+ structure.remarks = requestSection[i].remarks;
1778
+ structure.answers = qaAnswers[j].answers;
1779
+ structure.userAnswer = mcmo;
1780
+ structure.linkType = qaAnswers[j].linkType;
1781
+ structure.linkquestionenabled = requestSection[i].linkquestionenabled;
1782
+ structure.parentanswer = requestSection[i].parentanswer;
1783
+ structure.questionReferenceImage = qaAnswers[j].questionReferenceImage;
1784
+ structure.descriptivetype = qaAnswers[j].descriptivetype;
1785
+ structure.allowMultiple = qaAnswers[j].allowMultiple;
1786
+ if ( typeof qaAnswers[j]?.redo === 'boolean' && requestData.submittype === 'submit' ) {
1787
+ structure.redo = false;
1788
+ } else if ( requestData.submittype === 'draft' ) {
1789
+ structure.redo = qaAnswers[j]?.redo;
1790
+ }
1791
+ if ( qaAnswers[j]?.redoComment ) {
1792
+ structure.redoComment = qaAnswers[j]?.redoComment;
1793
+ };
1794
+ newArray.push( structure );
1687
1795
  } else if ( qaAnswers[j].answerType == 'multipleImage' ) {
1688
- let separatedArray = typeof requestSection[i].Multianswer == 'string' ? JSON.parse( requestSection[i].Multianswer ) : requestSection[i].Multianswer;
1796
+ let separatedArray = typeof requestSection[i].Multianswer == 'string' ? JSON.parse( requestSection[i].Multianswer ) : ( requestSection[i].Multianswer || [] );
1689
1797
  let mcmi = [];
1690
1798
  // for (let k = 0; k < qaans.length; k++) {
1691
1799
  for ( let s = 0; s < separatedArray.length; s++ ) {
@@ -1743,6 +1851,69 @@ export async function sopMobileTaskMultiSectionFormatter( req, res, next ) {
1743
1851
  structure.redoComment = qaAnswers[j]?.redoComment;
1744
1852
  };
1745
1853
  newArray.push( structure );
1854
+ } else if ( qaAnswers[j].answerType == 'image/video' ) {
1855
+ let separatedArray = typeof requestSection[i].Multianswer == 'string' ? JSON.parse( requestSection[i].Multianswer ) : requestSection[i].Multianswer;
1856
+ let mcmi = [];
1857
+ if ( separatedArray && separatedArray.length ) {
1858
+ for ( let s = 0; s < separatedArray.length; s++ ) {
1859
+ if ( separatedArray[s].answer && separatedArray[s].answer !='' ) {
1860
+ let newAnswer = {};
1861
+ let validationAnswer = decodeURIComponent( separatedArray[s].answer.split( '?' )[0] );
1862
+ if ( validationAnswer.length ) {
1863
+ let splitImgUrl = validationAnswer.split( '/' );
1864
+ if ( splitImgUrl.length > 1 ) {
1865
+ splitImgUrl.splice( 0, 3 );
1866
+ newAnswer.answer = splitImgUrl.join( '/' ) || '';
1867
+ }
1868
+ }
1869
+ newAnswer.answeroptionNumber = 0;
1870
+ newAnswer.sopFlag = false;
1871
+ newAnswer.validation = false;
1872
+ newAnswer.validationType = '';
1873
+ newAnswer.referenceImage = '';
1874
+ newAnswer.allowUploadfromGallery = false;
1875
+ newAnswer.descriptivetype = '';
1876
+ newAnswer.showLinked = false;
1877
+ newAnswer.linkedQuestion = 0;
1878
+ newAnswer.nestedQuestion = [];
1879
+ newAnswer.index = s;
1880
+ newAnswer.runAI = qaAnswers[j].answers[0]?.runAI || false;
1881
+ newAnswer.runAIFeatures = qaAnswers[j].answers[0]?.runAIFeatures || [];
1882
+ newAnswer.runAIDescription = qaAnswers[j].answers[0]?.runAIDescription || '';
1883
+ if ( separatedArray[s].answerType ) {
1884
+ newAnswer.answerType = separatedArray[s].answerType;
1885
+ }
1886
+ mcmi.push( newAnswer );
1887
+ }
1888
+ }
1889
+ }
1890
+ let structure = {};
1891
+ structure.qno = qaAnswers[j].qno;
1892
+ structure.qname = qaAnswers[j].qname;
1893
+ if ( qaAnswers[j].qcomment && qaAnswers[j].qcomment!='' ) {
1894
+ structure.qcomment = qaAnswers[j].qcomment;
1895
+ }
1896
+ structure.answerType = qaAnswers[j].answerType;
1897
+ structure.runAI = qaAnswers[j].runAI;
1898
+ structure.runAIDescription = qaAnswers[j].runAIDescription;
1899
+ structure.allowUploadfromGallery = qaAnswers[j].allowUploadfromGallery;
1900
+ structure.remarks = requestSection[i].remarks;
1901
+ structure.answers = qaAnswers[j].answers;
1902
+ structure.userAnswer = mcmi;
1903
+ structure.linkType = qaAnswers[j].linkType;
1904
+ structure.linkquestionenabled = requestSection[i].linkquestionenabled;
1905
+ structure.parentanswer = requestSection[i].parentanswer;
1906
+ structure.questionReferenceImage = qaAnswers[j].questionReferenceImage;
1907
+ structure.descriptivetype = qaAnswers[j].descriptivetype;
1908
+ if ( typeof qaAnswers[j]?.redo === 'boolean' && requestData.submittype === 'submit' ) {
1909
+ structure.redo = false;
1910
+ } else if ( requestData.submittype === 'draft' ) {
1911
+ structure.redo = qaAnswers[j]?.redo;
1912
+ }
1913
+ if ( qaAnswers[j]?.redoComment ) {
1914
+ structure.redoComment = qaAnswers[j]?.redoComment;
1915
+ };
1916
+ newArray.push( structure );
1746
1917
  } else {
1747
1918
  let des = [];
1748
1919
  if ( requestSection[i].answer != 'null' && requestSection[i].answer != '' && requestSection[i].answer != null ) {
@@ -2000,8 +2171,35 @@ export async function submitChecklist( req, res ) {
2000
2171
  logDetails: {},
2001
2172
  userType: req.user.userType,
2002
2173
  };
2003
- console.log( 'inserttraxlogs =>', inserttraxlogs );
2004
2174
  insertOpenSearchData( openSearch.traxActivityLog, inserttraxlogs );
2175
+ if ( updateData.questionFlag ) {
2176
+ let checklistDetails = await checklistService.findOne( { _id: getchecklist[0].sourceCheckList_id }, { notifyFlags: 1, approver: 1 } );
2177
+ if ( checklistDetails?.notifyFlags?.notifyType?.length ) {
2178
+ let emailList = checklistDetails?.notifyFlags?.notifyType.includes( 'approver' ) ? checklistDetails.approver.map( ( ele ) => ele?.value ): [];
2179
+ emailList = [ ...emailList, ...checklistDetails?.notifyFlags?.users?.map( ( ele ) => ele?.value ) ];
2180
+ let data = {
2181
+ storeName: getchecklist[0].storeName,
2182
+ flagCount: updateData.questionFlag,
2183
+ checklistName: getchecklist[0].checkListName,
2184
+ submittedBy: getchecklist[0].userName,
2185
+ time: updateData.submitTime_string,
2186
+ domain: `${JSON.parse( process.env.URL ).domain}/manage/trax/flags?date=${dayjs().format( 'YYYY-MM-DD' )}`,
2187
+ };
2188
+ const fileContent = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/flag.hbs', 'utf8' );
2189
+ const htmlContent = handlebars.compile( fileContent );
2190
+ const html = htmlContent( { data: data } );
2191
+ emailList.forEach( ( email ) => {
2192
+ let params = {
2193
+ toEmail: email,
2194
+ mailSubject: 'TangoEye | Checklist Flag',
2195
+ htmlBody: html,
2196
+ attachment: '',
2197
+ sourceEmail: JSON.parse( process.env.SES ).adminEmail,
2198
+ };
2199
+ sendEmailWithSES( params.toEmail, params.mailSubject, params.htmlBody, params.attachment, params.sourceEmail );
2200
+ } );
2201
+ }
2202
+ }
2005
2203
  }
2006
2204
 
2007
2205
  return res.sendSuccess( 'Checklist Updated Successfully' );
@@ -3231,6 +3429,7 @@ export async function questionList( req, res ) {
3231
3429
  startTime: { $ifNull: [ '$startTime', '' ] },
3232
3430
  submitTime: { $ifNull: [ '$submitTime', '' ] },
3233
3431
  allowedOverTime: { $ifNull: [ '$allowedOverTime', '' ] },
3432
+ sourceCheckList_id: 1,
3234
3433
  // allowedStoreLocation: { $ifNull: [ '$allowedStoreLocation', '' ] },
3235
3434
  allowedStoreLocation: {
3236
3435
  $cond: {
@@ -3256,6 +3455,7 @@ export async function questionList( req, res ) {
3256
3455
  videoUploadTimeLimit: { $ifNull: [ '$videoUploadTimeLimit', 0 ] },
3257
3456
  taskType: { $ifNull: [ '$planoType', '' ] },
3258
3457
  streamId: { $ifNull: [ '$streamId', '' ] },
3458
+ export: { $ifNull: [ '$export', '' ] },
3259
3459
  },
3260
3460
  } );
3261
3461
 
@@ -3286,7 +3486,7 @@ export async function questionList( req, res ) {
3286
3486
  }
3287
3487
 
3288
3488
  for ( let [ ansIndex, answer ] of question.answers.entries() ) {
3289
- if ( question.answerType == 'multiplechoicemultiple' ) {
3489
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
3290
3490
  let checkvalidation = null;
3291
3491
  if ( answer.validationAnswer && answer.validationAnswer !='' ) {
3292
3492
  if ( answer.validationType != 'Descriptive Answer' ) {
@@ -3340,24 +3540,24 @@ export async function questionList( req, res ) {
3340
3540
  getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].multiReferenceImage = userAns.multiReferenceImage;
3341
3541
  }
3342
3542
 
3343
- if ( question.answerType == 'multiplechoicemultiple' ) {
3543
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
3344
3544
  let ansIndex = Multianswer.findIndex( ( item ) => item.answer == userAns.answer );
3345
3545
  if ( ansIndex ) {
3346
3546
  Multianswer[ansIndex].validationAnswer = userAns.validationAnswer;
3347
3547
  }
3348
3548
  }
3349
- if ( question.answerType == 'multipleImage' ) {
3549
+ if ( [ 'image/video', 'multipleImage' ].includes( question.answerType ) ) {
3350
3550
  if ( userAns && userAns.answer && userAns.answer !='' ) {
3351
3551
  // let manswer = await signedUrl( { file_path: decodeURIComponent( userAns.answer ), Bucket: bucket.sop } );
3352
3552
  let manswer = `${cdnurl.TraxAnswerCDN}${userAns.answer}`;
3353
- Multianswer.push( { 'answer': manswer, 'no': userAnsIndex, 'validationAnswer': '' } );
3553
+ Multianswer.push( { 'answer': manswer, 'no': userAnsIndex, 'validationAnswer': '', ...( question.answerType == 'image/video' && { answerType: userAns?.answerType } ) } );
3354
3554
  } else {
3355
3555
 
3356
3556
  }
3357
3557
  }
3358
3558
  }
3359
3559
  }
3360
- if ( question.answerType == 'multiplechoicemultiple' ) {
3560
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
3361
3561
  Multianswer.forEach( ( item ) => {
3362
3562
  if ( item.validationAnswer == null ) {
3363
3563
  item.answer = null;
@@ -3369,11 +3569,11 @@ export async function questionList( req, res ) {
3369
3569
  question.Multianswer = Multianswer;
3370
3570
  }
3371
3571
  }
3372
- if ( question.answerType == 'multipleImage' ) {
3572
+ if ( [ 'image/video', 'multipleImage' ].includes( question.answerType ) ) {
3373
3573
  if ( Multianswer.length ) {
3374
3574
  question.Multianswer = Multianswer;
3375
3575
  } else {
3376
- Multianswer.push( { 'answer': null, 'no': 0, 'validationAnswer': null } );
3576
+ Multianswer.push( { 'answer': null, 'no': 0, 'validationAnswer': null, ...( question.answerType == 'image/video' && { answerType: null } ) } );
3377
3577
  question.Multianswer = Multianswer;
3378
3578
  }
3379
3579
  }
@@ -3418,6 +3618,11 @@ export async function questionList( req, res ) {
3418
3618
  }
3419
3619
  }
3420
3620
 
3621
+ let checklisDetails = await checklistService.findOne( { _id: getchecklist?.[0]?.sourceCheckList_id }, { export: 1 } );
3622
+ if ( checklisDetails ) {
3623
+ getchecklist[0]['export'] = checklisDetails.export;
3624
+ }
3625
+
3421
3626
  return res.sendSuccess( getchecklist );
3422
3627
  }
3423
3628
  } catch ( e ) {
@@ -3622,6 +3827,7 @@ export async function taskQuestionList( req, res ) {
3622
3827
  } else {
3623
3828
  logger.info( `v5 => Task Continue => store Name: ${getchecklist[0].storeName}, User Email: ${getchecklist[0].userEmail}, Task Name: ${getchecklist[0].checkListName}` );
3624
3829
  let bucket = JSON.parse( process.env.BUCKET );
3830
+ let cdnurl = JSON.parse( process.env.CDNURL );
3625
3831
  for ( let [ secIndex, section ] of getchecklist[0].questionAnswers.entries() ) {
3626
3832
  for ( let [ questionIndex, question ] of section.questions.entries() ) {
3627
3833
  let Multianswer = [];
@@ -3658,10 +3864,14 @@ export async function taskQuestionList( req, res ) {
3658
3864
  }
3659
3865
  }
3660
3866
 
3661
- if ( question.answerType == 'multiplechoicemultiple' ) {
3867
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
3662
3868
  let checkvalidation = null;
3663
3869
  if ( answer.validationAnswer && answer.validationAnswer != '' ) {
3664
- checkvalidation = await signedUrl( { file_path: decodeURIComponent( answer.validationAnswer ), Bucket: bucket.sop } );
3870
+ if ( answer.validationType != 'Descriptive Answer' ) {
3871
+ checkvalidation = await signedUrl( { file_path: decodeURIComponent( answer.validationAnswer ), Bucket: bucket.sop } );
3872
+ } else {
3873
+ checkvalidation = answer.validationAnswer;
3874
+ }
3665
3875
  }
3666
3876
  Multianswer.push( { 'answer': answer.answer, 'no': ansIndex, 'validationAnswer': checkvalidation } );
3667
3877
  getchecklist[0].questionAnswers[secIndex].questions[questionIndex].answers[ansIndex].index = ansIndex;
@@ -3676,41 +3886,48 @@ export async function taskQuestionList( req, res ) {
3676
3886
 
3677
3887
  if ( question?.userAnswer ) {
3678
3888
  for ( let [ userAnsIndex, userAns ] of question.userAnswer.entries() ) {
3889
+ const rawAnswer = userAns.answer;
3890
+ if ( question.answerType == 'linearscale' && question.answers?.[0]?.linearType ) {
3891
+ getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].linearType = question.answers[0].linearType;
3892
+ }
3679
3893
  if ( ( userAns.validationType == 'Capture Image' || userAns.validationType == 'Capture Video' ) && userAns.validationAnswer && userAns.validationAnswer != '' ) {
3680
3894
  getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].validationAnswer = await signedUrl( {
3681
3895
  file_path: decodeURIComponent( userAns.validationAnswer ),
3682
3896
  Bucket: bucket.sop,
3683
3897
  } );
3684
3898
  }
3685
- if ( [ 'image', 'descriptiveImage', 'video' ].includes( question.answerType ) && userAns.answer != '' ) {
3899
+ if ( [ 'image', 'descriptiveImage', 'video' ].includes( question.answerType ) && rawAnswer != '' ) {
3686
3900
  getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].answer = await signedUrl( {
3687
- file_path: decodeURIComponent( userAns.answer ),
3901
+ file_path: decodeURIComponent( rawAnswer ),
3688
3902
  Bucket: bucket.sop,
3689
3903
  } );
3690
3904
  }
3905
+ if ( question.answerType == 'image/video' && rawAnswer != '' ) {
3906
+ getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].answer = `${cdnurl.TraxAnswerCDN}${rawAnswer}`;
3907
+ }
3691
3908
  if ( userAns.referenceImage != '' ) {
3692
3909
  getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].referenceImage = await signedUrl( {
3693
3910
  file_path: decodeURIComponent( userAns.referenceImage ),
3694
3911
  Bucket: bucket.sop,
3695
3912
  } );
3696
3913
  }
3697
- if ( question.answerType == 'multiplechoicemultiple' ) {
3698
- let ansIndex = Multianswer.findIndex( ( item ) => item.answer == userAns.answer );
3699
- if ( ansIndex ) {
3914
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
3915
+ let ansIndex = Multianswer.findIndex( ( item ) => item.answer == rawAnswer );
3916
+ if ( ansIndex >= 0 ) {
3700
3917
  Multianswer[ansIndex].validationAnswer = userAns.validationAnswer;
3701
3918
  }
3702
3919
  }
3703
- if ( question.answerType == 'multipleImage' ) {
3704
- if ( userAns && userAns.answer && userAns.answer != '' ) {
3705
- let manswer = await signedUrl( { file_path: decodeURIComponent( userAns.answer ), Bucket: bucket.sop } );
3706
- Multianswer.push( { 'answer': manswer, 'no': userAnsIndex, 'validationAnswer': '' } );
3920
+ if ( question.answerType == 'multipleImage' || question.answerType == 'image/video' ) {
3921
+ if ( userAns && rawAnswer && rawAnswer != '' ) {
3922
+ let manswer = `${cdnurl.TraxAnswerCDN}${rawAnswer}`;
3923
+ Multianswer.push( { 'answer': manswer, 'no': userAnsIndex, 'validationAnswer': '', ...( question.answerType == 'image/video' && { answerType: userAns?.answerType } ) } );
3707
3924
  } else {
3708
3925
 
3709
3926
  }
3710
3927
  }
3711
3928
  }
3712
3929
  }
3713
- if ( question.answerType == 'multiplechoicemultiple' ) {
3930
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
3714
3931
  Multianswer.forEach( ( item ) => {
3715
3932
  if ( item.validationAnswer == null ) {
3716
3933
  item.answer = null;
@@ -3722,11 +3939,11 @@ export async function taskQuestionList( req, res ) {
3722
3939
  question.Multianswer = Multianswer;
3723
3940
  }
3724
3941
  }
3725
- if ( question.answerType == 'multipleImage' ) {
3942
+ if ( question.answerType == 'multipleImage' || question.answerType == 'image/video' ) {
3726
3943
  if ( Multianswer.length ) {
3727
3944
  question.Multianswer = Multianswer;
3728
3945
  } else {
3729
- Multianswer.push( { 'answer': null, 'no': 0, 'validationAnswer': null } );
3946
+ Multianswer.push( { 'answer': null, 'no': 0, 'validationAnswer': null, ...( question.answerType == 'image/video' && { answerType: null } ) } );
3730
3947
  question.Multianswer = Multianswer;
3731
3948
  }
3732
3949
  }
@@ -3813,8 +4030,9 @@ export async function uploadAnswerImage( req, res ) {
3813
4030
  if ( req.files && req.files.answerImage ) {
3814
4031
  let imageUrl;
3815
4032
  let filePath = `${folder}/${req.user.clientId}/${date}/${input.checklistId}/${input.sectionName.replace( ' ', '' )}/${input.questionNo}/`;
4033
+ const ext = path.extname( req.files.answerImage.name ).slice( 1 );
3816
4034
  let params = {
3817
- fileName: `${Date.now()}-${Math.floor( 1000 + Math.random() * 9000 )}.${req.files.answerImage.name.split( '.' )[1]}`,
4035
+ fileName: `${Date.now()}-${Math.floor( 1000 + Math.random() * 9000 )}.${ext}`,
3818
4036
  Key: filePath,
3819
4037
  Bucket: bucket.sop,
3820
4038
  body: req.files.answerImage.data,
@@ -4239,6 +4457,7 @@ export async function questionListV1( req, res ) {
4239
4457
  startTime: { $ifNull: [ '$startTime', '' ] },
4240
4458
  submitTime: { $ifNull: [ '$submitTime', '' ] },
4241
4459
  allowedOverTime: { $ifNull: [ '$allowedOverTime', '' ] },
4460
+ sourceCheckList_id: { $ifNull: [ '$sourceCheckList_id', '' ] },
4242
4461
  // allowedStoreLocation: { $ifNull: [ '$allowedStoreLocation', '' ] },
4243
4462
  allowedStoreLocation: {
4244
4463
  $cond: {
@@ -4294,7 +4513,7 @@ export async function questionListV1( req, res ) {
4294
4513
  }
4295
4514
 
4296
4515
  for ( let [ ansIndex, answer ] of question.answers.entries() ) {
4297
- if ( question.answerType == 'multiplechoicemultiple' ) {
4516
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
4298
4517
  let checkvalidation = null;
4299
4518
  if ( answer.validationAnswer && answer.validationAnswer !='' ) {
4300
4519
  if ( answer.validationType != 'Descriptive Answer' ) {
@@ -4346,13 +4565,13 @@ export async function questionListV1( req, res ) {
4346
4565
 
4347
4566
  getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].multiReferenceImage = userAns.multiReferenceImage;
4348
4567
  }
4349
- if ( question.answerType == 'multiplechoicemultiple' ) {
4568
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
4350
4569
  let ansIndex = Multianswer.findIndex( ( item ) => item.answer == userAns.answer );
4351
4570
  if ( ansIndex ) {
4352
4571
  Multianswer[ansIndex].validationAnswer = userAns.validationAnswer;
4353
4572
  }
4354
4573
  }
4355
- if ( question.answerType == 'multipleImage' ) {
4574
+ if ( question.answerType == 'multipleImage' || question.answerType == 'image/video' ) {
4356
4575
  if ( userAns && userAns.answer && userAns.answer !='' ) {
4357
4576
  let manswer = `${cdnurl.TraxAnswerCDN}${userAns.answer}`;
4358
4577
  Multianswer.push( { 'answer': manswer, 'no': userAnsIndex, 'validationAnswer': '' } );
@@ -4362,7 +4581,7 @@ export async function questionListV1( req, res ) {
4362
4581
  }
4363
4582
  }
4364
4583
  }
4365
- if ( question.answerType == 'multiplechoicemultiple' ) {
4584
+ if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
4366
4585
  Multianswer.forEach( ( item ) => {
4367
4586
  if ( item.validationAnswer == null ) {
4368
4587
  item.answer = null;
@@ -4374,7 +4593,7 @@ export async function questionListV1( req, res ) {
4374
4593
  question.Multianswer = Multianswer;
4375
4594
  }
4376
4595
  }
4377
- if ( question.answerType == 'multipleImage' ) {
4596
+ if ( question.answerType == 'multipleImage' || question.answerType == 'image/video' ) {
4378
4597
  if ( Multianswer.length ) {
4379
4598
  question.Multianswer = Multianswer;
4380
4599
  } else {
@@ -4423,6 +4642,11 @@ export async function questionListV1( req, res ) {
4423
4642
  }
4424
4643
  }
4425
4644
 
4645
+ let checklisDetails = await checklistService.findOne( { _id: getchecklist?.[0]?.sourceCheckList_id }, { export: 1 } );
4646
+ if ( checklisDetails ) {
4647
+ getchecklist[0]['export'] = checklisDetails.export;
4648
+ }
4649
+
4426
4650
  return res.sendSuccess( getchecklist );
4427
4651
  }
4428
4652
  } catch ( e ) {
@@ -4485,3 +4709,128 @@ export async function chunkUpload( req, res ) {
4485
4709
  return res.sendError( e, 500 );
4486
4710
  }
4487
4711
  }
4712
+
4713
+ export async function downloadChecklist( req, res ) {
4714
+ try {
4715
+ let requestData = req.body;
4716
+
4717
+ if ( !requestData.checklistId ) {
4718
+ return res.sendError( 'checklistId is Required', 400 );
4719
+ }
4720
+
4721
+ let checklistDetails;
4722
+
4723
+ if ( requestData.type == 'checklist' ) {
4724
+ checklistDetails = await processedchecklist.findOne( { _id: requestData.checklistId, checklistStatus: 'submit' } );
4725
+ } else {
4726
+ checklistDetails = await processedTask.findOne( { _id: requestData.checklistId, checklistStatus: 'submit' } );
4727
+ }
4728
+
4729
+ if ( !checklistDetails ) {
4730
+ return res.sendError( 'No data found', 204 );
4731
+ }
4732
+
4733
+ let storeDetails = await storeService.findOne( { storeId: checklistDetails.store_id }, { storeProfile: 1 } );
4734
+ if ( !storeDetails ) {
4735
+ return res.sendError( 'No data found', 204 );
4736
+ }
4737
+
4738
+ let clientDetails = await clientService.findOne( { clientId: checklistDetails.client_id } );
4739
+
4740
+ if ( !clientDetails ) {
4741
+ return res.sendError( 'No client found', 204 );
4742
+ }
4743
+
4744
+ checklistDetails = { ...checklistDetails.toObject(), ...storeDetails?.toObject()?.storeProfile };
4745
+
4746
+
4747
+ let scheduleDateTime = dayjs( checklistDetails.submitTime );
4748
+ checklistDetails.submitDate = scheduleDateTime.format( 'DD MMM, YYYY' );
4749
+ checklistDetails.submitTime = scheduleDateTime.format( 'hh:mm A' );
4750
+ if ( clientDetails?.profileDetails?.logo ) {
4751
+ let bucketpath = checklistDetails.client_id + '/logo';
4752
+
4753
+ let params = {
4754
+ Bucket: JSON.parse( process.env.BUCKET )?.assets,
4755
+ file_path: `${bucketpath}/${clientDetails?.profileDetails?.logo}`,
4756
+ };
4757
+ let brandImage = await signedUrl( params );
4758
+ if ( brandImage ) {
4759
+ checklistDetails['brandLogo'] = brandImage;
4760
+ }
4761
+ }
4762
+ checklistDetails['brandName'] = clientDetails?.clientName;
4763
+ checklistDetails.questionAnswers.forEach( ( section ) => {
4764
+ section.questions.forEach( ( question ) => {
4765
+ question.remarks = question.remarks == null || question.remarks == 'null' ? '' : question.remarks;
4766
+ question.userAnswer.forEach( ( answer ) => {
4767
+ if ( answer?.referenceImage?.trim() ) {
4768
+ answer.referenceImage = 'https://d1r0hc2sskgmri.cloudfront.net/'+answer.referenceImage;
4769
+ }
4770
+ if ( [ 'Capture Image', 'Capture Video' ].includes( answer.validationType ) && answer?.validationAnswer?.trim() ) {
4771
+ answer.validationAnswer = 'https://d1r0hc2sskgmri.cloudfront.net/'+answer.validationAnswer;
4772
+ }
4773
+ if ( answer?.answer?.trim() && [ 'image', 'descriptiveImage', 'multipleImage', 'image/video', 'video' ].includes( question.answerType ) ) {
4774
+ answer.answer = 'https://d1r0hc2sskgmri.cloudfront.net/'+answer.answer;
4775
+ }
4776
+ } );
4777
+ } );
4778
+ } );
4779
+
4780
+ checklistDetails['validateType']=[ 'yes/no', 'descriptive', 'multiplechoicesingle', 'multiplechoicemultiple', 'dropdown', 'date', 'linearscale', 'time' ];
4781
+
4782
+ const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/template.hbs', 'utf8' );
4783
+ const template = handlebars.compile( templateHtml );
4784
+ const html = template( { data: checklistDetails } );
4785
+
4786
+ // Generate PDF using puppeteer instead of deprecated html-pdf
4787
+ const browser = await puppeteer.launch( {
4788
+ headless: 'new',
4789
+ args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage' ],
4790
+ } );
4791
+
4792
+ const page = await browser.newPage();
4793
+
4794
+ await page.setContent( html, {
4795
+ waitUntil: 'domcontentloaded',
4796
+ } );
4797
+
4798
+ /* -------- WAIT FOR ALL IMAGES TO LOAD -------- */
4799
+
4800
+ await page.evaluate( async () => {
4801
+ const images = Array.from( document.images );
4802
+
4803
+ await Promise.all(
4804
+ images.map( ( img ) => {
4805
+ if ( img.complete ) return;
4806
+
4807
+ return new Promise( ( resolve ) => {
4808
+ img.onload = img.onerror = resolve;
4809
+ } );
4810
+ } ),
4811
+ );
4812
+ } );
4813
+
4814
+ /* ---------------- GENERATE PDF ---------------- */
4815
+
4816
+ const pdfBuffer = await page.pdf( {
4817
+ format: 'A4',
4818
+ printBackground: true,
4819
+ } );
4820
+
4821
+ await browser.close();
4822
+
4823
+ /* ---------------- RESPONSE ---------------- */
4824
+
4825
+ res.setHeader( 'Content-Type', 'application/pdf' );
4826
+ res.setHeader(
4827
+ 'Content-Disposition',
4828
+ 'attachment; filename=checkListDetails.pdf',
4829
+ );
4830
+
4831
+ return res.end( pdfBuffer );
4832
+ } catch ( e ) {
4833
+ logger.error( { functionName: 'getChecklistQuestionAnswers', error: e } );
4834
+ return res.sendError( e, 500 );
4835
+ }
4836
+ }