tango-app-api-trax 3.7.91 → 3.7.92

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.91",
3
+ "version": "3.7.92",
4
4
  "description": "Trax",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -18,7 +18,7 @@ import timeZone from 'dayjs/plugin/timezone.js';
18
18
  import utc from 'dayjs/plugin/utc.js';
19
19
  import { logger } from 'tango-app-api-middleware';
20
20
  import mongoose from 'mongoose';
21
- import { sendPushNotification, sendAiPushNotification, sendEmailWithSES, signedUrl, fileUpload } from 'tango-app-api-middleware';
21
+ import { sendPushNotification, sendAiPushNotification, sendEmailWithSES, signedUrl, fileUpload, getOpenSearchData } from 'tango-app-api-middleware';
22
22
  // import * as planoService from '../services/planogram.service.js';
23
23
  import * as clusterServices from '../services/cluster.service.js';
24
24
  import * as teamsServices from '../services/teams.service.js';
@@ -3455,8 +3455,158 @@ async function getBrandInfo( clientId ) {
3455
3455
 
3456
3456
  export const downloadInsertPdf = async ( req, res ) => {
3457
3457
  try {
3458
- res.sendSuccess( 'PDF generation started' );
3458
+ if ( !req.body.checklistId ) {
3459
+ return res.sendError( 'Checklist Id is required', 400 );
3460
+ }
3461
+ const cdnBase = JSON.parse( process.env.CDNURL )?.TraxAnswerCDN || '';
3462
+ const pdfTemplate = getCompiledVisitChecklistTemplate();
3463
+ const imageCache = createImageCache();
3464
+
3465
+ const browser = await puppeteer.launch( {
3466
+ headless: 'new',
3467
+ args: [ '--no-sandbox', '--disable-dev-shm-usage' ],
3468
+ } );
3469
+
3470
+ try {
3471
+ const page = await browser.newPage();
3472
+
3473
+ await page.setViewport( {
3474
+ width: 1280,
3475
+ height: 1800,
3476
+ } );
3477
+
3478
+ const safeName = ( str ) =>
3479
+ ( str || '' ).toString().replace( /[<>:"/\\|?*]+/g, '_' );
3480
+
3481
+ let query = {
3482
+ query: {
3483
+ bool: {
3484
+ must: [
3485
+ {
3486
+ term: {
3487
+ _id: req.body.checklistId,
3488
+ },
3489
+ },
3490
+ ],
3491
+ },
3492
+ },
3493
+ };
3494
+
3495
+ let aiDetails = await getOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxIndex, query );
3496
+ if ( aiDetails?.statusCode != 200 || !aiDetails?.body?.hits?.hits.length ) {
3497
+ return res.sendError( 'Checklist not found', 404 );
3498
+ }
3459
3499
 
3500
+ const doc = { ...aiDetails.body.hits.hits[0]._source };
3501
+
3502
+ const brandInfo = await getBrandInfo( doc.client_id );
3503
+
3504
+ const detectionPayload = {
3505
+ 'storeId': [ doc.store_id ],
3506
+ 'userEmail': doc.userEmail,
3507
+ 'sourceChecklist_id': doc.sourceCheckList_id,
3508
+ };
3509
+
3510
+ let complianceURL = JSON.parse( process.env.LAMBDAURL ).complianceHistory;
3511
+ const complianceData = await LamdaServiceCall( complianceURL, detectionPayload );
3512
+ if ( complianceData?.data.length ) {
3513
+ doc['historyData'] = complianceData.data;
3514
+ }
3515
+ // CDN fix
3516
+ ( doc.questionAnswers || [] ).forEach( ( section ) => {
3517
+ ( section.questions || [] ).forEach( ( question ) => {
3518
+ ( question.userAnswer || [] ).forEach( ( answer ) => {
3519
+ if ( answer?.referenceImage?.trim() ) {
3520
+ answer.referenceImage =
3521
+ cdnBase + answer.referenceImage;
3522
+ }
3523
+ } );
3524
+ } );
3525
+ } );
3526
+
3527
+ const templateData = buildVisitChecklistTemplateData(
3528
+ doc,
3529
+ brandInfo,
3530
+ );
3531
+
3532
+ const resolvedData = resolveTemplateUrls( templateData, cdnBase );
3533
+ await imageCache.resolveAllImages( resolvedData );
3534
+
3535
+ const html = pdfTemplate( resolvedData );
3536
+
3537
+ try {
3538
+ await page.setContent( html, {
3539
+ waitUntil: 'networkidle0',
3540
+ timeout: 30000,
3541
+ } );
3542
+
3543
+ await page.emulateMediaType( 'screen' );
3544
+ } catch ( err ) {
3545
+ logger.error( { functionName: 'setContent failed:', error: err } );
3546
+ }
3547
+
3548
+ let pdfBuffer;
3549
+
3550
+ try {
3551
+ pdfBuffer = await page.pdf( {
3552
+ format: 'A4',
3553
+ printBackground: true,
3554
+ margin: { top: '10mm', right: '10mm', bottom: '10mm', left: '10mm' },
3555
+ } );
3556
+ } catch ( err ) {
3557
+ logger.error( { functionName: 'downloadInsertPdfOld', message: 'PDF generation failed', error: err } );
3558
+ return res.sendError( 'PDF generation failed', 500 );
3559
+ }
3560
+
3561
+ if ( !pdfBuffer || pdfBuffer.length === 0 ) {
3562
+ logger.error( { functionName: 'downloadInsertPdfOld', message: 'Empty PDF', docId: doc._id } );
3563
+ return res.sendError( 'PDF generation resulted in empty buffer', 500 );
3564
+ }
3565
+
3566
+ const finalBuffer = Buffer.isBuffer( pdfBuffer ) ?
3567
+ pdfBuffer :
3568
+ Buffer.from( pdfBuffer );
3569
+
3570
+ const pdfName = `${safeName(
3571
+ doc.storeName || doc.store_id || doc._id || 'store',
3572
+ )}.pdf`;
3573
+
3574
+ res.set( {
3575
+ 'Content-Type': 'application/pdf',
3576
+ 'Content-Disposition': `attachment; filename="${pdfName}"`,
3577
+ 'Content-Length': finalBuffer.length,
3578
+ } );
3579
+
3580
+ return res.send( finalBuffer );
3581
+ } finally {
3582
+ await browser.close();
3583
+ }
3584
+ } catch ( e ) {
3585
+ console.log( e );
3586
+ logger.error( { functionName: 'downloadInsertPdfOld', error: e } );
3587
+ return res.sendError( e, 500 );
3588
+ }
3589
+ };
3590
+
3591
+ export async function checklistAutoMailList( req, res ) {
3592
+ try {
3593
+ const checklistInfoList = await CLconfig.find( {
3594
+ 'autoEmail.type': { $exists: true },
3595
+ '$expr': {
3596
+ $gt: [ { $size: { $ifNull: [ '$autoEmail.type', [] ] } }, 0 ],
3597
+ },
3598
+ }, { _id: 1 } );
3599
+
3600
+ return res.sendSuccess( checklistInfoList?.map( ( ele ) => ele?._id ) );
3601
+ } catch ( e ) {
3602
+ logger.error( { functionName: 'checklistAutoMailList', error: e } );
3603
+ return res.sendError( e, 500 );
3604
+ }
3605
+ }
3606
+
3607
+
3608
+ export const downloadInsertPdfOld = async ( req, res ) => {
3609
+ try {
3460
3610
  setImmediate( async () => {
3461
3611
  try {
3462
3612
  const cdnBase = JSON.parse( process.env.CDNURL )?.TraxAnswerCDN || '';
@@ -3596,11 +3746,10 @@ export const downloadInsertPdf = async ( req, res ) => {
3596
3746
 
3597
3747
  try {
3598
3748
  await page.setContent( html, {
3599
- waitUntil: 'domcontentloaded',
3600
- timeout: 0,
3749
+ waitUntil: 'networkidle0',
3750
+ timeout: 30000,
3601
3751
  } );
3602
3752
 
3603
- await new Promise( ( r ) => setTimeout( r, 300 ) );
3604
3753
  await page.emulateMediaType( 'screen' );
3605
3754
  } catch ( err ) {
3606
3755
  logger.error( { functionName: 'setContent failed:', error: err } );
@@ -38,6 +38,7 @@ internalTraxRouter
38
38
  .post( '/posblock', isAllowedInternalAPIHandler, internalController.getStoreTaskDetails )
39
39
  .post( '/runAIFlag', isAllowedInternalAPIHandler, internalController.runAIFlag )
40
40
  .post( '/downloadInsertPdf', isAllowedInternalAPIHandler, internalController.downloadInsertPdf )
41
+ .post( '/checklistAutoMailList', isAllowedInternalAPIHandler, internalController.checklistAutoMailList )
41
42
  ;
42
43
 
43
44