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.
- package/package.json +3 -3
- package/src/controllers/download.controller.js +132 -3
- package/src/controllers/gallery.controller.js +2 -0
- package/src/controllers/internalTrax.controller.js +49 -30
- package/src/controllers/mobileTrax.controller.js +875 -8
- package/src/controllers/teaxFlag.controller.js +43 -16
- package/src/controllers/trax.controller.js +22 -10
- package/src/controllers/traxDashboard.controllers.js +179 -129
- package/src/dtos/downloadValidation.dtos.js +5 -1
- package/src/routes/mobileTrax.routes.js +6 -0
- package/src/routes/trax.routes.js +17 -17
- package/src/services/processedTaskConfig.service.js +32 -0
- package/src/services/processedTaskList.service.js +30 -0
|
@@ -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(
|
|
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(
|
|
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(
|
|
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 {
|