tango-app-api-trax 3.8.13 → 3.8.14-nike

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.
@@ -1,4 +1,4 @@
1
- import { logger, signedUrl, fileUpload, getOtp, sendEmailWithSES, getUuid, insertOpenSearchData, listFileByPath, getObject, deleteFiles } from 'tango-app-api-middleware';
1
+ import { logger, signedUrl, fileUpload, getOtp, sendEmailWithSES, getUuid, insertOpenSearchData, listFileByPath, getObject, deleteFiles, sendMessageToQueue } from 'tango-app-api-middleware';
2
2
  import * as processedchecklist from '../services/processedchecklist.services.js';
3
3
  import * as processedtask from '../services/processedTaskList.service.js';
4
4
  import * as PCLconfig from '../services/processedchecklistconfig.services.js';
@@ -26,6 +26,7 @@ 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
+ import * as recurringFlagTracker from '../services/recurringFlagTracker.service.js';
29
30
  dayjs.extend( isSameOrBefore );
30
31
  import puppeteer from 'puppeteer';
31
32
  import handlebars from './handlebar-helper.js';
@@ -233,15 +234,15 @@ export async function startChecklist( req, res ) {
233
234
  },
234
235
  } );
235
236
  let getupdatedchecklist = await processedchecklist.aggregate( findQuery );
236
- let bucket = JSON.parse( process.env.BUCKET );
237
+ // let bucket = JSON.parse( process.env.BUCKET );
237
238
  getupdatedchecklist[0].questionAnswers.forEach( ( section ) => {
238
239
  section.questions.forEach( async ( question ) => {
239
240
  if ( question.questionReferenceImage && question.questionReferenceImage!='' ) {
240
- question.questionReferenceImage = await signedUrl( { Bucket: bucket.sop, file_path: decodeURIComponent( question.questionReferenceImage ) } );
241
+ question.questionReferenceImage = `${cdnurl.TraxAnswerCDN}${question.questionReferenceImage}`;
241
242
  }
242
243
  question.answers.forEach( async ( answer ) => {
243
244
  if ( answer.referenceImage != '' ) {
244
- answer.referenceImage = await signedUrl( { Bucket: bucket.sop, file_path: decodeURIComponent( answer.referenceImage ) } );
245
+ answer.referenceImage = `${cdnurl.TraxAnswerCDN}${answer.referenceImage}`;
245
246
  }
246
247
  } );
247
248
  } );
@@ -466,19 +467,16 @@ export async function startTask( req, res ) {
466
467
  } );
467
468
  const getUpdatedTask = await processedTask.aggregate( findQuery );
468
469
 
469
-
470
+ let cdnurl = JSON.parse( process.env.CDNURL );
470
471
  if ( !( task.checkListFrom && task.checkListFrom == 'api' ) ) {
471
- const bucket = JSON.parse( process.env.BUCKET );
472
+ // const bucket = JSON.parse( process.env.BUCKET );
472
473
  await Promise.all(
473
474
  getUpdatedTask[0].questionAnswers.map( ( section ) =>
474
475
  section.questions.map( async ( question ) => {
475
476
  if ( question.questionReferenceImage.length > 0 ) {
476
477
  question.questionReferenceImage = await Promise.all(
477
478
  question.questionReferenceImage.map( async ( image ) => {
478
- return await signedUrl( {
479
- Bucket: bucket.sop,
480
- file_path: decodeURIComponent( image ),
481
- } );
479
+ return `${cdnurl.TraxAnswerCDN}${image}`;
482
480
  } ),
483
481
  );
484
482
  }
@@ -488,10 +486,7 @@ export async function startTask( req, res ) {
488
486
  if ( answer.referenceImage.length > 0 ) {
489
487
  answer.referenceImage = await Promise.all(
490
488
  answer.referenceImage.map( async ( image ) => {
491
- return await signedUrl( {
492
- Bucket: bucket.sop,
493
- file_path: decodeURIComponent( image ),
494
- } );
489
+ return `${cdnurl.TraxAnswerCDN}${image}`;
495
490
  } ),
496
491
  );
497
492
  }
@@ -1443,7 +1438,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
1443
1438
  let des = [];
1444
1439
  if ( requestSection[i].answer != 'null' && requestSection[i].answer != '' && requestSection[i].answer != null ) {
1445
1440
  let validationAnswer = '';
1446
- if ( requestSection[i].answer.split( '?' ).length > 1 ) {
1441
+ if ( requestSection[i].answer.split( '?' ).length > 1 || requestSection[i].answer.includes( 'https://' ) ) {
1447
1442
  validationAnswer = decodeURIComponent( requestSection[i].answer.split( '?' )[0] );
1448
1443
  }
1449
1444
  if ( validationAnswer.length ) {
@@ -1937,7 +1932,7 @@ export async function sopMobileTaskMultiSectionFormatter( req, res, next ) {
1937
1932
  let des = [];
1938
1933
  if ( requestSection[i].answer != 'null' && requestSection[i].answer != '' && requestSection[i].answer != null ) {
1939
1934
  let validationAnswer = '';
1940
- if ( requestSection[i].answer.split( '?' ).length > 1 ) {
1935
+ if ( requestSection[i].answer.split( '?' ).length > 1 || requestSection[i].answer.includes( 'https://' ) ) {
1941
1936
  validationAnswer = decodeURIComponent( requestSection[i].answer.split( '?' )[0] );
1942
1937
  }
1943
1938
  if ( validationAnswer.length ) {
@@ -2034,6 +2029,98 @@ function QuestionFlag( req, res ) {
2034
2029
  }
2035
2030
  }
2036
2031
 
2032
+ async function updateRecurringFlagTracker( processedChecklist, questionAnswers, currentDateTime ) {
2033
+ try {
2034
+ if ( !processedChecklist?.sourceCheckList_id ) return;
2035
+
2036
+ const isUserBased = processedChecklist?.coverage === 'user';
2037
+ const storeId = isUserBased ? '' : ( processedChecklist?.store_id || '' );
2038
+ const userId = isUserBased ? ( processedChecklist?.userId ? String( processedChecklist.userId ) : ( processedChecklist?.userEmail || '' ) ) : '';
2039
+ if ( !isUserBased && !storeId ) return;
2040
+ if ( isUserBased && !userId ) return;
2041
+
2042
+ const today = currentDateTime ? currentDateTime.format( 'YYYY-MM-DD' ) : dayjs().format( 'YYYY-MM-DD' );
2043
+ const yesterday = dayjs( today, 'YYYY-MM-DD' ).subtract( 1, 'day' ).format( 'YYYY-MM-DD' );
2044
+
2045
+ const trackerKeyBase = {
2046
+ client_id: processedChecklist.client_id,
2047
+ sourceCheckList_id: processedChecklist.sourceCheckList_id,
2048
+ ...( isUserBased ) ? { user_id: userId } : { store_id: storeId },
2049
+ };
2050
+
2051
+ const existingRows = await recurringFlagTracker.find( trackerKeyBase, { section_id: 1, qno: 1, consecutiveCount: 1, lastFlaggedDate: 1 } );
2052
+ const existingMap = new Map();
2053
+ for ( const r of existingRows ) {
2054
+ existingMap.set( `${r.section_id || ''}::${r.qno || ''}`, r );
2055
+ }
2056
+
2057
+ const ops = [];
2058
+
2059
+ ( questionAnswers || [] ).forEach( ( section ) => {
2060
+ ( section?.questions || [] ).forEach( ( question ) => {
2061
+ const sectionId = section?.section_id || '';
2062
+ const qno = question?.qno || '';
2063
+ if ( qno === '' ) return;
2064
+
2065
+ const flaggedNow = Array.isArray( question?.userAnswer ) && question.userAnswer.some( ( a ) => a?.sopFlag === true );
2066
+ const key = `${sectionId}::${qno}`;
2067
+ const existing = existingMap.get( key );
2068
+ console.log( flaggedNow, 'test' );
2069
+ if ( flaggedNow ) {
2070
+ let newCount;
2071
+ if ( !existing ) {
2072
+ newCount = 1;
2073
+ } else if ( existing.lastFlaggedDate === today ) {
2074
+ // Multi-submit on same day: already counted, no-op.
2075
+ return;
2076
+ } else if ( existing.lastFlaggedDate === yesterday ) {
2077
+ newCount = ( existing.consecutiveCount || 0 ) + 1;
2078
+ } else {
2079
+ // Gap broke the streak — fresh start.
2080
+ newCount = 1;
2081
+ }
2082
+
2083
+ ops.push( {
2084
+ updateOne: {
2085
+ filter: { ...trackerKeyBase, section_id: sectionId, qno },
2086
+ update: {
2087
+ $set: {
2088
+ coverage: isUserBased ? 'user' : 'store',
2089
+ checkListName: processedChecklist.checkListName,
2090
+ storeName: isUserBased ? '' : ( processedChecklist.storeName || '' ),
2091
+ userName: processedChecklist.userName || '',
2092
+ userEmail: processedChecklist.userEmail || '',
2093
+ sectionName: section?.sectionName || '',
2094
+ qname: question?.qname || '',
2095
+ consecutiveCount: newCount,
2096
+ lastFlaggedDate: today,
2097
+ lastSubmittedBy: processedChecklist.userName || processedChecklist.userEmail || '--',
2098
+ lastSubmissionDate: currentDateTime ? currentDateTime.format( 'hh:mm A, DD MMM YYYY' ) : today,
2099
+ },
2100
+ },
2101
+ upsert: true,
2102
+ },
2103
+ } );
2104
+ } else if ( existing && ( existing.consecutiveCount || 0 ) > 0 ) {
2105
+ // Question answered correctly today — break the streak.
2106
+ ops.push( {
2107
+ updateOne: {
2108
+ filter: { ...trackerKeyBase, section_id: sectionId, qno },
2109
+ update: { $set: { lastFlaggedDate: today } },
2110
+ },
2111
+ } );
2112
+ }
2113
+ } );
2114
+ } );
2115
+ if ( ops.length ) {
2116
+ let data = await recurringFlagTracker.bulkWrite( ops );
2117
+ console.log( data );
2118
+ }
2119
+ } catch ( error ) {
2120
+ logger.error( { function: 'updateRecurringFlagTracker', error } );
2121
+ }
2122
+ }
2123
+
2037
2124
  export async function submitChecklist( req, res ) {
2038
2125
  try {
2039
2126
  let requestData = req.body;
@@ -2169,6 +2256,10 @@ export async function submitChecklist( req, res ) {
2169
2256
  // };
2170
2257
  // await detectionService.create( detectionData );
2171
2258
  if ( requestData.submittype == 'submit' ) {
2259
+ console.log( checklistDetails?.recurringFlag?.notifyType?.length );
2260
+ if ( checklistDetails?.recurringFlag?.notifyType?.length ) {
2261
+ updateRecurringFlagTracker( getchecklist[0], requestData.questionAnswers, currentDateTime );
2262
+ }
2172
2263
  updateOpenSearch( req.user, requestData );
2173
2264
  let openSearch = JSON.parse( process.env.OPENSEARCH );
2174
2265
  // console.log( 'openSearch', openSearch );
@@ -2340,8 +2431,16 @@ export async function submitTask( req, res ) {
2340
2431
  insertOpenSearchData( openSearch.traxActivityLog, inserttraxlogs );
2341
2432
  if ( submittype === 'submit' ) {
2342
2433
  const excludedChecklists = [ 'Store Hygiene Check' ];
2343
- if ( checklist.checkListName.includes( 'Store Hygiene' ) ) {
2344
-
2434
+ if ( checklist.checkListName.includes( 'Store Hygiene' ) && checklist?.streamId ) {
2435
+ let sqsData = {
2436
+ 'storeId': checklist.store_id,
2437
+ 'streamID': checklist.streamId,
2438
+ 'detectionTime': checklist?.questionAnswers?.[0]?.questions?.[0]?.answers?.[0]?.detectionTime,
2439
+ 'date': checklist.date_string,
2440
+ 'storeResponseTime': currentDateTime.format( 'HH:mm:ss - MMM DD, YYYY' ),
2441
+ 'message_mode': 'retriggered',
2442
+ };
2443
+ sendMessageToQueue( `${JSON.parse( process.env.SQS ).url}${JSON.parse( process.env.SQS ).storeHygiene}`, JSON.stringify( sqsData ) );
2345
2444
  }
2346
2445
  if ( !excludedChecklists.includes( checklist.checkListName ) ) {
2347
2446
  const query1 = [
@@ -3486,7 +3585,7 @@ export async function questionList( req, res ) {
3486
3585
  return res.sendError( 'Check List Got Edited Please Fill Again', 422 );
3487
3586
  } else {
3488
3587
  logger.info( `v5 => Checklist Continue => store Name: ${getchecklist[0].storeName}, User Email: ${getchecklist[0].userEmail}, Checklist Name: ${getchecklist[0].checkListName}` );
3489
- let bucket = JSON.parse( process.env.BUCKET );
3588
+ // let bucket = JSON.parse( process.env.BUCKET );
3490
3589
  let cdnurl = JSON.parse( process.env.CDNURL );
3491
3590
  for ( let [ secIndex, section ] of getchecklist[0].questionAnswers.entries() ) {
3492
3591
  for ( let [ questionIndex, question ] of section.questions.entries() ) {
@@ -3512,7 +3611,7 @@ export async function questionList( req, res ) {
3512
3611
  let checkvalidation = null;
3513
3612
  if ( answer.validationAnswer && answer.validationAnswer !='' ) {
3514
3613
  if ( answer.validationType != 'Descriptive Answer' ) {
3515
- checkvalidation = await signedUrl( { file_path: decodeURIComponent( answer.validationAnswer ), Bucket: bucket.sop } );
3614
+ checkvalidation = `${cdnurl.TraxAnswerCDN}${answer.validationAnswer}`;
3516
3615
  } else {
3517
3616
  checkvalidation = answer.validationAnswer;
3518
3617
  }
@@ -3533,23 +3632,23 @@ export async function questionList( req, res ) {
3533
3632
  answer.referenceImage= `${cdnurl.TraxAnswerCDN}${answer.referenceImage}`;
3534
3633
  }
3535
3634
  if ( ( answer.validationType == 'Capture Image' || answer.validationType == 'Capture Video' ) && answer.validationAnswer && answer.validationAnswer != '' ) {
3536
- getchecklist[0].questionAnswers[secIndex].questions[questionIndex].answers[ansIndex].validationAnswer = await signedUrl( { file_path: decodeURIComponent( answer.validationAnswer ), Bucket: bucket.sop } );
3635
+ getchecklist[0].questionAnswers[secIndex].questions[questionIndex].answers[ansIndex].validationAnswer = `${cdnurl.TraxAnswerCDN}${answer.validationAnswer}`;
3537
3636
  }
3538
3637
  }
3539
3638
  if ( question?.userAnswer ) {
3540
3639
  for ( let [ userAnsIndex, userAns ] of question.userAnswer.entries() ) {
3541
3640
  if ( ( userAns.validationType == 'Capture Image' || userAns.validationType == 'Capture Video' ) && userAns.validationAnswer && userAns.validationAnswer != '' ) {
3542
- getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].validationAnswer = await signedUrl( { file_path: decodeURIComponent( userAns.validationAnswer ), Bucket: bucket.sop } );
3641
+ getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].validationAnswer = `${cdnurl.TraxAnswerCDN}${userAns.validationAnswer}`;
3543
3642
  }
3544
3643
  if ( userAns.validationType == 'Capture Multiple Image with description' ) {
3545
3644
  let imageAnswers = userAns.validationImage;
3546
3645
  userAns.validationImage = [];
3547
3646
  for ( let image of imageAnswers ) {
3548
- getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].validationImage.push( await signedUrl( { file_path: decodeURIComponent( image ), Bucket: bucket.sop } ) );
3647
+ getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].validationImage.push( `${cdnurl.TraxAnswerCDN}${image}` );
3549
3648
  }
3550
3649
  }
3551
3650
  if ( [ 'image', 'descriptiveImage', 'video' ].includes( question.answerType ) && userAns.answer != '' ) {
3552
- getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].answer = await signedUrl( { file_path: decodeURIComponent( userAns.answer ), Bucket: bucket.sop } );
3651
+ getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].answer =`${cdnurl.TraxAnswerCDN}${userAns.answer}`;
3553
3652
  }
3554
3653
  if ( userAns.referenceImage != '' ) {
3555
3654
  // getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].referenceImage = await signedUrl( { file_path: decodeURIComponent( userAns.referenceImage ), Bucket: bucket.sop } );
@@ -3856,7 +3955,7 @@ export async function taskQuestionList( req, res ) {
3856
3955
  return res.sendError( 'Task Got Edited Please Fill Again', 422 );
3857
3956
  } else {
3858
3957
  logger.info( `v5 => Task Continue => store Name: ${getchecklist[0].storeName}, User Email: ${getchecklist[0].userEmail}, Task Name: ${getchecklist[0].checkListName}` );
3859
- let bucket = JSON.parse( process.env.BUCKET );
3958
+ // let bucket = JSON.parse( process.env.BUCKET );
3860
3959
  let cdnurl = JSON.parse( process.env.CDNURL );
3861
3960
  for ( let [ secIndex, section ] of getchecklist[0].questionAnswers.entries() ) {
3862
3961
  for ( let [ questionIndex, question ] of section.questions.entries() ) {
@@ -3867,13 +3966,10 @@ export async function taskQuestionList( req, res ) {
3867
3966
  if ( Array.isArray( questionReferenceImage ) ) {
3868
3967
  questionReferenceImage = questionReferenceImage.filter( ( item ) => item != '' );
3869
3968
  getchecklist[0].questionAnswers[secIndex].questions[questionIndex].questionReferenceImage = await Promise.all(
3870
- questionReferenceImage.map( async ( image ) => image ? await signedUrl( { file_path: decodeURIComponent( image ), Bucket: bucket.sop } ) : '' ),
3969
+ questionReferenceImage.map( async ( image ) => image ? `${cdnurl.TraxAnswerCDN}${image}` : '' ),
3871
3970
  );
3872
3971
  } else if ( questionReferenceImage !== '' ) {
3873
- getchecklist[0].questionAnswers[secIndex].questions[questionIndex].questionReferenceImage = await signedUrl( {
3874
- file_path: decodeURIComponent( questionReferenceImage ),
3875
- Bucket: bucket.sop,
3876
- } );
3972
+ getchecklist[0].questionAnswers[secIndex].questions[questionIndex].questionReferenceImage = `${cdnurl.TraxAnswerCDN}${questionReferenceImage}`;
3877
3973
  }
3878
3974
  }
3879
3975
 
@@ -3884,13 +3980,10 @@ export async function taskQuestionList( req, res ) {
3884
3980
  if ( Array.isArray( referenceImage ) ) {
3885
3981
  referenceImage = referenceImage.filter( ( item ) => item != '' );
3886
3982
  getchecklist[0].questionAnswers[secIndex].questions[questionIndex].answers[ansIndex].referenceImage = await Promise.all(
3887
- referenceImage.map( async ( image ) => image ? await signedUrl( { file_path: decodeURIComponent( image ), Bucket: bucket.sop } ) : '' ),
3983
+ referenceImage.map( async ( image ) => image ? `${cdnurl.TraxAnswerCDN}${image}` : '' ),
3888
3984
  );
3889
3985
  } else if ( referenceImage !== '' ) {
3890
- getchecklist[0].questionAnswers[secIndex].questions[questionIndex].answers[ansIndex].referenceImage = await signedUrl( {
3891
- file_path: decodeURIComponent( referenceImage ),
3892
- Bucket: bucket.sop,
3893
- } );
3986
+ getchecklist[0].questionAnswers[secIndex].questions[questionIndex].answers[ansIndex].referenceImage = `${cdnurl.TraxAnswerCDN}${referenceImage}`;
3894
3987
  }
3895
3988
  }
3896
3989
 
@@ -3898,7 +3991,7 @@ export async function taskQuestionList( req, res ) {
3898
3991
  let checkvalidation = null;
3899
3992
  if ( answer.validationAnswer && answer.validationAnswer != '' ) {
3900
3993
  if ( answer.validationType != 'Descriptive Answer' ) {
3901
- checkvalidation = await signedUrl( { file_path: decodeURIComponent( answer.validationAnswer ), Bucket: bucket.sop } );
3994
+ checkvalidation = `${cdnurl.TraxAnswerCDN}${answer.validationAnswer}`;
3902
3995
  } else {
3903
3996
  checkvalidation = answer.validationAnswer;
3904
3997
  }
@@ -3907,10 +4000,7 @@ export async function taskQuestionList( req, res ) {
3907
4000
  getchecklist[0].questionAnswers[secIndex].questions[questionIndex].answers[ansIndex].index = ansIndex;
3908
4001
  }
3909
4002
  if ( ( answer.validationType == 'Capture Image' || answer.validationType == 'Capture Video' ) && answer.validationAnswer && answer.validationAnswer != '' ) {
3910
- getchecklist[0].questionAnswers[secIndex].questions[questionIndex].answers[ansIndex].validationAnswer = await signedUrl( {
3911
- file_path: decodeURIComponent( answer.validationAnswer ),
3912
- Bucket: bucket.sop,
3913
- } );
4003
+ getchecklist[0].questionAnswers[secIndex].questions[questionIndex].answers[ansIndex].validationAnswer = `${cdnurl.TraxAnswerCDN}${answer.validationAnswer}`;
3914
4004
  }
3915
4005
  }
3916
4006
 
@@ -3921,25 +4011,16 @@ export async function taskQuestionList( req, res ) {
3921
4011
  getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].linearType = question.answers[0].linearType;
3922
4012
  }
3923
4013
  if ( ( userAns.validationType == 'Capture Image' || userAns.validationType == 'Capture Video' ) && userAns.validationAnswer && userAns.validationAnswer != '' ) {
3924
- getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].validationAnswer = await signedUrl( {
3925
- file_path: decodeURIComponent( userAns.validationAnswer ),
3926
- Bucket: bucket.sop,
3927
- } );
4014
+ getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].validationAnswer = `${cdnurl.TraxAnswerCDN}${userAns.validationAnswer}`;
3928
4015
  }
3929
4016
  if ( [ 'image', 'descriptiveImage', 'video' ].includes( question.answerType ) && rawAnswer != '' ) {
3930
- getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].answer = await signedUrl( {
3931
- file_path: decodeURIComponent( rawAnswer ),
3932
- Bucket: bucket.sop,
3933
- } );
4017
+ getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].answer = `${cdnurl.TraxAnswerCDN}${rawAnswer}`;
3934
4018
  }
3935
4019
  if ( question.answerType == 'image/video' && rawAnswer != '' ) {
3936
4020
  getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].answer = `${cdnurl.TraxAnswerCDN}${rawAnswer}`;
3937
4021
  }
3938
4022
  if ( userAns.referenceImage != '' ) {
3939
- getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].referenceImage = await signedUrl( {
3940
- file_path: decodeURIComponent( userAns.referenceImage ),
3941
- Bucket: bucket.sop,
3942
- } );
4023
+ getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].referenceImage = `${cdnurl.TraxAnswerCDN}${userAns.referenceImage}`;
3943
4024
  }
3944
4025
  if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
3945
4026
  let ansIndex = Multianswer.findIndex( ( item ) => item.answer == rawAnswer );
@@ -4786,18 +4867,28 @@ export async function downloadChecklist( req, res ) {
4786
4867
  }
4787
4868
  checklistDetails['brandName'] = clientDetails?.clientName;
4788
4869
  // checklistDetails['submitTime_string'] = dayjs( checklistDetails.submitTime_string, 'hh mm A, DD MMM YYYY' ).format( 'DD MMMM YYYY | hh:mm A' );
4870
+ const cdnPrefix = JSON.parse( process.env.CDNURL )?.TraxAnswerCDN;
4789
4871
  checklistDetails.questionAnswers.forEach( ( section ) => {
4790
4872
  section.questions.forEach( ( question ) => {
4791
4873
  question.remarks = question.remarks == null || question.remarks == 'null' ? '' : question.remarks;
4874
+ if ( question?.questionReferenceImage?.trim?.() ) {
4875
+ question.questionReferenceImage = cdnPrefix+question.questionReferenceImage;
4876
+ }
4877
+ if ( question?.multiQuestionReferenceImage?.length ) {
4878
+ question.multiQuestionReferenceImage = question.multiQuestionReferenceImage.map( ( ele ) => cdnPrefix+( ele?.imageURL || ele ) );
4879
+ }
4792
4880
  question.userAnswer.forEach( ( answer ) => {
4793
- if ( answer?.referenceImage?.trim() ) {
4794
- answer.referenceImage = JSON.parse( process.env.CDNURL )?.TraxAnswerCDN+answer.referenceImage;
4881
+ if ( answer?.referenceImage?.trim?.() ) {
4882
+ answer.referenceImage = cdnPrefix+answer.referenceImage;
4883
+ }
4884
+ if ( answer?.multiReferenceImage?.length ) {
4885
+ answer.multiReferenceImage = answer.multiReferenceImage.map( ( ele ) => cdnPrefix+( ele?.imageURL || ele ) );
4795
4886
  }
4796
4887
  if ( [ 'Capture Image', 'Capture Video' ].includes( answer.validationType ) && answer?.validationAnswer?.trim() ) {
4797
4888
  answer.validationAnswer = JSON.parse( process.env.CDNURL )?.TraxAnswerCDN+answer.validationAnswer;
4798
4889
  }
4799
4890
  if ( [ 'Capture Multiple Image with description' ].includes( answer.validationType ) && answer?.validationImage?.length ) {
4800
- answer.validationImage = answer?.validationImage?.map( ( ele ) => JSON.parse( process.env.CDNURL )?.TraxAnswerCDN+answer.ele );
4891
+ answer.validationImage = answer?.validationImage?.map( ( ele ) => JSON.parse( process.env.CDNURL )?.TraxAnswerCDN+ele );
4801
4892
  }
4802
4893
  if ( answer?.answer?.trim() && [ 'image', 'descriptiveImage', 'multipleImage', 'image/video', 'video' ].includes( question.answerType ) ) {
4803
4894
  answer.answer = JSON.parse( process.env.CDNURL )?.TraxAnswerCDN+answer.answer;
@@ -608,7 +608,7 @@ export const flagCardsV1 = async ( req, res ) => {
608
608
  {
609
609
  client_id: clientId,
610
610
  publish: true,
611
- checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert' ] },
611
+ checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'storehygienemonitoring' ] },
612
612
  },
613
613
  { checkListType: 1 },
614
614
  );
@@ -2743,7 +2743,7 @@ export const checklistDropdownV1 = async ( req, res ) => {
2743
2743
  $or: [
2744
2744
  { questionFlag: { $gte: 1 } },
2745
2745
  { timeFlag: { $gte: 1 } },
2746
- { checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert' ] } },
2746
+ { checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'storehygienemonitoring' ] } },
2747
2747
  {
2748
2748
  runAIQuestionCount: { $gte: 1 },
2749
2749
  },
@@ -2945,7 +2945,7 @@ export const flagComparisonCardsV2 = async ( req, res ) => {
2945
2945
  {
2946
2946
  client_id: requestData.clientId,
2947
2947
  publish: true,
2948
- checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert' ] },
2948
+ checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'storehygienemonitoring' ] },
2949
2949
  },
2950
2950
  { checkListType: 1 },
2951
2951
  );
@@ -3047,7 +3047,7 @@ export const flagTablesV2 = async ( req, res ) => {
3047
3047
  }
3048
3048
 
3049
3049
  if ( requestData?.filter === 'all' ) {
3050
- findAndQuery.push( { $or: [ { checkListType: { $in: [ 'custom', 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert' ] } } ] } );
3050
+ findAndQuery.push( { $or: [ { checkListType: { $in: [ 'custom', 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'storehygienemonitoring' ] } } ] } );
3051
3051
  } else if ( requestData?.filter === 'question' ) {
3052
3052
  findAndQuery.push( { checkListType: 'custom' } );
3053
3053
  findAndQuery.push( { questionFlag: { $gte: 1 } } );
@@ -3055,7 +3055,7 @@ export const flagTablesV2 = async ( req, res ) => {
3055
3055
  findAndQuery.push( { checkListType: 'custom' } );
3056
3056
  findAndQuery.push( { timeFlag: { $gte: 1 } } );
3057
3057
  } else if ( requestData?.filter === 'detection' ) {
3058
- findAndQuery.push( { checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert' ] } } );
3058
+ findAndQuery.push( { checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'storehygienemonitoring' ] } } );
3059
3059
  } else if ( requestData?.filter === 'runAI' ) {
3060
3060
  if ( req.body.runAIChecklistName ) {
3061
3061
  findAndQuery.push( { checkListName: { $in: req.body.runAIChecklistName } } );
@@ -4127,7 +4127,7 @@ async function updateOpenSearch( user, data ) {
4127
4127
  export const aiChecklist = async ( req, res ) => {
4128
4128
  try {
4129
4129
  let storeDetails = await storeService.count( { clientId: req.query.clientId, status: 'active' } );
4130
- let aiList = [ 'mobileusagedetection', 'storeopenandclose', 'uniformdetection', 'staffleftinthemiddle', 'customerunattended', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'cleaning', 'scrum', 'suspiciousactivity', 'boxalert', 'suspiciousfootfall', 'drinking', 'bagdetection', 'inventorycount', 'carsattended', 'numberplateinfo', 'vehicle_check_in', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert' ];
4130
+ let aiList = [ 'mobileusagedetection', 'storeopenandclose', 'uniformdetection', 'staffleftinthemiddle', 'customerunattended', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'cleaning', 'scrum', 'suspiciousactivity', 'suspiciousfootfall', 'drinking', 'bagdetection', 'inventorycount', 'carsattended', 'numberplateinfo', 'vehicle_check_in', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount' ];
4131
4131
  let checklistDetails = [];
4132
4132
  let publishList = [];
4133
4133
  let unpublishList = [];
@@ -4140,7 +4140,7 @@ export const aiChecklist = async ( req, res ) => {
4140
4140
  checklistDetails = [ ...publishList, ...unpublishList ];
4141
4141
 
4142
4142
  checklistDetails.forEach( ( item ) => {
4143
- if ( ![ 'mobileusagedetection', 'storeopenandclose', 'cleaning', 'scrum', 'uniformdetection', 'staffleftinthemiddle', 'customerunattended', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert' ].includes( item.checkListType ) ) {
4143
+ if ( ![ 'mobileusagedetection', 'storeopenandclose', 'cleaning', 'scrum', 'uniformdetection', 'staffleftinthemiddle', 'customerunattended', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount' ].includes( item.checkListType ) ) {
4144
4144
  item.storeCount = storeDetails;
4145
4145
  }
4146
4146
  } );