tango-app-api-payment-subscription 3.0.34-dev → 3.0.36-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.34-dev",
3
+ "version": "3.0.36-dev",
4
4
  "description": "paymentSubscription",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -375,7 +375,7 @@ export const updateSubscriptionOLD = async ( req, res ) => {
375
375
 
376
376
  let result = await paymentService.updateOne( { clientId: req.params.clientId }, details );
377
377
  let storeProduct = products.map( ( item ) => item.productName );
378
- await storeService.updateMany( { clientId: req.params.clientId, status: 'active' }, { product: storeProduct } );
378
+ await storeService.updateMany( { clientId: req.params.clientId }, { product: storeProduct } );
379
379
 
380
380
  if ( result.modifiedCount ) {
381
381
  return res.sendSuccess( { message: 'Subscription Updated Successfully' } );
@@ -391,6 +391,7 @@ export const updateSubscriptionOLD = async ( req, res ) => {
391
391
  export const updateSubscription = async ( req, res ) => {
392
392
  try {
393
393
  let requestBody = req.body;
394
+ let subscriptionCount = 0;
394
395
  if ( !requestBody?.products?.length ) {
395
396
  return res.sendError( 'product is required', 400 );
396
397
  }
@@ -438,6 +439,7 @@ export const updateSubscription = async ( req, res ) => {
438
439
  clientProducts[existsIndex].status = 'live';
439
440
  clientProducts[existsIndex].subscribedDate = new Date();
440
441
  }
442
+ subscriptionCount = subscriptionCount + 1;
441
443
  }
442
444
  }
443
445
 
@@ -458,10 +460,30 @@ export const updateSubscription = async ( req, res ) => {
458
460
  'currencyType': 'rupees',
459
461
  };
460
462
  let pricingDetails = await calculatePricing( req, res );
463
+ if ( subscriptionCount ) {
464
+ let userDetails= await userService.findOne( { clientId: requestBody.clientId, role: 'superadmin' } );
465
+ if ( userDetails ) {
466
+ let data = {
467
+ username: userDetails.userName,
468
+ };
469
+ const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialSubscriptionEmail.hbs', 'utf8' );
470
+ const template = Handlebars.compile( templateHtml );
471
+ const html = template( { data: data } );
472
+ let params = {
473
+ toEmail: userDetails.email,
474
+ mailSubject: 'Subscribe - Tango Eye',
475
+ htmlBody: html,
476
+ attachment: '',
477
+ sourceEmail: appConfig.cloud.aws.ses.adminEmail,
478
+ };
479
+ sendEmailWithSES( params.toEmail, params.mailSubject, params.htmlBody, params.attachment, params.sourceEmail );
480
+ }
481
+ }
461
482
  let data = {
462
483
  planDetails: details,
463
484
  price: pricingDetails.price,
464
485
  priceType: requestBody.priceType,
486
+
465
487
  };
466
488
 
467
489
  let result = await paymentService.updateOne( { clientId: req.params.clientId }, data );
@@ -477,7 +499,7 @@ export const updateSubscription = async ( req, res ) => {
477
499
  };
478
500
  insertOpenSearchData( 'tango-retail-activity-logs', logObj );
479
501
  let storeProduct = clientProducts.map( ( item ) => item.productName );
480
- await storeService.updateMany( { clientId: req.params.clientId, status: 'active' }, { product: storeProduct } );
502
+ await storeService.updateMany( { clientId: req.params.clientId }, { product: storeProduct } );
481
503
 
482
504
  if ( result.modifiedCount ) {
483
505
  req.body.clientId = req.params.clientId;
@@ -816,7 +838,7 @@ export const trialApproval = async ( req, res ) => {
816
838
  } );
817
839
  }
818
840
  clientProducts.save();
819
- await storeService.addremoveElement( { clientId: requestData.clientId, status: 'active' }, { $push: { product: requestData.name } } );
841
+ await storeService.addremoveElement( { clientId: requestData.clientId }, { $push: { product: requestData.name } } );
820
842
  req.body.clientId = requestData.clientId;
821
843
  updatePricing( req, res, true );
822
844
  let userDetails= await userService.findOne( { clientId: requestData.clientId, role: 'superadmin' } );
@@ -927,6 +949,7 @@ export const productSubscribe = async ( req, res ) => {
927
949
  try {
928
950
  let data = req.body.product;
929
951
  req.body.product = [];
952
+ let subscriptionCount = 0;
930
953
  data.forEach( ( item ) => {
931
954
  if ( item.type != 'cancel' ) {
932
955
  let arr = item.name.split( ',' );
@@ -967,8 +990,9 @@ export const productSubscribe = async ( req, res ) => {
967
990
  subscribedDate: new Date(),
968
991
  status: 'live',
969
992
  } );
993
+ subscriptionCount = subscriptionCount + 1;
970
994
  }
971
- await storeService.addremoveElement( { clientId: clientInfo.clientId, status: 'active' }, { $push: { product: item.name } } );
995
+ await storeService.addremoveElement( { clientId: clientInfo.clientId }, { $push: { product: item.name } } );
972
996
  } else {
973
997
  let productIndex = product.findIndex( ( ele ) => ele.productName == item.name );
974
998
  if ( productIndex != -1 ) {
@@ -976,6 +1000,7 @@ export const productSubscribe = async ( req, res ) => {
976
1000
  product[productIndex].subscribedDate = new Date();
977
1001
  product[productIndex].status = 'live';
978
1002
  }
1003
+ subscriptionCount = subscriptionCount + 1;
979
1004
  }
980
1005
  }
981
1006
  }
@@ -992,9 +1017,7 @@ export const productSubscribe = async ( req, res ) => {
992
1017
  if ( product.length > 1 ) {
993
1018
  clientInfo.planDetails.subscriptionType = 'premium';
994
1019
  }
995
- clientInfo.planDetails.product = product;
996
- clientInfo.save().then( async () => {
997
- updatePricing( req, res, true );
1020
+ if ( subscriptionCount ) {
998
1021
  let userDetails= await userService.findOne( { clientId: clientInfo.clientId, role: 'superadmin' } );
999
1022
  if ( userDetails ) {
1000
1023
  let data = {
@@ -1012,6 +1035,27 @@ export const productSubscribe = async ( req, res ) => {
1012
1035
  };
1013
1036
  sendEmailWithSES( params.toEmail, params.mailSubject, params.htmlBody, params.attachment, params.sourceEmail );
1014
1037
  }
1038
+ }
1039
+ clientInfo.planDetails.product = product;
1040
+ clientInfo.save().then( async () => {
1041
+ updatePricing( req, res, true );
1042
+ // let userDetails= await userService.findOne( { clientId: clientInfo.clientId, role: 'superadmin' } );
1043
+ // if ( userDetails ) {
1044
+ // let data = {
1045
+ // username: userDetails.userName,
1046
+ // };
1047
+ // const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialSubscriptionEmail.hbs', 'utf8' );
1048
+ // const template = Handlebars.compile( templateHtml );
1049
+ // const html = template( { data: data } );
1050
+ // let params = {
1051
+ // toEmail: userDetails.email,
1052
+ // mailSubject: 'Subscribe - Tango Eye',
1053
+ // htmlBody: html,
1054
+ // attachment: '',
1055
+ // sourceEmail: appConfig.cloud.aws.ses.adminEmail,
1056
+ // };
1057
+ // sendEmailWithSES( params.toEmail, params.mailSubject, params.htmlBody, params.attachment, params.sourceEmail );
1058
+ // }
1015
1059
  } );
1016
1060
  const logObj = {
1017
1061
  clientId: req.body.clientId,
@@ -1247,7 +1291,7 @@ export const storeViewList = async ( req, res ) => {
1247
1291
  export const storeLocationList = async ( req, res ) => {
1248
1292
  try {
1249
1293
  let storeDetails;
1250
- storeDetails = await storeService.find( { clientId: req.query.clientId, status: 'active' }, { 'storeId': 1, 'storeName': 1, 'storeProfile.city': 1 } );
1294
+ storeDetails = await storeService.find( { clientId: req.query.clientId }, { 'storeId': 1, 'storeName': 1, 'storeProfile.city': 1 } );
1251
1295
  let store = [];
1252
1296
  let location = [];
1253
1297
  if ( storeDetails.length ) {
@@ -1291,6 +1335,7 @@ export const addStoreProduct = async ( req, res ) => {
1291
1335
  let clientProduct = [];
1292
1336
  let storeProduct = [];
1293
1337
  let removedProduct = [];
1338
+ let subscriptionCount = 0;
1294
1339
  clientProduct = clientInfo.planDetails.product;
1295
1340
  req.body.product.forEach( ( item ) => {
1296
1341
  if ( item.type != 'unsubscribe' ) {
@@ -1333,11 +1378,31 @@ export const addStoreProduct = async ( req, res ) => {
1333
1378
  subscribedDate: new Date(),
1334
1379
  status: 'live',
1335
1380
  } );
1381
+ subscriptionCount = subscriptionCount + 1;
1336
1382
  }
1337
1383
  }
1338
1384
  }
1339
1385
  },
1340
1386
  );
1387
+ if ( subscriptionCount ) {
1388
+ let userDetails= await userService.findOne( { clientId: req.body.clientId, role: 'superadmin' } );
1389
+ if ( userDetails ) {
1390
+ let data = {
1391
+ username: userDetails.userName,
1392
+ };
1393
+ const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialSubscriptionEmail.hbs', 'utf8' );
1394
+ const template = Handlebars.compile( templateHtml );
1395
+ const html = template( { data: data } );
1396
+ let params = {
1397
+ toEmail: userDetails.email,
1398
+ mailSubject: 'Subscribe - Tango Eye',
1399
+ htmlBody: html,
1400
+ attachment: '',
1401
+ sourceEmail: appConfig.cloud.aws.ses.adminEmail,
1402
+ };
1403
+ sendEmailWithSES( params.toEmail, params.mailSubject, params.htmlBody, params.attachment, params.sourceEmail );
1404
+ }
1405
+ }
1341
1406
  clientInfo.planDetails.product = clientProduct;
1342
1407
  clientInfo.save();
1343
1408
  storeDetails.forEach( async ( item ) => {
@@ -1461,6 +1526,9 @@ export const invoiceList = async ( req, res ) => {
1461
1526
  if ( item.products?.length>0 ) {
1462
1527
  let newProducts = [];
1463
1528
  for ( let productIndex = 0; productIndex < item.products.length; productIndex++ ) {
1529
+ let [ firstWord, secondWord ] = item.products[productIndex]?.product?.product.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
1530
+ firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
1531
+ item.products[productIndex].product.product = firstWord + ' ' + secondWord;
1464
1532
  newProducts.push( item.products[productIndex]?.product?.product );
1465
1533
  }
1466
1534
  item.productList = newProducts;
@@ -1632,6 +1700,9 @@ export const pricingListUpdate = async ( req, res ) => {
1632
1700
  productList = JSON.parse( JSON.stringify( req.body ) );
1633
1701
  let amount =0;
1634
1702
  productList.products.forEach( ( item ) => {
1703
+ let [ firstWord, secondWord ] = item.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
1704
+ firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
1705
+ item.productName = firstWord + ' ' + secondWord;
1635
1706
  if ( req.body.client.paymentInvoice.currencyType == 'dollar' ) {
1636
1707
  item.basePrice = convertINRtoUSD( item.basePrice );
1637
1708
  item.price = convertINRtoUSD( item.price );
@@ -1719,6 +1790,7 @@ async function updatePricing( req, res, update ) {
1719
1790
  let clientDetails = await paymentService.findOne( { clientId: req.body.clientId } );
1720
1791
  if ( clientDetails ) {
1721
1792
  let products = clientDetails.planDetails.product.map( ( item ) => item.productName );
1793
+ let subscriptionCount = clientDetails.planDetails.product.map( ( item ) => item.status == 'live' );
1722
1794
  let standardList = [];
1723
1795
  let stepList = [];
1724
1796
  products.forEach( ( product ) => {
@@ -1775,9 +1847,18 @@ async function updatePricing( req, res, update ) {
1775
1847
  'currencyType': 'rupees',
1776
1848
  };
1777
1849
  let pricingDetails = await calculatePricing( req, res );
1850
+ let paymentStatus = clientDetails?.subscriptionType == 'free' ? 'free' : 'trial';
1851
+ if ( subscriptionCount ) {
1852
+ let invoiceCount = await invoiceService.count( { clientId: req.params.clientId, status: 'pending' } );
1853
+ if ( invoiceCount ) {
1854
+ paymentStatus ='due';
1855
+ } else {
1856
+ paymentStatus ='unbilled';
1857
+ }
1858
+ }
1778
1859
  let details = {
1779
1860
  'priceType': 'standard',
1780
- 'planDetails.paymentStatus': clientDetails?.subscriptionType == 'free' ? 'free' : 'trial',
1861
+ 'planDetails.paymentStatus': clientDetails?.subscriptionType == 'free' ? 'free' : paymentStatus,
1781
1862
  'planDetails.product': product,
1782
1863
  'price': pricingDetails.price,
1783
1864
  };
@@ -1801,6 +1882,13 @@ export const updatedRevisedPrice = async ( req, res ) => {
1801
1882
  let clientDetails = await paymentService.findOne( { clientId: invoiceDetails.clientId } );
1802
1883
  let amount = 0;
1803
1884
  invoiceDetails.products.forEach( ( item ) => {
1885
+ let [ firstWord, secondWord ] = item.product.product.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
1886
+ firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
1887
+ item.product.product = firstWord + ' ' + secondWord;
1888
+ if ( clientDetails?.paymentInvoice?.currencyType == 'dollar' ) {
1889
+ item.basePrice = convertINRtoUSD( item.basePrice );
1890
+ item.price = convertINRtoUSD( item.price );
1891
+ }
1804
1892
  if ( clientDetails.priceType == 'step' ) {
1805
1893
  item.count = item.product.storeRange;
1806
1894
  }
@@ -1814,7 +1902,8 @@ export const updatedRevisedPrice = async ( req, res ) => {
1814
1902
  clientName: clientDetails.clientName,
1815
1903
  extendDays: clientDetails.paymentInvoice.extendPaymentPeriodDays,
1816
1904
  address: clientDetails.billingDetails.billingAddress,
1817
- amount: amount,
1905
+ amount: amount.toFixed( 2 ),
1906
+ currencyType: clientDetails.paymentInvoice.currencyType == 'dollar' ? '$' : '₹',
1818
1907
  discount: req.body.discount,
1819
1908
  total: req.body.revisedAmount.toFixed( 2 ),
1820
1909
  invoiceDate,
@@ -1870,9 +1959,9 @@ export const getStoreProducts = async ( req, res ) => {
1870
1959
  try {
1871
1960
  let storeProductDetails;
1872
1961
  if ( !req.body.store.length ) {
1873
- storeProductDetails = await storeService.find( { clientId: req.body.clientId, status: 'active' } );
1962
+ storeProductDetails = await storeService.find( { clientId: req.body.clientId } );
1874
1963
  } else {
1875
- storeProductDetails = await storeService.find( { storeId: { $in: req.body.store }, clientId: req.body.clientId, status: 'active' } );
1964
+ storeProductDetails = await storeService.find( { storeId: { $in: req.body.store }, clientId: req.body.clientId } );
1876
1965
  }
1877
1966
 
1878
1967
  let product = new Set();
@@ -1899,15 +1988,18 @@ export const getRemindClients = async ( req, res ) => {
1899
1988
  clientDetails.forEach( async ( client ) => {
1900
1989
  if ( client.planDetails?.product && client.planDetails?.product.length ) {
1901
1990
  client.planDetails.product.forEach( async ( item ) => {
1902
- if ( item.status == 'trial' ) {
1903
- let date = new Date();
1904
- let userTimezoneOffset = item.trialEndDate.getTimezoneOffset() / 60000;
1905
- item.trialEndDate = new Date( item.trialEndDate.getTime() - userTimezoneOffset );
1906
- item.trialEndDate.setUTCHours( 0, 0, 0, 0 );
1907
- const diffTime = parseInt( ( item.trialEndDate - date ) / ( 1000 * 60 * 60 * 24 ), 10 ) + 1;
1991
+ if ( item.status == 'trial' && item?.trialEndDate ) {
1992
+ let endDate = dayjs( item.trialEndDate ).startOf( 'day' );
1993
+ let date = dayjs().startOf( 'day' );
1994
+ let leftDays = endDate.diff( date, 'day' );
1995
+ // let date = new Date();
1996
+ // let userTimezoneOffset = item.trialEndDate.getTimezoneOffset() / 60000;
1997
+ // item.trialEndDate = new Date( item.trialEndDate.getTime() - userTimezoneOffset );
1998
+ // item.trialEndDate.setUTCHours( 0, 0, 0, 0 );
1999
+ // const diffTime = parseInt( ( item.trialEndDate - date ) / ( 1000 * 60 * 60 * 24 ), 10 ) + 1;
1908
2000
  let userDetails= await userService.findOne( { clientId: client.clientId, role: 'superadmin' } );
1909
2001
  if ( userDetails ) {
1910
- if ( diffTime == 3 ) {
2002
+ if ( leftDays == 3 ) {
1911
2003
  let [ firstWord, secondWord ] = item.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
1912
2004
  firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
1913
2005
  let data = {
@@ -1939,7 +2031,7 @@ export const getRemindClients = async ( req, res ) => {
1939
2031
  };
1940
2032
 
1941
2033
 
1942
- export const getExpiredClients = async ( req, res ) => {
2034
+ export const getExpiredClientsOld = async ( req, res ) => {
1943
2035
  try {
1944
2036
  let start = new Date();
1945
2037
  let userTimezoneOffset = start.getTimezoneOffset() * 60000;
@@ -1958,7 +2050,6 @@ export const getExpiredClients = async ( req, res ) => {
1958
2050
  {
1959
2051
  $match: {
1960
2052
  'planDetails.product.status': 'trial',
1961
- 'planDetails.product.trialEndDate': { $gt: end },
1962
2053
  },
1963
2054
  },
1964
2055
  ];
@@ -1974,7 +2065,7 @@ export const getExpiredClients = async ( req, res ) => {
1974
2065
  let [ firstWord, secondWord ] = item.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
1975
2066
  firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
1976
2067
  let data = {
1977
- username: userDetails.userName,
2068
+ userName: userDetails.userName,
1978
2069
  product: firstWord +' '+secondWord,
1979
2070
  };
1980
2071
  const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialExpiredEmail.hbs', 'utf8' );
@@ -1997,6 +2088,56 @@ export const getExpiredClients = async ( req, res ) => {
1997
2088
  return res.sendError( e, 500 );
1998
2089
  }
1999
2090
  };
2091
+ export const getExpiredClients = async ( req, res ) => {
2092
+ try {
2093
+ let clientDetails = await paymentService.find( { status: 'active' } );
2094
+ if ( !clientDetails.length ) {
2095
+ return res.sendError( 'no data found', 204 );
2096
+ }
2097
+ clientDetails.forEach( async ( client ) => {
2098
+ if ( client.planDetails?.product && client.planDetails?.product.length ) {
2099
+ client.planDetails.product.forEach( async ( item ) => {
2100
+ if ( item.status == 'trial' && item?.trialEndDate ) {
2101
+ let endDate = dayjs( item.trialEndDate ).startOf( 'day' );
2102
+ let date = dayjs().startOf( 'day' );
2103
+ let leftDays = endDate.diff( date, 'day' );
2104
+ // let date = new Date();
2105
+ // let userTimezoneOffset = item.trialEndDate.getTimezoneOffset() / 60000;
2106
+ // item.trialEndDate = new Date( item.trialEndDate.getTime() - userTimezoneOffset );
2107
+ // item.trialEndDate.setUTCHours( 0, 0, 0, 0 );
2108
+ // const diffTime = parseInt( ( item.trialEndDate - date ) / ( 1000 * 60 * 60 * 24 ), 10 ) + 1;
2109
+ let userDetails= await userService.findOne( { clientId: client.clientId, role: 'superadmin' } );
2110
+ if ( userDetails ) {
2111
+ if ( leftDays == -1 ) {
2112
+ let [ firstWord, secondWord ] = item.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
2113
+ firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
2114
+ let data = {
2115
+ userName: userDetails.userName,
2116
+ product: firstWord + ' ' + secondWord,
2117
+ };
2118
+ const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialExpiredEmail.hbs', 'utf8' );
2119
+ const template = Handlebars.compile( templateHtml );
2120
+ const html = template( { data: data } );
2121
+ let params = {
2122
+ toEmail: userDetails.email,
2123
+ mailSubject: 'TangoEye | Trial Expired - Upgrade to Continue',
2124
+ htmlBody: html,
2125
+ attachment: '',
2126
+ sourceEmail: appConfig.cloud.aws.ses.adminEmail,
2127
+ };
2128
+ await sendEmailWithSES( params.toEmail, params.mailSubject, params.htmlBody, params.attachment, params.sourceEmail );
2129
+ }
2130
+ }
2131
+ }
2132
+ } );
2133
+ }
2134
+ } );
2135
+ return res.sendSuccess();
2136
+ } catch ( e ) {
2137
+ logger.error( { error: e, function: 'getExpiredClients' } );
2138
+ return res.sendError( e, 500 );
2139
+ }
2140
+ };
2000
2141
 
2001
2142
  export const invoiceDownload = async ( req, res ) => {
2002
2143
  try {
@@ -2006,6 +2147,9 @@ export const invoiceDownload = async ( req, res ) => {
2006
2147
  let clientDetails = await paymentService.findOne( { clientId: invoiceInfo.clientId } );
2007
2148
  let amount = 0;
2008
2149
  invoiceInfo.products.forEach( ( item ) => {
2150
+ let [ firstWord, secondWord ] = item.product.product.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
2151
+ firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
2152
+ item.product.product = firstWord + ' ' + secondWord;
2009
2153
  if ( clientDetails.paymentInvoice.currencyType == 'dollar' ) {
2010
2154
  item.basePrice = convertINRtoUSD( item.basePrice );
2011
2155
  item.price = convertINRtoUSD( item.price );
@@ -2307,7 +2451,7 @@ export const invoiceGenerate = async ( req, res ) => {
2307
2451
  };
2308
2452
  let storeCount = await storeService.count( storeQuery );
2309
2453
  let data = {
2310
- invoice: `invoice#${requestClient[clientIndex]}-${dayjs().format( 'MMM YYYY' )}`,
2454
+ invoice: `invoice#${requestClient[clientIndex]}-${new Date().getTime()}`,
2311
2455
  products: invoiceDetails,
2312
2456
  status: 'pending',
2313
2457
  amount: amount,
@@ -2353,6 +2497,9 @@ export const invoiceRevised = async ( req, res ) => {
2353
2497
  let days = clientDetails?.paymentInvoice?.extendPaymentPeriodDays || 10;
2354
2498
  let dueDate = invoiceDetails?.dueDate ? dayjs( invoiceDetails?.dueDate ).format( 'DD MMM, YYYY' ) : dayjs().add( days, 'days' ).format( 'DD MMM, YYYY' );
2355
2499
  invoiceDetails.products.forEach( ( item ) => {
2500
+ let [ firstWord, secondWord ] = item.product.product.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
2501
+ firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
2502
+ item.product.product = firstWord + ' ' + secondWord;
2356
2503
  if ( clientDetails?.paymentInvoice?.currencyType == 'dollar' ) {
2357
2504
  item.basePrice = convertINRtoUSD( item.basePrice );
2358
2505
  item.price = convertINRtoUSD( item.price );
@@ -80,6 +80,31 @@
80
80
  border: 0;
81
81
  outline: none;
82
82
  }
83
+
84
+ .invoicedescription {
85
+ /* width:300px;
86
+ padding-left:30px; */
87
+ color: #667085 !important
88
+ }
89
+
90
+ .productstext {
91
+ font-size: 16px !important;
92
+ font-weight: 500 !important;
93
+ text-align: left;
94
+ color: #475467 !important;
95
+ /* border-bottom:1px solid #f0ecea !important; */
96
+ line-height: 24px !important;
97
+ }
98
+
99
+ .invoicesub {
100
+ /* font-family: 'Inter'; */
101
+ color: #667085 !important;
102
+ font-size: 16px;
103
+ font-weight: 600;
104
+ line-height: 24px;
105
+ text-align: left;
106
+
107
+ }
83
108
  </style>
84
109
 
85
110
  </head>
@@ -133,7 +158,7 @@
133
158
  <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 680px;">
134
159
  <tr>
135
160
  <td align="left" bgcolor="#ffffff"
136
- style="padding-left: 30px;padding-right: 24px;padding-top:10px; font-size: 16px; line-height: 24px;font-weight:400;color:#384860">
161
+ style="padding-left: 30px;padding-right: 24px;padding-top:10px; font-size: 16px; line-height: 24px;font-weight:400;color:#384860; padding-bottom: 20px;">
137
162
  <p style="margin: 0;">"Notice:Subscription price revised.Please review updated pricing
138
163
  details.we <br />
139
164
  appreciated your continued
@@ -148,68 +173,70 @@
148
173
  <td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
149
174
  <table align="center" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%"
150
175
  style="max-width: 680px;">
151
- <tr bgcolor="#ffffff"
152
- style="border:none;height:40px;margin-top:10px;text-align:left">
153
- <th style="width:300px;padding-left:30px;">Description</th>
154
- <th style="width:120px;">Price</th>
155
- <th style="width:120px;">Stores</th>
156
- <th style="width:120px;">Total Amount</th>
176
+ <tr bgcolor="#F9FAFB"
177
+ style="border-bottom:1px solid #f0ecea;height:40px;margin-top:10px;text-align:left">
178
+ <th class="invoicedescription" style="width:300px;padding-left:30px;">Description</th>
179
+ <th class="invoicedescription" style="width:120px;">Price</th>
180
+ <th class="invoicedescription" style="width:120px;">Stores</th>
181
+ <th class="invoicedescription" style="width:120px;">Total Amount</th>
182
+ </tr>
183
+ <tr style="border:none;">
184
+ <td colspan="4" align="left" bgcolor="#ffffff" style="padding-left: 30px;padding-right: 24px; font-size: 14px; line-height: 24px;">
185
+ <p class="" style="border: 0px solid #EAECF0;">
186
+ </p>
187
+ </td>
157
188
  </tr>
158
189
  {{#each data.products}}
159
190
  <tr bgcolor="#ffffff" style="border:none;margin-top:10px;">
160
- <td style="padding-left:30px;">{{productName}}</td>
161
- <td>{{../data.currencyType}} {{basePrice}}</td>
162
- <td>{{storeCount}}</td>
163
- <td>{{../data.currencyType}} {{price}}</td>
191
+ <td class="productstext" style="padding-left:30px;">{{productName}}</td>
192
+ <td class="productstext">{{../data.currencyType}} {{basePrice}}</td>
193
+ <td class="productstext">{{storeCount}}</td>
194
+ <td class="productstext">{{../data.currencyType}} {{price}}</td>
164
195
  </tr>
165
196
  {{/each}}
166
197
  <tr>
167
- <td align="left" bgcolor="#ffffff"
198
+ <td colspan="4" align="left" bgcolor="#ffffff"
168
199
  style="padding-left: 30px;padding-right: 24px; font-size: 14px; line-height: 24px;">
169
- <p class="o_heading o_mb-xxs"
170
- style="width: 624px;height: 0px;border: 1px solid #CBD5E1;flex: none;order: 1;flex-grow: 0;">
200
+ <p class="" style="border: 1px solid #EAECF0;">
171
201
  </p>
172
202
  </td>
173
203
  </tr>
174
- <tr bgcolor="#ffffff"
175
- style="border:none;margin-top:0px;">
176
- <td style="padding-left:30px;">Sub Total</td>
204
+ <tr bgcolor="#ffffff" style="border:none;margin-top:0px;">
205
+ <td class="invoicesub" style="padding-left:30px; line-height: 24px;">Sub Total</td>
177
206
  <td></td>
178
207
  <td></td>
179
- <td>{{data.currencyType}} {{data.amount}}</td>
208
+ <td class="invoicesub">{{data.currencyType}} {{data.amount}}</td>
180
209
  </tr>
181
210
  <tr bgcolor="#ffffff" style="border:none;margin-top:0px;">
182
- <td style="padding-left:30px;">IGST</td>
211
+ <td class="invoicesub" style="padding-left:30px; line-height: 24px;">IGST</td>
183
212
  <td></td>
184
213
  <td></td>
185
- <td>0%</td>
214
+ <td class="invoicesub">0%</td>
186
215
  </tr>
187
216
  <tr bgcolor="#ffffff" style="border:none;margin-top:0px;">
188
- <td style="padding-left:30px;">Total</td>
217
+ <td class="invoicesub" style="padding-left:30px; line-height: 24px;">Total</td>
189
218
  <td></td>
190
219
  <td></td>
191
- <td>{{data.currencyType}} {{data.total}}</td>
220
+ <td class="invoicesub">{{data.currencyType}} {{data.total}}</td>
192
221
  </tr>
193
222
  <tr bgcolor="#ffffff" style="border:none;margin-top:0px;">
194
- <td style="padding-left:30px;">Discount</td>
223
+ <td class="invoicesub" style="padding-left:30px; line-height: 24px;">Discount</td>
195
224
  <td></td>
196
225
  <td></td>
197
- <td>{{data.discount}}%</td>
226
+ <td class="invoicesub">{{data.discount}}%</td>
198
227
  </tr>
199
228
  <tr>
200
- <td align="left" bgcolor="#ffffff"
229
+ <td colspan="4" align="left" bgcolor="#ffffff"
201
230
  style="padding-left: 30px;padding-right: 24px; font-size: 14px; line-height: 24px;">
202
- <p class="o_heading o_mb-xxs"
203
- style="width: 624px;height: 0px;border: 1px solid #CBD5E1;flex: none;order: 1;flex-grow: 0;">
231
+ <p class="" style="border: 1px solid #EAECF0;">
204
232
  </p>
205
233
  </td>
206
234
  </tr>
207
- <tr bgcolor="#ffffff"
208
- style="border:none;margin-top:10px;">
209
- <td style="padding-left:30px;">Final Value</td>
235
+ <tr bgcolor="#ffffff" style="border:none;margin-top:10px;">
236
+ <td class="invoicesub" style="padding-left:30px; ">Final Value</td>
210
237
  <td></td>
211
238
  <td></td>
212
- <td>{{data.currencyType}} {{data.total}}</td>
239
+ <td class="invoicesub">{{data.currencyType}} {{data.total}}</td>
213
240
  </tr>
214
241
  </table>
215
242
  </td>
@@ -385,6 +385,30 @@
385
385
  transform-origin: 0 0;
386
386
  transform: rotate(0deg) scale(1, 1);
387
387
  }
388
+ .invoicedescription {
389
+ /* width:300px;
390
+ padding-left:30px; */
391
+ color: #667085 !important
392
+ }
393
+ .productstext {
394
+ font-size: 16px !important;
395
+ font-weight: 500 !important;
396
+ text-align: left;
397
+ color: #475467 !important;
398
+ /* border-bottom:1px solid #f0ecea !important; */
399
+ line-height: 24px !important;
400
+ }
401
+
402
+ .invoicesub {
403
+ /* font-family: 'Inter'; */
404
+ color: #667085 !important;
405
+ font-size: 16px;
406
+ font-weight: 600;
407
+ line-height: 24px;
408
+ text-align: left;
409
+
410
+ }
411
+
388
412
  </style>
389
413
 
390
414
  </head>
@@ -441,7 +465,7 @@
441
465
  </tr> -->
442
466
  <tr>
443
467
  <td align="left" bgcolor="#ffffff"
444
- style="padding-left: 27px;padding-right: 24px;padding-top:10px; font-size: 16px; line-height: 24px;font-weight:400;color:#384860">
468
+ style="padding-left: 27px;padding-right: 24px;padding-top:10px; font-size: 16px; line-height: 24px;font-weight:400;color:#384860; padding-bottom: 20px;">
445
469
  <p style="margin: 0;">"Notice: Subscription price revised. Please review updated
446
470
  pricing details. We appreciate your continued support. Thank you for
447
471
  understanding."
@@ -452,61 +476,70 @@
452
476
  <td class="o_bg-white o_px-md o_py-xl o_xs-py-md"
453
477
  style="background-color: #ffffff;padding-left: 30px;padding-right: 24px;padding-bottom: 10px;">
454
478
  <table style="max-width: 600px;border:none" border="0" cellpadding="0" cellspacing="0" width="100%">
455
- <tr style="border:none;height:40px;margin-top:10px;text-align:left">
456
- <th style="width:300px;">Description</th>
457
- <th style="width:120px;">Price</th>
458
- <th style="width:120px;">Stores</th>
459
- <th style="width:120px;">Total Amount</th>
479
+ <tr bgcolor="#F9FAFB" style="border-bottom:1px solid #f0ecea;height:40px;;margin-top:10px;text-align:left">
480
+ <th class="invoicedescription" style="width:300px;">Description</th>
481
+ <th class="invoicedescription" style="width:120px;">Price</th>
482
+ <th class="invoicedescription" style="width:120px;">Stores</th>
483
+ <th class="invoicedescription" style="width:120px;">Total Amount</th>
484
+ </tr>
485
+ <tr style="border:none;">
486
+ <td colspan="4" align="left" bgcolor="#ffffff" style="font-size: 14px; line-height: 24px;">
487
+ <p class="" style="border: 0px solid #EAECF0;">
488
+ </p>
489
+ </td>
460
490
  </tr>
461
491
  {{#each data.products}}
462
492
  <tr style="border:none;margin-top:10px;">
463
- <td>{{product.product}}</td>
464
- <td>${{basePrice}}</td>
465
- <td>{{count}}</td>
466
- <td>${{price}}</td>
493
+ <td class="productstext">{{product.product}}</td>
494
+ <td class="productstext">{{../data.currencyType}} {{basePrice}}</td>
495
+ <td class="productstext">{{count}}</td>
496
+ <td class="productstext">{{../data.currencyType}} {{price}}</td>
467
497
  </tr>
468
498
  {{/each}}
469
- <tr style="border:none;">
470
- <td></td>
471
- <td></td>
472
- <td></td>
473
- <td></td>
499
+
500
+ <tr>
501
+ <td colspan="4" align="left" bgcolor="#ffffff"
502
+ style="font-size: 14px; line-height: 24px;">
503
+ <p class="" style="border: 1px solid #EAECF0;">
504
+ </p>
505
+ </td>
474
506
  </tr>
475
- <tr style="border:none;border-top: 5px solid #eaecf0;margin-top:10px;">
476
- <td>Sub Total</td>
507
+ <tr style="border:none;margin-top:10px;">
508
+ <td class="invoicesub">Sub Total</td>
477
509
  <td></td>
478
510
  <td></td>
479
- <td>${{data.amount}}</td>
511
+ <td class="invoicesub">{{data.currencyType}} {{data.amount}}</td>
480
512
  </tr>
481
513
  <tr style="border:none;margin-top:10px;">
482
- <td>IGST</td>
514
+ <td class="invoicesub">IGST</td>
483
515
  <td></td>
484
516
  <td></td>
485
- <td>0%</td>
517
+ <td class="invoicesub">0%</td>
486
518
  </tr>
487
519
  <tr style="border:none;margin-top:10px;">
488
- <td>Total</td>
520
+ <td class="invoicesub">Total</td>
489
521
  <td></td>
490
522
  <td></td>
491
- <td>${{data.total}}</td>
523
+ <td class="invoicesub">{{data.currencyType}} {{data.total}}</td>
492
524
  </tr>
493
525
  <tr style="border:none;margin-top:10px;">
494
- <td>Discount</td>
526
+ <td class="invoicesub">Discount</td>
495
527
  <td></td>
496
528
  <td></td>
497
- <td>{{data.discount}}</td>
529
+ <td class="invoicesub">{{data.discount}}</td>
498
530
  </tr>
499
- <tr style="border:none;">
500
- <td></td>
501
- <td></td>
502
- <td></td>
503
- <td></td>
531
+ <tr>
532
+ <td colspan="4" align="left" bgcolor="#ffffff"
533
+ style="font-size: 14px; line-height: 24px;">
534
+ <p class="" style="border: 1px solid #EAECF0;">
535
+ </p>
536
+ </td>
504
537
  </tr>
505
- <tr style="border:none;border-top: 5px solid #eaecf0;margin-top:10px;">
506
- <td>Final Value</td>
538
+ <tr style="border:none;margin-top:10px;">
539
+ <td class="invoicesub">Final Value</td>
507
540
  <td></td>
508
541
  <td></td>
509
- <td>${{data.total}}</td>
542
+ <td class="invoicesub">{{data.currencyType}} {{data.total}}</td>
510
543
  </tr>
511
544
  </table>
512
545
  </td>
@@ -514,41 +547,43 @@
514
547
  </table>
515
548
  </td>
516
549
  </tr>
517
- </table>
518
- </td>
519
- </tr>
520
-
521
-
522
- <tr>
523
- <td align="center" bgcolor="#dbe5ea" style="padding: 0px 15px 32px 15px;">
524
- <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 648px;">
525
- <tr>
526
- <td class="o_bg-white o_px-md o_py-xl o_xs-py-md"
527
- style="background-color: #ffffff;padding-left: 35px;padding-right: 24px;padding-top:10px">
528
- <div class="o_col-6s o_sans o_text-md o_text-light o_center"
529
- style="margin-top: 35px;margin-bottom: 0px;font-size: 12px;color: #202B3C;font-style: normal;font-weight: 400;font-size: 12px;line-height: 150%;">
530
- <p>
531
- If you'd rather not receive this kind of email, Don’t want any more emails from
532
- TangoEye? <a
533
- style="color: var(--Primary-Base, #00A3FF); text-decoration-line: underline; letter-spacing: 0.2px;">Unsubscribe.</a>
534
- </p>
535
- </div>
536
- </td>
537
- </tr>
538
550
  <tr>
539
- <td class="o_bg-white o_px-md o_py-xl o_xs-py-md"
540
- style="background-color: #ffffff;padding:0px 24px 15px 27px">
541
- <div class="o_col-6s o_sans o_text-md o_text-light o_center"
542
- style="margin-top: 0px;margin-bottom: 0px;font-size: 12px;color: #202B3C;font-style: normal;font-weight: 400;font-size: 12px;line-height: 150%; padding-left: 7px;">
543
- <p>
544
- © Tango Eye. All rights reserved.</p>
545
- </div>
551
+ <td align="center" bgcolor="#dbe5ea" style="padding:0 0px 32px 0px;">
552
+ <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 648px;">
553
+ <tr>
554
+ <td class="o_bg-white o_px-md o_py-xl o_xs-py-md"
555
+ style="background-color: #ffffff;padding-left: 35px;padding-right: 24px;padding-top:10px">
556
+ <div class="o_col-6s o_sans o_text-md o_text-light o_center"
557
+ style="margin-top: 35px;margin-bottom: 0px;font-size: 12px;color: #202B3C;font-style: normal;font-weight: 400;font-size: 12px;line-height: 150%;">
558
+ <p>
559
+ If you'd rather not receive this kind of email, Don’t want any more emails from
560
+ TangoEye? <a
561
+ style="color: var(--Primary-Base, #00A3FF); text-decoration-line: underline; letter-spacing: 0.2px;">Unsubscribe.</a>
562
+ </p>
563
+ </div>
564
+ </td>
565
+ </tr>
566
+ <tr>
567
+ <td class="o_bg-white o_px-md o_py-xl o_xs-py-md"
568
+ style="background-color: #ffffff;padding:0px 24px 15px 27px">
569
+ <div class="o_col-6s o_sans o_text-md o_text-light o_center"
570
+ style="margin-top: 0px;margin-bottom: 0px;font-size: 12px;color: #202B3C;font-style: normal;font-weight: 400;font-size: 12px;line-height: 150%; padding-left: 7px;">
571
+ <p>
572
+ © Tango Eye. All rights reserved.</p>
573
+ </div>
574
+ </td>
575
+ </tr>
576
+ </table>
546
577
  </td>
547
578
  </tr>
548
579
  </table>
549
580
  </td>
581
+
550
582
  </tr>
551
583
 
584
+
585
+
586
+
552
587
  </table>
553
588
 
554
589
  </body>
@@ -121,7 +121,7 @@
121
121
  style="margin-top: 0px;margin-bottom: 0px;font-size: 24px;line-height: 28px;color: #82899a;">
122
122
  <span class="o_heading o_text-dark o_mb-xxs"
123
123
  style="font-weight: 700;margin-top: 0px;margin-bottom: 4px;color: #121A26;line-height: 39px;">
124
- Unlock Premium Features - Your Tango Traffic Trial Has Ended</span>
124
+ Unlock Premium Features - Your {{data.product}} Trial Has Ended</span>
125
125
  </div>
126
126
  </td>
127
127
  </tr>
@@ -15,3 +15,7 @@ export const find = async ( query ={}, record={} ) => {
15
15
  export const create = async ( data ) => {
16
16
  return await model.invoiceModel.create( data );
17
17
  };
18
+
19
+ export const count = async ( query ) => {
20
+ return await model.invoiceModel.count( query );
21
+ };