tango-app-api-payment-subscription 3.0.44-dev → 3.0.45-dev

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-payment-subscription",
3
- "version": "3.0.44-dev",
3
+ "version": "3.0.45-dev",
4
4
  "description": "paymentSubscription",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -25,7 +25,7 @@
25
25
  "mongodb": "^6.4.0",
26
26
  "nodemon": "^3.1.0",
27
27
  "swagger-ui-express": "^5.0.0",
28
- "tango-api-schema": "^2.0.91",
28
+ "tango-api-schema": "^2.0.103",
29
29
  "tango-app-api-middleware": "^1.0.60-dev",
30
30
  "winston": "^3.12.0",
31
31
  "winston-daily-rotate-file": "^5.0.0"
@@ -1,6 +1,6 @@
1
1
 
2
2
  /* eslint-disable new-cap */
3
- import { logger, download, sendEmailWithSES, appConfig, insertOpenSearchData } from 'tango-app-api-middleware';
3
+ import { logger, download, sendEmailWithSES, appConfig, insertOpenSearchData, getOpenSearchData, updateOpenSearchData, getOpenSearchById } from 'tango-app-api-middleware';
4
4
  import * as paymentService from '../services/clientPayment.services.js';
5
5
  import * as basePriceService from '../services/basePrice.service.js';
6
6
  import * as storeService from '../services/store.service.js';
@@ -47,7 +47,7 @@ export const addBilling = async ( req, res ) => {
47
47
  changes: [ 'Billing Address', 'Gst Number' ],
48
48
  eventType: 'update',
49
49
  };
50
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
50
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
51
51
  return res.sendSuccess( { message: 'Billing Details Added Successfully', data: resultData } );
52
52
  } else {
53
53
  logger.error( 'Error Occurs WHile updating billing Details' );
@@ -430,7 +430,7 @@ export const updateSubscription = async ( req, res ) => {
430
430
  changes: [ 'Name', 'Description', 'Category' ],
431
431
  eventType: 'insert',
432
432
  };
433
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
433
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
434
434
  }
435
435
  }
436
436
  if ( item.type == 'subscription' ) {
@@ -440,6 +440,25 @@ export const updateSubscription = async ( req, res ) => {
440
440
  subscribedDate: new Date(),
441
441
  status: 'live',
442
442
  } );
443
+ let productObj = {
444
+ userName: req.user?.userName,
445
+ email: req.user?.email,
446
+ clientId: requestBody.clientId,
447
+ clientNotification: false,
448
+ adminNotification: true,
449
+ logSubType: 'Your subscription is now active! Get ready to maximize your instore sales potential with the Tangoeye suite',
450
+ category: 'Brand Activity Log',
451
+ features: 'Subscription',
452
+ // title: 'Subscribed',
453
+ alertCta: [],
454
+ markasRead: false,
455
+ logType: 'Subscribed',
456
+ showPushNotification: true,
457
+ changes: [ 'Plan Details', 'Price', 'Price Type' ],
458
+ eventType: 'update',
459
+ date: new Date(),
460
+ };
461
+ insertOpenSearchData( appConfig.opensearch.activityLog, productObj );
443
462
  } else {
444
463
  clientProducts[existsIndex].status = 'live';
445
464
  clientProducts[existsIndex].subscribedDate = new Date();
@@ -492,17 +511,17 @@ export const updateSubscription = async ( req, res ) => {
492
511
  };
493
512
 
494
513
  let result = await paymentService.updateOne( { clientId: req.params.clientId }, data );
495
- const logObj = {
496
- clientId: req.body.clientId,
497
- userName: req.user?.userName,
498
- email: req.user?.email,
499
- date: new Date(),
500
- logType: 'billing',
501
- logSubType: 'Subscrption Details updated',
502
- changes: [ 'Plan Details', 'Price', 'Price Type' ],
503
- eventType: 'update',
504
- };
505
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
514
+ // const logObj = {
515
+ // clientId: req.body.clientId,
516
+ // userName: req.user?.userName,
517
+ // email: req.user?.email,
518
+ // date: new Date(),
519
+ // logType: 'billing',
520
+ // logSubType: 'Subscrption Details updated',
521
+ // changes: [ 'Plan Details', 'Price', 'Price Type' ],
522
+ // eventType: 'update',
523
+ // };
524
+ // insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
506
525
  let storeProduct = clientProducts.map( ( item ) => item.productName );
507
526
  await storeService.updateMany( { clientId: req.params.clientId }, { product: storeProduct } );
508
527
 
@@ -623,7 +642,7 @@ export const unsubscribeProduct = async ( req, res ) => {
623
642
  changes: [ 'Reason', 'Description', 'Category' ],
624
643
  eventType: 'insert',
625
644
  };
626
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
645
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
627
646
 
628
647
  return res.sendSuccess( 'Request Send Successfully' );
629
648
  } catch ( e ) {
@@ -657,7 +676,7 @@ export const trialExtendRequest = async ( req, res ) => {
657
676
  changes: [ 'Name', 'Description', 'Category' ],
658
677
  eventType: 'insert',
659
678
  };
660
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
679
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
661
680
 
662
681
  return res.sendSuccess( 'Request Send Successfully' );
663
682
  } catch ( e ) {
@@ -693,7 +712,7 @@ export const trialRequest = async ( req, res ) => {
693
712
  changes: [ 'Name', 'Description', 'Category' ],
694
713
  eventType: 'insert',
695
714
  };
696
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
715
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
697
716
 
698
717
  return res.sendSuccess( 'Request Send Successfully' );
699
718
  } catch ( e ) {
@@ -764,7 +783,7 @@ export const updateInvoiceDetails = async ( req, res ) => {
764
783
  changes: [ 'Pro Rate', 'Payment Type', 'Payment Cycle', 'Currency Type', 'Invoice To', 'Payment Agreement To', 'Invoice On', 'Extend Payment PeriodDays' ],
765
784
  eventType: 'update',
766
785
  };
767
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
786
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
768
787
  return res.sendSuccess( 'Invoice Updated Successfully' );
769
788
  } ).catch( ( e ) => {
770
789
  return res.sendError( e, 500 );
@@ -862,6 +881,25 @@ export const trialApproval = async ( req, res ) => {
862
881
  requestData.status = 'completed';
863
882
  requestData.save().then( async () => {
864
883
  if ( req.body.type == 'approve' ) {
884
+ let logObj = {
885
+ userName: req.user?.userName,
886
+ email: req.user?.email,
887
+ clientId: requestData.clientId,
888
+ clientNotification: false,
889
+ adminNotification: true,
890
+ logSubType: 'Subscription - Your 14 Days free trial has been started',
891
+ category: 'Brand Activity Log',
892
+ features: 'Subscription',
893
+ // title: 'Start Trial',
894
+ alertCta: [],
895
+ markasRead: false,
896
+ logType: 'Start Trial',
897
+ showPushNotification: true,
898
+ date: new Date(),
899
+ changes: [ 'Plan Details' ],
900
+ eventType: 'update',
901
+ };
902
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
865
903
  let clientProducts = await paymentService.findOne( { clientId: requestData.clientId }, { planDetails: 1 } );
866
904
  if ( clientProducts?.planDetails.subscriptionType == 'free' ) {
867
905
  clientProducts.planDetails.subscriptionType = 'premium';
@@ -943,17 +981,17 @@ export const trialApproval = async ( req, res ) => {
943
981
  logger.error( { error: error, function: 'oldBulkStoreUpdate' } );
944
982
  } );
945
983
  }
946
- const logObj = {
947
- clientId: req.body.clientId,
948
- userName: req.user?.userName,
949
- email: req.user?.email,
950
- date: new Date(),
951
- logType: 'billing',
952
- logSubType: 'Trial Approved',
953
- changes: [ 'status' ],
954
- eventType: 'update',
955
- };
956
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
984
+ // const logObj = {
985
+ // clientId: req.body.clientId,
986
+ // userName: req.user?.userName,
987
+ // email: req.user?.email,
988
+ // date: new Date(),
989
+ // logType: 'billing',
990
+ // logSubType: 'Trial Approved',
991
+ // changes: [ 'status' ],
992
+ // eventType: 'update',
993
+ // };
994
+ // insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
957
995
  return res.sendSuccess( 'updated Successfully' );
958
996
  } );
959
997
  } catch ( e ) {
@@ -1005,17 +1043,36 @@ export const trialExtendRequestApproval = async ( req, res ) => {
1005
1043
  };
1006
1044
  sendEmailWithSES( params.toEmail, params.mailSubject, params.htmlBody, params.attachment, params.sourceEmail );
1007
1045
  }
1008
- const logObj = {
1009
- clientId: req.body.clientId,
1046
+ let notifyObj = {
1010
1047
  userName: req.user?.userName,
1011
1048
  email: req.user?.email,
1049
+ clientId: req.body.clientId,
1050
+ clientNotification: false,
1051
+ adminNotification: true,
1052
+ logSubType: `Your Trial has been extended for ${req.body.days} days, explore the service with no extra charge and keep unlocking better insights`,
1053
+ category: 'Brand Activity Log',
1054
+ features: 'Subscription',
1055
+ // title: 'Trial Extend',
1056
+ alertCta: [],
1057
+ markasRead: false,
1058
+ logType: 'Trial Extend',
1059
+ showPushNotification: true,
1012
1060
  date: new Date(),
1013
- logType: 'billing',
1014
- logSubType: 'Trial Extend Approved',
1015
1061
  changes: [ 'status' ],
1016
1062
  eventType: 'update',
1017
1063
  };
1018
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
1064
+ insertOpenSearchData( appConfig.opensearch.activityLog, notifyObj );
1065
+ // const logObj = {
1066
+ // clientId: req.body.clientId,
1067
+ // userName: req.user?.userName,
1068
+ // email: req.user?.email,
1069
+ // date: new Date(),
1070
+ // logType: 'billing',
1071
+ // logSubType: 'Trial Extend Approved',
1072
+ // changes: [ 'status' ],
1073
+ // eventType: 'update',
1074
+ // };
1075
+ // insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
1019
1076
  return res.sendSuccess( 'Trial Extended Successfully' );
1020
1077
  } ).catch( ( e ) => {
1021
1078
  logger.error( { error: e, function: 'trialExtendRequestApproval' } );
@@ -1054,9 +1111,29 @@ export const productSubscribe = async ( req, res ) => {
1054
1111
  for ( let item of req.body.product ) {
1055
1112
  if ( productList.includes( item.name ) && item.type == 'unsubscribe' ) {
1056
1113
  await storeService.addremoveElement( { clientId: clientInfo.clientId, product: { $in: item.name } }, { $pull: { product: item.name } } );
1114
+ await clientRequestService.deleteOne( { clientId: clientInfo.clientId, status: 'pending', name: item.name } );
1057
1115
  }
1058
1116
  if ( !productList.includes( item.name ) && [ 'trial', 'subscription' ].includes( item.type ) ) {
1059
1117
  if ( item.type == 'trial' ) {
1118
+ let logObj = {
1119
+ userName: req.user?.userName,
1120
+ email: req.user?.email,
1121
+ clientId: clientInfo.clientId,
1122
+ clientNotification: false,
1123
+ adminNotification: true,
1124
+ logSubType: 'Subscription - Your 14 Days free trial has been started',
1125
+ category: 'Brand Activity Log',
1126
+ features: 'Subscription',
1127
+ // title: 'Start Trial',
1128
+ alertCta: [],
1129
+ markasRead: false,
1130
+ logType: 'Start Trial',
1131
+ showPushNotification: true,
1132
+ date: new Date(),
1133
+ changes: [ 'Plan Details' ],
1134
+ eventType: 'update',
1135
+ };
1136
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
1060
1137
  product.push( {
1061
1138
  productName: item.name,
1062
1139
  trialStartDate: new Date(),
@@ -1068,6 +1145,25 @@ export const productSubscribe = async ( req, res ) => {
1068
1145
  let productName = firstWord + ' ' + secondWord;
1069
1146
  trialProduct.push( productName );
1070
1147
  } else {
1148
+ let logObj = {
1149
+ userName: req.user?.userName,
1150
+ email: req.user?.email,
1151
+ clientId: clientInfo.clientId,
1152
+ clientNotification: false,
1153
+ adminNotification: true,
1154
+ logSubType: 'Your subscription is now active! Get ready to maximize your instore sales potential with the Tangoeye suite',
1155
+ category: 'Brand Activity Log',
1156
+ features: 'Subscription',
1157
+ // title: 'Subscribed',
1158
+ alertCta: [],
1159
+ markasRead: false,
1160
+ logType: 'Subscribed',
1161
+ showPushNotification: true,
1162
+ date: new Date(),
1163
+ changes: [ 'Plan Details' ],
1164
+ eventType: 'update',
1165
+ };
1166
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
1071
1167
  product.push( {
1072
1168
  productName: item.name,
1073
1169
  subscribedDate: new Date(),
@@ -1170,17 +1266,17 @@ export const productSubscribe = async ( req, res ) => {
1170
1266
  logger.error( { error: error, function: 'oldBulkStoreUpdate' } );
1171
1267
  } );
1172
1268
  } );
1173
- const logObj = {
1174
- clientId: req.body.clientId,
1175
- userName: req.user?.userName,
1176
- email: req.user?.email,
1177
- date: new Date(),
1178
- logType: 'billing',
1179
- logSubType: 'Product subscribe and unsubscribe',
1180
- changes: [ 'Plan Details' ],
1181
- eventType: 'update',
1182
- };
1183
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
1269
+ // const logObj = {
1270
+ // clientId: req.body.clientId,
1271
+ // userName: req.user?.userName,
1272
+ // email: req.user?.email,
1273
+ // date: new Date(),
1274
+ // logType: 'billing',
1275
+ // logSubType: 'Product subscribe and unsubscribe',
1276
+ // changes: [ 'Plan Details' ],
1277
+ // eventType: 'update',
1278
+ // };
1279
+ // insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
1184
1280
  return res.sendSuccess( 'Product Subscribed Successfully' );
1185
1281
  } catch ( e ) {
1186
1282
  logger.error( { error: e, function: 'updateProductSubscribe' } );
@@ -1205,6 +1301,7 @@ export const unsubscribeApproval = async ( req, res ) => {
1205
1301
  clientProducts.save();
1206
1302
  await storeService.updateMany( { clientId: requestData.clientId }, { status: 'deactive' } );
1207
1303
  await userService.updateMany( { clientId: requestData.clientId }, { isActive: false } );
1304
+ await clientRequestService.deleteMany( { clientId: requestData.clientId } );
1208
1305
  let userDetails = await userService.findOne( { clientId: requestData.clientId, role: 'superadmin' } );
1209
1306
  if ( userDetails ) {
1210
1307
  const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialUnsubscribeEmail.hbs', 'utf8' );
@@ -1230,7 +1327,7 @@ export const unsubscribeApproval = async ( req, res ) => {
1230
1327
  changes: [ 'status' ],
1231
1328
  eventType: 'update',
1232
1329
  };
1233
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
1330
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
1234
1331
  return res.sendSuccess( 'updated Successfully' );
1235
1332
  } );
1236
1333
  } catch ( e ) {
@@ -1494,6 +1591,26 @@ export const addStoreProduct = async ( req, res ) => {
1494
1591
  firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
1495
1592
  let productName = firstWord + ' ' + secondWord;
1496
1593
  trialProduct.push( productName );
1594
+ let logObj = {
1595
+ userName: req.user?.userName,
1596
+ email: req.user?.email,
1597
+ clientId: req.body.clientId,
1598
+ clientNotification: false,
1599
+ adminNotification: true,
1600
+ logSubType: 'Subscription - Your 14 Days free trial has been started',
1601
+ category: 'Brand Activity Log',
1602
+ features: 'Subscription',
1603
+ // title: 'Start Trial',
1604
+ alertCta: [],
1605
+ markasRead: false,
1606
+ logType: 'Start Trial',
1607
+ showPushNotification: true,
1608
+ date: new Date(),
1609
+ changes: [ 'product' ],
1610
+ eventType: 'update',
1611
+
1612
+ };
1613
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
1497
1614
  }
1498
1615
  if ( item.type == 'subscription' ) {
1499
1616
  clientProduct.push( {
@@ -1502,6 +1619,25 @@ export const addStoreProduct = async ( req, res ) => {
1502
1619
  status: 'live',
1503
1620
  } );
1504
1621
  subscriptionCount = subscriptionCount + 1;
1622
+ let logObj = {
1623
+ userName: req.user?.userName,
1624
+ email: req.user?.email,
1625
+ clientId: req.body.clientId,
1626
+ clientNotification: false,
1627
+ adminNotification: true,
1628
+ logSubType: 'Your subscription is now active! Get ready to maximize your instore sales potential with the Tangoeye suite',
1629
+ category: 'Brand Activity Log',
1630
+ features: 'Subscription',
1631
+ // title: 'Subscribed',
1632
+ alertCta: [],
1633
+ markasRead: false,
1634
+ logType: 'Subscribed',
1635
+ showPushNotification: true,
1636
+ date: new Date(),
1637
+ changes: [ 'product' ],
1638
+ eventType: 'update',
1639
+ };
1640
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
1505
1641
  }
1506
1642
  }
1507
1643
  }
@@ -1569,17 +1705,17 @@ export const addStoreProduct = async ( req, res ) => {
1569
1705
  }
1570
1706
  await storeService.updateOne( { storeId: item.storeId, clientId: clientId }, { product: product } );
1571
1707
  } );
1572
- const logObj = {
1573
- clientId: clientId,
1574
- userName: req.user?.userName,
1575
- email: req.user?.email,
1576
- date: new Date(),
1577
- logType: 'billing',
1578
- logSubType: 'Store Prosuct Addition',
1579
- changes: [ 'product' ],
1580
- eventType: 'update',
1581
- };
1582
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
1708
+ // const logObj = {
1709
+ // clientId: clientId,
1710
+ // userName: req.user?.userName,
1711
+ // email: req.user?.email,
1712
+ // date: new Date(),
1713
+ // logType: 'billing',
1714
+ // logSubType: 'Store Product Addition',
1715
+ // changes: [ 'product' ],
1716
+ // eventType: 'update',
1717
+ // };
1718
+ // insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
1583
1719
  let products = clientInfo.planDetails.product.map( ( item ) => {
1584
1720
  let [ firstWord, secondWord ] = item.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
1585
1721
  return firstWord.toLowerCase() + '_' + secondWord.toLowerCase();
@@ -1978,7 +2114,7 @@ export const pricingListUpdate = async ( req, res ) => {
1978
2114
  changes: keys,
1979
2115
  eventType: 'update',
1980
2116
  };
1981
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
2117
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
1982
2118
  return res.sendSuccess( 'Pricig Updated Successfully' );
1983
2119
  } );
1984
2120
  } catch ( e ) {
@@ -2152,7 +2288,7 @@ export const updatedRevisedPrice = async ( req, res ) => {
2152
2288
  changes: [ 'amount', 'revisedAmount', 'discount' ],
2153
2289
  eventType: 'update',
2154
2290
  };
2155
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
2291
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
2156
2292
  return res.sendSuccess( 'Credit notes Updated Successfully' );
2157
2293
  } );
2158
2294
  } catch ( e ) {
@@ -2223,6 +2359,23 @@ export const getRemindClients = async ( req, res ) => {
2223
2359
  product: firstWord + ' ' + secondWord,
2224
2360
  domain: appConfig.url.domain,
2225
2361
  };
2362
+ let logObj = {
2363
+ clientId: client.clientId,
2364
+ clientNotification: false,
2365
+ adminNotification: true,
2366
+ logSubType: 'Subscription - Your Free trial is about to expire in 3 days. Pleas make sure to subscribe to the products',
2367
+ category: 'Brand Activity Log',
2368
+ features: 'Subscription',
2369
+ // title: 'Trial reminder',
2370
+ alertCta: [ { buttonName: 'Subscribe now', redirectionUrl: 'manage/settings/payment-subscription' }, { buttonName: 'Remind me later', redirectionUrl: 'cancel' } ],
2371
+ markasRead: false,
2372
+ logType: 'Trial reminder',
2373
+ showPushNotification: true,
2374
+ date: new Date(),
2375
+ userName: userDetails?.userName,
2376
+ email: userDetails?.email,
2377
+ };
2378
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
2226
2379
  const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialReminderEmail.hbs', 'utf8' );
2227
2380
  const template = Handlebars.compile( templateHtml );
2228
2381
  const html = template( { data: data } );
@@ -2413,7 +2566,6 @@ export const invoiceDownload = async ( req, res ) => {
2413
2566
  content: html,
2414
2567
  };
2415
2568
  let options = {
2416
- path: `../../invoice/test.pdf}`,
2417
2569
  format: 'A4', margin: {
2418
2570
  top: '0.5in',
2419
2571
  right: '0.5in',
@@ -2422,11 +2574,43 @@ export const invoiceDownload = async ( req, res ) => {
2422
2574
  },
2423
2575
  printBackground: true, preferCSSPageSize: true,
2424
2576
  };
2577
+ const date = dayjs( invoiceData.monthOfbilling, 'MM' );
2578
+ const monthName = date.format( 'MMMM' );
2579
+
2580
+
2425
2581
  htmlpdf.generatePdf( file, options ).then( async function( pdfBuffer ) {
2582
+ if ( req.body.sendInvoice ) {
2583
+ let mailSubject = `Invoice for ${monthName} - Tango/${clientDetails.clientName}`;
2584
+ let mailbody = `<div>Dear Team,</div>
2585
+ <div style="margin-top:10px">
2586
+ Please find attached the Invoice for the month of ${monthName}'24.
2587
+ </div>
2588
+ <div style="margin-top:10px">
2589
+ Best Regards,
2590
+ </div>
2591
+ <div style="margin-top:5px">
2592
+ Tango Finance
2593
+ </div>`;
2594
+
2595
+ let filename = `${clientDetails.clientName}-${invoiceData.invoice}-${monthName}.pdf`;
2596
+ let attachments = {
2597
+ filename: `${filename}`,
2598
+ content: pdfBuffer,
2599
+ contentType: 'application/pdf', // e.g., 'application/pdf'
2600
+ };
2601
+ clientDetails.paymentInvoice.invoiceCC = [ ...clientDetails.paymentInvoice.invoiceCC, ...[ 'sireesha@tangotech.co.in' ] ];
2602
+ // return;
2603
+ const result = await sendEmailWithSES( clientDetails.paymentInvoice.invoiceTo, mailSubject, mailbody, attachments, 'no-reply@tangotech.ai', clientDetails.paymentInvoice.invoiceCC );
2604
+ if ( result ) {
2605
+ await invoiceService.updateOne( { _id: req.params.invoiceId }, { status: req.body.status } );
2606
+ return res.sendSuccess( result );
2607
+ }
2608
+ }
2426
2609
  res.set( 'Content-Disposition', 'attachment; filename="generated-pdf.pdf"' );
2427
2610
  res.set( 'Content-Type', 'application/pdf' );
2428
2611
  res.send( pdfBuffer );
2429
2612
  } );
2613
+ return;
2430
2614
  }
2431
2615
 
2432
2616
 
@@ -2501,7 +2685,7 @@ export const updateInvoiceStatus = async ( req, res ) => {
2501
2685
  changes: [ 'amount', 'paymentType', 'status' ],
2502
2686
  eventType: 'update',
2503
2687
  };
2504
- insertOpenSearchData( 'tango-retail-activity-logs', logObj );
2688
+ insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
2505
2689
  return res.sendSuccess( 'Invoice updated Successfully' );
2506
2690
  } );
2507
2691
  } catch ( e ) {
@@ -2862,3 +3046,90 @@ export const invoiceRevised = async ( req, res ) => {
2862
3046
  return res.sendError( e, 500 );
2863
3047
  }
2864
3048
  };
3049
+
3050
+ export const clientNotificationList = async ( req, res ) => {
3051
+ try {
3052
+ let query;
3053
+ if ( req.user.role == 'superadmin' ) {
3054
+ query = {
3055
+ query: {
3056
+ bool: {
3057
+ must: [
3058
+ { match: { clientId: req.user.clientId } },
3059
+ { match: { type: 'notification' } },
3060
+ { match: { adminNotification: true } },
3061
+ { match: { markasRead: false } },
3062
+ ],
3063
+ },
3064
+ },
3065
+ _source: [ 'description', 'alertCta', 'clientId', 'markasRead', 'showPushNotification', 'date', 'title' ],
3066
+ stored_fields: [ '_source' ],
3067
+ };
3068
+ } else {
3069
+ query = {
3070
+ query: {
3071
+ bool: {
3072
+ must: [
3073
+ { match: { clientId: req.user.clientId } },
3074
+ { match: { type: 'notification' } },
3075
+ { match: { clientNotification: true } },
3076
+ { match: { markasRead: false } },
3077
+ ],
3078
+ },
3079
+ },
3080
+ _source: [ 'description', 'alertCta', 'clientId', 'markasRead', 'showPushNotification', 'date', 'title' ],
3081
+ stored_fields: [ '_source' ],
3082
+ };
3083
+ }
3084
+ let result = await getOpenSearchData( appConfig.opensearch.activityLog, query );
3085
+ if ( !result || !result.body.hits.hits.length ) {
3086
+ return res.sendError( 'no data found', 204 );
3087
+ }
3088
+ return res.sendSuccess( result.body.hits.hits );
3089
+ } catch ( e ) {
3090
+ logger.error( { error: e, function: 'clientNotificationList' } );
3091
+ return res.sendError( e, 500 );
3092
+ }
3093
+ };
3094
+
3095
+ export const updateNotification = async ( req, res ) => {
3096
+ try {
3097
+ let openSearchDetails = await getOpenSearchById( appConfig.opensearch.activityLog, req.params.notificationId );
3098
+ if ( openSearchDetails.statusCode == 200 && openSearchDetails?.body?._source ) {
3099
+ const document = {
3100
+ doc: {
3101
+ markasRead: true,
3102
+ },
3103
+ };
3104
+ let updateResult = await updateOpenSearchData( appConfig.opensearch.activityLog, req.params.notificationId, document );
3105
+ if ( updateResult?.statusCode == 200 && updateResult?.body?.result == 'updated' ) {
3106
+ return res.sendSuccess( 'Notification Updated SUccessfully' );
3107
+ }
3108
+ return res.sendError( 'Something went wrong', 500 );
3109
+ }
3110
+ } catch ( e ) {
3111
+ logger.error( { error: e, function: 'updateNotification' } );
3112
+ return res.sendError( e, 500 );
3113
+ }
3114
+ };
3115
+
3116
+ export const updatePushNotification = async ( req, res ) => {
3117
+ try {
3118
+ let openSearchDetails = await getOpenSearchById( appConfig.opensearch.activityLog, req.params.notificationId );
3119
+ if ( openSearchDetails.statusCode == 200 && openSearchDetails?.body?._source ) {
3120
+ const document = {
3121
+ doc: {
3122
+ showPushNotification: false,
3123
+ },
3124
+ };
3125
+ let updateResult = await updateOpenSearchData( appConfig.opensearch.activityLog, req.params.notificationId, document );
3126
+ if ( updateResult?.statusCode == 200 && updateResult?.body?.result == 'updated' ) {
3127
+ return res.sendSuccess( 'Notification Updated SUccessfully' );
3128
+ }
3129
+ return res.sendError( 'Something went wrong', 500 );
3130
+ }
3131
+ } catch ( e ) {
3132
+ logger.error( { error: e, function: 'updatePushNotification' } );
3133
+ return res.sendError( e, 500 );
3134
+ }
3135
+ };
@@ -248,3 +248,11 @@ export const validateInvoiceUpdateSchema = joi.object( {
248
248
  export const validateInvoiceUpdateParams = {
249
249
  body: validateInvoiceUpdateSchema,
250
250
  };
251
+
252
+ export const validateIdSchema = joi.object( {
253
+ notificationId: joi.string().required(),
254
+ } );
255
+
256
+ export const validateId = {
257
+ params: validateIdSchema,
258
+ };
@@ -160,3 +160,7 @@ paymentSubscriptionRouter.post( '/invoice/create', validateClient, paymentContro
160
160
  paymentSubscriptionRouter.post( '/invoiceGenerate', paymentController.invoiceGenerate );
161
161
  paymentSubscriptionRouter.post( '/dailyPricing/insert', validate( validationDtos.dailyPricingParams ), paymentController.dailyPricingInsert );
162
162
  paymentSubscriptionRouter.get( '/invoiceRevised/:invoiceId', validate( validationDtos.invoiceRevisedParams ), paymentController.invoiceRevised );
163
+ paymentSubscriptionRouter.get( '/notificationList', isAllowedSessionHandler, paymentController.clientNotificationList );
164
+ paymentSubscriptionRouter.put( '/notification/update/:notificationId', isAllowedSessionHandler, validate( validationDtos.validateId ), paymentController.updateNotification );
165
+ paymentSubscriptionRouter.put( '/pushNotification/update/:notificationId', isAllowedSessionHandler, validate( validationDtos.validateId ), paymentController.updatePushNotification );
166
+
@@ -16,3 +16,11 @@ export const find = async ( query ={}, record={} ) => {
16
16
  export const updateone = async ( query = {}, record ={} ) => {
17
17
  return await model.clientRequestModel.updateOne( query, { $set: record } );
18
18
  };
19
+
20
+ export const deleteMany = async ( query = {} ) => {
21
+ return await model.clientRequestModel.deleteMany( query );
22
+ };
23
+
24
+ export const deleteOne = async ( query = {} ) => {
25
+ return await model.clientRequestModel.deleteOne( query );
26
+ };
@@ -11,6 +11,9 @@ export const findOne = async ( query ={}, record={} ) => {
11
11
  export const find = async ( query ={}, record={} ) => {
12
12
  return await model.invoiceModel.find( query, record );
13
13
  };
14
+ export const updateOne = async ( query ={}, record={} ) => {
15
+ return await model.invoiceModel.updateOne( query, { $set: record } );
16
+ };
14
17
  export const findandsort = async ( query ={}, record={}, sort={} ) => {
15
18
  return await model.invoiceModel.find( query, record ).sort( sort );
16
19
  };