tango-app-api-trax 3.7.75 → 3.7.77

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-trax",
3
- "version": "3.7.75",
3
+ "version": "3.7.77",
4
4
  "description": "Trax",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -23,11 +23,13 @@
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.59",
31
+ "puppeteer": "^24.39.1",
32
+ "tango-api-schema": "^2.5.67",
31
33
  "tango-app-api-middleware": "^3.5.2",
32
34
  "url": "^0.11.4",
33
35
  "winston": "^3.13.1",
@@ -0,0 +1,31 @@
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
+ Handlebars.registerHelper( 'includes', function( array, value ) {
12
+ if ( !Array.isArray( array ) ) return false;
13
+ return array.includes( value );
14
+ } );
15
+
16
+ Handlebars.registerHelper( 'gte', function( a, b, options ) {
17
+ if ( options && options.fn ) {
18
+ return ( a >= b ) ? options.fn( this ) : options.inverse( this );
19
+ }
20
+ return a >= b;
21
+ } );
22
+
23
+ Handlebars.registerHelper( 'mult', function( a, b ) {
24
+ return Math.round( ( a || 0 ) * ( b || 1 ) );
25
+ } );
26
+
27
+ Handlebars.registerHelper( 'add', function( a, b ) {
28
+ return ( a || 0 ) + ( b || 0 );
29
+ } );
30
+
31
+ export default Handlebars;
@@ -595,6 +595,7 @@ export async function PCLconfigCreation( req, res ) {
595
595
  element4.remainder = getCLconfig?.remainder || [];
596
596
  element4.country = element4?.store?.[0]?.country || '';
597
597
  element4.state = element4?.store?.[0]?.state || '';
598
+ element4.complianceCount = getCLconfig?.complianceCount || 0;
598
599
 
599
600
  // if ( getCLconfig?.isPlano ) {
600
601
  // let planoDetails = await planoService.findOne( { storeId: element4.store_id, clientId: getCLconfig.client_id }, { _id: 1 } );
@@ -1362,6 +1363,42 @@ export async function insertTimeDelayFlags( req, res ) {
1362
1363
 
1363
1364
  let updatedDetails = await processedchecklist.updateMany( { _id: { $in: checklistId } }, { timeFlag: 1 } );
1364
1365
 
1366
+
1367
+ let notifyStores = await processedchecklist.find( { _id: { $in: checklistId }, notify: { $exists: false } } );
1368
+
1369
+ if ( notifyStores.length ) {
1370
+ Promise.all( notifyStores.map( async ( store ) => {
1371
+ let checklistDetails = await checklistService.findOne( { _id: store.sourceCheckList_id }, { notifyFlags: 1, approver: 1 } );
1372
+ if ( checklistDetails?.notifyFlags?.notifyType?.length ) {
1373
+ let emailList = checklistDetails?.notifyFlags?.notifyType.includes( 'approver' ) ? checklistDetails.approver.map( ( ele ) => ele?.value ): [];
1374
+ emailList = [ ...emailList, ...checklistDetails?.notifyFlags?.users?.map( ( ele ) => ele?.value ) ];
1375
+ let data = {
1376
+ storeName: store.storeName,
1377
+ flagCount: 1,
1378
+ checklistName: store.checkListName?.trim(),
1379
+ submittedBy: '--',
1380
+ time: '--',
1381
+ domain: `${JSON.parse( process.env.URL ).domain}/manage/trax/flags`,
1382
+ type: 'delay',
1383
+ };
1384
+ const fileContent = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/flag.hbs', 'utf8' );
1385
+ const htmlContent = handlebars.compile( fileContent );
1386
+ const html = htmlContent( { data: data } );
1387
+ emailList.forEach( ( email ) => {
1388
+ let params = {
1389
+ toEmail: email,
1390
+ mailSubject: 'TangoEye | Checklist Flag',
1391
+ htmlBody: html,
1392
+ attachment: '',
1393
+ sourceEmail: JSON.parse( process.env.SES ).adminEmail,
1394
+ };
1395
+ sendEmailWithSES( params.toEmail, params.mailSubject, params.htmlBody, params.attachment, params.sourceEmail );
1396
+ } );
1397
+ }
1398
+ await processedchecklist.updateOne( { _id: store._id }, { notify: true } );
1399
+ } ) );
1400
+ }
1401
+
1365
1402
  if ( updatedDetails ) {
1366
1403
  return res.sendSuccess( { message: 'Time Delay Updated Successfully' } );
1367
1404
  }
@@ -2715,8 +2752,13 @@ export async function updateChecklistConfig( req, res ) {
2715
2752
 
2716
2753
  export async function submittedList( req, res ) {
2717
2754
  try {
2755
+ let fromDate = new Date( dayjs().format( 'YYYY-MM-DD' ) );
2756
+ let toDate = new Date( dayjs().format( 'YYYY-MM-DD' ) );
2757
+ let userTimezoneOffset = toDate.getTimezoneOffset() * 60000;
2758
+ toDate = new Date( toDate.getTime() - userTimezoneOffset );
2759
+ toDate.setUTCHours( 23, 59, 59, 59 );
2718
2760
  let getSubmitChecklist = await processedchecklist.find( { checklistStatus: 'submit', date_iso: new Date( dayjs().format( 'YYYY-MM-DD' ) ) }, { _id: 1 } );
2719
- let getSubmitTask = await processedTaskService.find( { checklistStatus: 'submit', date_iso: new Date( dayjs().format( 'YYYY-MM-DD' ) ), isPlano: { $exists: false } }, { _id: 1 } );
2761
+ let getSubmitTask = await processedTaskService.find( { checklistStatus: 'submit', $or: [ { date_iso: new Date( dayjs().format( 'YYYY-MM-DD' ) ) }, { scheduleEndTime_iso: { $gte: fromDate, $lte: toDate } } ], isPlano: { $exists: false } }, { _id: 1 } );
2720
2762
 
2721
2763
  let result = [ ...getSubmitChecklist?.map( ( ele ) => ele?._id ), ...getSubmitTask?.map( ( ele ) => ele?._id ) ];
2722
2764
  return res.sendSuccess( result );
@@ -3203,9 +3245,37 @@ export async function checklistTaskSubmissionDetails( req, res ) {
3203
3245
  }
3204
3246
  let details = [];
3205
3247
  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' ) ) }, { submitTime: '$submitTime_string', status: '$checklistStatus', approvalStatus: '$approvalStatus', approvalTime: '$approvalTime_string', _id: 0 } );
3248
+ details = await processedchecklist.find( { sourceCheckList_id: req.body.checklistId, checklistStatus: 'submit', date_iso: new Date( dayjs( req.body.date ).format( 'YYYY-MM-DD' ) ) }, {
3249
+ date_string: 1,
3250
+ checkListName: 1,
3251
+ createdByName: 1,
3252
+ store_id: 1,
3253
+ storeName: 1,
3254
+ submmitedBy: '$userName',
3255
+ submmitedByEmail: '$userEmail',
3256
+ checklistStatus: 1,
3257
+ submitTime: 1,
3258
+ approvalTime: 1,
3259
+ approvalTime_string: 1,
3260
+ approvalByName: 1,
3261
+ approvalByEmail: 1,
3262
+ } );
3207
3263
  } else {
3208
- details = await processedTaskService.find( { sourceCheckList_id: req.body.checklistId, date_iso: new Date( dayjs( req.body.date ).format( 'YYYY-MM-DD' ) ) }, { submitTime: '$submitTime_string', status: '$checklistStatus', approvalStatus: '$approvalStatus', approvalTime: '$approvalTime_string', _id: 0 } );
3264
+ details = await processedTaskService.find( { sourceCheckList_id: req.body.checklistId, checklistStatus: 'submit', date_iso: new Date( dayjs( req.body.date ).format( 'YYYY-MM-DD' ) ) }, {
3265
+ date_string: 1,
3266
+ checkListName: 1,
3267
+ createdByName: 1,
3268
+ store_id: 1,
3269
+ storeName: 1,
3270
+ submmitedBy: '$userName',
3271
+ submmitedByEmail: '$userEmail',
3272
+ checklistStatus: 1,
3273
+ submitTime: 1,
3274
+ approvalTime: 1,
3275
+ approvalTime_string: 1,
3276
+ approvalByName: 1,
3277
+ approvalByEmail: 1,
3278
+ } );
3209
3279
  }
3210
3280
  return res.sendSuccess( details );
3211
3281
  } catch ( e ) {
@@ -3213,3 +3283,140 @@ export async function checklistTaskSubmissionDetails( req, res ) {
3213
3283
  return res.sendError( e, 500 );
3214
3284
  }
3215
3285
  }
3286
+
3287
+ export async function getStoreTaskDetails( req, res ) {
3288
+ try {
3289
+ const checklistQuery = [
3290
+ {
3291
+ $match: {
3292
+ storeName: req.body.storeName,
3293
+ checkListName: { $regex: 'Store Tour', $options: 'i' },
3294
+ },
3295
+ },
3296
+ {
3297
+ $group: {
3298
+ _id: '$storeName',
3299
+ checklistStatus: { $last: '$checklistStatus' },
3300
+ checkListName: { $last: '$checkListName' },
3301
+ scheduleEndTime_iso: { $last: '$scheduleEndTime_iso' },
3302
+ },
3303
+ },
3304
+ ];
3305
+ const checkListDetails = await processedchecklist.aggregate( checklistQuery );
3306
+ const taskQuery = [
3307
+ {
3308
+ $match: {
3309
+ storeName: req.body.storeName,
3310
+ isPlano: true,
3311
+ planoType: { $in: [ 'fixture', 'merchRollout', 'vmRollout' ] },
3312
+ },
3313
+ },
3314
+ {
3315
+ $group: {
3316
+ _id: { store: '$storeName', type: '$planoType' },
3317
+ checklistStatus: { $last: '$checklistStatus' },
3318
+ checkListName: { $last: '$checkListName' },
3319
+ scheduleEndTime_iso: { $last: '$scheduleEndTime_iso' },
3320
+ },
3321
+ },
3322
+ {
3323
+ $project: {
3324
+ store: '$_id.store',
3325
+ type: '$_id.type',
3326
+ checklistStatus: 1,
3327
+ checkListName: 1,
3328
+ scheduleEndTime_iso: 1,
3329
+ },
3330
+ },
3331
+ ];
3332
+
3333
+
3334
+ const taskDetails = await processedTaskService.aggregate( taskQuery );
3335
+ console.log( taskDetails );
3336
+ let info = [ ...checkListDetails, ...taskDetails ];
3337
+ // const details = {
3338
+ // storeTourVideoChecklist: ( !checkListDetails.length || checkListDetails?.[0]?.checklistStatus == 'submit' ) ? true : false,
3339
+ // FixtureVerification: ( !taskDetails.length || !taskDetails?.some( ( ele ) => ele?.type == 'fixture' ) || taskDetails?.some( ( ele ) => ele?.type == 'fixture' && ele?.checklistStatus == 'submit' ) ) ? true : false,
3340
+ // MerchRollout: ( !taskDetails.length || !taskDetails?.some( ( ele ) => ele?.type == 'merchRollout' ) || taskDetails?.some( ( ele ) => ele?.type == 'merchRollout' && ele?.checklistStatus == 'submit' ) ) ? true : false,
3341
+ // VmRollout: ( !taskDetails.length || !taskDetails?.some( ( ele ) => ele?.type == 'vmRollout' ) || taskDetails?.some( ( ele ) => ele?.type == 'vmRollout' && ele?.checklistStatus == 'submit' ) ) ? true : false,
3342
+ // };
3343
+
3344
+ let result = {
3345
+ storeId: req.body.storeName,
3346
+ tangoPosBlocks: info.filter( ( ele ) => ele.checklistStatus != 'submit' && dayjs( ele?.scheduleEndTime_iso ).format( 'YYYY-MM-DD' ) < dayjs().format( 'YYYY-MM-DD' ) ).map( ( ele ) => {
3347
+ return {
3348
+ blockName: ele?.checkListName,
3349
+ blockEnabled: true,
3350
+ blockReason: `${ele?.checkListName} is completed`,
3351
+ };
3352
+ } ),
3353
+ upcomingTangoPosBlocks: info.filter( ( ele ) => ele.checklistStatus !== 'submit' ).map( ( ele ) => {
3354
+ return {
3355
+ blockName: ele?.checkListName,
3356
+ blockReason: `Compelete ${ele?.checkListName} before ${dayjs( ele?.scheduleEndTime_iso ).format( 'YYYY-MM-DD' )} to avoid ABC block`,
3357
+ dueDate: dayjs( ele?.scheduleEndTime_iso ).format( 'YYYY-MM-DD' ),
3358
+ };
3359
+ } ),
3360
+ };
3361
+
3362
+
3363
+ return res.sendSuccess( result );
3364
+ } catch ( error ) {
3365
+ const err = error.message || 'Internal Server Error';
3366
+ logger.error( { error: error, message: req.body, function: 'getStoretaskDetails' } );
3367
+ return res.sendError( err, 500 );
3368
+ }
3369
+ }
3370
+
3371
+ export async function runAIFlag( req, res ) {
3372
+ try {
3373
+ let checklistDetails = await CLconfig.find( { publish: true, $expr: { $ne: [ { $size: '$notifyFlags.notifyType' }, 0 ] }, runAIQuestionCount: { $ne: 0 } }, { _id: 1 } );
3374
+ if ( checklistDetails.length ) {
3375
+ await Promise.all( checklistDetails.map( async ( ele ) => {
3376
+ let submitDetails = await processedchecklist.find( { sourceCheckList_id: ele._id, checklistStatus: 'submit' }, { storeName: 1, checkListName: 1, questionAnswers: 1 } );
3377
+ await Promise.all( submitDetails.map( ( store ) => {
3378
+ if ( questionAnswers.length ) {
3379
+ let runAIFlag = 0;
3380
+ questionAnswers.forEach( ( section ) => {
3381
+ section.questions.forEach( ( question ) => {
3382
+ if ( question.answerType == 'image' && ( question?.userAnswer?.[0]?.runAIDate.value == 'false' || !question?.userAnswer?.[0]?.runAIDate.value ) ) {
3383
+ runAIFlag++;
3384
+ }
3385
+ } );
3386
+ } );
3387
+
3388
+ if ( runAIFlag ) {
3389
+ let emailList = checklistDetails?.notifyFlags?.notifyType.includes( 'approver' ) ? checklistDetails.approver.map( ( ele ) => ele?.value ): [];
3390
+ emailList = [ ...emailList, ...checklistDetails?.notifyFlags?.users?.map( ( ele ) => ele?.value ) ];
3391
+ let data = {
3392
+ storeName: store.storeName,
3393
+ flagCount: 1,
3394
+ checklistName: store.checkListName?.trim(),
3395
+ submittedBy: '--',
3396
+ time: '--',
3397
+ domain: `${JSON.parse( process.env.URL ).domain}/manage/trax/flags`,
3398
+ type: 'delay',
3399
+ };
3400
+ const fileContent = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/flag.hbs', 'utf8' );
3401
+ const htmlContent = handlebars.compile( fileContent );
3402
+ const html = htmlContent( { data: data } );
3403
+ emailList.forEach( ( email ) => {
3404
+ let params = {
3405
+ toEmail: email,
3406
+ mailSubject: 'TangoEye | Checklist Flag',
3407
+ htmlBody: html,
3408
+ attachment: '',
3409
+ sourceEmail: JSON.parse( process.env.SES ).adminEmail,
3410
+ };
3411
+ sendEmailWithSES( params.toEmail, params.mailSubject, params.htmlBody, params.attachment, params.sourceEmail );
3412
+ } );
3413
+ }
3414
+ }
3415
+ } ) );
3416
+ } ) );
3417
+ }
3418
+ } catch ( e ) {
3419
+ logger.error( { functionName: 'runAIFlag', error: e } );
3420
+ return res.sendError( e, 500 );
3421
+ }
3422
+ }