tango-app-api-payment-subscription 3.0.43-dev → 3.0.44-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 +2 -3
- package/src/controllers/paymentSubscription.controllers.js +312 -191
- package/src/dtos/validation.dtos.js +4 -0
- package/src/hbs/invoicePdf.hbs +1558 -179
- package/src/hbs/invoicePdfold.hbs +198 -0
- package/src/routes/paymentSubscription.routes.js +1 -1
- package/src/services/invoice.service.js +3 -0
|
@@ -13,16 +13,18 @@ import dayjs from 'dayjs';
|
|
|
13
13
|
import Handlebars from 'handlebars';
|
|
14
14
|
import fs from 'fs';
|
|
15
15
|
import path from 'path';
|
|
16
|
-
import { JSDOM } from 'jsdom';
|
|
17
|
-
import pdfMake from 'pdfmake';
|
|
18
|
-
import htmlToPdfmake from 'html-to-pdfmake';
|
|
16
|
+
// import { JSDOM } from 'jsdom';
|
|
17
|
+
// import pdfMake from 'pdfmake';
|
|
18
|
+
// import htmlToPdfmake from 'html-to-pdfmake';
|
|
19
19
|
import axios from 'axios';
|
|
20
|
-
|
|
20
|
+
import htmlpdf from 'html-pdf-node';
|
|
21
21
|
export const addBilling = async ( req, res ) => {
|
|
22
22
|
try {
|
|
23
23
|
let params = {
|
|
24
24
|
'billingDetails.gstNumber': req.body.gstNo,
|
|
25
25
|
'billingDetails.billingAddress': req.body.billingAddress,
|
|
26
|
+
'billingDetails.companyName': req.body.companyName,
|
|
27
|
+
'billingDetails.PlaceOfSupply': req.body.PlaceOfSupply,
|
|
26
28
|
};
|
|
27
29
|
let result = await paymentService.updateOne( { clientId: req.body.clientId }, params );
|
|
28
30
|
if ( result.modifiedCount ) {
|
|
@@ -152,7 +154,7 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
|
|
|
152
154
|
element.toolTip = 'Trial Expired';
|
|
153
155
|
element.active = true;
|
|
154
156
|
} else {
|
|
155
|
-
trialProducts.push( { 'productName': element.productName, 'aliseProductName': element.aliseProductName, 'toolTip': differenceInDays +' days trial left' } );
|
|
157
|
+
trialProducts.push( { 'productName': element.productName, 'aliseProductName': element.aliseProductName, 'toolTip': differenceInDays + ' days trial left' } );
|
|
156
158
|
element.toolTip = 'On Trial';
|
|
157
159
|
element.active = true;
|
|
158
160
|
}
|
|
@@ -173,7 +175,7 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
|
|
|
173
175
|
let getPI = false;
|
|
174
176
|
if ( getPendingInvoice.length > 0 ) {
|
|
175
177
|
if ( getPendingInvoice[0].billingDate >= currentDate ) {
|
|
176
|
-
getPI= false;
|
|
178
|
+
getPI = false;
|
|
177
179
|
} else {
|
|
178
180
|
getPI = true;
|
|
179
181
|
}
|
|
@@ -202,7 +204,7 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
|
|
|
202
204
|
currentPlanInfo.expiredProducts = expiredProducts || '--';
|
|
203
205
|
currentPlanInfo.product = activeProducts || '--';
|
|
204
206
|
currentPlanInfo.pendingClientRequest = getPCR;
|
|
205
|
-
currentPlanInfo.currencyType = clientInfo[0].paymentInvoice.currencyType;
|
|
207
|
+
currentPlanInfo.currencyType = clientInfo[0].paymentInvoice && clientInfo[0].paymentInvoice.currencyType;
|
|
206
208
|
currentPlanInfo.dollarPrice = await convertINRtoUSD( clientInfo[0].price );
|
|
207
209
|
let data = {
|
|
208
210
|
_id: clientInfo[0]._id,
|
|
@@ -273,7 +275,7 @@ async function calculatePricing( req, res ) {
|
|
|
273
275
|
productDiscounts.push( getProduct.discoutPercentage );
|
|
274
276
|
}
|
|
275
277
|
let stage = 0;
|
|
276
|
-
if ( input.storesCount == '
|
|
278
|
+
if ( input.storesCount == '2-25' ) {
|
|
277
279
|
stage = 0;
|
|
278
280
|
} else if ( input.storesCount == '26-50' ) {
|
|
279
281
|
stage = 1;
|
|
@@ -298,7 +300,9 @@ async function calculatePricing( req, res ) {
|
|
|
298
300
|
} else if ( input.storesCount == '2000+' ) {
|
|
299
301
|
stage = 9;
|
|
300
302
|
}
|
|
301
|
-
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
let discountprice = Math.round( basicprice * ( Math.pow( 0.92, stage ) )/10 )*10;
|
|
302
306
|
dummy.push( discountprice );
|
|
303
307
|
OriginalPrice = OriginalPrice + discountprice;
|
|
304
308
|
finalPrice = finalPrice + discountprice;
|
|
@@ -462,7 +466,7 @@ export const updateSubscription = async ( req, res ) => {
|
|
|
462
466
|
};
|
|
463
467
|
let pricingDetails = await calculatePricing( req, res );
|
|
464
468
|
if ( subscriptionCount ) {
|
|
465
|
-
let userDetails= await userService.findOne( { clientId: requestBody.clientId, role: 'superadmin' } );
|
|
469
|
+
let userDetails = await userService.findOne( { clientId: requestBody.clientId, role: 'superadmin' } );
|
|
466
470
|
if ( userDetails ) {
|
|
467
471
|
let data = {
|
|
468
472
|
userName: userDetails.userName,
|
|
@@ -552,7 +556,7 @@ export const updateSubscription = async ( req, res ) => {
|
|
|
552
556
|
|
|
553
557
|
export const trialProductList = async ( req, res ) => {
|
|
554
558
|
try {
|
|
555
|
-
let query =[
|
|
559
|
+
let query = [
|
|
556
560
|
{
|
|
557
561
|
$match: {
|
|
558
562
|
clientId: req.query.clientId,
|
|
@@ -717,6 +721,8 @@ export const invoiceDetails = async ( req, res ) => {
|
|
|
717
721
|
paymentCycle: clientInvoiceDetails?.paymentInvoice?.paymentCycle || '',
|
|
718
722
|
currencyType: clientInvoiceDetails?.paymentInvoice?.currencyType || '',
|
|
719
723
|
invoiceTo: clientInvoiceDetails?.paymentInvoice?.invoiceTo || [],
|
|
724
|
+
invoiceCC: clientInvoiceDetails?.paymentInvoice?.invoiceCC || [],
|
|
725
|
+
PomNumber: clientInvoiceDetails?.paymentInvoice?.PomNumber || [],
|
|
720
726
|
paymentAgreementTo: clientInvoiceDetails?.paymentInvoice?.paymentAgreementTo || [],
|
|
721
727
|
invoiceOn: clientInvoiceDetails?.paymentInvoice?.invoiceOn || '',
|
|
722
728
|
extendPaymentPeriodDays: clientInvoiceDetails?.paymentInvoice?.extendPaymentPeriodDays || '',
|
|
@@ -741,6 +747,9 @@ export const updateInvoiceDetails = async ( req, res ) => {
|
|
|
741
747
|
clientInvoiceDetails.paymentInvoice.paymentCycle = data.paymentCycle;
|
|
742
748
|
clientInvoiceDetails.paymentInvoice.currencyType = data.currencyType;
|
|
743
749
|
clientInvoiceDetails.paymentInvoice.invoiceTo = data.invoiceTo;
|
|
750
|
+
clientInvoiceDetails.paymentInvoice.invoiceCC = data.invoiceCC;
|
|
751
|
+
clientInvoiceDetails.paymentInvoice.invoiceCC = data.invoiceCC;
|
|
752
|
+
clientInvoiceDetails.paymentInvoice.PomNumber = data.PomNumber;
|
|
744
753
|
clientInvoiceDetails.paymentInvoice.paymentAgreementTo = data.paymentAgreementTo;
|
|
745
754
|
clientInvoiceDetails.paymentInvoice.invoiceOn = data.invoiceOn;
|
|
746
755
|
clientInvoiceDetails.paymentInvoice.extendPaymentPeriodDays = data.extendPaymentPeriodDays;
|
|
@@ -808,7 +817,7 @@ export const notificationList = async ( req, res ) => {
|
|
|
808
817
|
let date = dayjs().startOf( 'day' );
|
|
809
818
|
let days = date.diff( startDate, 'day' );
|
|
810
819
|
let totalDays = endDate.diff( startDate, 'day' );
|
|
811
|
-
let percentage = Math.round( ( days / totalDays )* 100 );
|
|
820
|
+
let percentage = Math.round( ( days / totalDays ) * 100 );
|
|
812
821
|
let leftDays = endDate.diff( date, 'day' );
|
|
813
822
|
notificationList.push( {
|
|
814
823
|
product: item.product.productName,
|
|
@@ -877,13 +886,13 @@ export const trialApproval = async ( req, res ) => {
|
|
|
877
886
|
await storeService.addremoveElement( { clientId: requestData.clientId }, { $push: { product: requestData.name } } );
|
|
878
887
|
req.body.clientId = requestData.clientId;
|
|
879
888
|
updatePricing( req, res, true );
|
|
880
|
-
let userDetails= await userService.findOne( { clientId: requestData.clientId, role: 'superadmin' } );
|
|
889
|
+
let userDetails = await userService.findOne( { clientId: requestData.clientId, role: 'superadmin' } );
|
|
881
890
|
let [ firstWord, secondWord ] = requestData.name.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
882
891
|
firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
883
892
|
if ( userDetails ) {
|
|
884
893
|
let data = {
|
|
885
894
|
userName: userDetails.userName,
|
|
886
|
-
product: firstWord +' '+ secondWord,
|
|
895
|
+
product: firstWord + ' ' + secondWord,
|
|
887
896
|
domain: appConfig.url.domain,
|
|
888
897
|
};
|
|
889
898
|
const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialInitiateEmail.hbs', 'utf8' );
|
|
@@ -973,13 +982,13 @@ export const trialExtendRequestApproval = async ( req, res ) => {
|
|
|
973
982
|
requestData.status = 'completed';
|
|
974
983
|
requestData.save();
|
|
975
984
|
}
|
|
976
|
-
let userDetails= await userService.findOne( { clientId: req.body.clientId, role: 'superadmin' } );
|
|
985
|
+
let userDetails = await userService.findOne( { clientId: req.body.clientId, role: 'superadmin' } );
|
|
977
986
|
if ( userDetails ) {
|
|
978
987
|
let [ firstWord, secondWord ] = req.body.product.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
979
988
|
firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
980
989
|
let data = {
|
|
981
990
|
userName: userDetails.userName,
|
|
982
|
-
product: firstWord +' '+secondWord,
|
|
991
|
+
product: firstWord + ' ' + secondWord,
|
|
983
992
|
days: req.body.days,
|
|
984
993
|
date: dayjs( trialDate ).format( 'YYYY-MM-DD' ),
|
|
985
994
|
domain: appConfig.url.domain,
|
|
@@ -1043,7 +1052,7 @@ export const productSubscribe = async ( req, res ) => {
|
|
|
1043
1052
|
let removeProducts = req.body.product.filter( ( item ) => item.type == 'unsubscribe' ).map( ( item ) => item.name );
|
|
1044
1053
|
let productList = product.map( ( item ) => item.productName );
|
|
1045
1054
|
for ( let item of req.body.product ) {
|
|
1046
|
-
if ( productList.includes( item.name ) && item.type =='unsubscribe' ) {
|
|
1055
|
+
if ( productList.includes( item.name ) && item.type == 'unsubscribe' ) {
|
|
1047
1056
|
await storeService.addremoveElement( { clientId: clientInfo.clientId, product: { $in: item.name } }, { $pull: { product: item.name } } );
|
|
1048
1057
|
}
|
|
1049
1058
|
if ( !productList.includes( item.name ) && [ 'trial', 'subscription' ].includes( item.type ) ) {
|
|
@@ -1056,7 +1065,7 @@ export const productSubscribe = async ( req, res ) => {
|
|
|
1056
1065
|
} );
|
|
1057
1066
|
let [ firstWord, secondWord ] = item.name.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
1058
1067
|
firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
1059
|
-
let productName =firstWord + ' ' +secondWord;
|
|
1068
|
+
let productName = firstWord + ' ' + secondWord;
|
|
1060
1069
|
trialProduct.push( productName );
|
|
1061
1070
|
} else {
|
|
1062
1071
|
product.push( {
|
|
@@ -1082,7 +1091,7 @@ export const productSubscribe = async ( req, res ) => {
|
|
|
1082
1091
|
if ( product.length > 1 ) {
|
|
1083
1092
|
clientInfo.planDetails.subscriptionType = 'premium';
|
|
1084
1093
|
}
|
|
1085
|
-
let userDetails= await userService.findOne( { clientId: clientInfo.clientId, role: 'superadmin' } );
|
|
1094
|
+
let userDetails = await userService.findOne( { clientId: clientInfo.clientId, role: 'superadmin' } );
|
|
1086
1095
|
if ( subscriptionCount ) {
|
|
1087
1096
|
if ( userDetails ) {
|
|
1088
1097
|
let data = {
|
|
@@ -1196,7 +1205,7 @@ export const unsubscribeApproval = async ( req, res ) => {
|
|
|
1196
1205
|
clientProducts.save();
|
|
1197
1206
|
await storeService.updateMany( { clientId: requestData.clientId }, { status: 'deactive' } );
|
|
1198
1207
|
await userService.updateMany( { clientId: requestData.clientId }, { isActive: false } );
|
|
1199
|
-
let userDetails= await userService.findOne( { clientId: requestData.clientId, role: 'superadmin' } );
|
|
1208
|
+
let userDetails = await userService.findOne( { clientId: requestData.clientId, role: 'superadmin' } );
|
|
1200
1209
|
if ( userDetails ) {
|
|
1201
1210
|
const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialUnsubscribeEmail.hbs', 'utf8' );
|
|
1202
1211
|
const template = Handlebars.compile( templateHtml );
|
|
@@ -1463,7 +1472,7 @@ export const addStoreProduct = async ( req, res ) => {
|
|
|
1463
1472
|
};
|
|
1464
1473
|
let [ firstWord, secondWord ] = item.name.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
1465
1474
|
firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
1466
|
-
let productName =firstWord + ' ' +secondWord;
|
|
1475
|
+
let productName = firstWord + ' ' + secondWord;
|
|
1467
1476
|
trialProduct.push( productName );
|
|
1468
1477
|
} else {
|
|
1469
1478
|
clientProduct[productExistsIndex] = {
|
|
@@ -1483,7 +1492,7 @@ export const addStoreProduct = async ( req, res ) => {
|
|
|
1483
1492
|
} );
|
|
1484
1493
|
let [ firstWord, secondWord ] = item.name.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
1485
1494
|
firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
1486
|
-
let productName =firstWord + ' ' +secondWord;
|
|
1495
|
+
let productName = firstWord + ' ' + secondWord;
|
|
1487
1496
|
trialProduct.push( productName );
|
|
1488
1497
|
}
|
|
1489
1498
|
if ( item.type == 'subscription' ) {
|
|
@@ -1498,7 +1507,7 @@ export const addStoreProduct = async ( req, res ) => {
|
|
|
1498
1507
|
}
|
|
1499
1508
|
},
|
|
1500
1509
|
);
|
|
1501
|
-
let userDetails= await userService.findOne( { clientId: req.body.clientId, role: 'superadmin' } );
|
|
1510
|
+
let userDetails = await userService.findOne( { clientId: req.body.clientId, role: 'superadmin' } );
|
|
1502
1511
|
if ( subscriptionCount ) {
|
|
1503
1512
|
if ( userDetails ) {
|
|
1504
1513
|
let data = {
|
|
@@ -1620,13 +1629,13 @@ export const invoiceList = async ( req, res ) => {
|
|
|
1620
1629
|
req.body.limit = 10000;
|
|
1621
1630
|
}
|
|
1622
1631
|
let limit = req.body.limit || 10;
|
|
1623
|
-
let offset = ( req.body.offset-1 ) || 0;
|
|
1632
|
+
let offset = ( req.body.offset - 1 ) || 0;
|
|
1624
1633
|
let skip = limit * offset;
|
|
1625
1634
|
let date;
|
|
1626
1635
|
let endDate;
|
|
1627
1636
|
if ( req.body.filter && req.body.filter == 'current' ) {
|
|
1628
1637
|
date = new Date( dayjs().startOf( 'month' ).format( 'YYYY-MM-DD' ) );
|
|
1629
|
-
endDate= new Date( dayjs().endOf( 'month' ).format( 'YYYY-MM-DD' ) );
|
|
1638
|
+
endDate = new Date( dayjs().endOf( 'month' ).format( 'YYYY-MM-DD' ) );
|
|
1630
1639
|
}
|
|
1631
1640
|
if ( req.body.filter && req.body.filter == 'prev' ) {
|
|
1632
1641
|
date = new Date( dayjs().subtract( 1, 'month' ).startOf( 'month' ).format( 'YYYY-MM-DD' ) );
|
|
@@ -1634,7 +1643,7 @@ export const invoiceList = async ( req, res ) => {
|
|
|
1634
1643
|
}
|
|
1635
1644
|
if ( req.body.filter && req.body.filter == 'last' ) {
|
|
1636
1645
|
date = new Date( dayjs().subtract( 2, 'month' ).startOf( 'month' ).format( 'YYYY-MM-DD' ) );
|
|
1637
|
-
endDate= new Date( dayjs().endOf( 'month' ).format( 'YYYY-MM-DD' ) );
|
|
1646
|
+
endDate = new Date( dayjs().endOf( 'month' ).format( 'YYYY-MM-DD' ) );
|
|
1638
1647
|
}
|
|
1639
1648
|
let query = [];
|
|
1640
1649
|
query = [
|
|
@@ -1694,7 +1703,7 @@ export const invoiceList = async ( req, res ) => {
|
|
|
1694
1703
|
}
|
|
1695
1704
|
invoiceDetails[0].data.forEach( ( item ) => {
|
|
1696
1705
|
item.billingDate = dayjs( item.billingDate ).format( 'DD MMM, YYYY' );
|
|
1697
|
-
if ( item.products?.length>0 ) {
|
|
1706
|
+
if ( item.products?.length > 0 ) {
|
|
1698
1707
|
let newProducts = [];
|
|
1699
1708
|
for ( let productIndex = 0; productIndex < item.products.length; productIndex++ ) {
|
|
1700
1709
|
let [ firstWord, secondWord ] = item.products[productIndex]?.product?.product.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
@@ -1800,7 +1809,7 @@ export const priceList = async ( req, res ) => {
|
|
|
1800
1809
|
} else {
|
|
1801
1810
|
product.showImg = false;
|
|
1802
1811
|
product.showEditDelete = false;
|
|
1803
|
-
if ( index == productDetails.length-1 ) {
|
|
1812
|
+
if ( index == productDetails.length - 1 ) {
|
|
1804
1813
|
if ( index != 0 ) {
|
|
1805
1814
|
product.showImg = true;
|
|
1806
1815
|
product.showEditDelete = true;
|
|
@@ -1815,7 +1824,7 @@ export const priceList = async ( req, res ) => {
|
|
|
1815
1824
|
let rangeArray = product.storeRange.split( '-' );
|
|
1816
1825
|
let startNumber = parseInt( rangeArray[0] );
|
|
1817
1826
|
let endNumber = parseInt( rangeArray[1] );
|
|
1818
|
-
let diff = endNumber - startNumber +1;
|
|
1827
|
+
let diff = endNumber - startNumber + 1;
|
|
1819
1828
|
product.storeCount = diff;
|
|
1820
1829
|
item.storeCount = item.storeCount - diff;
|
|
1821
1830
|
}
|
|
@@ -1875,8 +1884,8 @@ export const pricingListUpdate = async ( req, res ) => {
|
|
|
1875
1884
|
let productList;
|
|
1876
1885
|
if ( req.body?.products && req.body?.products?.length ) {
|
|
1877
1886
|
productList = JSON.parse( JSON.stringify( req.body ) );
|
|
1878
|
-
let amount =0;
|
|
1879
|
-
let origPrice=0;
|
|
1887
|
+
let amount = 0;
|
|
1888
|
+
let origPrice = 0;
|
|
1880
1889
|
let IGST = 18;
|
|
1881
1890
|
let CGST = 9;
|
|
1882
1891
|
let SGST = 9;
|
|
@@ -2024,10 +2033,10 @@ async function updatePricing( req, res, update ) {
|
|
|
2024
2033
|
let clientId = req.body.clientId;
|
|
2025
2034
|
let paymentInvoice = clientDetails.paymentInvoice;
|
|
2026
2035
|
if ( !update ) {
|
|
2027
|
-
let userDetails= await userService.findOne( { clientId: req.body.clientId, role: 'superadmin' } );
|
|
2036
|
+
let userDetails = await userService.findOne( { clientId: req.body.clientId, role: 'superadmin' } );
|
|
2028
2037
|
paymentInvoice.invoiceTo = [ userDetails.email ];
|
|
2029
2038
|
paymentInvoice.paymentAgreementTo = [ userDetails.email ];
|
|
2030
|
-
paymentInvoice.currencyType = userDetails.countryCode == '91' ? 'inr': 'dollar';
|
|
2039
|
+
paymentInvoice.currencyType = userDetails.countryCode == '91' ? 'inr' : 'dollar';
|
|
2031
2040
|
clientDetails.planDetails.product.forEach( ( item ) => {
|
|
2032
2041
|
product.push( {
|
|
2033
2042
|
productName: item.productName,
|
|
@@ -2051,9 +2060,9 @@ async function updatePricing( req, res, update ) {
|
|
|
2051
2060
|
if ( subscriptionProduct.length ) {
|
|
2052
2061
|
let invoiceCount = await invoiceService.count( { clientId: req.params.clientId, status: 'pending' } );
|
|
2053
2062
|
if ( invoiceCount ) {
|
|
2054
|
-
paymentStatus ='due';
|
|
2063
|
+
paymentStatus = 'due';
|
|
2055
2064
|
} else {
|
|
2056
|
-
paymentStatus ='unbilled';
|
|
2065
|
+
paymentStatus = 'unbilled';
|
|
2057
2066
|
}
|
|
2058
2067
|
}
|
|
2059
2068
|
let details = {
|
|
@@ -2099,7 +2108,7 @@ export const updatedRevisedPrice = async ( req, res ) => {
|
|
|
2099
2108
|
}
|
|
2100
2109
|
amount = amount + item.price;
|
|
2101
2110
|
} );
|
|
2102
|
-
let invoiceDate= dayjs( invoiceDetails.createdAt ).format( 'DD MMM, YYYY' );
|
|
2111
|
+
let invoiceDate = dayjs( invoiceDetails.createdAt ).format( 'DD MMM, YYYY' );
|
|
2103
2112
|
let days = clientDetails?.paymentInvoice?.extendPaymentPeriodDays || 10;
|
|
2104
2113
|
let dueDate = invoiceDetails?.dueDate ? dayjs( invoiceDetails?.dueDate ).format( 'DD MMM, YYYY' ) : dayjs().add( days, 'days' ).format( 'DD MMM, YYYY' );
|
|
2105
2114
|
let discountAmount = ( amount * req.body.discount ) / 100;
|
|
@@ -2204,7 +2213,7 @@ export const getRemindClients = async ( req, res ) => {
|
|
|
2204
2213
|
let endDate = dayjs( item.trialEndDate ).startOf( 'day' ).add( 1, 'days' );
|
|
2205
2214
|
let date = dayjs().startOf( 'day' );
|
|
2206
2215
|
let leftDays = endDate.diff( date, 'day' );
|
|
2207
|
-
let userDetails= await userService.findOne( { clientId: client.clientId, role: 'superadmin' } );
|
|
2216
|
+
let userDetails = await userService.findOne( { clientId: client.clientId, role: 'superadmin' } );
|
|
2208
2217
|
if ( userDetails ) {
|
|
2209
2218
|
if ( leftDays == 3 ) {
|
|
2210
2219
|
let [ firstWord, secondWord ] = item.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
@@ -2268,13 +2277,13 @@ export const getExpiredClientsOld = async ( req, res ) => {
|
|
|
2268
2277
|
clientDetails.forEach( async ( client ) => {
|
|
2269
2278
|
if ( client.planDetails?.product ) {
|
|
2270
2279
|
let item = client.planDetails.product;
|
|
2271
|
-
let userDetails= await userService.findOne( { clientId: client.clientId, role: 'superadmin' } );
|
|
2280
|
+
let userDetails = await userService.findOne( { clientId: client.clientId, role: 'superadmin' } );
|
|
2272
2281
|
if ( userDetails ) {
|
|
2273
2282
|
let [ firstWord, secondWord ] = item.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
2274
2283
|
firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
2275
2284
|
let data = {
|
|
2276
2285
|
userName: userDetails.userName,
|
|
2277
|
-
product: firstWord +' '+secondWord,
|
|
2286
|
+
product: firstWord + ' ' + secondWord,
|
|
2278
2287
|
domain: appConfig.url.domain,
|
|
2279
2288
|
};
|
|
2280
2289
|
const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialExpiredEmail.hbs', 'utf8' );
|
|
@@ -2310,7 +2319,7 @@ export const getExpiredClients = async ( req, res ) => {
|
|
|
2310
2319
|
let endDate = dayjs( item.trialEndDate ).startOf( 'day' );
|
|
2311
2320
|
let date = dayjs().startOf( 'day' );
|
|
2312
2321
|
let leftDays = endDate.diff( date, 'day' );
|
|
2313
|
-
let userDetails= await userService.findOne( { clientId: client.clientId, role: 'superadmin' } );
|
|
2322
|
+
let userDetails = await userService.findOne( { clientId: client.clientId, role: 'superadmin' } );
|
|
2314
2323
|
if ( userDetails ) {
|
|
2315
2324
|
if ( leftDays == -1 ) {
|
|
2316
2325
|
let [ firstWord, secondWord ] = item.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
@@ -2346,12 +2355,12 @@ export const getExpiredClients = async ( req, res ) => {
|
|
|
2346
2355
|
|
|
2347
2356
|
export const invoiceDownload = async ( req, res ) => {
|
|
2348
2357
|
try {
|
|
2349
|
-
let
|
|
2358
|
+
let invoiceData;
|
|
2350
2359
|
let invoiceInfo = await invoiceService.findOne( { _id: req.params.invoiceId } );
|
|
2351
2360
|
if ( invoiceInfo ) {
|
|
2352
2361
|
let clientDetails = await paymentService.findOne( { clientId: invoiceInfo.clientId } );
|
|
2353
2362
|
let amount = 0;
|
|
2354
|
-
invoiceInfo.products.forEach( ( item ) => {
|
|
2363
|
+
invoiceInfo.products.forEach( ( item, index ) => {
|
|
2355
2364
|
let [ firstWord, secondWord ] = item.product.product.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
2356
2365
|
firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
2357
2366
|
item.product.product = firstWord + ' ' + secondWord;
|
|
@@ -2359,60 +2368,110 @@ export const invoiceDownload = async ( req, res ) => {
|
|
|
2359
2368
|
item.basePrice = convertINRtoUSD( item.basePrice );
|
|
2360
2369
|
item.price = convertINRtoUSD( item.price );
|
|
2361
2370
|
}
|
|
2371
|
+
item.index = index + 1;
|
|
2362
2372
|
if ( clientDetails.priceType == 'step' ) {
|
|
2363
2373
|
item.count = item.product.storeRange;
|
|
2364
2374
|
}
|
|
2375
|
+
|
|
2365
2376
|
amount = amount + item.price;
|
|
2377
|
+
|
|
2378
|
+
item.basePrice = item.basePrice.toLocaleString( 'en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 } );
|
|
2379
|
+
item.price = item.price.toLocaleString( 'en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 } );
|
|
2380
|
+
item.currency = clientDetails?.paymentInvoice?.currencyType == 'dollar' ? '$' : '₹';
|
|
2366
2381
|
} );
|
|
2367
|
-
let
|
|
2382
|
+
for ( let tax of invoiceInfo.tax ) {
|
|
2383
|
+
tax.taxAmount = tax.taxAmount.toLocaleString( 'en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 } );
|
|
2384
|
+
}
|
|
2385
|
+
let invoiceDate = dayjs( invoiceInfo.createdAt ).format( 'DD/MM/YYYY' );
|
|
2368
2386
|
let days = clientDetails?.paymentInvoice?.extendPaymentPeriodDays || 10;
|
|
2369
|
-
let dueDate = invoiceInfo?.dueDate ? dayjs( invoiceInfo?.dueDate ).format( 'DD
|
|
2387
|
+
let dueDate = invoiceInfo?.dueDate ? dayjs( invoiceInfo?.dueDate ).format( 'DD/MM/YYYY' ) : dayjs().add( days, 'days' ).format( 'DD/MM/YYYY' );
|
|
2370
2388
|
|
|
2371
|
-
|
|
2389
|
+
invoiceInfo.totalAmount = invoiceInfo.totalAmount;
|
|
2390
|
+
let AmountinWords = inWords( invoiceInfo.totalAmount );
|
|
2391
|
+
invoiceData = {
|
|
2372
2392
|
...invoiceInfo._doc,
|
|
2373
2393
|
clientName: clientDetails.clientName,
|
|
2374
2394
|
extendDays: clientDetails.paymentInvoice.extendPaymentPeriodDays,
|
|
2375
2395
|
address: clientDetails.billingDetails.billingAddress,
|
|
2376
|
-
|
|
2396
|
+
subtotal: amount.toLocaleString( 'en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 } ),
|
|
2397
|
+
companyName: invoiceInfo.companyName,
|
|
2398
|
+
companyAddress: invoiceInfo.companyAddress,
|
|
2399
|
+
PlaceOfSupply: invoiceInfo.PlaceOfSupply,
|
|
2400
|
+
GSTNumber: invoiceInfo.GSTNumber,
|
|
2401
|
+
PoNum: '',
|
|
2402
|
+
amountwords: AmountinWords,
|
|
2403
|
+
Terms: `Term ${clientDetails.paymentInvoice.extendPaymentPeriodDays}`,
|
|
2377
2404
|
currencyType: clientDetails?.paymentInvoice?.currencyType == 'dollar' ? '$' : '₹',
|
|
2378
|
-
|
|
2379
|
-
total: amount.toFixed( 2 ),
|
|
2405
|
+
totalAmount: invoiceInfo.totalAmount.toLocaleString( 'en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 } ),
|
|
2380
2406
|
invoiceDate,
|
|
2381
2407
|
dueDate,
|
|
2382
2408
|
};
|
|
2409
|
+
const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/invoicePdf.hbs', 'utf8' );
|
|
2410
|
+
const template = Handlebars.compile( templateHtml );
|
|
2411
|
+
const html = template( { ...invoiceData } );
|
|
2412
|
+
let file = {
|
|
2413
|
+
content: html,
|
|
2414
|
+
};
|
|
2415
|
+
let options = {
|
|
2416
|
+
path: `../../invoice/test.pdf}`,
|
|
2417
|
+
format: 'A4', margin: {
|
|
2418
|
+
top: '0.5in',
|
|
2419
|
+
right: '0.5in',
|
|
2420
|
+
bottom: '0.5in',
|
|
2421
|
+
left: '0.5in',
|
|
2422
|
+
},
|
|
2423
|
+
printBackground: true, preferCSSPageSize: true,
|
|
2424
|
+
};
|
|
2425
|
+
htmlpdf.generatePdf( file, options ).then( async function( pdfBuffer ) {
|
|
2426
|
+
res.set( 'Content-Disposition', 'attachment; filename="generated-pdf.pdf"' );
|
|
2427
|
+
res.set( 'Content-Type', 'application/pdf' );
|
|
2428
|
+
res.send( pdfBuffer );
|
|
2429
|
+
} );
|
|
2383
2430
|
}
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
const
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
res.setHeader( 'Content-
|
|
2408
|
-
|
|
2409
|
-
pdfDoc.
|
|
2410
|
-
pdfDoc.end();
|
|
2431
|
+
|
|
2432
|
+
|
|
2433
|
+
// let fonts = {
|
|
2434
|
+
// Helvetica: {
|
|
2435
|
+
// normal: 'Helvetica',
|
|
2436
|
+
// bold: 'Helvetica-Bold',
|
|
2437
|
+
// italics: 'Helvetica-Oblique',
|
|
2438
|
+
// bolditalics: 'Helvetica-BoldOblique',
|
|
2439
|
+
// },
|
|
2440
|
+
// };
|
|
2441
|
+
// let printer = new pdfMake( fonts );
|
|
2442
|
+
|
|
2443
|
+
// let { window } = new JSDOM( '' );
|
|
2444
|
+
// const htmlTemplate = htmlToPdfmake( html, { window: window, tableAutoSize: true } );
|
|
2445
|
+
// const docDefinition = {
|
|
2446
|
+
// pageMargins: [ 40, 10, 40, 40 ],
|
|
2447
|
+
// content: htmlTemplate,
|
|
2448
|
+
// defaultStyle: {
|
|
2449
|
+
// font: 'Helvetica',
|
|
2450
|
+
// },
|
|
2451
|
+
// };
|
|
2452
|
+
// let pdfDoc = printer.createPdfKitDocument( docDefinition );
|
|
2453
|
+
// res.setHeader( 'Content-disposition', `attachment; filename=Report_1.pdf` );
|
|
2454
|
+
// res.setHeader( 'Content-Type', 'application/pdf' );
|
|
2455
|
+
// pdfDoc.pipe( res );
|
|
2456
|
+
// pdfDoc.end();
|
|
2411
2457
|
} catch ( e ) {
|
|
2412
2458
|
logger.error( { error: e, function: 'invoiceDownload' } );
|
|
2413
2459
|
return res.sendError( e, 500 );
|
|
2414
2460
|
}
|
|
2415
2461
|
};
|
|
2462
|
+
function inWords( num ) {
|
|
2463
|
+
let a = [ '', 'one ', 'two ', 'three ', 'four ', 'five ', 'six ', 'seven ', 'eight ', 'nine ', 'ten ', 'eleven ', 'twelve ', 'thirteen ', 'fourteen ', 'fifteen ', 'sixteen ', 'seventeen ', 'eighteen ', 'nineteen ' ]; let b = [ '', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety' ];
|
|
2464
|
+
if ( ( num = num.toString() ).length > 9 ) return 'overflow';
|
|
2465
|
+
let n = ( '000000000' + num ).substr( -9 ).match( /^(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})$/ );
|
|
2466
|
+
if ( !n ) return; let str = '';
|
|
2467
|
+
str += ( n[1] != 0 ) ? ( a[Number( n[1] )] || b[n[1][0]] + ' ' + a[n[1][1]] ) + 'crore ' : '';
|
|
2468
|
+
str += ( n[2] != 0 ) ? ( a[Number( n[2] )] || b[n[2][0]] + ' ' + a[n[2][1]] ) + 'lakh ' : '';
|
|
2469
|
+
str += ( n[3] != 0 ) ? ( a[Number( n[3] )] || b[n[3][0]] + ' ' + a[n[3][1]] ) + 'thousand ' : '';
|
|
2470
|
+
str += ( n[4] != 0 ) ? ( a[Number( n[4] )] || b[n[4][0]] + ' ' + a[n[4][1]] ) + 'hundred ' : '';
|
|
2471
|
+
str += ( n[5] != 0 ) ? ( ( str != '' ) ? 'and ' : '' ) + ( a[Number( n[5] )] || b[n[5][0]] + ' ' + a[n[5][1]] ) : '';
|
|
2472
|
+
|
|
2473
|
+
return str.toLowerCase().split( ' ' ).map( ( word ) => word.charAt( 0 ).toUpperCase() + word.slice( 1 ) ).join( ' ' );
|
|
2474
|
+
}
|
|
2416
2475
|
|
|
2417
2476
|
export const updateInvoiceStatus = async ( req, res ) => {
|
|
2418
2477
|
try {
|
|
@@ -2491,7 +2550,12 @@ export const invoiceCreate = async ( req, res ) => {
|
|
|
2491
2550
|
export const dailyPricingInsert = async ( req, res ) => {
|
|
2492
2551
|
try {
|
|
2493
2552
|
let requestData = req.body;
|
|
2494
|
-
let
|
|
2553
|
+
let clientlist = await paymentService.find( { 'status': 'active' } );
|
|
2554
|
+
let requestClient = [];
|
|
2555
|
+
|
|
2556
|
+
for ( let client of clientlist ) {
|
|
2557
|
+
requestClient.push( client.clientId );
|
|
2558
|
+
}
|
|
2495
2559
|
if ( requestData.clientId && requestClient.length > 0 ) {
|
|
2496
2560
|
for ( let clientIndex = 0; clientIndex < requestClient.length; clientIndex++ ) {
|
|
2497
2561
|
let getClient = await paymentService.findOne( { clientId: requestClient[clientIndex], status: 'active' } );
|
|
@@ -2502,55 +2566,57 @@ export const dailyPricingInsert = async ( req, res ) => {
|
|
|
2502
2566
|
let storeList = [];
|
|
2503
2567
|
for ( let storeIndex = 0; storeIndex < getStore.length; storeIndex++ ) {
|
|
2504
2568
|
let productList = [];
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
let
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2569
|
+
if ( getBaseprice ) {
|
|
2570
|
+
let priceDetails = getClient.priceType == 'standard' ? getBaseprice.standard : getBaseprice.step;
|
|
2571
|
+
for ( let storeProductIndex = 0; storeProductIndex < getStore[storeIndex].product.length; storeProductIndex++ ) {
|
|
2572
|
+
let productDetails;
|
|
2573
|
+
if ( getClient.priceType == 'standard' ) {
|
|
2574
|
+
productDetails = priceDetails.find( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
2575
|
+
} else {
|
|
2576
|
+
productDetails = priceDetails.find( ( item ) => {
|
|
2577
|
+
let range = item.storeRange.split( '-' );
|
|
2578
|
+
if ( parseInt( range[0] ) <= ( storeIndex + 1 ) && parseInt( range[1] ) >= ( storeIndex + 1 ) ) {
|
|
2579
|
+
return ( item.productName == getStore[storeIndex].product[storeProductIndex] && parseInt( range[0] ) <= ( storeIndex + 1 ) && parseInt( range[1] ) >= ( storeIndex + 1 ) );
|
|
2580
|
+
}
|
|
2581
|
+
} );
|
|
2582
|
+
if ( !productDetails ) {
|
|
2583
|
+
let stepProductDetails = priceDetails.filter( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
2584
|
+
productDetails = stepProductDetails[stepProductDetails.length - 1];
|
|
2515
2585
|
}
|
|
2516
|
-
}
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2586
|
+
}
|
|
2587
|
+
let productStatus = getClient.planDetails.product.find( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
2588
|
+
if ( productDetails ) {
|
|
2589
|
+
let newObject = {
|
|
2590
|
+
productName: productDetails.productName,
|
|
2591
|
+
status: productStatus ? productStatus.status : '',
|
|
2592
|
+
price: productStatus ? [ 'trial', 'free' ].includes( productStatus.status ) ? 0 : productDetails.negotiatePrice : 0,
|
|
2593
|
+
featureStoreCount: storeIndex + 1,
|
|
2594
|
+
basePrice: productDetails.negotiatePrice,
|
|
2595
|
+
...( getClient.priceType == 'step' ? { storeRange: productDetails.storeRange } : { storeRange: 'standard' } ),
|
|
2596
|
+
};
|
|
2597
|
+
productList.push( newObject );
|
|
2520
2598
|
}
|
|
2521
2599
|
}
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2600
|
+
storeList.push(
|
|
2601
|
+
{
|
|
2602
|
+
storeId: getStore[storeIndex].storeId,
|
|
2603
|
+
products: productList,
|
|
2604
|
+
},
|
|
2605
|
+
);
|
|
2606
|
+
if ( storeIndex == getStore.length - 1 ) {
|
|
2607
|
+
let params = {
|
|
2608
|
+
clientId: requestClient[clientIndex],
|
|
2609
|
+
stores: storeList,
|
|
2610
|
+
dateISO: new Date( requestData.date ),
|
|
2611
|
+
dateString: dayjs( requestData.date ).format( 'YYYY-MM-DD' ),
|
|
2531
2612
|
};
|
|
2532
|
-
|
|
2613
|
+
await dailyPriceService.create( params );
|
|
2533
2614
|
}
|
|
2534
2615
|
}
|
|
2535
|
-
storeList.push(
|
|
2536
|
-
{
|
|
2537
|
-
storeId: getStore[storeIndex].storeId,
|
|
2538
|
-
products: productList,
|
|
2539
|
-
},
|
|
2540
|
-
);
|
|
2541
|
-
if ( storeIndex == getStore.length-1 ) {
|
|
2542
|
-
let params = {
|
|
2543
|
-
clientId: requestClient[clientIndex],
|
|
2544
|
-
stores: storeList,
|
|
2545
|
-
dateISO: new Date( requestData.date ),
|
|
2546
|
-
dateString: dayjs( requestData.date ).format( 'YYYY-MM-DD' ),
|
|
2547
|
-
};
|
|
2548
|
-
await dailyPriceService.create( params );
|
|
2549
|
-
}
|
|
2550
2616
|
}
|
|
2551
2617
|
}
|
|
2552
2618
|
}
|
|
2553
|
-
if ( clientIndex == requestClient.length-1 ) {
|
|
2619
|
+
if ( clientIndex == requestClient.length - 1 ) {
|
|
2554
2620
|
return res.sendSuccess( 'Price Details Inserted Successfully' );
|
|
2555
2621
|
}
|
|
2556
2622
|
}
|
|
@@ -2563,13 +2629,18 @@ export const dailyPricingInsert = async ( req, res ) => {
|
|
|
2563
2629
|
|
|
2564
2630
|
export const invoiceGenerate = async ( req, res ) => {
|
|
2565
2631
|
try {
|
|
2566
|
-
let requestData = req.body;
|
|
2567
|
-
|
|
2568
|
-
let
|
|
2569
|
-
let
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2632
|
+
// let requestData = req.body;
|
|
2633
|
+
|
|
2634
|
+
let clientlist = await paymentService.find( { 'status': 'active' } );
|
|
2635
|
+
let requestClient = [];
|
|
2636
|
+
|
|
2637
|
+
for ( let client of clientlist ) {
|
|
2638
|
+
requestClient.push( client.clientId );
|
|
2639
|
+
}
|
|
2640
|
+
const currentYear = dayjs().year();
|
|
2641
|
+
const date = dayjs( `${currentYear}-${req.body.monthOfbilling}-01` );
|
|
2642
|
+
let billingmonth = dayjs( date ).format( 'MMM-YYYY' );
|
|
2643
|
+
|
|
2573
2644
|
for ( let clientIndex = 0; clientIndex < requestClient.length; clientIndex++ ) {
|
|
2574
2645
|
let getClient = await paymentService.findOne( { clientId: requestClient[clientIndex], status: 'active' } );
|
|
2575
2646
|
if ( getClient ) {
|
|
@@ -2578,10 +2649,17 @@ export const invoiceGenerate = async ( req, res ) => {
|
|
|
2578
2649
|
$match: {
|
|
2579
2650
|
$and: [
|
|
2580
2651
|
{ clientId: requestClient[clientIndex] },
|
|
2581
|
-
{ dateISO: { $gte: start, $lte: end } },
|
|
2582
2652
|
],
|
|
2583
2653
|
},
|
|
2584
2654
|
},
|
|
2655
|
+
{
|
|
2656
|
+
$sort: {
|
|
2657
|
+
_id: -1,
|
|
2658
|
+
},
|
|
2659
|
+
},
|
|
2660
|
+
{
|
|
2661
|
+
$limit: 1,
|
|
2662
|
+
},
|
|
2585
2663
|
{
|
|
2586
2664
|
$unwind: '$stores',
|
|
2587
2665
|
},
|
|
@@ -2590,10 +2668,13 @@ export const invoiceGenerate = async ( req, res ) => {
|
|
|
2590
2668
|
},
|
|
2591
2669
|
{
|
|
2592
2670
|
$group: {
|
|
2593
|
-
_id: {
|
|
2671
|
+
_id: {
|
|
2672
|
+
product: '$stores.products.productName',
|
|
2673
|
+
storeRange: '$stores.products.storeRange',
|
|
2674
|
+
},
|
|
2594
2675
|
price: { $sum: '$stores.products.price' },
|
|
2595
2676
|
count: { $sum: 1 },
|
|
2596
|
-
basePrice: { $first: '$stores.products.
|
|
2677
|
+
basePrice: { $first: '$stores.products.price' },
|
|
2597
2678
|
},
|
|
2598
2679
|
},
|
|
2599
2680
|
{
|
|
@@ -2605,72 +2686,104 @@ export const invoiceGenerate = async ( req, res ) => {
|
|
|
2605
2686
|
basePrice: 1,
|
|
2606
2687
|
},
|
|
2607
2688
|
},
|
|
2689
|
+
{
|
|
2690
|
+
$project: {
|
|
2691
|
+
'price': 1,
|
|
2692
|
+
'count': 1,
|
|
2693
|
+
'basePrice': 1,
|
|
2694
|
+
'product': 1,
|
|
2695
|
+
'HSNnumber': '998314',
|
|
2696
|
+
'Month': billingmonth,
|
|
2697
|
+
'description': 'Footfall Traffic Analytics',
|
|
2698
|
+
},
|
|
2699
|
+
},
|
|
2608
2700
|
];
|
|
2609
|
-
|
|
2610
|
-
// $facet: {
|
|
2611
|
-
// data: [
|
|
2612
|
-
// {
|
|
2613
|
-
// $unwind: '$stores',
|
|
2614
|
-
// },
|
|
2615
|
-
// {
|
|
2616
|
-
// $unwind: '$stores.products',
|
|
2617
|
-
// },
|
|
2618
|
-
// {
|
|
2619
|
-
// $group: {
|
|
2620
|
-
// _id: { product: '$stores.products.productName', storeRange: '$stores.products.storeRange' },
|
|
2621
|
-
// price: { $sum: '$stores.products.price' },
|
|
2622
|
-
// },
|
|
2623
|
-
// },
|
|
2624
|
-
// {
|
|
2625
|
-
// $project: {
|
|
2626
|
-
// _id: 0,
|
|
2627
|
-
// product: '$_id',
|
|
2628
|
-
// price: 1,
|
|
2629
|
-
// },
|
|
2630
|
-
// },
|
|
2631
|
-
// ],
|
|
2632
|
-
// count: [
|
|
2633
|
-
// {
|
|
2634
|
-
// $unwind: '$stores',
|
|
2635
|
-
// },
|
|
2636
|
-
// { $sort: { 'stores.products._id': -1 } },
|
|
2637
|
-
// { $project: { lastElement: { $arrayElemAt: [ '$stores.products', -1 ] } } },
|
|
2638
|
-
// { $project: {
|
|
2639
|
-
// count: '$lastElement.featureStoreCount',
|
|
2640
|
-
// },
|
|
2641
|
-
// },
|
|
2642
|
-
// ],
|
|
2643
|
-
// },
|
|
2644
|
-
// },
|
|
2701
|
+
|
|
2645
2702
|
let invoiceDetails = await dailyPriceService.aggregate( query );
|
|
2646
|
-
if (
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2703
|
+
if ( invoiceDetails.length > 0 ) {
|
|
2704
|
+
let amount = 0;
|
|
2705
|
+
invoiceDetails.forEach( ( item ) => {
|
|
2706
|
+
amount = item.price + amount;
|
|
2707
|
+
} );
|
|
2708
|
+
let storeQuery = {
|
|
2709
|
+
clientId: requestClient[clientIndex],
|
|
2710
|
+
status: 'active',
|
|
2711
|
+
};
|
|
2712
|
+
let storeCount = await storeService.count( storeQuery );
|
|
2713
|
+
let Finacialyear = getCurrentFinancialYear();
|
|
2714
|
+
|
|
2715
|
+
let taxList = [];
|
|
2716
|
+
let totalAmount = 0;
|
|
2717
|
+
if ( getClient.billingDetails.gstNumber && getClient.billingDetails.gstNumber.slice( 0, 2 ) == '33' ) {
|
|
2718
|
+
let taxAmount = ( amount * 9 ) / 100;
|
|
2719
|
+
totalAmount = amount + taxAmount;
|
|
2720
|
+
taxList.push(
|
|
2721
|
+
{
|
|
2722
|
+
'currency': '₹',
|
|
2723
|
+
'type': 'CGST',
|
|
2724
|
+
'value': 9,
|
|
2725
|
+
'taxAmount': taxAmount,
|
|
2726
|
+
}, {
|
|
2727
|
+
'currency': '₹',
|
|
2728
|
+
'type': 'SGST',
|
|
2729
|
+
'value': 9,
|
|
2730
|
+
'taxAmount': taxAmount,
|
|
2731
|
+
},
|
|
2732
|
+
);
|
|
2733
|
+
} else {
|
|
2734
|
+
let taxAmount = ( amount * 18 ) / 100;
|
|
2735
|
+
totalAmount = amount + taxAmount;
|
|
2736
|
+
|
|
2737
|
+
taxList.push(
|
|
2738
|
+
{
|
|
2739
|
+
'currency': '₹',
|
|
2740
|
+
'type': 'IGST',
|
|
2741
|
+
'value': 18,
|
|
2742
|
+
'taxAmount': taxAmount,
|
|
2743
|
+
},
|
|
2744
|
+
);
|
|
2745
|
+
}
|
|
2746
|
+
|
|
2747
|
+
|
|
2748
|
+
let previousinvoice = await invoiceService.findandsort( {}, {}, { _id: -1 } );
|
|
2749
|
+
let invoiceNo = '00001';
|
|
2750
|
+
if ( previousinvoice && previousinvoice.length > 0 ) {
|
|
2751
|
+
invoiceNo = Number( previousinvoice[0].invoiceIndex ) + 1;
|
|
2752
|
+
invoiceNo = invoiceNo.toString().padStart( 5, '0' );
|
|
2753
|
+
}
|
|
2754
|
+
let data = {
|
|
2755
|
+
invoice: `INV-${Finacialyear}-${invoiceNo}`,
|
|
2756
|
+
products: invoiceDetails,
|
|
2757
|
+
status: 'pending',
|
|
2758
|
+
amount: amount,
|
|
2759
|
+
monthOfbilling: req.body.monthOfbilling,
|
|
2760
|
+
invoiceIndex: invoiceNo,
|
|
2761
|
+
tax: taxList,
|
|
2762
|
+
companyName: getClient.billingDetails.companyName,
|
|
2763
|
+
companyAddress: getClient.billingDetails.billingAddress,
|
|
2764
|
+
PlaceOfSupply: getClient.billingDetails.PlaceOfSupply,
|
|
2765
|
+
GSTNumber: getClient.billingDetails.gstNumber,
|
|
2766
|
+
totalAmount: totalAmount,
|
|
2767
|
+
clientId: requestClient[clientIndex],
|
|
2768
|
+
paymentMethod: getClient?.paymentInvoice?.paymentType || 'Fund Trasfer',
|
|
2769
|
+
billingDate: new Date(),
|
|
2770
|
+
stores: storeCount,
|
|
2771
|
+
};
|
|
2772
|
+
|
|
2773
|
+
let invoiceExists = await invoiceService.findOne( { monthOfbilling: req.body.monthOfbilling, clientId: getClient.clientId } );
|
|
2774
|
+
|
|
2669
2775
|
|
|
2670
|
-
|
|
2671
|
-
|
|
2776
|
+
if ( invoiceExists ) {
|
|
2777
|
+
logger.info( `invoice already exist for the month${req.body.monthOfbilling} for ${getClient.clientId}` );
|
|
2778
|
+
} else {
|
|
2779
|
+
await invoiceService.create( data );
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
if ( clientIndex == requestClient.length - 1 ) {
|
|
2672
2783
|
return res.sendSuccess( 'invocie Generated Succesfully' );
|
|
2673
2784
|
}
|
|
2785
|
+
} else {
|
|
2786
|
+
return res.sendError( 'client not found', 204 );
|
|
2674
2787
|
}
|
|
2675
2788
|
}
|
|
2676
2789
|
} catch ( e ) {
|
|
@@ -2680,12 +2793,20 @@ export const invoiceGenerate = async ( req, res ) => {
|
|
|
2680
2793
|
};
|
|
2681
2794
|
|
|
2682
2795
|
function convertINRtoUSD( amountINR ) {
|
|
2683
|
-
// Current exchange rate (1 INR = 0.012 USD)
|
|
2684
2796
|
const exchangeRate = 0.012;
|
|
2685
|
-
// Convert INR to USD
|
|
2686
2797
|
const amountUSD = amountINR * exchangeRate;
|
|
2687
2798
|
return amountUSD;
|
|
2688
2799
|
}
|
|
2800
|
+
function getCurrentFinancialYear() {
|
|
2801
|
+
const today = new Date();
|
|
2802
|
+
const currentMonth = today.getMonth();
|
|
2803
|
+
const currentYear = today.getFullYear();
|
|
2804
|
+
if ( currentMonth >= 3 ) {
|
|
2805
|
+
return currentYear.toString().slice( -2 ) + '-' + ( currentYear + 1 ).toString().slice( -2 );
|
|
2806
|
+
} else {
|
|
2807
|
+
return ( ( currentYear - 1 ).toString().slice( -2 ) ) + '-' + currentYear.toString().slice( -2 );
|
|
2808
|
+
}
|
|
2809
|
+
}
|
|
2689
2810
|
|
|
2690
2811
|
|
|
2691
2812
|
export const invoiceRevised = async ( req, res ) => {
|
|
@@ -2694,11 +2815,11 @@ export const invoiceRevised = async ( req, res ) => {
|
|
|
2694
2815
|
if ( !invoiceDetails ) {
|
|
2695
2816
|
return res.sendError( 'no data found', 204 );
|
|
2696
2817
|
}
|
|
2697
|
-
let userDetails= await userService.findOne( { clientId: invoiceDetails.clientId, role: 'superadmin' } );
|
|
2818
|
+
let userDetails = await userService.findOne( { clientId: invoiceDetails.clientId, role: 'superadmin' } );
|
|
2698
2819
|
let clientDetails = await paymentService.findOne( { clientId: invoiceDetails.clientId } );
|
|
2699
2820
|
if ( userDetails ) {
|
|
2700
2821
|
let amount = 0;
|
|
2701
|
-
let invoiceDate= dayjs( invoiceDetails.createdAt ).format( 'DD MMM, YYYY' );
|
|
2822
|
+
let invoiceDate = dayjs( invoiceDetails.createdAt ).format( 'DD MMM, YYYY' );
|
|
2702
2823
|
let days = clientDetails?.paymentInvoice?.extendPaymentPeriodDays || 10;
|
|
2703
2824
|
let dueDate = invoiceDetails?.dueDate ? dayjs( invoiceDetails?.dueDate ).format( 'DD MMM, YYYY' ) : dayjs().add( days, 'days' ).format( 'DD MMM, YYYY' );
|
|
2704
2825
|
invoiceDetails.products.forEach( ( item ) => {
|