tango-app-api-trax 3.7.56 → 3.7.58
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 -2
- package/src/controllers/handlebar-helper.js +11 -0
- package/src/controllers/internalTrax.controller.js +30 -2
- package/src/controllers/mobileTrax.controller.js +199 -17
- package/src/controllers/trax.controller.js +69 -0
- package/src/hbs/flag.hbs +249 -0
- package/src/hbs/login-otp.hbs +943 -943
- package/src/hbs/template.hbs +327 -0
- package/src/routes/mobileTrax.routes.js +3 -1
- package/src/routes/trax.routes.js +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-trax",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.58",
|
|
4
4
|
"description": "Trax",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -23,11 +23,12 @@
|
|
|
23
23
|
"firebase-admin": "^13.0.0",
|
|
24
24
|
"fs": "^0.0.1-security",
|
|
25
25
|
"handlebars": "^4.7.8",
|
|
26
|
+
"html-pdf": "^3.0.1",
|
|
26
27
|
"lodash": "^4.17.21",
|
|
27
28
|
"mongodb": "^6.8.0",
|
|
28
29
|
"nodemon": "^3.1.4",
|
|
29
30
|
"path": "^0.12.7",
|
|
30
|
-
"tango-api-schema": "^2.5.
|
|
31
|
+
"tango-api-schema": "^2.5.61",
|
|
31
32
|
"tango-app-api-middleware": "^3.5.2",
|
|
32
33
|
"url": "^0.11.4",
|
|
33
34
|
"winston": "^3.13.1",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Handlebars from 'handlebars';
|
|
2
|
+
|
|
3
|
+
Handlebars.registerHelper( 'eq', function( arg1, arg2, options ) {
|
|
4
|
+
return ( arg1 == arg2 ) ? options.fn( this ) : options.inverse( this );
|
|
5
|
+
} );
|
|
6
|
+
|
|
7
|
+
Handlebars.registerHelper( 'neq', function( a, b, options ) {
|
|
8
|
+
return a !== b ? options.fn( this ) : options.inverse( this );
|
|
9
|
+
} );
|
|
10
|
+
|
|
11
|
+
export default Handlebars;
|
|
@@ -3203,9 +3203,37 @@ export async function checklistTaskSubmissionDetails( req, res ) {
|
|
|
3203
3203
|
}
|
|
3204
3204
|
let details = [];
|
|
3205
3205
|
if ( req.body.type == 'checklist' ) {
|
|
3206
|
-
details = await processedchecklist.find( { sourceCheckList_id: req.body.checklistId, date_iso: new Date( dayjs( req.body.date ).format( 'YYYY-MM-DD' ) ) }, {
|
|
3206
|
+
details = await processedchecklist.find( { sourceCheckList_id: req.body.checklistId, checklistStatus: 'submit', date_iso: new Date( dayjs( req.body.date ).format( 'YYYY-MM-DD' ) ) }, {
|
|
3207
|
+
date_string: 1,
|
|
3208
|
+
checkListName: 1,
|
|
3209
|
+
createdByName: 1,
|
|
3210
|
+
store_id: 1,
|
|
3211
|
+
storeName: 1,
|
|
3212
|
+
submmitedBy: '$userName',
|
|
3213
|
+
submmitedByEmail: '$userEmail',
|
|
3214
|
+
checklistStatus: 1,
|
|
3215
|
+
submitTime: 1,
|
|
3216
|
+
approvalTime: 1,
|
|
3217
|
+
approvalTime_string: 1,
|
|
3218
|
+
approvalByName: 1,
|
|
3219
|
+
approvalByEmail: 1,
|
|
3220
|
+
} );
|
|
3207
3221
|
} else {
|
|
3208
|
-
details = await processedTaskService.find( { sourceCheckList_id: req.body.checklistId, date_iso: new Date( dayjs( req.body.date ).format( 'YYYY-MM-DD' ) ) }, {
|
|
3222
|
+
details = await processedTaskService.find( { sourceCheckList_id: req.body.checklistId, checklistStatus: 'submit', date_iso: new Date( dayjs( req.body.date ).format( 'YYYY-MM-DD' ) ) }, {
|
|
3223
|
+
date_string: 1,
|
|
3224
|
+
checkListName: 1,
|
|
3225
|
+
createdByName: 1,
|
|
3226
|
+
store_id: 1,
|
|
3227
|
+
storeName: 1,
|
|
3228
|
+
submmitedBy: '$userName',
|
|
3229
|
+
submmitedByEmail: '$userEmail',
|
|
3230
|
+
checklistStatus: 1,
|
|
3231
|
+
submitTime: 1,
|
|
3232
|
+
approvalTime: 1,
|
|
3233
|
+
approvalTime_string: 1,
|
|
3234
|
+
approvalByName: 1,
|
|
3235
|
+
approvalByEmail: 1,
|
|
3236
|
+
} );
|
|
3209
3237
|
}
|
|
3210
3238
|
return res.sendSuccess( details );
|
|
3211
3239
|
} catch ( e ) {
|
|
@@ -21,12 +21,19 @@ import * as clientService from '../services/clients.services.js';
|
|
|
21
21
|
import { create } from '../services/authentication.service.js';
|
|
22
22
|
import { readFileSync } from 'fs';
|
|
23
23
|
import { join } from 'path';
|
|
24
|
-
import handlebars from 'handlebars';
|
|
24
|
+
// import handlebars from 'handlebars';
|
|
25
25
|
dayjs.extend( customParseFormat );
|
|
26
26
|
dayjs.extend( timeZone );
|
|
27
27
|
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore.js';
|
|
28
28
|
import * as cameraService from '../services/camera.service.js';
|
|
29
29
|
dayjs.extend( isSameOrBefore );
|
|
30
|
+
import * as pdf from 'html-pdf';
|
|
31
|
+
import handlebars from './handlebar-helper.js';
|
|
32
|
+
import fs from 'fs';
|
|
33
|
+
import { fileURLToPath } from 'url';
|
|
34
|
+
import path from 'path';
|
|
35
|
+
const __filename = fileURLToPath( import.meta.url );
|
|
36
|
+
const __dirname = path.dirname( __filename );
|
|
30
37
|
|
|
31
38
|
export async function storeList( req, res ) {
|
|
32
39
|
try {
|
|
@@ -1082,7 +1089,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
|
|
|
1082
1089
|
|
|
1083
1090
|
if ( requestData.submittype == 'submit' ) {
|
|
1084
1091
|
reqAnswers.forEach( ( reqA ) => {
|
|
1085
|
-
if ( ![ 'multiplechoicemultiple', 'multipleImage' ].includes( reqA?.answerType ) ) {
|
|
1092
|
+
if ( ![ 'multiplechoicemultiple', 'multipleImage', 'image/video' ].includes( reqA?.answerType ) && ( reqA.answerType == 'dropDown' && !reqA.allowMultiple ) ) {
|
|
1086
1093
|
if ( ( !reqA.linkType && ( reqA.answer == null || reqA.answer == '' ) ) || ( reqA.linkType && reqA.linkquestionenabled && ( reqA.answer == null || reqA.answer == '' ) ) ) {
|
|
1087
1094
|
return res.sendError( 'Please Fill All Fields', 400 );
|
|
1088
1095
|
}
|
|
@@ -1220,7 +1227,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
|
|
|
1220
1227
|
structure.redoComment = qaAnswers[j]?.redoComment;
|
|
1221
1228
|
};
|
|
1222
1229
|
newArray.push( structure );
|
|
1223
|
-
} else if ( qaAnswers[j].answerType == 'multiplechoicesingle' ) {
|
|
1230
|
+
} else if ( qaAnswers[j].answerType == 'multiplechoicesingle' || ( qaAnswers[j].answerType == 'dropdown' && !qaAnswers[j].allowMultiple ) ) {
|
|
1224
1231
|
let qaans = qaAnswers[j].answers;
|
|
1225
1232
|
let ms = [];
|
|
1226
1233
|
for ( let k = 0; k < qaans.length; k++ ) {
|
|
@@ -1261,6 +1268,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
|
|
|
1261
1268
|
structure.questionReferenceImage = qaAnswers[j].questionReferenceImage || '';
|
|
1262
1269
|
structure.multiQuestionReferenceImage = qaAnswers[j].multiQuestionReferenceImage || [];
|
|
1263
1270
|
structure.descriptivetype = qaAnswers[j].descriptivetype;
|
|
1271
|
+
structure.allowMultiple = qaAnswers[j].allowMultiple;
|
|
1264
1272
|
// structure.parentQuestion = requestSection[i]?.parentQuestion || qaAnswers[j].qno;
|
|
1265
1273
|
structure.oldQname = qaAnswers[j]?.oldQname || qaAnswers[j].qname;
|
|
1266
1274
|
if ( qaAnswers[j]?.taskId ) {
|
|
@@ -1276,7 +1284,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
|
|
|
1276
1284
|
structure.redoComment = qaAnswers[j]?.redoComment;
|
|
1277
1285
|
};
|
|
1278
1286
|
newArray.push( structure );
|
|
1279
|
-
} else if ( qaAnswers[j].answerType == 'multiplechoicemultiple' ) {
|
|
1287
|
+
} else if ( qaAnswers[j].answerType == 'multiplechoicemultiple' || ( qaAnswers[j].answerType == 'dropdown' && qaAnswers[j].allowMultiple ) ) {
|
|
1280
1288
|
let qaans = qaAnswers[j].answers;
|
|
1281
1289
|
let mcmo = [];
|
|
1282
1290
|
for ( let k = 0; k < qaans.length; k++ ) {
|
|
@@ -1321,6 +1329,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
|
|
|
1321
1329
|
structure.questionReferenceImage = qaAnswers[j].questionReferenceImage || '';
|
|
1322
1330
|
structure.multiQuestionReferenceImage = qaAnswers[j].multiQuestionReferenceImage || [];
|
|
1323
1331
|
structure.descriptivetype = qaAnswers[j].descriptivetype;
|
|
1332
|
+
structure.allowMultiple = qaAnswers[j].allowMultiple;
|
|
1324
1333
|
// structure.parentQuestion = requestSection[i]?.parentQuestion || qaAnswers[j].qno;
|
|
1325
1334
|
structure.oldQname = qaAnswers[j]?.oldQname || qaAnswers[j].qname;
|
|
1326
1335
|
if ( qaAnswers[j]?.taskId ) {
|
|
@@ -1336,7 +1345,7 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
|
|
|
1336
1345
|
structure.redoComment = qaAnswers[j]?.redoComment;
|
|
1337
1346
|
};
|
|
1338
1347
|
newArray.push( structure );
|
|
1339
|
-
} else if ( qaAnswers[j].answerType
|
|
1348
|
+
} else if ( [ 'image/video', 'multipleImage' ].includes( qaAnswers[j].answerType ) ) {
|
|
1340
1349
|
let separatedArray = typeof requestSection[i].Multianswer == 'string' ? JSON.parse( requestSection[i].Multianswer ) : requestSection[i].Multianswer;
|
|
1341
1350
|
let mcmi = [];
|
|
1342
1351
|
// for (let k = 0; k < qaans.length; k++) {
|
|
@@ -1366,6 +1375,9 @@ export async function sopMobilechecklistMultiSectionFormatterv1( req, res, next
|
|
|
1366
1375
|
newAnswer.runAI = qaAnswers[j].answers[0]?.runAI || false;
|
|
1367
1376
|
newAnswer.runAIFeatures = qaAnswers[j].answers[0]?.runAIFeatures || [];
|
|
1368
1377
|
newAnswer.runAIDescription = qaAnswers[j].answers[0]?.runAIDescription || '';
|
|
1378
|
+
if ( qaAnswers[j].answerType == 'image/video' ) {
|
|
1379
|
+
newAnswer.answerType = separatedArray[s].answerType;
|
|
1380
|
+
}
|
|
1369
1381
|
mcmi.push( newAnswer );
|
|
1370
1382
|
}
|
|
1371
1383
|
}
|
|
@@ -2002,6 +2014,32 @@ export async function submitChecklist( req, res ) {
|
|
|
2002
2014
|
};
|
|
2003
2015
|
console.log( 'inserttraxlogs =>', inserttraxlogs );
|
|
2004
2016
|
insertOpenSearchData( openSearch.traxActivityLog, inserttraxlogs );
|
|
2017
|
+
let checklistDetails = await checklistService.findOne( { _id: getchecklist[0].sourceCheckList_id }, { notifyFlags: 1, approver: 1 } );
|
|
2018
|
+
if ( checklistDetails?.notifyFlags?.notifyType?.length ) {
|
|
2019
|
+
let emailList = checklistDetails?.notifyFlags?.notifyType.includes( 'approver' ) ? checklistDetails.approver.flatMap( ( ele ) => ele?.value ): [];
|
|
2020
|
+
emailList = [ ...emailList, ...checklistDetails?.notifyFlags?.notifyType?.users.flatMap( ( ele ) => ele?.value ) ];
|
|
2021
|
+
let data = {
|
|
2022
|
+
storeName: getchecklist[0].storeName,
|
|
2023
|
+
flagCount: updateData.questionFlag,
|
|
2024
|
+
checklistName: getchecklist[0].checkListName,
|
|
2025
|
+
submittedBy: getchecklist[0].userName,
|
|
2026
|
+
time: updateData.submitMobileTime,
|
|
2027
|
+
domain: JSON.parse( process.env.URL ).domain,
|
|
2028
|
+
};
|
|
2029
|
+
const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialExtentionEmail.hbs', 'utf8' );
|
|
2030
|
+
const template = Handlebars.compile( templateHtml );
|
|
2031
|
+
const html = template( { data: data } );
|
|
2032
|
+
emailList.forEach( ( email ) => {
|
|
2033
|
+
let params = {
|
|
2034
|
+
toEmail: email,
|
|
2035
|
+
mailSubject: 'TangoEye | Checklist Flag',
|
|
2036
|
+
htmlBody: html,
|
|
2037
|
+
attachment: '',
|
|
2038
|
+
sourceEmail: JSON.parse( process.env.SES ).adminEmail,
|
|
2039
|
+
};
|
|
2040
|
+
sendEmailWithSES( params.toEmail, params.mailSubject, params.htmlBody, params.attachment, params.sourceEmail );
|
|
2041
|
+
} );
|
|
2042
|
+
}
|
|
2005
2043
|
}
|
|
2006
2044
|
|
|
2007
2045
|
return res.sendSuccess( 'Checklist Updated Successfully' );
|
|
@@ -3230,6 +3268,7 @@ export async function questionList( req, res ) {
|
|
|
3230
3268
|
startTime: { $ifNull: [ '$startTime', '' ] },
|
|
3231
3269
|
submitTime: { $ifNull: [ '$submitTime', '' ] },
|
|
3232
3270
|
allowedOverTime: { $ifNull: [ '$allowedOverTime', '' ] },
|
|
3271
|
+
sourceCheckList_id: 1,
|
|
3233
3272
|
// allowedStoreLocation: { $ifNull: [ '$allowedStoreLocation', '' ] },
|
|
3234
3273
|
allowedStoreLocation: {
|
|
3235
3274
|
$cond: {
|
|
@@ -3285,7 +3324,7 @@ export async function questionList( req, res ) {
|
|
|
3285
3324
|
}
|
|
3286
3325
|
|
|
3287
3326
|
for ( let [ ansIndex, answer ] of question.answers.entries() ) {
|
|
3288
|
-
if ( question.answerType == 'multiplechoicemultiple' ) {
|
|
3327
|
+
if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
|
|
3289
3328
|
let checkvalidation = null;
|
|
3290
3329
|
if ( answer.validationAnswer && answer.validationAnswer !='' ) {
|
|
3291
3330
|
if ( answer.validationType != 'Descriptive Answer' ) {
|
|
@@ -3339,24 +3378,24 @@ export async function questionList( req, res ) {
|
|
|
3339
3378
|
getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].multiReferenceImage = userAns.multiReferenceImage;
|
|
3340
3379
|
}
|
|
3341
3380
|
|
|
3342
|
-
if ( question.answerType == 'multiplechoicemultiple' ) {
|
|
3381
|
+
if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
|
|
3343
3382
|
let ansIndex = Multianswer.findIndex( ( item ) => item.answer == userAns.answer );
|
|
3344
3383
|
if ( ansIndex ) {
|
|
3345
3384
|
Multianswer[ansIndex].validationAnswer = userAns.validationAnswer;
|
|
3346
3385
|
}
|
|
3347
3386
|
}
|
|
3348
|
-
if (
|
|
3387
|
+
if ( [ 'image/video', 'multipleImage' ].includes( question.answerType ) ) {
|
|
3349
3388
|
if ( userAns && userAns.answer && userAns.answer !='' ) {
|
|
3350
3389
|
// let manswer = await signedUrl( { file_path: decodeURIComponent( userAns.answer ), Bucket: bucket.sop } );
|
|
3351
3390
|
let manswer = `${cdnurl.TraxAnswerCDN}${userAns.answer}`;
|
|
3352
|
-
Multianswer.push( { 'answer': manswer, 'no': userAnsIndex, 'validationAnswer': '' } );
|
|
3391
|
+
Multianswer.push( { 'answer': manswer, 'no': userAnsIndex, 'validationAnswer': '', ...( question.answerType == 'image/video' && { answerType: userAns?.answerType } ) } );
|
|
3353
3392
|
} else {
|
|
3354
3393
|
|
|
3355
3394
|
}
|
|
3356
3395
|
}
|
|
3357
3396
|
}
|
|
3358
3397
|
}
|
|
3359
|
-
if ( question.answerType == 'multiplechoicemultiple' ) {
|
|
3398
|
+
if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
|
|
3360
3399
|
Multianswer.forEach( ( item ) => {
|
|
3361
3400
|
if ( item.validationAnswer == null ) {
|
|
3362
3401
|
item.answer = null;
|
|
@@ -3368,11 +3407,11 @@ export async function questionList( req, res ) {
|
|
|
3368
3407
|
question.Multianswer = Multianswer;
|
|
3369
3408
|
}
|
|
3370
3409
|
}
|
|
3371
|
-
if (
|
|
3410
|
+
if ( [ 'image/video', 'multipleImage' ].includes( question.answerType ) ) {
|
|
3372
3411
|
if ( Multianswer.length ) {
|
|
3373
3412
|
question.Multianswer = Multianswer;
|
|
3374
3413
|
} else {
|
|
3375
|
-
Multianswer.push( { 'answer': null, 'no': 0, 'validationAnswer': null } );
|
|
3414
|
+
Multianswer.push( { 'answer': null, 'no': 0, 'validationAnswer': null, ...( question.answerType == 'image/video' && { answerType: null } ) } );
|
|
3376
3415
|
question.Multianswer = Multianswer;
|
|
3377
3416
|
}
|
|
3378
3417
|
}
|
|
@@ -3417,6 +3456,11 @@ export async function questionList( req, res ) {
|
|
|
3417
3456
|
}
|
|
3418
3457
|
}
|
|
3419
3458
|
|
|
3459
|
+
let checklisDetails = await checklistService.findOne( { _id: getchecklist?.[0]?.sourceCheckList_id }, { export: 1 } );
|
|
3460
|
+
if ( checklisDetails ) {
|
|
3461
|
+
getchecklist[0]['export'] = checklisDetails.export;
|
|
3462
|
+
}
|
|
3463
|
+
|
|
3420
3464
|
return res.sendSuccess( getchecklist );
|
|
3421
3465
|
}
|
|
3422
3466
|
} catch ( e ) {
|
|
@@ -4238,6 +4282,7 @@ export async function questionListV1( req, res ) {
|
|
|
4238
4282
|
startTime: { $ifNull: [ '$startTime', '' ] },
|
|
4239
4283
|
submitTime: { $ifNull: [ '$submitTime', '' ] },
|
|
4240
4284
|
allowedOverTime: { $ifNull: [ '$allowedOverTime', '' ] },
|
|
4285
|
+
sourceCheckList_id: { $ifNull: [ '$sourceCheckList_id', '' ] },
|
|
4241
4286
|
// allowedStoreLocation: { $ifNull: [ '$allowedStoreLocation', '' ] },
|
|
4242
4287
|
allowedStoreLocation: {
|
|
4243
4288
|
$cond: {
|
|
@@ -4293,7 +4338,7 @@ export async function questionListV1( req, res ) {
|
|
|
4293
4338
|
}
|
|
4294
4339
|
|
|
4295
4340
|
for ( let [ ansIndex, answer ] of question.answers.entries() ) {
|
|
4296
|
-
if ( question.answerType == 'multiplechoicemultiple' ) {
|
|
4341
|
+
if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
|
|
4297
4342
|
let checkvalidation = null;
|
|
4298
4343
|
if ( answer.validationAnswer && answer.validationAnswer !='' ) {
|
|
4299
4344
|
if ( answer.validationType != 'Descriptive Answer' ) {
|
|
@@ -4345,13 +4390,13 @@ export async function questionListV1( req, res ) {
|
|
|
4345
4390
|
|
|
4346
4391
|
getchecklist[0].questionAnswers[secIndex].questions[questionIndex].userAnswer[userAnsIndex].multiReferenceImage = userAns.multiReferenceImage;
|
|
4347
4392
|
}
|
|
4348
|
-
if ( question.answerType == 'multiplechoicemultiple' ) {
|
|
4393
|
+
if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
|
|
4349
4394
|
let ansIndex = Multianswer.findIndex( ( item ) => item.answer == userAns.answer );
|
|
4350
4395
|
if ( ansIndex ) {
|
|
4351
4396
|
Multianswer[ansIndex].validationAnswer = userAns.validationAnswer;
|
|
4352
4397
|
}
|
|
4353
4398
|
}
|
|
4354
|
-
if ( question.answerType == 'multipleImage' ) {
|
|
4399
|
+
if ( question.answerType == 'multipleImage' || question.answerType == 'image/video' ) {
|
|
4355
4400
|
if ( userAns && userAns.answer && userAns.answer !='' ) {
|
|
4356
4401
|
let manswer = `${cdnurl.TraxAnswerCDN}${userAns.answer}`;
|
|
4357
4402
|
Multianswer.push( { 'answer': manswer, 'no': userAnsIndex, 'validationAnswer': '' } );
|
|
@@ -4361,7 +4406,7 @@ export async function questionListV1( req, res ) {
|
|
|
4361
4406
|
}
|
|
4362
4407
|
}
|
|
4363
4408
|
}
|
|
4364
|
-
if ( question.answerType == 'multiplechoicemultiple' ) {
|
|
4409
|
+
if ( question.answerType == 'multiplechoicemultiple' || ( question.answerType == 'dropdown' && question.allowMultiple ) ) {
|
|
4365
4410
|
Multianswer.forEach( ( item ) => {
|
|
4366
4411
|
if ( item.validationAnswer == null ) {
|
|
4367
4412
|
item.answer = null;
|
|
@@ -4373,7 +4418,7 @@ export async function questionListV1( req, res ) {
|
|
|
4373
4418
|
question.Multianswer = Multianswer;
|
|
4374
4419
|
}
|
|
4375
4420
|
}
|
|
4376
|
-
if ( question.answerType == 'multipleImage' ) {
|
|
4421
|
+
if ( question.answerType == 'multipleImage' || question.answerType == 'image/video' ) {
|
|
4377
4422
|
if ( Multianswer.length ) {
|
|
4378
4423
|
question.Multianswer = Multianswer;
|
|
4379
4424
|
} else {
|
|
@@ -4422,6 +4467,11 @@ export async function questionListV1( req, res ) {
|
|
|
4422
4467
|
}
|
|
4423
4468
|
}
|
|
4424
4469
|
|
|
4470
|
+
let checklisDetails = await checklistService.findOne( { _id: getchecklist?.[0]?.sourceCheckList_id }, { export: 1 } );
|
|
4471
|
+
if ( checklisDetails ) {
|
|
4472
|
+
getchecklist[0]['export'] = checklisDetails.export;
|
|
4473
|
+
}
|
|
4474
|
+
|
|
4425
4475
|
return res.sendSuccess( getchecklist );
|
|
4426
4476
|
}
|
|
4427
4477
|
} catch ( e ) {
|
|
@@ -4484,3 +4534,135 @@ export async function chunkUpload( req, res ) {
|
|
|
4484
4534
|
return res.sendError( e, 500 );
|
|
4485
4535
|
}
|
|
4486
4536
|
}
|
|
4537
|
+
|
|
4538
|
+
export async function downloadChecklist( req, res ) {
|
|
4539
|
+
try {
|
|
4540
|
+
let requestData = req.body;
|
|
4541
|
+
|
|
4542
|
+
if ( !requestData.checklistId ) {
|
|
4543
|
+
res.sendBadRequest( 'checklistId is Required' );
|
|
4544
|
+
}
|
|
4545
|
+
|
|
4546
|
+
let checklistDetails;
|
|
4547
|
+
|
|
4548
|
+
if ( requestData.type == 'checklist' ) {
|
|
4549
|
+
checklistDetails = await processedchecklist.findOne( { _id: requestData.checklistId, checklistStatus: 'submit' } );
|
|
4550
|
+
} else {
|
|
4551
|
+
checklistDetails = await processedTask.findOne( { _id: requestData.checklistId, checklistStatus: 'submit' } );
|
|
4552
|
+
}
|
|
4553
|
+
|
|
4554
|
+
if ( !checklistDetails ) {
|
|
4555
|
+
return res.sendError( 'No data found', 204 );
|
|
4556
|
+
}
|
|
4557
|
+
|
|
4558
|
+
let storeDetails = await storeService.findOne( { storeId: checklistDetails.store_id }, { storeProfile: 1 } );
|
|
4559
|
+
if ( !storeDetails ) {
|
|
4560
|
+
return res.sendError( 'No data found', 204 );
|
|
4561
|
+
}
|
|
4562
|
+
|
|
4563
|
+
let clientDetails = await clientService.findOne( { clientId: checklistDetails.client_id } );
|
|
4564
|
+
|
|
4565
|
+
if ( !clientDetails ) {
|
|
4566
|
+
return res.sendError( 'No client found', 204 );
|
|
4567
|
+
}
|
|
4568
|
+
|
|
4569
|
+
checklistDetails = { ...checklistDetails.toObject(), ...storeDetails?.toObject()?.storeProfile };
|
|
4570
|
+
|
|
4571
|
+
|
|
4572
|
+
let scheduleDateTime = dayjs( checklistDetails.submitTime );
|
|
4573
|
+
checklistDetails.submitDate = scheduleDateTime.format( 'DD MMM, YYYY' );
|
|
4574
|
+
checklistDetails.submitTime = scheduleDateTime.format( 'hh:mm A' );
|
|
4575
|
+
if ( clientDetails?.profileDetails?.logo ) {
|
|
4576
|
+
let bucketpath = checklistDetails.client_id + '/logo';
|
|
4577
|
+
|
|
4578
|
+
let params = {
|
|
4579
|
+
Bucket: JSON.parse( process.env.BUCKET )?.assets,
|
|
4580
|
+
file_path: `${bucketpath}/${clientDetails?.profileDetails?.logo}`,
|
|
4581
|
+
};
|
|
4582
|
+
let url = await signedUrl( params );
|
|
4583
|
+
let brandImage = await convertUrltoBase64( url );
|
|
4584
|
+
if ( brandImage ) {
|
|
4585
|
+
checklistDetails['brandLogo'] = brandImage;
|
|
4586
|
+
}
|
|
4587
|
+
}
|
|
4588
|
+
checklistDetails['brandName'] = clientDetails?.clientName;
|
|
4589
|
+
for ( let section of checklistDetails.questionAnswers ) {
|
|
4590
|
+
for ( let question of section.questions ) {
|
|
4591
|
+
question.remarks = question.remarks == null || question.remarks == 'null' ? '' : question.remarks;
|
|
4592
|
+
for ( let answer of question.userAnswer ) {
|
|
4593
|
+
if ( answer?.referenceImage?.trim() ) {
|
|
4594
|
+
let inputData = {
|
|
4595
|
+
Bucket: JSON.parse( process.env.BUCKET )?.sop,
|
|
4596
|
+
file_path: answer.referenceImage,
|
|
4597
|
+
};
|
|
4598
|
+
let url = await signedUrl( inputData );
|
|
4599
|
+
const base64Image = await convertUrltoBase64( url );
|
|
4600
|
+
if ( base64Image ) {
|
|
4601
|
+
answer.referenceImage = base64Image;
|
|
4602
|
+
}
|
|
4603
|
+
}
|
|
4604
|
+
if ( answer.validationType == 'Capture Image' && answer?.validationAnswer?.trim() ) {
|
|
4605
|
+
let inputData = {
|
|
4606
|
+
Bucket: JSON.parse( process.env.BUCKET )?.sop,
|
|
4607
|
+
file_path: answer.validationAnswer,
|
|
4608
|
+
};
|
|
4609
|
+
let url = await signedUrl( inputData );
|
|
4610
|
+
const base64Image = await convertUrltoBase64( url );
|
|
4611
|
+
if ( base64Image ) {
|
|
4612
|
+
answer.validationAnswer = base64Image;
|
|
4613
|
+
}
|
|
4614
|
+
}
|
|
4615
|
+
if ( answer?.answer?.trim() && [ 'image', 'descriptiveImage', 'multipleImage', 'image/video' ].includes( question.answerType ) ) {
|
|
4616
|
+
let inputData = {
|
|
4617
|
+
Bucket: JSON.parse( process.env.BUCKET )?.sop,
|
|
4618
|
+
file_path: answer.answer,
|
|
4619
|
+
};
|
|
4620
|
+
let url = await signedUrl( inputData );
|
|
4621
|
+
const base64Image = await convertUrltoBase64( url );
|
|
4622
|
+
if ( base64Image ) {
|
|
4623
|
+
answer.answer = base64Image;
|
|
4624
|
+
}
|
|
4625
|
+
}
|
|
4626
|
+
}
|
|
4627
|
+
}
|
|
4628
|
+
}
|
|
4629
|
+
const targetFolder = path.join( __dirname, '..', '/hbs/template.hbs' );
|
|
4630
|
+
const templateHtml = fs.readFileSync( targetFolder, 'utf8' );
|
|
4631
|
+
const template = handlebars.compile( templateHtml );
|
|
4632
|
+
const html = template( { data: checklistDetails } );
|
|
4633
|
+
pdf.create( html ).toBuffer( ( err, buffer ) => {
|
|
4634
|
+
if ( err ) {
|
|
4635
|
+
res.status( 500 ).send( 'Error Generating PDF' );
|
|
4636
|
+
} else {
|
|
4637
|
+
res.setHeader( 'Content-Disposition', 'attachment; filename=checkListDetails.pdf' );
|
|
4638
|
+
res.contentType( 'application/pdf' );
|
|
4639
|
+
res.send( buffer );
|
|
4640
|
+
}
|
|
4641
|
+
} );
|
|
4642
|
+
} catch ( e ) {
|
|
4643
|
+
console.log( 'getChecklistQuestionAnswers =>', e );
|
|
4644
|
+
return false;
|
|
4645
|
+
}
|
|
4646
|
+
}
|
|
4647
|
+
|
|
4648
|
+
async function convertUrltoBase64( url ) {
|
|
4649
|
+
try {
|
|
4650
|
+
const response = await fetch( url );
|
|
4651
|
+
|
|
4652
|
+
if ( !response.ok ) {
|
|
4653
|
+
throw new Error( 'Failed to fetch image' );
|
|
4654
|
+
}
|
|
4655
|
+
|
|
4656
|
+
const contentType = response.headers.get( 'content-type' );
|
|
4657
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
4658
|
+
|
|
4659
|
+
const base64Image =
|
|
4660
|
+
`data:${contentType};base64,` +
|
|
4661
|
+
Buffer.from( arrayBuffer ).toString( 'base64' );
|
|
4662
|
+
|
|
4663
|
+
return base64Image;
|
|
4664
|
+
} catch ( error ) {
|
|
4665
|
+
// console.error( 'Error fetching image:', error.message );
|
|
4666
|
+
return false;
|
|
4667
|
+
}
|
|
4668
|
+
}
|
|
@@ -26,6 +26,7 @@ import * as teamsServices from '../services/teams.service.js';
|
|
|
26
26
|
import * as runAIFeatureServices from '../services/runAIFeatures.services.js';
|
|
27
27
|
import * as runAIRequestServices from '../services/runAIRequest.services.js';
|
|
28
28
|
import * as processedTaskService from '../services/processedTaskList.service.js';
|
|
29
|
+
import ExcelJS from 'exceljs';
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
export const checklist = async ( req, res ) => {
|
|
@@ -5075,3 +5076,71 @@ export async function updateOSProcessedData( req, res ) {
|
|
|
5075
5076
|
return res.sendError( error, 500 );
|
|
5076
5077
|
}
|
|
5077
5078
|
}
|
|
5079
|
+
|
|
5080
|
+
export async function downloadQuestionTemplate( req, res ) {
|
|
5081
|
+
try {
|
|
5082
|
+
let questionDetails = await questionService.find( { checkListId: req.body.checklistId } );
|
|
5083
|
+
let answerType = {
|
|
5084
|
+
'descriptive': 'Descriptive Answer',
|
|
5085
|
+
'yes/no': 'A/B Question',
|
|
5086
|
+
'multiplechoicesingle': 'Multiple Choice Single',
|
|
5087
|
+
'multiplechoicemultiple': 'Multiple Choice Multiple',
|
|
5088
|
+
'descriptiveImage': 'Capture Image with Description',
|
|
5089
|
+
'image': 'Capture Image as answer',
|
|
5090
|
+
'video': 'Capture video as answer',
|
|
5091
|
+
'multipleImage': 'Capture Multiple Image',
|
|
5092
|
+
'date': 'Date',
|
|
5093
|
+
'linearscale': 'Linear Scale',
|
|
5094
|
+
'image/video': 'Capture Image/Video as Answer',
|
|
5095
|
+
'time': 'Time',
|
|
5096
|
+
'dropdown': 'Dropdown',
|
|
5097
|
+
};
|
|
5098
|
+
const workbook = new ExcelJS.Workbook();
|
|
5099
|
+
const sheet = workbook.addWorksheet( 'Fixture Library' );
|
|
5100
|
+
|
|
5101
|
+
sheet.getRow( 1 ).values = [ 'Section Name', 'Question', 'Answer Type', 'Answer Options' ];
|
|
5102
|
+
|
|
5103
|
+
let rowStart = 2;
|
|
5104
|
+
|
|
5105
|
+
questionDetails.forEach( ( section ) => {
|
|
5106
|
+
section.question.forEach( ( qn ) => {
|
|
5107
|
+
sheet.getRow( rowStart ).values = [ section.section, qn.qname, answerType[`${qn.answerType}`], [ 'multiplechoicesingle', 'multiplechoicemultiple', 'dropdown' ].includes( qn.answerType ) ? qn.answers.map( ( ans ) => ans.answer )?.toString() : '' ];
|
|
5108
|
+
rowStart += 1;
|
|
5109
|
+
} );
|
|
5110
|
+
} );
|
|
5111
|
+
|
|
5112
|
+
|
|
5113
|
+
const maxRows = 500000;
|
|
5114
|
+
|
|
5115
|
+
let dropDownRange = [ { key: `C2:C${maxRows}`, optionList: [ '"Descriptive Answer,A/B Question,Multiple Choice Single,Multiple Choice Multiple,Capture Image with Description,Capture Image as answer,Capture video as answer,Capture Multiple Image,Date,Linear Scale,Capture Image/Video as Answer,Time,Dropdown,"' ] } ];
|
|
5116
|
+
|
|
5117
|
+
dropDownRange.forEach( ( ele ) => {
|
|
5118
|
+
sheet.dataValidations.add( ele.key, {
|
|
5119
|
+
type: 'list',
|
|
5120
|
+
allowBlank: true,
|
|
5121
|
+
formulae: ele.optionList,
|
|
5122
|
+
showErrorMessage: true,
|
|
5123
|
+
errorTitle: 'Invalid Choice',
|
|
5124
|
+
error: 'Please select from the dropdown list.',
|
|
5125
|
+
} );
|
|
5126
|
+
} );
|
|
5127
|
+
|
|
5128
|
+
sheet.columns.forEach( ( column ) => {
|
|
5129
|
+
let maxLength = 10;
|
|
5130
|
+
column.eachCell( { includeEmpty: true }, ( cell ) => {
|
|
5131
|
+
const cellValue = cell.value ? cell.value.toString() : '';
|
|
5132
|
+
if ( cellValue.length > maxLength ) {
|
|
5133
|
+
maxLength = cellValue.length;
|
|
5134
|
+
}
|
|
5135
|
+
} );
|
|
5136
|
+
column.width = maxLength + 2;
|
|
5137
|
+
} );
|
|
5138
|
+
const buffer = await workbook.xlsx.writeBuffer();
|
|
5139
|
+
res.setHeader( 'Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' );
|
|
5140
|
+
res.setHeader( 'Content-Disposition', 'attachment; filename="Checklist Question.xlsx"' );
|
|
5141
|
+
return res.send( buffer );
|
|
5142
|
+
} catch ( e ) {
|
|
5143
|
+
logger.error( { functionName: 'downloadQuestionTemplate', error: e } );
|
|
5144
|
+
return res.sendError( e, 500 );
|
|
5145
|
+
}
|
|
5146
|
+
}
|