tango-app-api-payment-subscription 3.0.9-dev → 3.0.11-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.
|
|
3
|
+
"version": "3.0.11-dev",
|
|
4
4
|
"description": "paymentSubscription",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"handlebars": "^4.7.8",
|
|
21
21
|
"mongodb": "^6.4.0",
|
|
22
22
|
"nodemon": "^3.1.0",
|
|
23
|
-
"tango-api-schema": "^2.0.
|
|
23
|
+
"tango-api-schema": "^2.0.54",
|
|
24
24
|
"tango-app-api-middleware": "^1.0.29",
|
|
25
25
|
"winston": "^3.12.0",
|
|
26
26
|
"winston-daily-rotate-file": "^5.0.0"
|
|
@@ -36,7 +36,6 @@ export const addBilling = async ( req, res ) => {
|
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
|
|
40
39
|
export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
|
|
41
40
|
try {
|
|
42
41
|
let query = [
|
|
@@ -88,51 +87,56 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
|
|
|
88
87
|
}
|
|
89
88
|
|
|
90
89
|
let singleActiveProducts = [];
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
for ( let i = 0; i < tangoProducts.length; i++ ) {
|
|
96
|
-
if ( !singleActiveProducts.includes( tangoProducts[i] ) ) {
|
|
97
|
-
activeProducts.push( { productName: tangoProducts[i], active: false } );
|
|
90
|
+
if ( activeProducts && activeProducts.length ) {
|
|
91
|
+
for ( let i = 0; i < activeProducts.length; i++ ) {
|
|
92
|
+
singleActiveProducts.push( activeProducts[i].productName );
|
|
98
93
|
}
|
|
99
|
-
}
|
|
100
94
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
break;
|
|
106
|
-
case 'tangoZone':
|
|
107
|
-
element.aliseProductName = 'Tango Zone';
|
|
108
|
-
break;
|
|
109
|
-
case 'tangoSOP':
|
|
110
|
-
element.aliseProductName = 'Tango SOP';
|
|
111
|
-
break;
|
|
112
|
-
case 'prioritySupport':
|
|
113
|
-
element.aliseProductName = 'Priority Support';
|
|
114
|
-
break;
|
|
115
|
-
default:
|
|
116
|
-
break;
|
|
95
|
+
for ( let i = 0; i < tangoProducts.length; i++ ) {
|
|
96
|
+
if ( !singleActiveProducts.includes( tangoProducts[i] ) ) {
|
|
97
|
+
activeProducts.push( { productName: tangoProducts[i], active: false } );
|
|
98
|
+
}
|
|
117
99
|
}
|
|
118
100
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
101
|
+
activeProducts.forEach( ( element ) => {
|
|
102
|
+
switch ( element.productName ) {
|
|
103
|
+
case 'tangoTraffic':
|
|
104
|
+
element.aliseProductName = 'Tango Traffic';
|
|
105
|
+
break;
|
|
106
|
+
case 'tangoZone':
|
|
107
|
+
element.aliseProductName = 'Tango Zone';
|
|
108
|
+
break;
|
|
109
|
+
case 'tangoSOP':
|
|
110
|
+
element.aliseProductName = 'Tango SOP';
|
|
111
|
+
break;
|
|
112
|
+
case 'prioritySupport':
|
|
113
|
+
element.aliseProductName = 'Priority Support';
|
|
114
|
+
break;
|
|
115
|
+
default:
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if ( element.status == 'live' ) {
|
|
120
|
+
liveProducts.push( { 'productName': element.productName, 'aliseProductName': element.aliseProductName } );
|
|
121
|
+
element.toolTip = 'Subscribed';
|
|
122
|
+
element.active = true;
|
|
123
|
+
}
|
|
124
|
+
if ( element.status == 'trial' ) {
|
|
125
|
+
let differenceInDays = 14;
|
|
126
|
+
if ( element?.trialEndDate ) {
|
|
127
|
+
differenceInDays = dateDifference( element?.trialEndDate, currentDate );
|
|
128
|
+
}
|
|
129
|
+
trialProducts.push( { 'productName': element.productName, 'aliseProductName': element.aliseProductName, 'toolTip': differenceInDays +' days trial left' } );
|
|
130
|
+
element.toolTip = 'On Trial';
|
|
131
|
+
element.active = true;
|
|
132
|
+
}
|
|
133
|
+
if ( element.status == 'trial' && ( element.trialEndDate < currentDate ) ) {
|
|
134
|
+
expiredProducts.push( { 'productName': element.productName, 'aliseProductName': element.aliseProductName, 'toolTip': 'Trial Expired' } );
|
|
135
|
+
element.toolTip = 'Trial Expired';
|
|
136
|
+
element.active = true;
|
|
137
|
+
}
|
|
138
|
+
} );
|
|
139
|
+
}
|
|
136
140
|
|
|
137
141
|
let priceType = '';
|
|
138
142
|
if ( clientInfo[0].priceType == 'step' ) {
|
|
@@ -169,7 +173,7 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
|
|
|
169
173
|
currentPlanInfo.storeCount = storeCount || '--';
|
|
170
174
|
currentPlanInfo.totalCamera = clientInfo[0].planDetails.totalCamera || '--';
|
|
171
175
|
currentPlanInfo.totalStores = clientInfo[0].planDetails.totalStores || '--';
|
|
172
|
-
currentPlanInfo.storeSize = clientInfo[0].planDetails.
|
|
176
|
+
currentPlanInfo.storeSize = clientInfo[0].planDetails.storeSize || '--';
|
|
173
177
|
currentPlanInfo.liveProducts = liveProducts || '--';
|
|
174
178
|
currentPlanInfo.trialProducts = trialProducts || '--';
|
|
175
179
|
currentPlanInfo.expiredProducts = expiredProducts || '--';
|
|
@@ -195,6 +199,13 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
|
|
|
195
199
|
|
|
196
200
|
export const pricingInfo = async ( req, res ) => {
|
|
197
201
|
try {
|
|
202
|
+
let input = req.body;
|
|
203
|
+
let finalPrice = 0;
|
|
204
|
+
let dummy = [];
|
|
205
|
+
let camaraArray = [];
|
|
206
|
+
let OriginalPrice = 0;
|
|
207
|
+
let productDiscounts = [];
|
|
208
|
+
let dollerpriceOriginal = 0;
|
|
198
209
|
let query = [
|
|
199
210
|
{ $unwind: '$basePricing' },
|
|
200
211
|
{
|
|
@@ -203,23 +214,92 @@ export const pricingInfo = async ( req, res ) => {
|
|
|
203
214
|
'basePricing.productName': { $in: req.body.products },
|
|
204
215
|
},
|
|
205
216
|
},
|
|
206
|
-
{
|
|
207
|
-
$group: {
|
|
208
|
-
_id: '',
|
|
209
|
-
price: {
|
|
210
|
-
$sum: '$basePricing.basePrice' },
|
|
211
|
-
},
|
|
212
|
-
},
|
|
213
217
|
{
|
|
214
218
|
$project: {
|
|
215
219
|
_id: 0,
|
|
216
|
-
|
|
220
|
+
basePricing: 1,
|
|
217
221
|
},
|
|
218
222
|
},
|
|
219
223
|
];
|
|
220
224
|
let pricingDetails = await basePricingService.aggregate( query );
|
|
221
|
-
|
|
222
|
-
|
|
225
|
+
if ( !pricingDetails.length ) {
|
|
226
|
+
return res.sendError( 'no data found', 204 );
|
|
227
|
+
}
|
|
228
|
+
let productList = pricingDetails.map( ( item ) => {
|
|
229
|
+
return { ...item.basePricing };
|
|
230
|
+
} );
|
|
231
|
+
input.products.forEach( async ( element, index ) => {
|
|
232
|
+
let getProduct = productList.find( ( item ) => item.productName == element );
|
|
233
|
+
let camaraPerSqft = getProduct.camaraPerStores.filter( ( data ) => data.sqft == input.camaraPerSqft );
|
|
234
|
+
console.log( camaraPerSqft, 'rest' );
|
|
235
|
+
let basicprice = Math.round( getProduct.basePrice * ( camaraPerSqft[0].camaraCount ) );
|
|
236
|
+
productDiscounts.push( getProduct.discoutPercentage );
|
|
237
|
+
let stage = 0;
|
|
238
|
+
if ( input.storesCount == '1-25' ) {
|
|
239
|
+
stage = 0;
|
|
240
|
+
} else if ( input.storesCount == '26-50' ) {
|
|
241
|
+
stage = 1;
|
|
242
|
+
} else if ( input.storesCount == '51-75' ) {
|
|
243
|
+
stage = 2;
|
|
244
|
+
} else if ( input.storesCount == '76-100' ) {
|
|
245
|
+
stage = 2;
|
|
246
|
+
} else if ( input.storesCount == '51-100' ) {
|
|
247
|
+
stage = 2;
|
|
248
|
+
} else if ( input.storesCount == '101-150' || input.storesCount == '101+' ) {
|
|
249
|
+
stage = 3;
|
|
250
|
+
} else if ( input.storesCount == '151-200' ) {
|
|
251
|
+
stage = 4;
|
|
252
|
+
} else if ( input.storesCount == '201-250' ) {
|
|
253
|
+
stage = 5;
|
|
254
|
+
} else if ( input.storesCount == '251-500' ) {
|
|
255
|
+
stage = 6;
|
|
256
|
+
} else if ( input.storesCount == '501-1000' ) {
|
|
257
|
+
stage = 7;
|
|
258
|
+
} else if ( input.storesCount == '1001-2000' ) {
|
|
259
|
+
stage = 8;
|
|
260
|
+
} else if ( input.storesCount == '2000+' ) {
|
|
261
|
+
stage = 9;
|
|
262
|
+
}
|
|
263
|
+
let discountprice = Math.round( basicprice * Math.pow( 0.9, stage ) );
|
|
264
|
+
dummy.push( discountprice );
|
|
265
|
+
OriginalPrice = OriginalPrice + discountprice;
|
|
266
|
+
// console.log("====>", OriginalPrice);
|
|
267
|
+
finalPrice = finalPrice + discountprice;
|
|
268
|
+
camaraArray.push( Number( Math.ceil( camaraPerSqft[0].camaraCount ) ) );
|
|
269
|
+
if ( dummy.length == input.products.length ) {
|
|
270
|
+
if ( input.products.length > 1 ) {
|
|
271
|
+
// for extra product to add maximum discount
|
|
272
|
+
let maxProductDiscounts = Math.max( ...productDiscounts );
|
|
273
|
+
let addtionalDiscount = ( finalPrice * maxProductDiscounts ) / 100;
|
|
274
|
+
console.log( 'addtional product discount', addtionalDiscount );
|
|
275
|
+
finalPrice = finalPrice - addtionalDiscount;
|
|
276
|
+
console.log( finalPrice, 'test' );
|
|
277
|
+
// OriginalPrice = OriginalPrice + addtionalDiscount
|
|
278
|
+
}
|
|
279
|
+
if ( input.planName == 'quarterly' ) {
|
|
280
|
+
let extraDiscount = ( finalPrice * 10 ) / 100;
|
|
281
|
+
console.log( 'halfyearly extraDiscount', extraDiscount );
|
|
282
|
+
finalPrice = finalPrice - extraDiscount;
|
|
283
|
+
console.log( finalPrice, 'rtyu' );
|
|
284
|
+
// OriginalPrice = OriginalPrice + extra_discount
|
|
285
|
+
}
|
|
286
|
+
if ( input.planName == 'annual' ) {
|
|
287
|
+
let extraDiscount = ( finalPrice * 20 ) / 100;
|
|
288
|
+
console.log( 'yearly extraDiscount', extraDiscount );
|
|
289
|
+
finalPrice = finalPrice - extraDiscount;
|
|
290
|
+
console.log( finalPrice, 'fgvbh' );
|
|
291
|
+
// OriginalPrice = OriginalPrice + extra_discount
|
|
292
|
+
}
|
|
293
|
+
finalPrice = Math.ceil( finalPrice / 10 ) * 10; // for round off to 10 position
|
|
294
|
+
if ( input.currencyType && input.currencyType == 'dollar' ) {
|
|
295
|
+
dollerprice = ( ( finalPrice * 50 ) / 100 );
|
|
296
|
+
finalPrice = ( dollerprice + finalPrice ) / 84;
|
|
297
|
+
dollerpriceOriginal = ( ( OriginalPrice * 50 ) / 100 );
|
|
298
|
+
OriginalPrice = ( dollerpriceOriginal + OriginalPrice ) / 84;
|
|
299
|
+
}
|
|
300
|
+
res.sendSuccess( { OriginalPrice: Math.round( OriginalPrice ), price: Math.round( finalPrice ) } );
|
|
301
|
+
}
|
|
302
|
+
} );
|
|
223
303
|
} catch ( e ) {
|
|
224
304
|
console.log( 'pricingInfo=>', e );
|
|
225
305
|
logger.error( { error: e, function: 'pricingInfo' } );
|
|
@@ -227,7 +307,7 @@ export const pricingInfo = async ( req, res ) => {
|
|
|
227
307
|
}
|
|
228
308
|
};
|
|
229
309
|
|
|
230
|
-
export const
|
|
310
|
+
export const updateSubscriptionOLD = async ( req, res ) => {
|
|
231
311
|
try {
|
|
232
312
|
if ( !req?.body?.currentPlanInfo ) {
|
|
233
313
|
return res.sendError( 'Plan info detail is required', 400 );
|
|
@@ -279,6 +359,86 @@ export const updateSubscription = async ( req, res ) => {
|
|
|
279
359
|
}
|
|
280
360
|
};
|
|
281
361
|
|
|
362
|
+
export const updateSubscription = async ( req, res ) => {
|
|
363
|
+
try {
|
|
364
|
+
let requestBody = req.body;
|
|
365
|
+
if ( !req?.body?.currentPlanInfo ) {
|
|
366
|
+
return res.sendError( 'Plan info detail is required', 400 );
|
|
367
|
+
}
|
|
368
|
+
let price = requestBody.currentPlanInfo.price;
|
|
369
|
+
let priceType = requestBody.currentPlanInfo.priceType;
|
|
370
|
+
delete requestBody.currentPlanInfo.price;
|
|
371
|
+
delete requestBody.currentPlanInfo.priceType;
|
|
372
|
+
delete requestBody.currentPlanInfo.storeCount;
|
|
373
|
+
|
|
374
|
+
console.log( 'requestBody.currentPlanInfo.product 1=>', requestBody.currentPlanInfo.product );
|
|
375
|
+
for ( let i = 0; i < requestBody.currentPlanInfo.product.length; i++ ) {
|
|
376
|
+
if ( requestBody.currentPlanInfo.product[i].status == 'live' && requestBody.currentPlanInfo.product[i].active == true ) {};
|
|
377
|
+
if ( requestBody.currentPlanInfo.product[i].status == 'trial' && requestBody.currentPlanInfo.product[i].active == true ) {
|
|
378
|
+
if ( requestBody.currentPlanInfo.product[i].confirmation == 'subscribenow' ) {
|
|
379
|
+
requestBody.currentPlanInfo.product[i].subscribedDate = new Date();
|
|
380
|
+
requestBody.currentPlanInfo.product[i].status = 'live';
|
|
381
|
+
requestBody.currentPlanInfo.product[i].trialStartDate = requestBody.currentPlanInfo.product[i]?.trialStartDate || '';
|
|
382
|
+
requestBody.currentPlanInfo.product[i].trialEndDate = requestBody.currentPlanInfo.product[i]?.trialEndDate || '';
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
if ( requestBody.currentPlanInfo.product[i].active == true && !requestBody.currentPlanInfo.product[i].hasOwnProperty( 'status' ) ) {
|
|
386
|
+
if ( requestBody.currentPlanInfo.product[i].confirmation == 'subscribenow' ) {
|
|
387
|
+
requestBody.currentPlanInfo.product[i].subscribedDate = new Date();
|
|
388
|
+
requestBody.currentPlanInfo.product[i].status = 'live';
|
|
389
|
+
requestBody.currentPlanInfo.product[i].trialStartDate = requestBody.currentPlanInfo.product[i]?.trialStartDate || '';
|
|
390
|
+
requestBody.currentPlanInfo.product[i].trialEndDate = requestBody.currentPlanInfo.product[i]?.trialEndDate || '';
|
|
391
|
+
}
|
|
392
|
+
if ( requestBody.currentPlanInfo.product[i].confirmation == 'starttrail' ) {
|
|
393
|
+
requestBody.currentPlanInfo.product[i].status = 'trial';
|
|
394
|
+
let params = {
|
|
395
|
+
user: '65e966e12b1991393cf8ce30', // need to login user id here
|
|
396
|
+
clientId: requestBody.clientId,
|
|
397
|
+
name: requestBody.currentPlanInfo.product[i].productName,
|
|
398
|
+
description: 'Request for Trial',
|
|
399
|
+
category: 'Trial',
|
|
400
|
+
status: 'pending',
|
|
401
|
+
};
|
|
402
|
+
await clientRequestService.insert( params );
|
|
403
|
+
}
|
|
404
|
+
if ( requestBody.currentPlanInfo.product[i].confirmation == 'doitlater' ) {
|
|
405
|
+
console.log( 'check' );
|
|
406
|
+
// need to do price changes
|
|
407
|
+
requestBody.currentPlanInfo.product.splice( i, 1 );
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
for ( let j = 0; j < requestBody.currentPlanInfo.product.length; j++ ) {
|
|
413
|
+
delete requestBody.currentPlanInfo.product[j]?.aliseProductName;
|
|
414
|
+
delete requestBody.currentPlanInfo.product[j]?.toolTip;
|
|
415
|
+
delete requestBody.currentPlanInfo.product[j]?.active;
|
|
416
|
+
delete requestBody.currentPlanInfo.product[j]?.confirmation;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
console.log( 'requestBody.currentPlanInfo.product 2=>', requestBody.currentPlanInfo.product );
|
|
420
|
+
let details = {
|
|
421
|
+
planDetails: requestBody.currentPlanInfo,
|
|
422
|
+
price: price,
|
|
423
|
+
priceType: priceType,
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
let result = await paymentService.updateOne( { clientId: req.params.clientId }, details );
|
|
427
|
+
// let storeProduct = requestBody.currentPlanInfo.product.map( ( item ) => item.productName );
|
|
428
|
+
// await storeService.updateMany( { clientId: req.params.clientId, status: 'active' }, { product: storeProduct } );
|
|
429
|
+
|
|
430
|
+
if ( result.modifiedCount ) {
|
|
431
|
+
return res.sendSuccess( { message: 'Subscription Updated Successfully' } );
|
|
432
|
+
} else {
|
|
433
|
+
return res.sendError( 'Something went wrong', 500 );
|
|
434
|
+
}
|
|
435
|
+
} catch ( e ) {
|
|
436
|
+
console.log( e );
|
|
437
|
+
logger.error( { error: e, function: 'updateSubscription' } );
|
|
438
|
+
return res.sendError( e, 500 );
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
|
|
282
442
|
export const trialProductList = async ( req, res ) => {
|
|
283
443
|
try {
|
|
284
444
|
let query =[
|
|
@@ -305,7 +465,16 @@ export const trialProductList = async ( req, res ) => {
|
|
|
305
465
|
if ( !getClientInfo.length ) {
|
|
306
466
|
return res.sendError( 'no data found', 204 );
|
|
307
467
|
}
|
|
308
|
-
let products =
|
|
468
|
+
let products = [];
|
|
469
|
+
getClientInfo.forEach( ( item ) => {
|
|
470
|
+
let [ firstWord, secondWord ] = item.product.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
471
|
+
firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
472
|
+
products.push( {
|
|
473
|
+
name: `${firstWord} ${secondWord}`,
|
|
474
|
+
value: item.product,
|
|
475
|
+
},
|
|
476
|
+
);
|
|
477
|
+
} );
|
|
309
478
|
return res.sendSuccess( products );
|
|
310
479
|
} catch ( e ) {
|
|
311
480
|
console.log( 'trialRequest =>', e );
|
|
@@ -530,40 +699,58 @@ export const trialExtendRequestApproval = async ( req, res ) => {
|
|
|
530
699
|
|
|
531
700
|
export const productSubscribe = async ( req, res ) => {
|
|
532
701
|
try {
|
|
702
|
+
let data = req.body.product;
|
|
703
|
+
req.body.product = [];
|
|
704
|
+
data.forEach( ( item ) => {
|
|
705
|
+
if ( item.type != 'cancel' ) {
|
|
706
|
+
let arr = item.name.split( ',' );
|
|
707
|
+
arr.forEach( ( product ) => {
|
|
708
|
+
req.body.product.push( {
|
|
709
|
+
name: product,
|
|
710
|
+
type: item.type,
|
|
711
|
+
} );
|
|
712
|
+
} );
|
|
713
|
+
}
|
|
714
|
+
} );
|
|
715
|
+
console.log( req.body.product, 'product' );
|
|
533
716
|
let clientInfo = await paymentService.findOne( { clientId: req.body.clientId, status: 'active' }, { clientId: 1, planDetails: 1 } );
|
|
534
717
|
if ( !clientInfo ) {
|
|
535
718
|
return res.sendError( 'no data found', 204 );
|
|
536
719
|
}
|
|
537
720
|
let product = clientInfo.planDetails.product;
|
|
721
|
+
let removeProducts = req.body.product.filter( ( item ) => item.type == 'unsubscribe' ).map( ( item ) => item.name );
|
|
538
722
|
let productList = product.map( ( item ) => item.productName );
|
|
539
723
|
for ( let item of req.body.product ) {
|
|
540
724
|
if ( productList.includes( item.name ) && item.type =='unsubscribe' ) {
|
|
541
|
-
let findIndex = product.findIndex( ( product ) => product.productName );
|
|
542
|
-
product.splice( findIndex, 1 );
|
|
543
|
-
console.log( clientInfo.clientId );
|
|
725
|
+
// let findIndex = product.findIndex( ( product ) => product.productName );
|
|
726
|
+
// product.splice( findIndex, 1 );
|
|
727
|
+
// console.log( clientInfo.clientId );
|
|
544
728
|
await storeService.addremoveElement( { clientId: clientInfo.clientId, status: 'active', product: { $in: item.name } }, { $pull: { product: item.name } } );
|
|
545
729
|
}
|
|
546
|
-
if ( !productList.includes( item.name ) &&
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
730
|
+
if ( !productList.includes( item.name ) && [ 'trial', 'subscription' ].includes( item.type ) ) {
|
|
731
|
+
if ( item.type == 'trial' ) {
|
|
732
|
+
product.push( {
|
|
733
|
+
productName: item.name,
|
|
734
|
+
trialStartDate: new Date(),
|
|
735
|
+
trialEndDate: new Date( dayjs().add( 13, 'days' ).format( 'YYYY-MM-DD' ) ),
|
|
736
|
+
status: 'trial',
|
|
737
|
+
} );
|
|
738
|
+
} else {
|
|
739
|
+
product.push( {
|
|
740
|
+
productName: item.name,
|
|
741
|
+
subscribedDate: new Date(),
|
|
742
|
+
status: 'live',
|
|
743
|
+
} );
|
|
744
|
+
}
|
|
560
745
|
await storeService.addremoveElement( { clientId: clientInfo.clientId, status: 'active' }, { $push: { product: item.name } } );
|
|
561
746
|
}
|
|
562
747
|
}
|
|
748
|
+
product = product.filter( ( item ) => !removeProducts.includes( item.productName ) );
|
|
749
|
+
console.log( product, 'product' );
|
|
563
750
|
clientInfo.planDetails.product = product;
|
|
564
751
|
clientInfo.save().then( async () => {
|
|
565
|
-
return res.sendSuccess( 'Product Subscribed Successfully' );
|
|
566
752
|
} );
|
|
753
|
+
return res.sendSuccess( 'Product Subscribed Successfully' );
|
|
567
754
|
} catch ( e ) {
|
|
568
755
|
console.log( 'updateProductSubscribe =>', e );
|
|
569
756
|
logger.error( { error: e, function: 'updateProductSubscribe' } );
|
|
@@ -622,18 +809,42 @@ export const productViewList = async ( req, res ) => {
|
|
|
622
809
|
},
|
|
623
810
|
];
|
|
624
811
|
let storeProductCount = await storeService.aggregate( query );
|
|
625
|
-
|
|
812
|
+
let clientProduct = await paymentService.findOne( { clientId: req.query.clientId }, { 'planDetails.product': 1 } );
|
|
813
|
+
|
|
814
|
+
if ( !clientProduct ) {
|
|
626
815
|
return res.sendError( 'no data found', 204 );
|
|
627
816
|
}
|
|
817
|
+
console.log( clientProduct.planDetails.product );
|
|
628
818
|
let productPrice = await basePricingService.findOne( { clientId: { $exists: false } }, { basePricing: 1 } );
|
|
629
|
-
console.log(
|
|
630
|
-
|
|
631
|
-
|
|
819
|
+
console.log( storeProductCount, 'price' );
|
|
820
|
+
let products = [];
|
|
821
|
+
clientProduct.planDetails.product.forEach( ( item ) => {
|
|
822
|
+
let price;
|
|
823
|
+
let count;
|
|
824
|
+
let productBasePrice = productPrice.basePricing.find( ( product ) => product.productName == item.productName );
|
|
825
|
+
let productCount = storeProductCount.find( ( product ) => product.product == item.productName );
|
|
632
826
|
if ( productBasePrice ) {
|
|
633
|
-
|
|
827
|
+
price = productBasePrice.basePrice;
|
|
828
|
+
}
|
|
829
|
+
if ( productCount ) {
|
|
830
|
+
count = productCount.storeCount;
|
|
634
831
|
}
|
|
832
|
+
products.push(
|
|
833
|
+
{
|
|
834
|
+
product: item.productName,
|
|
835
|
+
basePrice: price,
|
|
836
|
+
storeCount: count,
|
|
837
|
+
status: item.status,
|
|
838
|
+
},
|
|
839
|
+
);
|
|
635
840
|
} );
|
|
636
|
-
|
|
841
|
+
// storeProductCount.forEach( ( item ) => {
|
|
842
|
+
// let productBasePrice = productPrice.basePricing.find( ( product ) => product.productName == item.product );
|
|
843
|
+
// if ( productBasePrice ) {
|
|
844
|
+
// item.basePrice = productBasePrice.basePrice;
|
|
845
|
+
// }
|
|
846
|
+
// } );
|
|
847
|
+
return res.sendSuccess( products );
|
|
637
848
|
} catch ( e ) {
|
|
638
849
|
console.log( 'productViewList =>', e );
|
|
639
850
|
logger.error( { error: e, function: 'productViewList' } );
|
|
@@ -714,7 +925,10 @@ export const storeViewList = async ( req, res ) => {
|
|
|
714
925
|
},
|
|
715
926
|
);
|
|
716
927
|
|
|
928
|
+
console.log( JSON.stringify( query ), 'query' );
|
|
929
|
+
|
|
717
930
|
let storeDetails = await storeService.aggregate( query );
|
|
931
|
+
console.log( storeDetails );
|
|
718
932
|
|
|
719
933
|
if ( !storeDetails[0].data.length ) {
|
|
720
934
|
return res.sendError( 'no data found', 204 );
|
|
@@ -878,12 +1092,12 @@ export const invoiceList = async ( req, res ) => {
|
|
|
878
1092
|
|
|
879
1093
|
export const priceList = async ( req, res ) => {
|
|
880
1094
|
try {
|
|
881
|
-
let pricingDetails = await basePricingService.findOne( { clientId: { $exists: true }, clientId: req.
|
|
1095
|
+
let pricingDetails = await basePricingService.findOne( { clientId: { $exists: true }, clientId: req.body.clientId }, { standard: 1, step: 1 } );
|
|
882
1096
|
if ( !pricingDetails ) {
|
|
883
1097
|
return res.sendError( 'no data found', 204 );
|
|
884
1098
|
}
|
|
885
1099
|
let data = [];
|
|
886
|
-
if (
|
|
1100
|
+
if ( req.body.priceType == 'standard' ) {
|
|
887
1101
|
data = pricingDetails.standard;
|
|
888
1102
|
} else {
|
|
889
1103
|
data = pricingDetails.step;
|
|
@@ -891,7 +1105,7 @@ export const priceList = async ( req, res ) => {
|
|
|
891
1105
|
let query = [
|
|
892
1106
|
{
|
|
893
1107
|
$match: {
|
|
894
|
-
clientId: req.
|
|
1108
|
+
clientId: req.body.clientId,
|
|
895
1109
|
status: 'active',
|
|
896
1110
|
},
|
|
897
1111
|
},
|
|
@@ -913,21 +1127,29 @@ export const priceList = async ( req, res ) => {
|
|
|
913
1127
|
let storeProduct = await storeService.aggregate( query );
|
|
914
1128
|
let originalTotalPrice = 0;
|
|
915
1129
|
let discountTotalPrice = 0;
|
|
1130
|
+
let totalProductPrice = 0;
|
|
1131
|
+
let totalnegotiatePrice = 0;
|
|
916
1132
|
let temp = [];
|
|
917
|
-
console.log( data );
|
|
918
|
-
console.log( storeProduct );
|
|
919
1133
|
storeProduct.forEach( ( item ) => {
|
|
920
1134
|
let productDetails = data.filter( ( ele ) => ele.productName == item.product );
|
|
921
1135
|
productDetails.forEach( ( product, index ) => {
|
|
922
|
-
if ( req.body.
|
|
1136
|
+
if ( req.body.priceType == 'standard' ) {
|
|
923
1137
|
product.storeCount = item.storeCount;
|
|
924
1138
|
} else {
|
|
1139
|
+
product.showImg = false;
|
|
1140
|
+
product.showEditDelete = false;
|
|
925
1141
|
if ( index == productDetails.length-1 ) {
|
|
1142
|
+
if ( index != 0 ) {
|
|
1143
|
+
product.showImg = true;
|
|
1144
|
+
product.showEditDelete = true;
|
|
1145
|
+
}
|
|
926
1146
|
product.storeCount = item.storeCount;
|
|
1147
|
+
product.lastIndex = true;
|
|
927
1148
|
} else if ( index == 0 ) {
|
|
928
1149
|
product.storeCount = 100;
|
|
929
1150
|
item.storeCount = item.storeCount - 100;
|
|
930
1151
|
} else {
|
|
1152
|
+
product.showImg = true;
|
|
931
1153
|
let rangeArray = product.storeRange.split( '-' );
|
|
932
1154
|
let startNumber = parseInt( rangeArray[0] );
|
|
933
1155
|
let endNumber = parseInt( rangeArray[1] );
|
|
@@ -938,19 +1160,29 @@ export const priceList = async ( req, res ) => {
|
|
|
938
1160
|
}
|
|
939
1161
|
let discountPrice = product.basePrice * ( product.discountPercentage / 100 );
|
|
940
1162
|
let price = product.basePrice - discountPrice;
|
|
1163
|
+
totalProductPrice = totalProductPrice + product.basePrice;
|
|
1164
|
+
totalnegotiatePrice = totalnegotiatePrice + product.negotiatePrice;
|
|
941
1165
|
product.price = price * product.storeCount;
|
|
942
1166
|
temp.push( product );
|
|
943
1167
|
let originalPrice = product.basePrice * product.storeCount;
|
|
1168
|
+
product.originalPrice = originalPrice;
|
|
944
1169
|
originalTotalPrice = originalTotalPrice + originalPrice;
|
|
945
1170
|
discountTotalPrice = discountTotalPrice + product.price;
|
|
946
1171
|
} );
|
|
947
1172
|
} );
|
|
948
1173
|
data = temp;
|
|
949
|
-
|
|
1174
|
+
let discountPrice = originalTotalPrice - discountTotalPrice;
|
|
1175
|
+
let discountPercentage = ( discountTotalPrice / originalTotalPrice ) * 100;
|
|
1176
|
+
let finalValue = discountTotalPrice * ( 18 / 100 );
|
|
950
1177
|
let result = {
|
|
951
1178
|
product: data,
|
|
952
1179
|
totalActualPrice: originalTotalPrice,
|
|
953
|
-
|
|
1180
|
+
totalNegotiatePrice: discountTotalPrice,
|
|
1181
|
+
actualPrice: totalProductPrice,
|
|
1182
|
+
negotiatePrice: totalnegotiatePrice,
|
|
1183
|
+
discountPrice: discountPrice,
|
|
1184
|
+
discountPercentage: discountPercentage.toFixed(),
|
|
1185
|
+
finalValue: finalValue.toFixed( 2 ),
|
|
954
1186
|
};
|
|
955
1187
|
return res.sendSuccess( result );
|
|
956
1188
|
} catch ( e ) {
|
|
@@ -963,6 +1195,19 @@ export const priceList = async ( req, res ) => {
|
|
|
963
1195
|
|
|
964
1196
|
export const pricingListUpdate = async ( req, res ) => {
|
|
965
1197
|
try {
|
|
1198
|
+
req.body.products.forEach( ( item ) => {
|
|
1199
|
+
delete item.originalPrice;
|
|
1200
|
+
delete item.oldPrice;
|
|
1201
|
+
delete item.oldStoreCount;
|
|
1202
|
+
delete item.storeCount;
|
|
1203
|
+
delete item.price;
|
|
1204
|
+
if ( req.body.type == 'step' ) {
|
|
1205
|
+
delete item.showImg;
|
|
1206
|
+
delete item.showEditDelete;
|
|
1207
|
+
delete item.lastIndex;
|
|
1208
|
+
}
|
|
1209
|
+
} );
|
|
1210
|
+
console.log( req.body.products, 'products' );
|
|
966
1211
|
let getPriceInfo = await basePricingService.findOne( { clientId: { $exists: true }, clientId: req.body.clientId }, { standard: 1, step: 1 } );
|
|
967
1212
|
let data = {
|
|
968
1213
|
...( req.body.type == 'standard' ) ? { standard: req.body.products } : { step: req.body.products },
|
|
@@ -994,6 +1239,8 @@ export const updatedRevisedPrice = async ( req, res ) => {
|
|
|
994
1239
|
return res.sendError( 'no data found', 204 );
|
|
995
1240
|
}
|
|
996
1241
|
invoiceDetails.amount = req.body.revisedAmount;
|
|
1242
|
+
invoiceDetails.revisedAmount = req.body.revisedAmount;
|
|
1243
|
+
invoiceDetails.discount = req.body.discount;
|
|
997
1244
|
invoiceDetails.save().then( () => {
|
|
998
1245
|
return res.sendSuccess( 'Credit notes Updated Successfully' );
|
|
999
1246
|
} );
|
|
@@ -1006,7 +1253,7 @@ export const updatedRevisedPrice = async ( req, res ) => {
|
|
|
1006
1253
|
|
|
1007
1254
|
export const unpaidInvoiceList = async ( req, res ) => {
|
|
1008
1255
|
try {
|
|
1009
|
-
let invoiceDetails = await invoiceService.find( { clientId: req.params.clientId, status: { $ne: 'paid' } } );
|
|
1256
|
+
let invoiceDetails = await invoiceService.find( { clientId: req.params.clientId, status: { $ne: 'paid' } }, { invoice: 1, status: 1, amount: 1, revisedAmount: 1, totalAmount: 1, discount: 1 } );
|
|
1010
1257
|
if ( !invoiceDetails.length ) {
|
|
1011
1258
|
return res.sendError( 'no data found', 204 );
|
|
1012
1259
|
}
|
|
@@ -22,11 +22,11 @@ export const validateStoreParams = {
|
|
|
22
22
|
|
|
23
23
|
export const validateProducts = {
|
|
24
24
|
body: joi.object( {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
camaraPerSqft: joi.string().required(),
|
|
26
|
+
currencyType: joi.string().required(),
|
|
27
|
+
planName: joi.string().required(),
|
|
28
28
|
products: joi.array().required(),
|
|
29
|
-
|
|
29
|
+
storesCount: joi.string().required(),
|
|
30
30
|
} ),
|
|
31
31
|
};
|
|
32
32
|
|
|
@@ -74,12 +74,12 @@ export const validateStoreViewParams = {
|
|
|
74
74
|
limit: joi.number().required(),
|
|
75
75
|
offset: joi.number().required(),
|
|
76
76
|
clientId: joi.string().required(),
|
|
77
|
-
sortColumn: joi.string().optional(),
|
|
78
|
-
sortBy: joi.number().optional(),
|
|
79
|
-
searchValue: joi.string().optional(),
|
|
80
|
-
product: joi.array().optional(),
|
|
81
|
-
store: joi.array().optional(),
|
|
82
|
-
location: joi.array().optional(),
|
|
77
|
+
sortColumn: joi.string().optional().empty( '' ),
|
|
78
|
+
sortBy: joi.number().optional().empty( '' ),
|
|
79
|
+
searchValue: joi.string().optional().empty( '' ),
|
|
80
|
+
product: joi.array().optional().empty(),
|
|
81
|
+
store: joi.array().optional().empty(),
|
|
82
|
+
location: joi.array().optional().empty(),
|
|
83
83
|
} ),
|
|
84
84
|
};
|
|
85
85
|
|
|
@@ -116,6 +116,14 @@ export const revisedParams = {
|
|
|
116
116
|
body: joi.object( {
|
|
117
117
|
invoice: joi.string().required(),
|
|
118
118
|
revisedAmount: joi.number().required(),
|
|
119
|
+
discount: joi.number().required(),
|
|
119
120
|
} ),
|
|
120
121
|
};
|
|
121
122
|
|
|
123
|
+
|
|
124
|
+
export const validatePriceListParams = {
|
|
125
|
+
body: joi.object( {
|
|
126
|
+
priceType: joi.string().required(),
|
|
127
|
+
clientId: joi.string().required(),
|
|
128
|
+
} ),
|
|
129
|
+
};
|
|
@@ -46,9 +46,9 @@ paymentSubscriptionRouter.post( '/admin/addStoreProduct', isAllowedSessionHandle
|
|
|
46
46
|
|
|
47
47
|
paymentSubscriptionRouter.post( '/invoiceList', isAllowedSessionHandler, validate( validationDtos.validateInvoiceParams ), validateClient, paymentController.invoiceList );
|
|
48
48
|
|
|
49
|
-
paymentSubscriptionRouter.
|
|
49
|
+
paymentSubscriptionRouter.post( '/admin/priceList', isAllowedSessionHandler, validate( validationDtos.validatePriceListParams ), validateClient, paymentController.priceList );
|
|
50
50
|
|
|
51
|
-
paymentSubscriptionRouter.post( '/pricing', isAllowedSessionHandler, validate( validationDtos.validatePriceParams ), validateClient, paymentController.pricingListUpdate );
|
|
51
|
+
paymentSubscriptionRouter.post( '/admin/pricing', isAllowedSessionHandler, validate( validationDtos.validatePriceParams ), validateClient, paymentController.pricingListUpdate );
|
|
52
52
|
|
|
53
53
|
paymentSubscriptionRouter.post( '/creditNotes', isAllowedSessionHandler, validate( validationDtos.revisedParams ), paymentController.updatedRevisedPrice );
|
|
54
54
|
|