tango-app-api-trax 1.0.0-alpha.98 → 1.0.0-task.118

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,8 +1,11 @@
1
1
  import { logger, signedUrl, fileUpload, getOtp, sendEmailWithSES, getUuid } from 'tango-app-api-middleware';
2
2
  import * as processedchecklist from '../services/processedchecklist.services.js';
3
+ import * as processedtask from '../services/processedTaskList.service.js';
3
4
  import * as PCLconfig from '../services/processedchecklistconfig.services.js';
5
+ import * as processedTaskConfigService from '../services/processedTaskConfig.service.js';
4
6
  import * as storeService from '../services/store.service.js';
5
7
  import * as checklistService from '../services/checklist.service.js';
8
+ import * as processedTask from '../services/processedTaskList.service.js';
6
9
  import * as checklistLogs from '../services/checklistlog.service.js';
7
10
  import { insertSingleProcessData } from './trax.controller.js';
8
11
  import * as userService from '../services/user.service.js';
@@ -50,6 +53,40 @@ export async function storeList( req, res ) {
50
53
  }
51
54
  }
52
55
 
56
+ export async function storeListv1( req, res ) {
57
+ try {
58
+ if ( !req.query?.date ) {
59
+ return res.sendError( 'date is required', 400 );
60
+ }
61
+ let userChecklist = await processedchecklist.find( { userId: req.user._id, userEmail: req.user.email, date_string: dayjs( req.query.date ).format( 'YYYY-MM-DD' ) }, { store_id: 1, storeName: 1 } );
62
+
63
+ let userTask = await processedTask.find( { userId: req.user._id, userEmail: req.user.email, date_string: dayjs( req.query.date ).format( 'YYYY-MM-DD' ) }, { store_id: 1, storeName: 1 } );
64
+
65
+ if ( !userChecklist.length && !userTask.length ) {
66
+ return res.sendSuccess( [] );
67
+ }
68
+
69
+ let allStores = [ ...userChecklist, ...userTask ];
70
+
71
+ allStores = Array.from(
72
+ new Map( allStores.map( ( item ) => [ item.store_id, item ] ) ).values(),
73
+ );
74
+
75
+ let storeIdList = allStores.map( ( item ) => item.store_id );
76
+ let storeStatus = await storeService.find( { storeId: { $in: storeIdList }, status: 'active' }, { storeId: 1, storeName: 1 } );
77
+ if ( storeStatus.length ) {
78
+ storeStatus = storeStatus.map( ( item ) => {
79
+ return { store_id: item.storeId, storeName: item.storeName };
80
+ } );
81
+ }
82
+
83
+ return res.sendSuccess( storeStatus );
84
+ } catch ( e ) {
85
+ logger.error( { function: 'storeListv1', error: e } );
86
+ return res.sendError( e, 500 );
87
+ }
88
+ }
89
+
53
90
  export async function startChecklist( req, res ) {
54
91
  try {
55
92
  let requestData = req.body;
@@ -207,6 +244,149 @@ export async function startChecklist( req, res ) {
207
244
  return res.sendError( e, 500 );
208
245
  }
209
246
  }
247
+
248
+ export async function startTask( req, res ) {
249
+ try {
250
+ const { body: requestData, user } = req;
251
+
252
+ const findQuery = [
253
+ {
254
+ $match: {
255
+ $and: [
256
+ { _id: new ObjectId( requestData.processedcheckListId ) },
257
+ { userId: user._id },
258
+ { date_string: requestData.date },
259
+ ],
260
+ },
261
+ },
262
+ ];
263
+
264
+ const getBeforeTask = await processedTask.aggregate( findQuery );
265
+ if ( !getBeforeTask.length ) {
266
+ return res.sendError( 'Task edited. Please fill again.', 422 );
267
+ }
268
+
269
+ const task = getBeforeTask[0];
270
+ if ( task.checklistStatus !== 'open' ) {
271
+ return res.sendError( 'Task already started', 400 );
272
+ }
273
+
274
+ logger.info(
275
+ `v5 => Checklist Started => store Name: ${task.storeName}, User Email: ${task.userEmail}, Checklist Name: ${task.checkListName}`,
276
+ );
277
+
278
+ const processedTaskConfig = await processedTaskConfigService.findOne( { _id: new ObjectId( task.checkListId ) } );
279
+
280
+ if ( processedTaskConfig?.questionAnswers?.length > 0 ) {
281
+ for ( const section of processedTaskConfig.questionAnswers ) {
282
+ for ( const question of section.questions ) {
283
+ if ( [ 'multiplechoicemultiple', 'multipleImage' ].includes( question.answerType ) ) {
284
+ question.Multianswer = question.answers.map( ( _, index ) => ( {
285
+ answer: null,
286
+ no: index,
287
+ validationAnswer: null,
288
+ } ) );
289
+ } else {
290
+ question.Multianswer = [];
291
+ }
292
+ }
293
+ }
294
+ }
295
+
296
+ const storeTimeZone = await storeService.findOne(
297
+ { storeName: task.storeName },
298
+ { 'storeProfile.timeZone': 1 },
299
+ );
300
+ const currentDateTime = storeTimeZone?.storeProfile?.timeZone ?
301
+ dayjs().tz( storeTimeZone.storeProfile.timeZone ) :
302
+ dayjs();
303
+
304
+ const updateData = {
305
+ checklistStatus: 'inprogress',
306
+ startMobileTime: requestData?.currentTime,
307
+ questionAnswers: processedTaskConfig.questionAnswers || [],
308
+ startTime_string: currentDateTime.format( 'hh:mm A, DD MMM YYYY' ),
309
+ startTime: dayjs
310
+ .utc( currentDateTime.format( 'hh:mm A, DD MMM YYYY' ), 'hh:mm A, DD MMM YYYY' )
311
+ .format(),
312
+ };
313
+
314
+ const updateQuery = {
315
+ _id: new ObjectId( requestData.processedcheckListId ),
316
+ userId: user._id,
317
+ date_string: requestData.date,
318
+ };
319
+
320
+ const updateTaskResult = await processedTask.updateOne( updateQuery, updateData );
321
+
322
+ if ( !updateTaskResult ) {
323
+ return res.sendError( 'Something went wrong, please try again', 500 );
324
+ }
325
+
326
+ processedTaskConfig.startTime = updateData.startTime;
327
+ await processedTaskConfig.save();
328
+
329
+ findQuery.push( {
330
+ $project: {
331
+ checkListName: { $ifNull: [ '$checkListName', '' ] },
332
+ scheduleStartTime: { $ifNull: [ '$scheduleStartTime', '' ] },
333
+ scheduleStartTime_iso: { $ifNull: [ '$scheduleStartTime_iso', '' ] },
334
+ scheduleEndTime: { $ifNull: [ '$scheduleEndTime', '' ] },
335
+ scheduleEndTime_iso: { $ifNull: [ '$scheduleEndTime_iso', '' ] },
336
+ checklistStatus: { $ifNull: [ '$checklistStatus', '' ] },
337
+ checkListId: { $ifNull: [ '$checkListId', '' ] },
338
+ startTime: { $ifNull: [ '$startTime', '' ] },
339
+ submitTime: { $ifNull: [ '$submitTime', '' ] },
340
+ allowedOverTime: { $ifNull: [ '$allowedOverTime', '' ] },
341
+ allowedStoreLocation: { $ifNull: [ '$allowedStoreLocation', false ] },
342
+ questionAnswers: { $ifNull: [ '$questionAnswers', '' ] },
343
+ },
344
+ } );
345
+ const getUpdatedTask = await processedTask.aggregate( findQuery );
346
+
347
+
348
+ const bucket = JSON.parse( process.env.BUCKET );
349
+ await Promise.all(
350
+ getUpdatedTask[0].questionAnswers.map( ( section ) =>
351
+ section.questions.map( async ( question ) => {
352
+ if ( question.questionReferenceImage ) {
353
+ question.questionReferenceImage = await signedUrl( {
354
+ Bucket: bucket.sop,
355
+ file_path: decodeURIComponent( question.questionReferenceImage ),
356
+ } );
357
+ }
358
+ await Promise.all(
359
+ question.answers.map( async ( answer ) => {
360
+ if ( answer.referenceImage ) {
361
+ answer.referenceImage = await signedUrl( {
362
+ Bucket: bucket.sop,
363
+ file_path: decodeURIComponent( answer.referenceImage ),
364
+ } );
365
+ }
366
+ } ),
367
+ );
368
+ } ),
369
+ ).flat(),
370
+ );
371
+
372
+
373
+ const logData = {
374
+ store_id: task.store_id,
375
+ storeName: task.storeName,
376
+ action: 'started',
377
+ checklistId: task.checkListId,
378
+ checkListName: task.checkListName,
379
+ client_id: user.clientId,
380
+ };
381
+ await checklistLogs.create( logData );
382
+
383
+ return res.sendSuccess( getUpdatedTask );
384
+ } catch ( error ) {
385
+ logger.error( { function: 'startTask', error } );
386
+ return res.sendError( error, 500 );
387
+ }
388
+ }
389
+
210
390
  export async function sopMobilechecklistValidater( req, res, next ) {
211
391
  try {
212
392
  let requestData = req.body;
@@ -284,6 +464,47 @@ export async function sopMobilechecklistQuestionValidator( req, res, next ) {
284
464
  }
285
465
  };
286
466
 
467
+ export async function sopMobileTaskQuestionValidator( req, res, next ) {
468
+ try {
469
+ let requestData = req.body;
470
+ requestData.questionAnswers = typeof requestData.questionAnswers == 'string' ? JSON.parse( requestData.questionAnswers ) : requestData.questionAnswers;
471
+ let getChecklistQA = await processedtask.findOne( { _id: new ObjectId( requestData.processedcheckListId ) }, { questionAnswers: 1 } );
472
+ if ( !getChecklistQA ) {
473
+ return res.sendError( 'Check List Got Edited Please Fill Again', 422 );
474
+ }
475
+ if ( requestData.submittype == 'submit' ) {
476
+ let reqAnswers = requestData.questionAnswers;
477
+ let CLQAnswers = getChecklistQA.questionAnswers;
478
+ let validationCount= 0;
479
+ CLQAnswers.forEach( ( section ) => {
480
+ let requestSection = reqAnswers.filter( ( reqSection ) => reqSection.section_id == section.section_id );
481
+ section.questions.forEach( ( question ) => {
482
+ question.answers.forEach( ( answer ) => {
483
+ let sectionQuestion = requestSection.filter( ( secQuestion ) => secQuestion.qno == question.qno );
484
+ if ( question.answerType == 'multiplechoicemultiple' && ( sectionQuestion[0].Multianswer == null || sectionQuestion[0].Multianswer == '' || !sectionQuestion[0].Multianswer.length ) ) {
485
+ validationCount++;
486
+ } else {
487
+ 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 == '' ) ) ) ) {
488
+ validationCount++;
489
+ }
490
+ }
491
+ } );
492
+ } );
493
+ } );
494
+ if ( validationCount ) {
495
+ return res.sendError( 'Please Fill all Required Fields', 400 );
496
+ } else {
497
+ next();
498
+ }
499
+ } else {
500
+ next();
501
+ }
502
+ } catch ( e ) {
503
+ logger.error( { function: 'sopMobileTaskQuestionValidator', error: e } );
504
+ return res.sendError( e, 500 );
505
+ }
506
+ };
507
+
287
508
  export async function sopMobilechecklistMultiSectionFormatter( req, res, next ) {
288
509
  try {
289
510
  let requestData = req.body;
@@ -327,7 +548,7 @@ export async function sopMobilechecklistMultiSectionFormatter( req, res, next )
327
548
  if ( requestSection[i].answer == qaans[k].answer ) {
328
549
  if ( qaans[k].validationType == 'Capture Image' || qaans[k].validationType == 'Capture Video' ) {
329
550
  if ( requestSection[i].validationAnswer ) {
330
- let validateAns = requestSection[i].validationAnswer.split( '?' )[0];
551
+ let validateAns = decodeURIComponent( requestSection[i].validationAnswer.split( '?' )[0] );
331
552
  if ( validateAns.length ) {
332
553
  let splitImgUrl = validateAns.split( '/' );
333
554
  if ( splitImgUrl.length > 1 ) {
@@ -366,7 +587,7 @@ export async function sopMobilechecklistMultiSectionFormatter( req, res, next )
366
587
  if ( requestSection[i].answer == qaans[k].answer ) {
367
588
  if ( qaans[k].validationType == 'Capture Image' || qaans[k].validationType == 'Capture Video' ) {
368
589
  if ( requestSection[i].validationAnswer ) {
369
- let validationAnswer = requestSection[i].validationAnswer.split( '?' )[0];
590
+ let validationAnswer = decodeURIComponent( requestSection[i].validationAnswer.split( '?' )[0] );
370
591
  if ( validationAnswer.length ) {
371
592
  let splitImgUrl = validationAnswer.split( '/' );
372
593
  if ( splitImgUrl.length > 1 ) {
@@ -407,7 +628,7 @@ export async function sopMobilechecklistMultiSectionFormatter( req, res, next )
407
628
  if ( separatedArray[s].answer == qaans[k].answer ) {
408
629
  if ( qaans[k].validationType == 'Capture Image' || qaans[k].validationType == 'Capture Video' ) {
409
630
  if ( separatedArray[s].validationAnswer ) {
410
- let validationAnswer = separatedArray[s].validationAnswer.split( '?' )[0];
631
+ let validationAnswer = decodeURIComponent( separatedArray[s].validationAnswer.split( '?' )[0] );
411
632
  if ( validationAnswer.length ) {
412
633
  let splitImgUrl = validationAnswer.split( '/' );
413
634
  if ( splitImgUrl.length > 1 ) {
@@ -448,7 +669,7 @@ export async function sopMobilechecklistMultiSectionFormatter( req, res, next )
448
669
  for ( let s = 0; s < separatedArray.length; s++ ) {
449
670
  if ( separatedArray[s].answer && separatedArray[s].answer !='' ) {
450
671
  let newAnswer = {};
451
- let validationAnswer = separatedArray[s].answer.split( '?' )[0];
672
+ let validationAnswer = decodeURIComponent( separatedArray[s].answer.split( '?' )[0] );
452
673
  if ( validationAnswer.length ) {
453
674
  let splitImgUrl = validationAnswer.split( '/' );
454
675
  if ( splitImgUrl.length > 1 ) {
@@ -492,7 +713,7 @@ export async function sopMobilechecklistMultiSectionFormatter( req, res, next )
492
713
  } else {
493
714
  let des = [];
494
715
  if ( requestSection[i].answer != 'null' && requestSection[i].answer != '' && requestSection[i].answer != null ) {
495
- let validationAnswer = requestSection[i].answer.split( '?' )[0];
716
+ let validationAnswer = decodeURIComponent( requestSection[i].answer.split( '?' )[0] );
496
717
  if ( validationAnswer.length ) {
497
718
  let splitImgUrl = validationAnswer.split( '/' );
498
719
  if ( splitImgUrl.length > 1 ) {
@@ -554,6 +775,276 @@ export async function sopMobilechecklistMultiSectionFormatter( req, res, next )
554
775
  }
555
776
  };
556
777
 
778
+ export async function sopMobileTaskMultiSectionFormatter( req, res, next ) {
779
+ try {
780
+ let requestData = req.body;
781
+ requestData.questionAnswers = typeof requestData.questionAnswers == 'string' ? JSON.parse( requestData.questionAnswers ) : requestData.questionAnswers;
782
+ let getChecklistQA = await processedTask.findOne( { _id: new ObjectId( requestData.processedcheckListId ) }, { questionAnswers: 1 } );
783
+ let reqAnswers = requestData.questionAnswers;
784
+ let CLQAnswers = getChecklistQA.questionAnswers;
785
+
786
+ if ( requestData.submittype == 'submit' ) {
787
+ reqAnswers.forEach( ( reqA ) => {
788
+ if ( ![ 'multiplechoicemultiple', 'multipleImage' ].includes( reqA?.answerType ) ) {
789
+ if ( ( !reqA.linkType && ( reqA.answer == null || reqA.answer == '' ) ) || ( reqA.linkType && reqA.linkquestionenabled && ( reqA.answer == null || reqA.answer == '' ) ) ) {
790
+ return res.sendError( 'Please Fill All Fields', 400 );
791
+ }
792
+ }
793
+ } );
794
+ }
795
+
796
+ let sectionFormat = [];
797
+ let uniqueSections = {};
798
+ reqAnswers.forEach( ( item ) => {
799
+ const key = `${item.section_id}-${item.sectionName}`;
800
+ if ( !uniqueSections[key] ) {
801
+ uniqueSections[key] = { id: item.section_id, name: item.sectionName };
802
+ }
803
+ } );
804
+ const uniqueArray = Object.values( uniqueSections );
805
+ for ( let section of uniqueArray ) {
806
+ let CLQSection = CLQAnswers.find( ( item ) => item.section_id == section.id );
807
+ if ( CLQSection ) {
808
+ let newArray = [];
809
+ let qaAnswers = CLQSection.questions;
810
+ let requestSection = reqAnswers.filter( ( item ) => item.section_id == section.id );
811
+ for ( let i = 0; i < requestSection.length; i++ ) {
812
+ for ( let j = 0; j < qaAnswers.length; j++ ) {
813
+ if ( requestSection[i].qno == qaAnswers[j].qno ) {
814
+ if ( qaAnswers[j].answerType == 'yes/no' ) {
815
+ let qaans = qaAnswers[j].answers;
816
+ let yn = [];
817
+ for ( let k = 0; k < qaans.length; k++ ) {
818
+ if ( requestSection[i].answer == qaans[k].answer ) {
819
+ if ( qaans[k].validationType == 'Capture Image' || qaans[k].validationType == 'Capture Video' ) {
820
+ if ( requestSection[i].validationAnswer ) {
821
+ let validateAns = decodeURIComponent( requestSection[i].validationAnswer.split( '?' )[0] );
822
+ if ( validateAns.length ) {
823
+ let splitImgUrl = validateAns.split( '/' );
824
+ if ( splitImgUrl.length > 1 ) {
825
+ splitImgUrl.splice( 0, 3 );
826
+ qaans[k].validationAnswer = splitImgUrl.join( '/' ) || '';
827
+ }
828
+ }
829
+ }
830
+ } else {
831
+ qaans[k].descriptivetype = qaAnswers[j].descriptivetype || '';
832
+ qaans[k].validationAnswer = requestSection[i].validationAnswer || '';
833
+ }
834
+ yn.push( qaans[k] );
835
+ }
836
+ }
837
+ let structure = {};
838
+ structure.qno = qaAnswers[j].qno;
839
+ structure.qname = qaAnswers[j].qname;
840
+ structure.answerType = qaAnswers[j].answerType;
841
+ structure.runAI = qaAnswers[j].runAI;
842
+ structure.runAIDescription = qaAnswers[j].runAIDescription;
843
+ structure.allowUploadfromGallery = qaAnswers[j].allowUploadfromGallery;
844
+ structure.remarks = requestSection[i].remarks;
845
+ structure.answers = qaAnswers[j].answers;
846
+ structure.userAnswer = yn;
847
+ structure.linkType = qaAnswers[j].linkType,
848
+ structure.linkquestionenabled = requestSection[i].linkquestionenabled,
849
+ structure.parentanswer = requestSection[i].parentanswer,
850
+ structure.questionReferenceImage = qaAnswers[j].questionReferenceImage,
851
+ structure.descriptivetype = qaAnswers[j].descriptivetype,
852
+ newArray.push( structure );
853
+ } else if ( qaAnswers[j].answerType == 'multiplechoicesingle' ) {
854
+ let qaans = qaAnswers[j].answers;
855
+ let ms = [];
856
+ for ( let k = 0; k < qaans.length; k++ ) {
857
+ if ( requestSection[i].answer == qaans[k].answer ) {
858
+ if ( qaans[k].validationType == 'Capture Image' || qaans[k].validationType == 'Capture Video' ) {
859
+ if ( requestSection[i].validationAnswer ) {
860
+ let validationAnswer = decodeURIComponent( requestSection[i].validationAnswer.split( '?' )[0] );
861
+ if ( validationAnswer.length ) {
862
+ let splitImgUrl = validationAnswer.split( '/' );
863
+ if ( splitImgUrl.length > 1 ) {
864
+ splitImgUrl.splice( 0, 3 );
865
+ qaans[k].validationAnswer = splitImgUrl.join( '/' ) || '';
866
+ }
867
+ }
868
+ }
869
+ } else {
870
+ qaans[k].descriptivetype = qaAnswers[j].descriptivetype || '';
871
+ qaans[k].validationAnswer = requestSection[i].validationAnswer || '';
872
+ }
873
+ ms.push( qaans[k] );
874
+ }
875
+ }
876
+ let structure = {};
877
+ structure.qno = qaAnswers[j].qno;
878
+ structure.qname = qaAnswers[j].qname;
879
+ structure.answerType = qaAnswers[j].answerType;
880
+ structure.runAI = qaAnswers[j].runAI;
881
+ structure.runAIDescription = qaAnswers[j].runAIDescription;
882
+ structure.allowUploadfromGallery = qaAnswers[j].allowUploadfromGallery;
883
+ structure.remarks = requestSection[i].remarks;
884
+ structure.answers = qaAnswers[j].answers;
885
+ structure.userAnswer = ms;
886
+ structure.linkType = qaAnswers[j].linkType,
887
+ structure.linkquestionenabled = requestSection[i].linkquestionenabled,
888
+ structure.parentanswer = requestSection[i].parentanswer,
889
+ structure.questionReferenceImage = qaAnswers[j].questionReferenceImage,
890
+ structure.descriptivetype = qaAnswers[j].descriptivetype,
891
+ newArray.push( structure );
892
+ } else if ( qaAnswers[j].answerType == 'multiplechoicemultiple' ) {
893
+ let qaans = qaAnswers[j].answers;
894
+ let mcmo = [];
895
+ for ( let k = 0; k < qaans.length; k++ ) {
896
+ let separatedArray = typeof requestSection[i].Multianswer == 'string' ? JSON.parse( requestSection[i].Multianswer ) : requestSection[i].Multianswer;
897
+ for ( let s = 0; s < separatedArray.length; s++ ) {
898
+ if ( separatedArray[s].answer == qaans[k].answer ) {
899
+ if ( qaans[k].validationType == 'Capture Image' || qaans[k].validationType == 'Capture Video' ) {
900
+ if ( separatedArray[s].validationAnswer ) {
901
+ let validationAnswer = decodeURIComponent( separatedArray[s].validationAnswer.split( '?' )[0] );
902
+ if ( validationAnswer.length ) {
903
+ let splitImgUrl = validationAnswer.split( '/' );
904
+ if ( splitImgUrl.length > 1 ) {
905
+ splitImgUrl.splice( 0, 3 );
906
+ qaans[k].validationAnswer = splitImgUrl.join( '/' ) || '';
907
+ }
908
+ }
909
+ }
910
+ } else {
911
+ qaans[k].descriptivetype = qaAnswers[j].descriptivetype || '';
912
+ qaans[k].validationAnswer = separatedArray[s].validationAnswer || '';
913
+ }
914
+
915
+ mcmo.push( qaans[k] );
916
+ }
917
+ }
918
+ }
919
+ let structure = {};
920
+ structure.qno = qaAnswers[j].qno;
921
+ structure.qname = qaAnswers[j].qname;
922
+ structure.answerType = qaAnswers[j].answerType;
923
+ structure.runAI = qaAnswers[j].runAI;
924
+ structure.runAIDescription = qaAnswers[j].runAIDescription;
925
+ structure.allowUploadfromGallery = qaAnswers[j].allowUploadfromGallery;
926
+ structure.remarks = requestSection[i].remarks;
927
+ structure.answers = qaAnswers[j].answers;
928
+ structure.userAnswer = mcmo;
929
+ structure.linkType = qaAnswers[j].linkType,
930
+ structure.linkquestionenabled = requestSection[i].linkquestionenabled,
931
+ structure.parentanswer = requestSection[i].parentanswer,
932
+ structure.questionReferenceImage = qaAnswers[j].questionReferenceImage,
933
+ structure.descriptivetype = qaAnswers[j].descriptivetype,
934
+ newArray.push( structure );
935
+ } else if ( qaAnswers[j].answerType == 'multipleImage' ) {
936
+ let separatedArray = typeof requestSection[i].Multianswer == 'string' ? JSON.parse( requestSection[i].Multianswer ) : requestSection[i].Multianswer;
937
+ let mcmi = [];
938
+ // for (let k = 0; k < qaans.length; k++) {
939
+ for ( let s = 0; s < separatedArray.length; s++ ) {
940
+ if ( separatedArray[s].answer && separatedArray[s].answer !='' ) {
941
+ let newAnswer = {};
942
+ let validationAnswer = decodeURIComponent( separatedArray[s].answer.split( '?' )[0] );
943
+ if ( validationAnswer.length ) {
944
+ let splitImgUrl = validationAnswer.split( '/' );
945
+ if ( splitImgUrl.length > 1 ) {
946
+ splitImgUrl.splice( 0, 3 );
947
+ newAnswer.answer = splitImgUrl.join( '/' ) || '';
948
+ }
949
+ }
950
+
951
+ newAnswer.answeroptionNumber = 0;
952
+ newAnswer.sopFlag = false;
953
+ newAnswer.validation = false;
954
+ newAnswer.validationType = '';
955
+ newAnswer.referenceImage = '';
956
+ newAnswer.allowUploadfromGallery = false;
957
+ newAnswer.runAI = false;
958
+ newAnswer.descriptivetype = '';
959
+ newAnswer.showLinked = false;
960
+ newAnswer.linkedQuestion = 0;
961
+ newAnswer.nestedQuestion = [];
962
+ newAnswer.index = s;
963
+ mcmi.push( newAnswer );
964
+ }
965
+ }
966
+ // }
967
+ let structure = {};
968
+ structure.qno = qaAnswers[j].qno;
969
+ structure.qname = qaAnswers[j].qname;
970
+ structure.answerType = qaAnswers[j].answerType;
971
+ structure.runAI = qaAnswers[j].runAI;
972
+ structure.runAIDescription = qaAnswers[j].runAIDescription;
973
+ structure.allowUploadfromGallery = qaAnswers[j].allowUploadfromGallery;
974
+ structure.remarks = requestSection[i].remarks;
975
+ structure.answers = qaAnswers[j].answers;
976
+ structure.userAnswer = mcmi;
977
+ structure.linkType = qaAnswers[j].linkType,
978
+ structure.linkquestionenabled = requestSection[i].linkquestionenabled,
979
+ structure.parentanswer = requestSection[i].parentanswer,
980
+ structure.questionReferenceImage = qaAnswers[j].questionReferenceImage,
981
+ structure.descriptivetype = qaAnswers[j].descriptivetype,
982
+ newArray.push( structure );
983
+ } else {
984
+ let des = [];
985
+ if ( requestSection[i].answer != 'null' && requestSection[i].answer != '' && requestSection[i].answer != null ) {
986
+ let validationAnswer = decodeURIComponent( requestSection[i].answer.split( '?' )[0] );
987
+ if ( validationAnswer.length ) {
988
+ let splitImgUrl = validationAnswer.split( '/' );
989
+ if ( splitImgUrl.length > 1 ) {
990
+ splitImgUrl.splice( 0, 3 );
991
+ requestSection[i].answer = splitImgUrl.join( '/' );
992
+ }
993
+ }
994
+ let ansstructure = {
995
+ answer: requestSection[i].answer,
996
+ answeroptionNumber: 1,
997
+ sopFlag: false,
998
+ validation: false,
999
+ validationType: '',
1000
+ validationAnswer: '',
1001
+ referenceImage: qaAnswers[j].answers[0]?.referenceImage,
1002
+ showLinked: qaAnswers[j].answers[0]?.showLinked,
1003
+ linkedQuestion: qaAnswers[j].answers[0]?.linkedQuestion,
1004
+ };
1005
+ if ( qaAnswers[j].answerType == 'date' ) {
1006
+ ansstructure.dateRangeType = requestSection[i].dateRangeType || false;
1007
+ }
1008
+ des.push( ansstructure );
1009
+ }
1010
+ let structure = {};
1011
+ structure.qno = qaAnswers[j].qno;
1012
+ structure.qname = qaAnswers[j].qname;
1013
+ structure.answerType = qaAnswers[j].answerType;
1014
+ structure.runAI = qaAnswers[j].runAI;
1015
+ structure.runAIDescription = qaAnswers[j].runAIDescription;
1016
+ structure.allowUploadfromGallery = qaAnswers[j].allowUploadfromGallery;
1017
+ structure.remarks = requestSection[i].remarks;
1018
+ structure.answers = qaAnswers[j].answers;
1019
+ structure.userAnswer = des;
1020
+ structure.linkType = qaAnswers[j].linkType,
1021
+ structure.linkquestionenabled = requestSection[i].linkquestionenabled,
1022
+ structure.parentanswer = requestSection[i].parentanswer,
1023
+ structure.questionReferenceImage = qaAnswers[j].questionReferenceImage,
1024
+ structure.descriptivetype = qaAnswers[j].descriptivetype,
1025
+ newArray.push( structure );
1026
+ }
1027
+ }
1028
+ }
1029
+ }
1030
+ let sectionData = {
1031
+ 'section_id': section.id,
1032
+ 'sectionName': section.name,
1033
+ 'questions': newArray,
1034
+ };
1035
+ sectionFormat.push( sectionData );
1036
+ }
1037
+ }
1038
+
1039
+
1040
+ requestData.questionAnswers = sectionFormat;
1041
+ next();
1042
+ } catch ( error ) {
1043
+ logger.error( { function: 'sopMobileValidater error =>', error: error } );
1044
+ return res.sendError( error, 500 );
1045
+ }
1046
+ };
1047
+
557
1048
  function QuestionFlag( req, res ) {
558
1049
  try {
559
1050
  let flagCount = 0;
@@ -620,13 +1111,13 @@ export async function submitChecklist( req, res ) {
620
1111
  if ( requestData.submittype == 'draft' ) {
621
1112
  logger.info( `v5 => Checklist Save => store Name: ${getchecklist[0].storeName}, User Email: ${getchecklist[0].userEmail}, Checklist Name: ${getchecklist[0].checkListName}` );
622
1113
  updateData.questionAnswers = requestData.questionAnswers;
623
- updateData.updatedAt = dayjs.utc( updateData.startTime_string, 'hh:mm A, DD MMM YYYY' ).format();
1114
+ updateData.updatedAt = dayjs.utc( currentDateTime.format( 'hh:mm:ss A, DD MMM YYYY' ), 'hh:mm:ss A, DD MMM YYYY' ).format();
624
1115
  } else {
625
1116
  logger.info( `v5 => Checklist Submit => store Name: ${getchecklist[0].storeName}, User Email: ${getchecklist[0].userEmail}, Checklist Name: ${getchecklist[0].checkListName}` );
626
1117
  updateData.questionAnswers = requestData.questionAnswers;
627
- updateData.submitTime = dayjs.utc( updateData.submitTime_string, 'hh:mm A, DD MMM YYYY' ).format();
1118
+ updateData.submitTime = dayjs.utc( currentDateTime.format( 'hh:mm:ss A, DD MMM YYYY' ), 'hh:mm:ss A, DD MMM YYYY' ).format();
628
1119
  updateData.checklistStatus = 'submit';
629
- updateData.updatedAt = dayjs.utc( updateData.submitTime_string, 'hh:mm A, DD MMM YYYY' ).format();
1120
+ updateData.updatedAt = dayjs.utc( currentDateTime.format( 'hh:mm:ss A, DD MMM YYYY' ), 'hh:mm:ss A, DD MMM YYYY' ).format();
630
1121
  updateData.submitMobileTime = requestData?.currentTime;
631
1122
  }
632
1123
  let updatechecklist = await processedchecklist.updateOne( updateQuery, updateData );
@@ -700,6 +1191,99 @@ export async function submitChecklist( req, res ) {
700
1191
  }
701
1192
  }
702
1193
 
1194
+ export async function submitTask( req, res ) {
1195
+ try {
1196
+ const { body: requestData, user } = req;
1197
+ const { processedcheckListId, date, submittype, currentTime, questionAnswers } = requestData;
1198
+
1199
+ const findQuery = [
1200
+ {
1201
+ $match: {
1202
+ _id: new ObjectId( processedcheckListId ),
1203
+ userId: user._id,
1204
+ date_string: date,
1205
+ },
1206
+ },
1207
+ ];
1208
+
1209
+ const [ checklist ] = await processedTask.aggregate( findQuery );
1210
+
1211
+ if ( !checklist ) {
1212
+ return res.sendError( 'Task edited. Please fill again', 422 );
1213
+ }
1214
+
1215
+ // eslint-disable-next-line camelcase
1216
+ const { checklistStatus, storeName, userEmail, checkListName, store_id, checkListId } = checklist;
1217
+
1218
+ if ( checklistStatus === 'open' ) {
1219
+ return res.sendError( 'Checklist is in open status. Please start.', 400 );
1220
+ }
1221
+
1222
+ if ( checklistStatus === 'submit' ) {
1223
+ return res.sendError( 'Checklist already submitted', 400 );
1224
+ }
1225
+
1226
+ const storeTimeZone = await storeService.findOne( { storeName }, { 'storeProfile.timeZone': 1 } );
1227
+ const currentDateTime = storeTimeZone?.storeProfile?.timeZone ?
1228
+ dayjs().tz( storeTimeZone.storeProfile.timeZone ) :
1229
+ dayjs();
1230
+
1231
+ const updateQuery = {
1232
+ _id: new ObjectId( processedcheckListId ),
1233
+ userId: user._id,
1234
+ date_string: date,
1235
+ };
1236
+
1237
+ const updateData = {
1238
+ questionAnswers,
1239
+ updatedAt: dayjs.utc( currentDateTime.format( 'hh:mm:ss A, DD MMM YYYY' ), 'hh:mm:ss A, DD MMM YYYY' ).format(),
1240
+ questionFlag: QuestionFlag( req, res ),
1241
+ };
1242
+
1243
+ if ( submittype === 'draft' ) {
1244
+ logger.info(
1245
+ `v5 => Checklist Save => store Name: ${storeName}, User Email: ${userEmail}, Checklist Name: ${checkListName}`,
1246
+ );
1247
+ updateData.submitTime_string = currentDateTime.format( 'hh:mm A, DD MMM YYYY' );
1248
+ } else {
1249
+ logger.info(
1250
+ `v5 => Checklist Submit => store Name: ${storeName}, User Email: ${userEmail}, Checklist Name: ${checkListName}`,
1251
+ );
1252
+ Object.assign( updateData, {
1253
+ submitTime: dayjs.utc( currentDateTime.format( 'hh:mm:ss A, DD MMM YYYY' ), 'hh:mm:ss A, DD MMM YYYY' ).format(),
1254
+ checklistStatus: 'submit',
1255
+ submitMobileTime: currentTime,
1256
+ submitTime_string: currentDateTime.format( 'hh:mm A, DD MMM YYYY' ),
1257
+ } );
1258
+ }
1259
+
1260
+ const updateResult = await processedTask.updateOne( updateQuery, updateData );
1261
+
1262
+ if ( updateResult.modifiedCount > 0 ) {
1263
+ const logInsertData = {
1264
+ // eslint-disable-next-line camelcase
1265
+ store_id,
1266
+ storeName,
1267
+ action: submittype === 'draft' ? 'saved' : 'submitted',
1268
+ checklistId: checkListId,
1269
+ checkListName,
1270
+ client_id: user.clientId,
1271
+ };
1272
+ await checklistLogs.create( logInsertData );
1273
+
1274
+ updateOpenSearch( user, requestData );
1275
+
1276
+ return res.sendSuccess( 'Task Updated Successfully' );
1277
+ } else {
1278
+ return res.sendError( 'Something went wrong. Please try again', 500 );
1279
+ }
1280
+ } catch ( error ) {
1281
+ logger.error( { function: 'submitTask', error } );
1282
+ return res.sendError( error.message || 'Internal Server Error', 500 );
1283
+ }
1284
+ }
1285
+
1286
+
703
1287
  async function updateOpenSearch( user, data ) {
704
1288
  let findQuery = [ {
705
1289
  $match: {
@@ -828,6 +1412,80 @@ export async function dashboard( req, res ) {
828
1412
  }
829
1413
  }
830
1414
 
1415
+ export async function dashboardv1( req, res ) {
1416
+ try {
1417
+ // eslint-disable-next-line camelcase
1418
+ const { store_id, date } = req.query;
1419
+ const userId = req.user._id;
1420
+
1421
+ const baseMatch = {
1422
+ // eslint-disable-next-line camelcase
1423
+ store_id,
1424
+ userId,
1425
+ date_string: date,
1426
+ timeFlagStatus: true,
1427
+ };
1428
+
1429
+ const buildPipeline = ( matchExtraConditions = {} ) => [
1430
+ { $match: { ...baseMatch, ...matchExtraConditions } },
1431
+ {
1432
+ $facet: {
1433
+ total: [ { $count: 'total' } ],
1434
+ toDo: [
1435
+ { $match: { checklistStatus: 'open' } },
1436
+ { $group: { _id: '', count: { $sum: 1 } } },
1437
+ ],
1438
+ inprogress: [
1439
+ { $match: { checklistStatus: 'inprogress' } },
1440
+ { $group: { _id: '', count: { $sum: 1 } } },
1441
+ ],
1442
+ submit: [
1443
+ { $match: { checklistStatus: 'submit' } },
1444
+ { $group: { _id: '', count: { $sum: 1 } } },
1445
+ ],
1446
+ },
1447
+ },
1448
+ ];
1449
+
1450
+ const processResult = ( result ) => ( {
1451
+ totalchecklist: result[0]?.total[0]?.total || 0,
1452
+ todo: result[0]?.toDo[0]?.count || 0,
1453
+ inprogress: result[0]?.inprogress[0]?.count || 0,
1454
+ done: result[0]?.submit[0]?.count || 0,
1455
+ } );
1456
+
1457
+ const checklistQuery = buildPipeline( { checkListType: 'custom' } );
1458
+ const taskQuery = buildPipeline();
1459
+
1460
+ const [ checklistResult, taskResult ] = await Promise.allSettled( [
1461
+ processedchecklist.aggregate( checklistQuery ),
1462
+ processedTask.aggregate( taskQuery ),
1463
+ ] );
1464
+
1465
+ const checklistResultData =
1466
+ checklistResult.status === 'fulfilled' ?
1467
+ processResult( checklistResult.value ) :
1468
+ { totalchecklist: 0, todo: 0, inprogress: 0, done: 0 };
1469
+
1470
+ const taskResultData =
1471
+ taskResult.status === 'fulfilled' ?
1472
+ processResult( taskResult.value ) :
1473
+ { totalchecklist: 0, todo: 0, inprogress: 0, done: 0 };
1474
+
1475
+ const totalResult = {
1476
+ totalchecklist: checklistResultData.totalchecklist + taskResultData.totalchecklist,
1477
+ todo: checklistResultData.todo + taskResultData.todo,
1478
+ inprogress: checklistResultData.inprogress + taskResultData.inprogress,
1479
+ done: checklistResultData.done + taskResultData.done,
1480
+ };
1481
+
1482
+ return res.sendSuccess( totalResult );
1483
+ } catch ( e ) {
1484
+ logger.error( { function: 'dashboardv1', error: e } );
1485
+ return res.sendError( e, 500 );
1486
+ }
1487
+ }
1488
+
831
1489
  export async function checklist( req, res ) {
832
1490
  try {
833
1491
  let requestData = req.query;
@@ -913,6 +1571,101 @@ export async function checklist( req, res ) {
913
1571
  }
914
1572
  }
915
1573
 
1574
+ export async function checklistv1( req, res ) {
1575
+ try {
1576
+ // eslint-disable-next-line camelcase
1577
+ const { store_id, date, checklistStatus, searchValue } = req.query;
1578
+ const userId = req.user._id;
1579
+
1580
+ const buildPipeline = ( matchExtraConditions = [], type ) => {
1581
+ const matchConditions = [
1582
+ // eslint-disable-next-line camelcase
1583
+ { store_id },
1584
+ { userId },
1585
+ { date_string: date },
1586
+ { timeFlagStatus: true },
1587
+ ...matchExtraConditions,
1588
+ ];
1589
+
1590
+ if ( checklistStatus ) {
1591
+ matchConditions.push( { checklistStatus } );
1592
+ }
1593
+
1594
+ const pipeline = [
1595
+ { $match: { $and: matchConditions } },
1596
+ ...( searchValue ?
1597
+ [ { $match: { $or: [ { checkListName: { $regex: searchValue, $options: 'i' } } ] } } ] :
1598
+ [] ),
1599
+ {
1600
+ $project: {
1601
+ checkListName: { $ifNull: [ '$checkListName', '' ] },
1602
+ scheduleStartTime: { $ifNull: [ '$scheduleStartTime', '' ] },
1603
+ scheduleStartTime_iso: { $ifNull: [ '$scheduleStartTime_iso', '' ] },
1604
+ scheduleEndTime: { $ifNull: [ '$scheduleEndTime', '' ] },
1605
+ scheduleEndTime_iso: { $ifNull: [ '$scheduleEndTime_iso', '' ] },
1606
+ checklistStatus: { $ifNull: [ '$checklistStatus', '' ] },
1607
+ checkListId: { $ifNull: [ '$checkListId', '' ] },
1608
+ startTime: { $ifNull: [ '$startTime', '' ] },
1609
+ submitTime: { $ifNull: [ '$submitTime', '' ] },
1610
+ allowedOverTime: { $ifNull: [ '$allowedOverTime', '' ] },
1611
+ allowedStoreLocation: { $ifNull: [ '$allowedStoreLocation', '' ] },
1612
+ reinitiateStatus: { $ifNull: [ '$reinitiateStatus', '' ] },
1613
+ startTime_string: { $ifNull: [ '$startTime_string', '' ] },
1614
+ submitTime_string: { $ifNull: [ '$submitTime_string', '' ] },
1615
+ timeFlag: { $ifNull: [ '$timeFlag', '' ] },
1616
+ scheduleRepeatedType: { $ifNull: [ '$scheduleRepeatedType', '' ] },
1617
+ timeDifference: { $subtract: [ '$scheduleEndTime_iso', '$date_iso' ] },
1618
+ redoStatus: { $ifNull: [ '$redoStatus', false ] },
1619
+ type: type,
1620
+ },
1621
+ },
1622
+ ];
1623
+
1624
+ return pipeline;
1625
+ };
1626
+
1627
+ const [ checklistResult, taskResult ] = await Promise.allSettled( [
1628
+ processedchecklist.aggregate( buildPipeline( [ { checkListType: 'custom' } ], 'checklist' ) ),
1629
+ processedTask.aggregate( buildPipeline( [], 'task' ) ),
1630
+ ] );
1631
+
1632
+ const checklistData = checklistResult.status === 'fulfilled' ? checklistResult.value : [];
1633
+ const taskData = taskResult.status === 'fulfilled' ? taskResult.value : [];
1634
+
1635
+ const totalData = [ ...checklistData, ...taskData ];
1636
+
1637
+ if ( !totalData.length ) {
1638
+ return res.sendError( { error: 'No Data Found' }, 204 );
1639
+ }
1640
+
1641
+ const getSortingParams = ( status ) => {
1642
+ switch ( status ) {
1643
+ case 'submit':
1644
+ return { column: 'submitTime', order: -1 };
1645
+ case 'open':
1646
+ case 'inprogress':
1647
+ default:
1648
+ return { column: 'timeDifference', order: 1 };
1649
+ }
1650
+ };
1651
+
1652
+ const { column: sortColumnName, order: sortBy } = getSortingParams( checklistStatus );
1653
+
1654
+ totalData.sort( ( a, b ) => {
1655
+ if ( sortBy === 1 ) {
1656
+ return ( a[sortColumnName] || 0 ) - ( b[sortColumnName] || 0 );
1657
+ } else {
1658
+ return ( b[sortColumnName] || 0 ) - ( a[sortColumnName] || 0 );
1659
+ }
1660
+ } );
1661
+
1662
+ return res.sendSuccess( { count: totalData.length, data: totalData } );
1663
+ } catch ( e ) {
1664
+ logger.error( { function: 'checklistv1', error: e } );
1665
+ return res.sendError( e, 500 );
1666
+ }
1667
+ }
1668
+
916
1669
  export async function questionList( req, res ) {
917
1670
  try {
918
1671
  let requestData = req.query;
@@ -1070,6 +1823,120 @@ export async function questionList( req, res ) {
1070
1823
  }
1071
1824
  }
1072
1825
 
1826
+ export async function taskQuestionList( req, res ) {
1827
+ try {
1828
+ const { processedcheckListId } = req.query;
1829
+
1830
+ if ( !processedcheckListId ) {
1831
+ return res.sendError( 'processedcheckListId is required', 400 );
1832
+ }
1833
+
1834
+ const findQuery = [
1835
+ {
1836
+ $match: {
1837
+ _id: new ObjectId( processedcheckListId ),
1838
+ },
1839
+ },
1840
+ {
1841
+ $project: {
1842
+ checkListName: { $ifNull: [ '$checkListName', '' ] },
1843
+ scheduleStartTime: { $ifNull: [ '$scheduleStartTime', '' ] },
1844
+ scheduleStartTime_iso: { $ifNull: [ '$scheduleStartTime_iso', '' ] },
1845
+ scheduleEndTime: { $ifNull: [ '$scheduleEndTime', '' ] },
1846
+ scheduleEndTime_iso: { $ifNull: [ '$scheduleEndTime_iso', '' ] },
1847
+ checklistStatus: { $ifNull: [ '$checklistStatus', '' ] },
1848
+ checkListId: { $ifNull: [ '$checkListId', '' ] },
1849
+ startTime: { $ifNull: [ '$startTime', '' ] },
1850
+ submitTime: { $ifNull: [ '$submitTime', '' ] },
1851
+ allowedOverTime: { $ifNull: [ '$allowedOverTime', '' ] },
1852
+ allowedStoreLocation: { $ifNull: [ '$allowedStoreLocation', '' ] },
1853
+ reinitiateStatus: { $ifNull: [ '$reinitiateStatus', '' ] },
1854
+ questionAnswers: { $ifNull: [ '$questionAnswers', '' ] },
1855
+ userEmail: { $ifNull: [ '$userEmail', '' ] },
1856
+ storeName: { $ifNull: [ '$storeName', '' ] },
1857
+ },
1858
+ },
1859
+ ];
1860
+
1861
+ const [ checklist ] = await processedTask.aggregate( findQuery );
1862
+
1863
+ if ( !checklist ) {
1864
+ return res.sendError( 'Task got edited, please fill again', 422 );
1865
+ }
1866
+
1867
+ logger.info(
1868
+ `v5 => Checklist Continue => store Name: ${checklist.storeName}, User Email: ${checklist.userEmail}, Checklist Name: ${checklist.checkListName}`,
1869
+ );
1870
+
1871
+ const bucket = JSON.parse( process.env.BUCKET );
1872
+ const sopBucket = bucket.sop;
1873
+
1874
+ const getSignedUrl = async ( filePath ) =>
1875
+ filePath && filePath !== '' ?
1876
+ await signedUrl( { file_path: decodeURIComponent( filePath ), Bucket: sopBucket } ) :
1877
+ null;
1878
+
1879
+ for ( const section of checklist.questionAnswers || [] ) {
1880
+ for ( const question of section.questions || [] ) {
1881
+ const { answerType, answers = [], userAnswer = [] } = question;
1882
+ const multiAnswer = [];
1883
+
1884
+ question.questionReferenceImage = await getSignedUrl( question.questionReferenceImage );
1885
+
1886
+ for ( const [ ansIndex, answer ] of answers.entries() ) {
1887
+ answer.index = ansIndex;
1888
+
1889
+ answer.referenceImage = await getSignedUrl( answer.referenceImage );
1890
+
1891
+ if ( [ 'Capture Image', 'Capture Video' ].includes( answer.validationType ) ) {
1892
+ answer.validationAnswer = await getSignedUrl( answer.validationAnswer );
1893
+ }
1894
+
1895
+ if ( answerType === 'multiplechoicemultiple' ) {
1896
+ const validationAnswer = await getSignedUrl( answer.validationAnswer );
1897
+ multiAnswer.push( { answer: answer.answer, no: ansIndex, validationAnswer } );
1898
+ }
1899
+ }
1900
+
1901
+ for ( const [ userAnsIndex, userAns ] of userAnswer.entries() ) {
1902
+ if ( [ 'Capture Image', 'Capture Video' ].includes( userAns.validationType ) ) {
1903
+ userAns.validationAnswer = await getSignedUrl( userAns.validationAnswer );
1904
+ }
1905
+
1906
+ if ( [ 'image', 'descriptiveImage', 'video' ].includes( answerType ) ) {
1907
+ userAns.answer = await getSignedUrl( userAns.answer );
1908
+ }
1909
+
1910
+ userAns.referenceImage = await getSignedUrl( userAns.referenceImage );
1911
+
1912
+ if ( answerType === 'multiplechoicemultiple' ) {
1913
+ const ansIndex = multiAnswer.findIndex( ( item ) => item.answer === userAns.answer );
1914
+ if ( ansIndex >= 0 ) {
1915
+ multiAnswer[ansIndex].validationAnswer = userAns.validationAnswer;
1916
+ }
1917
+ }
1918
+
1919
+ if ( answerType === 'multipleImage' && userAns.answer ) {
1920
+ const manswer = await getSignedUrl( userAns.answer );
1921
+ multiAnswer.push( { answer: manswer, no: userAnsIndex, validationAnswer: '' } );
1922
+ }
1923
+ }
1924
+
1925
+ if ( [ 'multiplechoicemultiple', 'multipleImage' ].includes( answerType ) ) {
1926
+ question.Multianswer = multiAnswer.length ?
1927
+ multiAnswer.map( ( item ) => ( { ...item, answer: item.validationAnswer ? item.answer : null } ) ) :
1928
+ [ { answer: null, no: 0, validationAnswer: null } ];
1929
+ }
1930
+ }
1931
+ }
1932
+
1933
+ return res.sendSuccess( checklist );
1934
+ } catch ( error ) {
1935
+ logger.error( { function: 'taskQuestionList', error } );
1936
+ return res.sendError( error.message || 'Internal Server Error', 500 );
1937
+ }
1938
+ }
1939
+
1073
1940
 
1074
1941
  export async function uploadAnswerImage( req, res ) {
1075
1942
  try {