tango-app-api-payment-subscription 3.0.60-dev → 3.0.62-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/.eslintrc.cjs +1 -1
- package/index.js +5 -1
- package/package.json +3 -3
- package/src/controllers/billing.controllers.js +672 -0
- package/src/controllers/invoice.controller.js +1011 -0
- package/src/controllers/payment.controller.js +47 -0
- package/src/controllers/paymentSubscription.controllers.js +221 -100
- package/src/dtos/validation.dtos.js +149 -5
- package/src/hbs/invoicePdf.hbs +134 -44
- package/src/hbs/invoicePdf1.hbs +1577 -0
- package/src/hbs/invoicepaymentemail.hbs +925 -0
- package/src/routes/billing.routes.js +50 -0
- package/src/routes/invoice.routes.js +13 -0
- package/src/routes/payment.routes.js +26 -0
- package/src/routes/paymentSubscription.routes.js +2 -0
- package/src/services/billing.service.js +34 -0
- package/src/services/invoice.service.js +4 -0
- package/src/services/paymentAccount.service.js +11 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
import { createOrder } from 'tango-app-api-middleware';
|
|
3
|
+
import { findOneAccount } from '../services/paymentAccount.service.js';
|
|
4
|
+
import * as invoiceService from '../services/invoice.service.js';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export const generateOrder = async ( req, res ) => {
|
|
8
|
+
try {
|
|
9
|
+
const order = await createOrder( { amount: req.body.amount, currency: req.body.currency } );
|
|
10
|
+
|
|
11
|
+
if ( !order ) {
|
|
12
|
+
return res.sendError( 'Failed to generate order id', 500 );
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return res.sendSuccess( order );
|
|
16
|
+
} catch ( error ) {
|
|
17
|
+
logger.error( { error: error, function: 'generateOrder' } );
|
|
18
|
+
return res.sendError( error, 500 );
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const getVirtualAccount = async ( req, res ) => {
|
|
23
|
+
try {
|
|
24
|
+
const account = await findOneAccount( { clientId: req.query.clientId }, { accountNumber: 1, ifsc: 1, branch: 1, paymentType: 1, credit: 1, _id: 0 } );
|
|
25
|
+
|
|
26
|
+
if ( !account ) {
|
|
27
|
+
return res.sendError( 'No data found', 204 );
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return res.sendSuccess( account );
|
|
31
|
+
} catch ( error ) {
|
|
32
|
+
logger.error( { error: error, function: 'getVirtualAccount' } );
|
|
33
|
+
return res.sendError( error, 500 );
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const payUsingVallet = async ( req, res ) => {
|
|
38
|
+
try {
|
|
39
|
+
const invoice = await invoiceService.findOne( { ivoice: req.params.invoice } );
|
|
40
|
+
if ( !invoice ) {
|
|
41
|
+
return res.sendError( 'No data found', 204 );
|
|
42
|
+
}
|
|
43
|
+
} catch ( error ) {
|
|
44
|
+
logger.error( { error: error, function: 'payUsingVallet' } );
|
|
45
|
+
return res.sendError( error, 500 );
|
|
46
|
+
}
|
|
47
|
+
};
|
|
@@ -10,6 +10,8 @@ import * as invoiceService from '../services/invoice.service.js';
|
|
|
10
10
|
import * as userService from '../services/user.service.js';
|
|
11
11
|
import * as dailyPriceService from '../services/dailyPrice.service.js';
|
|
12
12
|
import * as cameraService from '../services/camera.service.js';
|
|
13
|
+
import * as billingService from '../services/billing.service.js';
|
|
14
|
+
|
|
13
15
|
import dayjs from 'dayjs';
|
|
14
16
|
import Handlebars from 'handlebars';
|
|
15
17
|
import fs from 'fs';
|
|
@@ -93,14 +95,39 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
|
|
|
93
95
|
if ( !clientInfo ) {
|
|
94
96
|
return res.sendError( 'no data found', 204 );
|
|
95
97
|
}
|
|
96
|
-
let storeCount = await storeService.count( { clientId: clientInfo[0].clientId } );
|
|
97
|
-
let
|
|
98
|
+
let storeCount = await storeService.count( { clientId: clientInfo[0].clientId, status: 'active' } );
|
|
99
|
+
let tangoProductsList = await basePricingService.findOne( { clientId: { $exists: false } }, { basePricing: 1 } );
|
|
100
|
+
let tangoProducts = tangoProductsList.basePricing.map( ( item ) => item.productName );
|
|
98
101
|
let activeProducts = clientInfo[0].planDetails.product;
|
|
99
102
|
let liveProducts = [];
|
|
100
103
|
let trialProducts = [];
|
|
101
104
|
let expiredProducts = [];
|
|
102
105
|
let currentDate = new Date();
|
|
103
106
|
|
|
107
|
+
let storeQuery = [
|
|
108
|
+
{
|
|
109
|
+
$match: {
|
|
110
|
+
clientId: clientInfo[0].clientId,
|
|
111
|
+
status: 'active',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
{ $unwind: '$product' },
|
|
115
|
+
{
|
|
116
|
+
$group: {
|
|
117
|
+
_id: '$product',
|
|
118
|
+
total: { $sum: 1 },
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
$project: {
|
|
123
|
+
_id: 0,
|
|
124
|
+
product: '$_id',
|
|
125
|
+
count: '$total',
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
];
|
|
129
|
+
|
|
130
|
+
let productDetails = await storeService.aggregate( storeQuery );
|
|
104
131
|
// Function to calculate the difference between two dates
|
|
105
132
|
function dateDifference( date1, date2 ) {
|
|
106
133
|
// Convert both dates to milliseconds
|
|
@@ -125,22 +152,29 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
|
|
|
125
152
|
}
|
|
126
153
|
|
|
127
154
|
activeProducts.forEach( ( element ) => {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
break;
|
|
132
|
-
case 'tangoZone':
|
|
133
|
-
element.aliseProductName = 'Tango Zone';
|
|
134
|
-
break;
|
|
135
|
-
case 'tangoSop':
|
|
136
|
-
element.aliseProductName = 'Tango SOP';
|
|
137
|
-
break;
|
|
138
|
-
case 'prioritySupport':
|
|
139
|
-
element.aliseProductName = 'Priority Support';
|
|
140
|
-
break;
|
|
141
|
-
default:
|
|
142
|
-
break;
|
|
155
|
+
let price = tangoProductsList.basePricing.find( ( item ) => item.productName == element.productName );
|
|
156
|
+
if ( price ) {
|
|
157
|
+
element.price = price.basePrice;
|
|
143
158
|
}
|
|
159
|
+
let getProductCount = productDetails.find( ( item ) => item.product == element.productName );
|
|
160
|
+
element.storeCount = getProductCount?.count || 0;
|
|
161
|
+
element.aliseProductName = convertTitleCase( element.productName );
|
|
162
|
+
// switch ( element.productName ) {
|
|
163
|
+
// case 'tangoTraffic':
|
|
164
|
+
// element.aliseProductName = 'Tango Traffic';
|
|
165
|
+
// break;
|
|
166
|
+
// case 'tangoZone':
|
|
167
|
+
// element.aliseProductName = 'Tango Zone';
|
|
168
|
+
// break;
|
|
169
|
+
// case 'tangoTrax':
|
|
170
|
+
// element.aliseProductName = 'Tango Trax';
|
|
171
|
+
// break;
|
|
172
|
+
// case 'prioritySupport':
|
|
173
|
+
// element.aliseProductName = 'Priority Support';
|
|
174
|
+
// break;
|
|
175
|
+
// default:
|
|
176
|
+
// break;
|
|
177
|
+
// }
|
|
144
178
|
|
|
145
179
|
if ( element.status == 'live' ) {
|
|
146
180
|
liveProducts.push( { 'productName': element.productName, 'aliseProductName': element.aliseProductName } );
|
|
@@ -226,6 +260,16 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
|
|
|
226
260
|
|
|
227
261
|
export const pricingInfo = async ( req, res ) => {
|
|
228
262
|
try {
|
|
263
|
+
if ( req.query?.clientId ) {
|
|
264
|
+
let clientDetails = await paymentService.findOne( { clientId: req.query.clientId }, { planDetails: 1, paymentInvoice: 1 } );
|
|
265
|
+
if ( clientDetails ) {
|
|
266
|
+
req.body.storesCount = clientDetails.planDetails.totalStores;
|
|
267
|
+
req.body.products = req.body?.products || clientDetails.planDetails.product.map( ( product ) => product.productName );
|
|
268
|
+
req.body.planName = req.body?.planName || clientDetails.planDetails.subscriptionPeriod;
|
|
269
|
+
req.body.currencyType = clientDetails.paymentInvoice?.currencyType ? clientDetails.paymentInvoice?.currencyType == 'inr' ? 'rupees' : 'dollar' : 'rupees';
|
|
270
|
+
req.body.camaraPerSqft = clientDetails.planDetails.storeSize;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
229
273
|
req.body.calculateSignup = true;
|
|
230
274
|
let pricingDetails = await calculatePricing( req, res );
|
|
231
275
|
return res.sendSuccess( pricingDetails );
|
|
@@ -1491,7 +1535,7 @@ export const productViewList = async ( req, res ) => {
|
|
|
1491
1535
|
{
|
|
1492
1536
|
$match: {
|
|
1493
1537
|
clientId: req.query.clientId,
|
|
1494
|
-
|
|
1538
|
+
status: 'active',
|
|
1495
1539
|
},
|
|
1496
1540
|
},
|
|
1497
1541
|
{ $unwind: '$product' },
|
|
@@ -1511,6 +1555,7 @@ export const productViewList = async ( req, res ) => {
|
|
|
1511
1555
|
];
|
|
1512
1556
|
|
|
1513
1557
|
let storeProductCount = await storeService.aggregate( query );
|
|
1558
|
+
|
|
1514
1559
|
let clientProduct = await paymentService.findOne( { clientId: req.query.clientId }, { 'planDetails.product': 1 } );
|
|
1515
1560
|
|
|
1516
1561
|
if ( !clientProduct.planDetails.product.length ) {
|
|
@@ -1535,6 +1580,7 @@ export const productViewList = async ( req, res ) => {
|
|
|
1535
1580
|
basePrice: price,
|
|
1536
1581
|
storeCount: count,
|
|
1537
1582
|
status: item.status,
|
|
1583
|
+
totalCost: Math.round( price*count ),
|
|
1538
1584
|
},
|
|
1539
1585
|
);
|
|
1540
1586
|
} );
|
|
@@ -1549,7 +1595,21 @@ export const productViewList = async ( req, res ) => {
|
|
|
1549
1595
|
// item.basePrice = productBasePrice.basePrice;
|
|
1550
1596
|
// }
|
|
1551
1597
|
// } );
|
|
1552
|
-
|
|
1598
|
+
let storecount = await storeService.count( {
|
|
1599
|
+
clientId: req.query.clientId,
|
|
1600
|
+
status: 'active',
|
|
1601
|
+
} );
|
|
1602
|
+
|
|
1603
|
+
let totalSum = products.reduce( ( sum, product ) => sum + product.totalCost, 0 );
|
|
1604
|
+
|
|
1605
|
+
|
|
1606
|
+
let planDetails = {
|
|
1607
|
+
totalSum: totalSum,
|
|
1608
|
+
totalStores: storecount,
|
|
1609
|
+
accountcredit: 0,
|
|
1610
|
+
|
|
1611
|
+
};
|
|
1612
|
+
return res.sendSuccess( { products: products, planDetails: planDetails } );
|
|
1553
1613
|
} catch ( e ) {
|
|
1554
1614
|
logger.error( { error: e, function: 'productViewList' } );
|
|
1555
1615
|
return res.sendError( e, 500 );
|
|
@@ -2015,11 +2075,17 @@ export const invoiceList = async ( req, res ) => {
|
|
|
2015
2075
|
if ( item.products?.length > 0 ) {
|
|
2016
2076
|
let newProducts = [];
|
|
2017
2077
|
for ( let productIndex = 0; productIndex < item.products.length; productIndex++ ) {
|
|
2018
|
-
let [ firstWord, secondWord ] = item.products[productIndex]?.
|
|
2078
|
+
let [ firstWord, secondWord ] = item.products[productIndex]?.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
2019
2079
|
firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
2020
|
-
item.products[productIndex].
|
|
2021
|
-
newProducts.push( item.products[productIndex]?.
|
|
2080
|
+
item.products[productIndex].productName = firstWord + ' ' + secondWord;
|
|
2081
|
+
newProducts.push( item.products[productIndex]?.productName );
|
|
2022
2082
|
}
|
|
2083
|
+
// for ( let productIndex = 0; productIndex < item.products.length; productIndex++ ) {
|
|
2084
|
+
// let [ firstWord, secondWord ] = item.products[productIndex]?.product?.product.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
2085
|
+
// firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
2086
|
+
// item.products[productIndex].product.product = firstWord + ' ' + secondWord;
|
|
2087
|
+
// newProducts.push( item.products[productIndex]?.product?.product );
|
|
2088
|
+
// }
|
|
2023
2089
|
item.productList = newProducts;
|
|
2024
2090
|
}
|
|
2025
2091
|
} );
|
|
@@ -2726,10 +2792,10 @@ export const invoiceDownload = async ( req, res ) => {
|
|
|
2726
2792
|
let [ firstWord, secondWord ] = item.product.product.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
2727
2793
|
firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
2728
2794
|
item.product.product = firstWord + ' ' + secondWord;
|
|
2729
|
-
if ( clientDetails.paymentInvoice.currencyType == 'dollar' ) {
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
}
|
|
2795
|
+
// if ( clientDetails.paymentInvoice.currencyType == 'dollar' ) {
|
|
2796
|
+
// item.basePrice = convertINRtoUSD( item.basePrice );
|
|
2797
|
+
// item.price = convertINRtoUSD( item.price );
|
|
2798
|
+
// }
|
|
2733
2799
|
item.index = index + 1;
|
|
2734
2800
|
if ( clientDetails.priceType == 'step' ) {
|
|
2735
2801
|
item.count = item.product.storeRange;
|
|
@@ -2768,7 +2834,7 @@ export const invoiceDownload = async ( req, res ) => {
|
|
|
2768
2834
|
invoiceDate,
|
|
2769
2835
|
dueDate,
|
|
2770
2836
|
};
|
|
2771
|
-
const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/
|
|
2837
|
+
const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/invoicePdf1.hbs', 'utf8' );
|
|
2772
2838
|
const template = Handlebars.compile( templateHtml );
|
|
2773
2839
|
const html = template( { ...invoiceData } );
|
|
2774
2840
|
let file = {
|
|
@@ -2784,8 +2850,8 @@ export const invoiceDownload = async ( req, res ) => {
|
|
|
2784
2850
|
printBackground: true, preferCSSPageSize: true,
|
|
2785
2851
|
};
|
|
2786
2852
|
const date = dayjs( invoiceData.monthOfbilling, 'MM' );
|
|
2787
|
-
|
|
2788
|
-
|
|
2853
|
+
let monthName = date.format( 'MMMM' );
|
|
2854
|
+
monthName = 'Jul-Sep';
|
|
2789
2855
|
|
|
2790
2856
|
htmlpdf.generatePdf( file, options ).then( async function( pdfBuffer ) {
|
|
2791
2857
|
if ( req.body.sendInvoice ) {
|
|
@@ -2811,7 +2877,7 @@ export const invoiceDownload = async ( req, res ) => {
|
|
|
2811
2877
|
// return;
|
|
2812
2878
|
const result = await sendEmailWithSES( clientDetails.paymentInvoice.invoiceTo, mailSubject, mailbody, attachments, 'no-reply@tangotech.ai', clientDetails.paymentInvoice.invoiceCC );
|
|
2813
2879
|
if ( result ) {
|
|
2814
|
-
await invoiceService.updateOne( { _id: req.params.invoiceId }, { status:
|
|
2880
|
+
await invoiceService.updateOne( { _id: req.params.invoiceId }, { status: 'Invoice Sent' } );
|
|
2815
2881
|
return res.sendSuccess( result );
|
|
2816
2882
|
}
|
|
2817
2883
|
}
|
|
@@ -3038,7 +3104,6 @@ export const dailyPricingInsert = async ( req, res ) => {
|
|
|
3038
3104
|
if ( !requestData?.date ) {
|
|
3039
3105
|
requestData.date = dayjs().format( 'YYYY-MM-DD' );
|
|
3040
3106
|
}
|
|
3041
|
-
|
|
3042
3107
|
if ( requestData.clientId && requestClient.length > 0 ) {
|
|
3043
3108
|
for ( let clientIndex = 0; clientIndex < requestClient.length; clientIndex++ ) {
|
|
3044
3109
|
let getClient = await paymentService.findOne( { clientId: requestClient[clientIndex] } );
|
|
@@ -3050,43 +3115,12 @@ export const dailyPricingInsert = async ( req, res ) => {
|
|
|
3050
3115
|
for ( let storeIndex = 0; storeIndex < getStore.length; storeIndex++ ) {
|
|
3051
3116
|
let productList = [];
|
|
3052
3117
|
if ( getBaseprice ) {
|
|
3053
|
-
let priceDetails = getClient.priceType == 'standard' ? getBaseprice.standard : getBaseprice.step;
|
|
3054
|
-
for ( let storeProductIndex = 0; storeProductIndex < getStore[storeIndex].product.length; storeProductIndex++ ) {
|
|
3055
|
-
let productDetails;
|
|
3056
|
-
if ( getClient.priceType == 'standard' ) {
|
|
3057
|
-
productDetails = priceDetails.find( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3058
|
-
} else {
|
|
3059
|
-
productDetails = priceDetails.find( ( item ) => {
|
|
3060
|
-
let range = item.storeRange.split( '-' );
|
|
3061
|
-
if ( parseInt( range[0] ) <= ( storeIndex + 1 ) && parseInt( range[1] ) >= ( storeIndex + 1 ) ) {
|
|
3062
|
-
return ( item.productName == getStore[storeIndex].product[storeProductIndex] && parseInt( range[0] ) <= ( storeIndex + 1 ) && parseInt( range[1] ) >= ( storeIndex + 1 ) );
|
|
3063
|
-
}
|
|
3064
|
-
} );
|
|
3065
|
-
if ( !productDetails ) {
|
|
3066
|
-
let stepProductDetails = priceDetails.filter( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3067
|
-
productDetails = stepProductDetails[stepProductDetails.length - 1];
|
|
3068
|
-
}
|
|
3069
|
-
}
|
|
3070
|
-
// let productStatus = getClient.planDetails.product.find( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3071
|
-
if ( productDetails ) {
|
|
3072
|
-
let newObject = {
|
|
3073
|
-
productName: productDetails.productName,
|
|
3074
|
-
// status: productStatus ? productStatus.status : '',
|
|
3075
|
-
// price: productStatus ? [ 'trial', 'free' ].includes( productStatus.status ) ? 0 : productDetails.negotiatePrice : 0,
|
|
3076
|
-
// featureStoreCount: storeIndex + 1,
|
|
3077
|
-
// basePrice: productDetails.negotiatePrice,
|
|
3078
|
-
...( getClient.priceType == 'step' ? { storeRange: productDetails.storeRange } : { storeRange: 'standard' } ),
|
|
3079
|
-
};
|
|
3080
|
-
productList.push( newObject );
|
|
3081
|
-
}
|
|
3082
|
-
}
|
|
3083
|
-
|
|
3084
3118
|
await axios.get( `${JSON.parse( process.env.URL ).oldapidomain}/processedDayData/getDailyData?clientId=${requestClient[clientIndex]}&storeId=${getStore[storeIndex].storeId}&date=${requestData.date}`, { headers: { Authorization: 'Bearer d47433f8-9a33-47c7-ba43-1a0fbac28f66' } } ).then( async ( response ) => {
|
|
3085
3119
|
let processedFileDate = response.data?.data?.firstFileDate || null;
|
|
3086
3120
|
let query = [
|
|
3087
3121
|
{
|
|
3088
3122
|
$match: {
|
|
3089
|
-
clientId:
|
|
3123
|
+
clientId: getClient.clientId,
|
|
3090
3124
|
},
|
|
3091
3125
|
},
|
|
3092
3126
|
{ $unwind: '$stores' },
|
|
@@ -3110,6 +3144,48 @@ export const dailyPricingInsert = async ( req, res ) => {
|
|
|
3110
3144
|
];
|
|
3111
3145
|
let dailyData = await dailyPriceService.aggregate( query );
|
|
3112
3146
|
let cameraDetails = await cameraService.find( { storeId: getStore[storeIndex].storeId, clientId: requestClient[clientIndex], isActivated: true, isUp: true }, { streamName: 1 } );
|
|
3147
|
+
let firstDate = dayjs( getStore[storeIndex]?.edge?.firstFileDate ).format( 'YYYY-MM-DD' );
|
|
3148
|
+
let workingdays;
|
|
3149
|
+
if ( firstDate < requestData.date && getStore[storeIndex]?.status == 'active' &&
|
|
3150
|
+
dailyData[0]?.dateString != dayjs( requestData.date, 'YYYY-MM-DD' ).format( 'YYYY-MM-DD' ) ) {
|
|
3151
|
+
if ( dailyData.length && dailyData[0]?.stores?.daysDifference ) {
|
|
3152
|
+
workingdays = dailyData[0]?.stores?.daysDifference + 1;
|
|
3153
|
+
} else {
|
|
3154
|
+
workingdays = 1;
|
|
3155
|
+
}
|
|
3156
|
+
} else {
|
|
3157
|
+
if ( dailyData[0]?.stores?.daysDifference ) {
|
|
3158
|
+
workingdays = dailyData[0]?.stores?.daysDifference;
|
|
3159
|
+
} else {
|
|
3160
|
+
workingdays = 0;
|
|
3161
|
+
}
|
|
3162
|
+
}
|
|
3163
|
+
let priceDetails = getClient.priceType == 'standard' ? getBaseprice.standard : getBaseprice.step;
|
|
3164
|
+
for ( let storeProductIndex = 0; storeProductIndex < getStore[storeIndex].product.length; storeProductIndex++ ) {
|
|
3165
|
+
let productDetails;
|
|
3166
|
+
if ( getClient.priceType == 'standard' ) {
|
|
3167
|
+
productDetails = priceDetails.find( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3168
|
+
} else {
|
|
3169
|
+
productDetails = priceDetails.find( ( item ) => {
|
|
3170
|
+
let range = item.storeRange.split( '-' );
|
|
3171
|
+
if ( parseInt( range[0] ) <= ( storeIndex + 1 ) && parseInt( range[1] ) >= ( storeIndex + 1 ) ) {
|
|
3172
|
+
return ( item.productName == getStore[storeIndex].product[storeProductIndex] && parseInt( range[0] ) <= ( storeIndex + 1 ) && parseInt( range[1] ) >= ( storeIndex + 1 ) );
|
|
3173
|
+
}
|
|
3174
|
+
} );
|
|
3175
|
+
if ( !productDetails ) {
|
|
3176
|
+
let stepProductDetails = priceDetails.filter( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3177
|
+
productDetails = stepProductDetails[stepProductDetails.length - 1];
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3180
|
+
|
|
3181
|
+
if ( productDetails ) {
|
|
3182
|
+
let newObject = {
|
|
3183
|
+
productName: productDetails.productName,
|
|
3184
|
+
workingdays: workingdays,
|
|
3185
|
+
};
|
|
3186
|
+
productList.push( newObject );
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3113
3189
|
storeList.push(
|
|
3114
3190
|
{
|
|
3115
3191
|
storeId: getStore[storeIndex].storeId,
|
|
@@ -3120,20 +3196,21 @@ export const dailyPricingInsert = async ( req, res ) => {
|
|
|
3120
3196
|
edgefirstFileDate: getStore[storeIndex]?.edge?.firstFileDate || null,
|
|
3121
3197
|
date: new Date( requestData.date ),
|
|
3122
3198
|
processfirstFileDate: processedFileDate?.date_iso || null,
|
|
3123
|
-
daysDifference:
|
|
3199
|
+
daysDifference: workingdays,
|
|
3124
3200
|
products: productList,
|
|
3125
3201
|
camera: cameraDetails.map( ( item ) => item.streamName ),
|
|
3126
3202
|
cameraCount: cameraDetails.length,
|
|
3127
3203
|
},
|
|
3128
3204
|
);
|
|
3129
3205
|
if ( storeIndex == getStore.length - 1 ) {
|
|
3206
|
+
let activestores = storeList.filter( ( store ) => store.status=='active' );
|
|
3130
3207
|
let params = {
|
|
3131
3208
|
clientId: requestClient[clientIndex],
|
|
3132
3209
|
stores: storeList,
|
|
3133
3210
|
dateISO: new Date( requestData.date ),
|
|
3134
3211
|
accountType: getClient?.planDetails?.subscriptionType,
|
|
3135
3212
|
status: getClient?.status,
|
|
3136
|
-
activeStores:
|
|
3213
|
+
activeStores: activestores?.length,
|
|
3137
3214
|
brandName: getClient?.clientName,
|
|
3138
3215
|
proRate: getClient?.paymentInvoice?.proRate,
|
|
3139
3216
|
dateString: dayjs( requestData.date, 'YYYY-MM-DD' ).format( 'YYYY-MM-DD' ),
|
|
@@ -3143,8 +3220,12 @@ export const dailyPricingInsert = async ( req, res ) => {
|
|
|
3143
3220
|
} ).catch( ( error ) => {
|
|
3144
3221
|
logger.error( { error: error, function: 'old processedDayData' } );
|
|
3145
3222
|
} );
|
|
3223
|
+
} else {
|
|
3224
|
+
// console.log( 'base price not found' );
|
|
3146
3225
|
}
|
|
3147
3226
|
}
|
|
3227
|
+
} else {
|
|
3228
|
+
// console.log( 'store not found' );
|
|
3148
3229
|
}
|
|
3149
3230
|
}
|
|
3150
3231
|
if ( clientIndex == requestClient.length - 1 ) {
|
|
@@ -3165,6 +3246,7 @@ export const dailyPricingInsertV1 = async ( req, res ) => {
|
|
|
3165
3246
|
let requestClient = [];
|
|
3166
3247
|
if ( !requestData?.clientId || !requestData?.clientId?.length ) {
|
|
3167
3248
|
clientlist = await paymentService.find( { 'status': 'active' } );
|
|
3249
|
+
|
|
3168
3250
|
for ( let client of clientlist ) {
|
|
3169
3251
|
requestClient.push( client.clientId );
|
|
3170
3252
|
}
|
|
@@ -3182,7 +3264,7 @@ export const dailyPricingInsertV1 = async ( req, res ) => {
|
|
|
3182
3264
|
dayList.push( dayjs( requestData.date ).add( i, 'day' ).format( 'YYYY-MM-DD' ) );
|
|
3183
3265
|
}
|
|
3184
3266
|
|
|
3185
|
-
if ( requestData
|
|
3267
|
+
if ( requestData && requestClient.length > 0 ) {
|
|
3186
3268
|
for ( let i=0; i<dayList.length; i++ ) {
|
|
3187
3269
|
requestData.date = dayList[i];
|
|
3188
3270
|
for ( let clientIndex = 0; clientIndex < requestClient.length; clientIndex++ ) {
|
|
@@ -3195,43 +3277,12 @@ export const dailyPricingInsertV1 = async ( req, res ) => {
|
|
|
3195
3277
|
for ( let storeIndex = 0; storeIndex < getStore.length; storeIndex++ ) {
|
|
3196
3278
|
let productList = [];
|
|
3197
3279
|
if ( getBaseprice ) {
|
|
3198
|
-
let priceDetails = getClient.priceType == 'standard' ? getBaseprice.standard : getBaseprice.step;
|
|
3199
|
-
for ( let storeProductIndex = 0; storeProductIndex < getStore[storeIndex].product.length; storeProductIndex++ ) {
|
|
3200
|
-
let productDetails;
|
|
3201
|
-
if ( getClient.priceType == 'standard' ) {
|
|
3202
|
-
productDetails = priceDetails.find( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3203
|
-
} else {
|
|
3204
|
-
productDetails = priceDetails.find( ( item ) => {
|
|
3205
|
-
let range = item.storeRange.split( '-' );
|
|
3206
|
-
if ( parseInt( range[0] ) <= ( storeIndex + 1 ) && parseInt( range[1] ) >= ( storeIndex + 1 ) ) {
|
|
3207
|
-
return ( item.productName == getStore[storeIndex].product[storeProductIndex] && parseInt( range[0] ) <= ( storeIndex + 1 ) && parseInt( range[1] ) >= ( storeIndex + 1 ) );
|
|
3208
|
-
}
|
|
3209
|
-
} );
|
|
3210
|
-
if ( !productDetails ) {
|
|
3211
|
-
let stepProductDetails = priceDetails.filter( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3212
|
-
productDetails = stepProductDetails[stepProductDetails.length - 1];
|
|
3213
|
-
}
|
|
3214
|
-
}
|
|
3215
|
-
// let productStatus = getClient.planDetails.product.find( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3216
|
-
if ( productDetails ) {
|
|
3217
|
-
let newObject = {
|
|
3218
|
-
productName: productDetails.productName,
|
|
3219
|
-
// status: productStatus ? productStatus.status : '',
|
|
3220
|
-
// price: productStatus ? [ 'trial', 'free' ].includes( productStatus.status ) ? 0 : productDetails.negotiatePrice : 0,
|
|
3221
|
-
// featureStoreCount: storeIndex + 1,
|
|
3222
|
-
// basePrice: productDetails.negotiatePrice,
|
|
3223
|
-
...( getClient.priceType == 'step' ? { storeRange: productDetails.storeRange } : { storeRange: 'standard' } ),
|
|
3224
|
-
};
|
|
3225
|
-
productList.push( newObject );
|
|
3226
|
-
}
|
|
3227
|
-
}
|
|
3228
|
-
|
|
3229
3280
|
await axios.get( `${JSON.parse( process.env.URL ).oldapidomain}/processedDayData/getDailyData?clientId=${requestClient[clientIndex]}&storeId=${getStore[storeIndex].storeId}&date=${requestData.date}`, { headers: { Authorization: 'Bearer d47433f8-9a33-47c7-ba43-1a0fbac28f66' } } ).then( async ( response ) => {
|
|
3230
3281
|
let processedFileDate = response.data?.data?.firstFileDate || null;
|
|
3231
3282
|
let query = [
|
|
3232
3283
|
{
|
|
3233
3284
|
$match: {
|
|
3234
|
-
clientId:
|
|
3285
|
+
clientId: getClient.clientId,
|
|
3235
3286
|
},
|
|
3236
3287
|
},
|
|
3237
3288
|
{ $unwind: '$stores' },
|
|
@@ -3256,6 +3307,47 @@ export const dailyPricingInsertV1 = async ( req, res ) => {
|
|
|
3256
3307
|
let dailyData = await dailyPriceService.aggregate( query );
|
|
3257
3308
|
let cameraDetails = await cameraService.find( { storeId: getStore[storeIndex].storeId, clientId: requestClient[clientIndex], isActivated: true, isUp: true }, { streamName: 1 } );
|
|
3258
3309
|
let firstDate = dayjs( getStore[storeIndex]?.edge?.firstFileDate ).format( 'YYYY-MM-DD' );
|
|
3310
|
+
let workingdays;
|
|
3311
|
+
if ( firstDate < requestData.date && getStore[storeIndex]?.status == 'active' &&
|
|
3312
|
+
dailyData[0]?.dateString != dayjs( requestData.date, 'YYYY-MM-DD' ).format( 'YYYY-MM-DD' ) ) {
|
|
3313
|
+
if ( dailyData.length && dailyData[0]?.stores?.daysDifference ) {
|
|
3314
|
+
workingdays = dailyData[0]?.stores?.daysDifference + 1;
|
|
3315
|
+
} else {
|
|
3316
|
+
workingdays = 1;
|
|
3317
|
+
}
|
|
3318
|
+
} else {
|
|
3319
|
+
if ( dailyData[0]?.stores?.daysDifference ) {
|
|
3320
|
+
workingdays = dailyData[0]?.stores?.daysDifference;
|
|
3321
|
+
} else {
|
|
3322
|
+
workingdays = 0;
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3325
|
+
let priceDetails = getClient.priceType == 'standard' ? getBaseprice.standard : getBaseprice.step;
|
|
3326
|
+
for ( let storeProductIndex = 0; storeProductIndex < getStore[storeIndex].product.length; storeProductIndex++ ) {
|
|
3327
|
+
let productDetails;
|
|
3328
|
+
if ( getClient.priceType == 'standard' ) {
|
|
3329
|
+
productDetails = priceDetails.find( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3330
|
+
} else {
|
|
3331
|
+
productDetails = priceDetails.find( ( item ) => {
|
|
3332
|
+
let range = item.storeRange.split( '-' );
|
|
3333
|
+
if ( parseInt( range[0] ) <= ( storeIndex + 1 ) && parseInt( range[1] ) >= ( storeIndex + 1 ) ) {
|
|
3334
|
+
return ( item.productName == getStore[storeIndex].product[storeProductIndex] && parseInt( range[0] ) <= ( storeIndex + 1 ) && parseInt( range[1] ) >= ( storeIndex + 1 ) );
|
|
3335
|
+
}
|
|
3336
|
+
} );
|
|
3337
|
+
if ( !productDetails ) {
|
|
3338
|
+
let stepProductDetails = priceDetails.filter( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3339
|
+
productDetails = stepProductDetails[stepProductDetails.length - 1];
|
|
3340
|
+
}
|
|
3341
|
+
}
|
|
3342
|
+
// let productStatus = getClient.planDetails.product.find( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3343
|
+
if ( productDetails ) {
|
|
3344
|
+
let newObject = {
|
|
3345
|
+
productName: productDetails.productName,
|
|
3346
|
+
workingdays: workingdays,
|
|
3347
|
+
};
|
|
3348
|
+
productList.push( newObject );
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3259
3351
|
storeList.push(
|
|
3260
3352
|
{
|
|
3261
3353
|
storeId: getStore[storeIndex].storeId,
|
|
@@ -3266,20 +3358,21 @@ export const dailyPricingInsertV1 = async ( req, res ) => {
|
|
|
3266
3358
|
edgefirstFileDate: getStore[storeIndex]?.edge?.firstFileDate || null,
|
|
3267
3359
|
date: new Date( requestData.date ),
|
|
3268
3360
|
processfirstFileDate: processedFileDate?.date_iso || null,
|
|
3269
|
-
daysDifference:
|
|
3361
|
+
daysDifference: workingdays,
|
|
3270
3362
|
products: productList,
|
|
3271
3363
|
camera: cameraDetails.map( ( item ) => item.streamName ),
|
|
3272
3364
|
cameraCount: cameraDetails.length,
|
|
3273
3365
|
},
|
|
3274
3366
|
);
|
|
3275
3367
|
if ( storeIndex == getStore.length - 1 ) {
|
|
3368
|
+
let activestores = storeList.filter( ( store ) => store.status=='active' );
|
|
3276
3369
|
let params = {
|
|
3277
3370
|
clientId: requestClient[clientIndex],
|
|
3278
3371
|
stores: storeList,
|
|
3279
3372
|
dateISO: new Date( requestData.date ),
|
|
3280
3373
|
accountType: getClient?.planDetails?.subscriptionType,
|
|
3281
3374
|
status: getClient?.status,
|
|
3282
|
-
activeStores:
|
|
3375
|
+
activeStores: activestores?.length,
|
|
3283
3376
|
brandName: getClient?.clientName,
|
|
3284
3377
|
proRate: getClient?.paymentInvoice?.proRate,
|
|
3285
3378
|
dateString: dayjs( requestData.date, 'YYYY-MM-DD' ).format( 'YYYY-MM-DD' ),
|
|
@@ -3289,8 +3382,12 @@ export const dailyPricingInsertV1 = async ( req, res ) => {
|
|
|
3289
3382
|
} ).catch( ( error ) => {
|
|
3290
3383
|
logger.error( { error: error, function: 'old processedDayData' } );
|
|
3291
3384
|
} );
|
|
3385
|
+
} else {
|
|
3386
|
+
// console.log( 'base price not found' );
|
|
3292
3387
|
}
|
|
3293
3388
|
}
|
|
3389
|
+
} else {
|
|
3390
|
+
// console.log( 'store not found' );
|
|
3294
3391
|
}
|
|
3295
3392
|
}
|
|
3296
3393
|
if ( i == dayList.length - 1 ) {
|
|
@@ -3298,6 +3395,8 @@ export const dailyPricingInsertV1 = async ( req, res ) => {
|
|
|
3298
3395
|
}
|
|
3299
3396
|
}
|
|
3300
3397
|
}
|
|
3398
|
+
} else {
|
|
3399
|
+
res.sendError( 'No client Found', 500 );
|
|
3301
3400
|
}
|
|
3302
3401
|
} catch ( e ) {
|
|
3303
3402
|
logger.error( { error: e, function: 'invoiceCreate' } );
|
|
@@ -3667,3 +3766,25 @@ function convertTitleCase( data ) {
|
|
|
3667
3766
|
}
|
|
3668
3767
|
|
|
3669
3768
|
|
|
3769
|
+
export async function createDefaultbillings( req, res ) {
|
|
3770
|
+
let clientlist = await paymentService.find( { 'status': 'active' } );
|
|
3771
|
+
|
|
3772
|
+
for ( let client of clientlist ) {
|
|
3773
|
+
let storeslist = await storeService.find( { clientId: client.clientId }, { storeId: 1 } );
|
|
3774
|
+
storeslist = storeslist.map( ( a ) => a.storeId );
|
|
3775
|
+
let payload = {
|
|
3776
|
+
clientId: client.clientId,
|
|
3777
|
+
registeredCompanyName: client.billingDetails.companyName,
|
|
3778
|
+
gst: client.billingDetails.gstNumber,
|
|
3779
|
+
addressLineOne: client.billingDetails.billingAddress,
|
|
3780
|
+
placeOfSupply: client.billingDetails.PlaceOfSupply,
|
|
3781
|
+
stores: storeslist,
|
|
3782
|
+
currency: client.paymentInvoice.currencyType,
|
|
3783
|
+
generateInvoiceTo: [ ...client.paymentInvoice.invoiceCC, ...client.paymentInvoice.invoiceCC.invoiceTo?client.paymentInvoice.invoiceCC.invoiceTo:[] ],
|
|
3784
|
+
isPrimary: true,
|
|
3785
|
+
|
|
3786
|
+
};
|
|
3787
|
+
await billingService.create( payload );
|
|
3788
|
+
}
|
|
3789
|
+
}
|
|
3790
|
+
|