tango-app-api-payment-subscription 3.0.17-dev → 3.0.19-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.17-dev",
3
+ "version": "3.0.19-dev",
4
4
  "description": "paymentSubscription",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -10,6 +10,9 @@ import dayjs from 'dayjs';
10
10
  import Handlebars from 'handlebars';
11
11
  import fs from 'fs';
12
12
  import path from 'path';
13
+ import { JSDOM } from 'jsdom';
14
+ import pdfMake from 'pdfmake';
15
+ import htmlToPdfmake from 'html-to-pdfmake';
13
16
 
14
17
  export const addBilling = async ( req, res ) => {
15
18
  try {
@@ -600,6 +603,7 @@ export const notificationList = async ( req, res ) => {
600
603
  query.status = 'pending';
601
604
  if ( req?.query?.clientId ) {
602
605
  query.clientId = req?.query?.clientId;
606
+ query.category = { $ne: 'TrialExtend' };
603
607
  }
604
608
  let notificationList = await clientRequestService.find( query, { createdAt: 0, updatedAt: 0 } );
605
609
  query = [
@@ -629,13 +633,13 @@ export const notificationList = async ( req, res ) => {
629
633
  if ( item.product?.trialStartDate && item.product?.trialEndDate ) {
630
634
  let [ firstWord, secondWord ] = item.product.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
631
635
  firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
632
- let startDate = dayjs( item.product.trialStartDate );
633
- let endDate = dayjs( item.product.trialEndDate ).startOf( 'day' );
636
+ let startDate = dayjs( item.product.trialStartDate ).startOf( 'day' );
637
+ let endDate = dayjs( item.product.trialEndDate ).startOf( 'day' ).add( 1, 'days' );
634
638
  let date = dayjs().startOf( 'day' );
635
639
  let days = date.diff( startDate, 'day' );
636
640
  let totalDays = endDate.diff( startDate, 'day' );
637
641
  let percentage = Math.round( ( days / totalDays )* 100 );
638
- let leftDays = endDate.diff( date, 'day' ) + 1;
642
+ let leftDays = endDate.diff( date, 'day' );
639
643
  notificationList.push( {
640
644
  product: item.product.productName,
641
645
  name: `${firstWord} ${secondWord}`,
@@ -757,7 +761,7 @@ export const trialExtendRequestApproval = async ( req, res ) => {
757
761
  days: req.body.days,
758
762
  date: trialDate,
759
763
  };
760
- const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialExtensionEmail.hbs', 'utf8' );
764
+ const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialExtentionEmail.hbs', 'utf8' );
761
765
  const template = Handlebars.compile( templateHtml );
762
766
  const html = template( { data: data } );
763
767
  let params = {
@@ -771,6 +775,7 @@ export const trialExtendRequestApproval = async ( req, res ) => {
771
775
  }
772
776
  return res.sendSuccess( 'Trial Extended Successfully' );
773
777
  } ).catch( ( e ) => {
778
+ logger.error( { error: e, function: 'trialExtendRequestApproval' } );
774
779
  return res.sendError( e, 500 );
775
780
  } );
776
781
  } catch ( e ) {
@@ -924,6 +929,7 @@ export const productViewList = async ( req, res ) => {
924
929
  },
925
930
  },
926
931
  ];
932
+
927
933
  let storeProductCount = await storeService.aggregate( query );
928
934
  let clientProduct = await paymentService.findOne( { clientId: req.query.clientId }, { 'planDetails.product': 1 } );
929
935
 
@@ -952,6 +958,11 @@ export const productViewList = async ( req, res ) => {
952
958
  },
953
959
  );
954
960
  } );
961
+ if ( req.query.sortBy == -1 ) {
962
+ products.sort( ( a, b ) => b.storeCount - a.storeCount ? -1 : 1 );
963
+ } else {
964
+ products.sort( ( a, b ) => a.storeCount - b.storeCount ? 1 : -1 );
965
+ }
955
966
  // storeProductCount.forEach( ( item ) => {
956
967
  // let productBasePrice = productPrice.basePricing.find( ( product ) => product.productName == item.product );
957
968
  // if ( productBasePrice ) {
@@ -1222,6 +1233,21 @@ export const invoiceList = async ( req, res ) => {
1222
1233
  } );
1223
1234
  }
1224
1235
 
1236
+ query.push( {
1237
+ $project: {
1238
+ _id: 1,
1239
+ invoice: 1,
1240
+ billingDate: 1,
1241
+ stores: 1,
1242
+ products: 1,
1243
+ amount: 1,
1244
+ paymentMethod: 1,
1245
+ status: 1,
1246
+ discount: 1,
1247
+ revisedAmount: 1,
1248
+ },
1249
+ } );
1250
+
1225
1251
  query.push(
1226
1252
  {
1227
1253
  $facet: {
@@ -1241,6 +1267,16 @@ export const invoiceList = async ( req, res ) => {
1241
1267
  if ( !invoiceDetails[0]?.data.length ) {
1242
1268
  return res.sendError( 'no data found', 204 );
1243
1269
  }
1270
+ invoiceDetails[0].data.forEach( ( item ) => {
1271
+ item.billingDate = dayjs( item.billingDate ).format( 'DD MMM, YYYY' );
1272
+ } );
1273
+ if ( req.user.userType == 'client' ) {
1274
+ invoiceDetails[0].data.forEach( ( item ) => {
1275
+ delete item.discount;
1276
+ delete item.revisedAmount;
1277
+ delete item.products;
1278
+ } );
1279
+ }
1244
1280
  let data = {
1245
1281
  data: invoiceDetails[0].data,
1246
1282
  count: invoiceDetails[0].count[0].count,
@@ -1248,7 +1284,25 @@ export const invoiceList = async ( req, res ) => {
1248
1284
  if ( !req.body.export ) {
1249
1285
  return res.sendSuccess( data );
1250
1286
  } else {
1251
- download( invoiceDetails[0].data, res );
1287
+ let exportData = [];
1288
+ invoiceDetails[0].data.forEach( ( item ) => {
1289
+ if ( item.status == 'trial' ) {
1290
+ item.amount = 'Trial';
1291
+ }
1292
+ if ( item.status == 'free' ) {
1293
+ item.amount = 'Free';
1294
+ }
1295
+ exportData.push( {
1296
+ 'Invoice': item.invoice,
1297
+ 'Billing Date': item.billingDate,
1298
+ 'Stores': item.stores,
1299
+ ...( req.user.userType == 'tango' ? { 'Products': item.products } : {} ),
1300
+ 'Amount': item.amount,
1301
+ ...( req.user.userType == 'client' ? { 'Payment Method': item.paymentMethod } : {} ),
1302
+ 'Status': item.status,
1303
+ } );
1304
+ } );
1305
+ await download( exportData, res );
1252
1306
  }
1253
1307
  } catch ( e ) {
1254
1308
  logger.error( { error: e, function: 'invoiceList' } );
@@ -1344,7 +1398,7 @@ export const priceList = async ( req, res ) => {
1344
1398
  let result = {
1345
1399
  product: data,
1346
1400
  totalActualPrice: originalTotalPrice,
1347
- totalNegotiatePrice: discountTotalPrice,
1401
+ totalNegotiatePrice: discountTotalPrice.toFixed( 2 ),
1348
1402
  actualPrice: totalProductPrice,
1349
1403
  negotiatePrice: totalnegotiatePrice,
1350
1404
  discountPrice: discountPrice,
@@ -1378,7 +1432,7 @@ export const pricingListUpdate = async ( req, res ) => {
1378
1432
  productName: product,
1379
1433
  discountPercentage: baseDetails.discoutPercentage,
1380
1434
  basePrice: baseDetails.basePrice,
1381
- negotiatePrice: baseDetails.basePrice - discountPrice,
1435
+ negotiatePrice: discountPrice,
1382
1436
  },
1383
1437
  );
1384
1438
  stepList.push(
@@ -1386,7 +1440,7 @@ export const pricingListUpdate = async ( req, res ) => {
1386
1440
  productName: product,
1387
1441
  discountPercentage: baseDetails.discoutPercentage,
1388
1442
  basePrice: baseDetails.basePrice,
1389
- negotiatePrice: baseDetails.basePrice - discountPrice,
1443
+ negotiatePrice: discountPrice,
1390
1444
  storeRange: '1-100',
1391
1445
  },
1392
1446
  );
@@ -1495,7 +1549,7 @@ export const updatedRevisedPrice = async ( req, res ) => {
1495
1549
 
1496
1550
  export const unpaidInvoiceList = async ( req, res ) => {
1497
1551
  try {
1498
- let invoiceDetails = await invoiceService.find( { clientId: req.params.clientId, status: { $ne: 'paid' } }, { invoice: 1, status: 1, amount: 1, revisedAmount: 1, totalAmount: 1, discount: 1 } );
1552
+ let invoiceDetails = await invoiceService.find( { clientId: req.params.clientId, status: { $nin: [ 'paid', 'trial', 'free' ] } }, { invoice: 1, status: 1, amount: 1, revisedAmount: 1, totalAmount: 1, discount: 1 } );
1499
1553
  if ( !invoiceDetails.length ) {
1500
1554
  return res.sendError( 'no data found', 204 );
1501
1555
  }
@@ -1641,12 +1695,34 @@ export const getExpiredClients = async ( req, res ) => {
1641
1695
 
1642
1696
  export const invoiceDownload = async ( req, res ) => {
1643
1697
  try {
1644
- // const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/invoicePdf.hbs', 'utf8' );
1645
- // const template = Handlebars.compile( templateHtml );
1646
- // const html = template( { data: '' } );
1647
- // console.log( html );
1698
+ const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/invoicePdf.hbs', 'utf8' );
1699
+ const template = Handlebars.compile( templateHtml );
1700
+ const html = template( { data: '' } );
1701
+ let fonts = {
1702
+ Helvetica: {
1703
+ normal: 'Helvetica',
1704
+ bold: 'Helvetica-Bold',
1705
+ italics: 'Helvetica-Oblique',
1706
+ bolditalics: 'Helvetica-BoldOblique',
1707
+ },
1708
+ };
1709
+ let printer = new pdfMake( fonts );
1710
+
1711
+ let { window } = new JSDOM( '' );
1712
+ const htmlTemplate = htmlToPdfmake( html, { window: window, tableAutoSize: true } );
1713
+
1714
+ const docDefinition = {
1715
+ content: htmlTemplate,
1716
+ defaultStyle: {
1717
+ font: 'Helvetica',
1718
+ },
1719
+ };
1720
+ let pdfDoc = printer.createPdfKitDocument( docDefinition );
1721
+ res.setHeader( 'Content-disposition', `attachment; filename=Report_1.pdf` );
1722
+ res.setHeader( 'Content-Type', 'application/pdf' );
1723
+ pdfDoc.pipe( res );
1724
+ pdfDoc.end();
1648
1725
  } catch ( e ) {
1649
- // console.log( e );
1650
1726
  logger.error( { error: e, function: 'invoiceDownload' } );
1651
1727
  return res.sendError( e, 500 );
1652
1728
  }
@@ -1661,7 +1737,7 @@ export const updateInvoiceStatus = async ( req, res ) => {
1661
1737
  if ( !invoiceDetails ) {
1662
1738
  return res.sendError( 'no data found', 204 );
1663
1739
  }
1664
- invoiceDetails.status = req.body?.status || 'paid';
1740
+ invoiceDetails.status = req.body?.status || 'Payment Received';
1665
1741
  invoiceDetails.save().then( async () => {
1666
1742
  let clientInfo = await paymentService.findOne( { clientId: invoiceDetails.clientId } );
1667
1743
  if ( clientInfo ) {
@@ -1671,7 +1747,7 @@ export const updateInvoiceStatus = async ( req, res ) => {
1671
1747
  return res.sendSuccess( 'Invoice updated Successfully' );
1672
1748
  } );
1673
1749
  } catch ( e ) {
1674
- logger.error( { error: e, function: 'invoiceDownload' } );
1750
+ logger.error( { error: e, function: 'updateInvoiceStatus' } );
1675
1751
  return res.sendError( e, 500 );
1676
1752
  }
1677
1753
  };
@@ -1682,12 +1758,13 @@ export const invoiceCreate = async ( req, res ) => {
1682
1758
  let products = req.body.client.planDetails.product.map( ( item ) => item.productName );
1683
1759
  let storeDetails = await storeService.count( { clientId: req.body.clientId, status: 'active' } );
1684
1760
  let data;
1761
+ let clientId = req.body.clientId;
1685
1762
  data = {
1686
1763
  invoice: `invoice #0${req.body.client.clientId} - ${Math.floor( Math.random() * 100 ) + 1}`,
1687
1764
  billingDate: new Date(),
1688
1765
  products: products,
1689
1766
  stores: storeDetails,
1690
- status: '',
1767
+ status: 'pending',
1691
1768
  clientId: req.body.clientId,
1692
1769
  };
1693
1770
  req.body = {
@@ -1700,15 +1777,14 @@ export const invoiceCreate = async ( req, res ) => {
1700
1777
  let pricingDetails = await calculatePricing( req, res );
1701
1778
  data.amount = pricingDetails.price;
1702
1779
  await invoiceService.create( data );
1703
- let clientInfo = await paymentService.findOne( { clientId: req.body.clientId } );
1780
+ let clientInfo = await paymentService.findOne( { clientId: clientId } );
1704
1781
  if ( clientInfo ) {
1705
1782
  clientInfo.planDetails.paymentStatus = 'due';
1706
1783
  clientInfo.save();
1707
1784
  }
1708
1785
  return res.sendSuccess( 'Invoice Created Successfully' );
1709
1786
  } catch ( e ) {
1710
- // console.log( e );
1711
- logger.error( { error: e, function: 'invoiceDownload' } );
1787
+ logger.error( { error: e, function: 'invoiceCreate' } );
1712
1788
  return res.sendError( e, 500 );
1713
1789
  }
1714
1790
  };
@@ -20,6 +20,14 @@ export const validateStoreParams = {
20
20
  } ),
21
21
  };
22
22
 
23
+ export const validateProductListParams = {
24
+ query: joi.object( {
25
+ clientId: joi.string().required(),
26
+ sortColumn: joi.string().required(),
27
+ sortBy: joi.number().required(),
28
+ } ),
29
+ };
30
+
23
31
  export const validateProducts = {
24
32
  body: joi.object( {
25
33
  camaraPerSqft: joi.string().required(),
@@ -97,7 +105,7 @@ export const validateInvoiceParams = {
97
105
  body: joi.object( {
98
106
  limit: joi.number().required(),
99
107
  offset: joi.number().required(),
100
- searchValue: joi.string().optional(),
108
+ searchValue: joi.string().optional().empty( '' ),
101
109
  filter: joi.string().optional(),
102
110
  sortColumn: joi.string().optional(),
103
111
  sortBy: joi.number().optional(),
@@ -96,7 +96,7 @@ paymentSubscriptionRouter.get( '/admin/getProductViewList', isAllowedSessionHand
96
96
  userType: [ 'tango' ], access: [
97
97
  { featureName: 'settings', name: 'paymentSubscriptions', permissions: [ 'isView' ] },
98
98
  ],
99
- } ), validate( validationDtos.validateStoreParams ), validateClient, paymentController.productViewList );
99
+ } ), validate( validationDtos.validateProductListParams ), validateClient, paymentController.productViewList );
100
100
 
101
101
  paymentSubscriptionRouter.post( '/admin/getstoreViewList', isAllowedSessionHandler, authorize( {
102
102
  userType: [ 'tango' ], access: [
@@ -154,7 +154,7 @@ paymentSubscriptionRouter.post( '/admin/getStoreProducts', isAllowedSessionHandl
154
154
 
155
155
  paymentSubscriptionRouter.get( '/trialRemaindList', paymentController.getRemindClients );
156
156
  paymentSubscriptionRouter.get( '/trialExpiredList', paymentController.getExpiredClients );
157
- paymentSubscriptionRouter.get( '/invoiceDownload', paymentController.invoiceDownload );
157
+ paymentSubscriptionRouter.post( '/invoiceDownload', paymentController.invoiceDownload );
158
158
  paymentSubscriptionRouter.post( '/invoiceStatusUpdate/:invoiceId', paymentController.updateInvoiceStatus );
159
159
  paymentSubscriptionRouter.post( '/invoice/create', validateClient, paymentController.invoiceCreate );
160
160
 
@@ -1,7 +1,7 @@
1
1
  import model from 'tango-api-schema';
2
2
 
3
3
  export const aggregate = async ( query ={} ) => {
4
- return await model.invoiceModel.aggregate( query );
4
+ return await model.invoiceModel.aggregate( query, { collation: { locale: 'en_US', numericOrdering: true } } );
5
5
  };
6
6
 
7
7
  export const findOne = async ( query ={}, record={} ) => {