tango-app-api-payment-subscription 3.0.11-dev → 3.0.13-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 -0
- package/package.json +1 -1
- package/src/controllers/paymentSubscription.controllers.js +246 -139
- package/src/dtos/validation.dtos.js +26 -2
- package/src/hbs/trialInitiateEmail.hbs +322 -0
- package/src/routes/paymentSubscription.routes.js +3 -1
- package/src/services/store.service.js +4 -0
- package/src/utils/validations/client.validation.js +0 -1
- package/src/utils/validations/helper/handlebar.helper.js +14 -0
- package/script-new.js +0 -376
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { logger } from 'tango-app-api-middleware';
|
|
1
|
+
import { logger, download, sendEmailWithSES } from 'tango-app-api-middleware';
|
|
2
2
|
import * as paymentService from '../services/clientPayment.services.js';
|
|
3
3
|
import * as storeService from '../services/store.service.js';
|
|
4
4
|
import * as basePricingService from '../services/basePrice.service.js';
|
|
5
5
|
import * as clientRequestService from '../services/clientRequest.service.js';
|
|
6
6
|
import * as invoiceService from '../services/invoice.service.js';
|
|
7
7
|
import dayjs from 'dayjs';
|
|
8
|
+
import appConfig from '../../config/env/env.js';
|
|
9
|
+
import Handlebars from 'handlebars';
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
8
12
|
|
|
9
13
|
|
|
10
14
|
export const addBilling = async ( req, res ) => {
|
|
@@ -30,7 +34,6 @@ export const addBilling = async ( req, res ) => {
|
|
|
30
34
|
return res.sendError( 'Something Went Wrong', 500 );
|
|
31
35
|
}
|
|
32
36
|
} catch ( e ) {
|
|
33
|
-
console.log( e );
|
|
34
37
|
logger.error( { error: e, function: 'addBilling' } );
|
|
35
38
|
return res.sendError( e, 500 );
|
|
36
39
|
}
|
|
@@ -68,7 +71,7 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
|
|
|
68
71
|
return res.sendError( 'no data found', 204 );
|
|
69
72
|
}
|
|
70
73
|
let storeCount = await storeService.count( { clientId: clientInfo[0].clientId } );
|
|
71
|
-
let tangoProducts = [ 'tangoTraffic', 'tangoZone', '
|
|
74
|
+
let tangoProducts = [ 'tangoTraffic', 'tangoZone', 'tangoSop', 'prioritySupport' ];
|
|
72
75
|
let activeProducts = clientInfo[0].planDetails.product;
|
|
73
76
|
let liveProducts = [];
|
|
74
77
|
let trialProducts = [];
|
|
@@ -106,7 +109,7 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
|
|
|
106
109
|
case 'tangoZone':
|
|
107
110
|
element.aliseProductName = 'Tango Zone';
|
|
108
111
|
break;
|
|
109
|
-
case '
|
|
112
|
+
case 'tangoSop':
|
|
110
113
|
element.aliseProductName = 'Tango SOP';
|
|
111
114
|
break;
|
|
112
115
|
case 'prioritySupport':
|
|
@@ -191,7 +194,6 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
|
|
|
191
194
|
|
|
192
195
|
return res.sendSuccess( data );
|
|
193
196
|
} catch ( e ) {
|
|
194
|
-
console.log( e );
|
|
195
197
|
logger.error( { error: e, function: 'billingInfo' } );
|
|
196
198
|
return res.sendError( e, 500 );
|
|
197
199
|
}
|
|
@@ -231,7 +233,6 @@ export const pricingInfo = async ( req, res ) => {
|
|
|
231
233
|
input.products.forEach( async ( element, index ) => {
|
|
232
234
|
let getProduct = productList.find( ( item ) => item.productName == element );
|
|
233
235
|
let camaraPerSqft = getProduct.camaraPerStores.filter( ( data ) => data.sqft == input.camaraPerSqft );
|
|
234
|
-
console.log( camaraPerSqft, 'rest' );
|
|
235
236
|
let basicprice = Math.round( getProduct.basePrice * ( camaraPerSqft[0].camaraCount ) );
|
|
236
237
|
productDiscounts.push( getProduct.discoutPercentage );
|
|
237
238
|
let stage = 0;
|
|
@@ -263,31 +264,25 @@ export const pricingInfo = async ( req, res ) => {
|
|
|
263
264
|
let discountprice = Math.round( basicprice * Math.pow( 0.9, stage ) );
|
|
264
265
|
dummy.push( discountprice );
|
|
265
266
|
OriginalPrice = OriginalPrice + discountprice;
|
|
266
|
-
// console.log("====>", OriginalPrice);
|
|
267
267
|
finalPrice = finalPrice + discountprice;
|
|
268
268
|
camaraArray.push( Number( Math.ceil( camaraPerSqft[0].camaraCount ) ) );
|
|
269
|
+
let camaraCount = Math.max( ...camaraArray );
|
|
269
270
|
if ( dummy.length == input.products.length ) {
|
|
270
271
|
if ( input.products.length > 1 ) {
|
|
271
272
|
// for extra product to add maximum discount
|
|
272
273
|
let maxProductDiscounts = Math.max( ...productDiscounts );
|
|
273
274
|
let addtionalDiscount = ( finalPrice * maxProductDiscounts ) / 100;
|
|
274
|
-
console.log( 'addtional product discount', addtionalDiscount );
|
|
275
275
|
finalPrice = finalPrice - addtionalDiscount;
|
|
276
|
-
console.log( finalPrice, 'test' );
|
|
277
276
|
// OriginalPrice = OriginalPrice + addtionalDiscount
|
|
278
277
|
}
|
|
279
278
|
if ( input.planName == 'quarterly' ) {
|
|
280
279
|
let extraDiscount = ( finalPrice * 10 ) / 100;
|
|
281
|
-
console.log( 'halfyearly extraDiscount', extraDiscount );
|
|
282
280
|
finalPrice = finalPrice - extraDiscount;
|
|
283
|
-
console.log( finalPrice, 'rtyu' );
|
|
284
281
|
// OriginalPrice = OriginalPrice + extra_discount
|
|
285
282
|
}
|
|
286
283
|
if ( input.planName == 'annual' ) {
|
|
287
284
|
let extraDiscount = ( finalPrice * 20 ) / 100;
|
|
288
|
-
console.log( 'yearly extraDiscount', extraDiscount );
|
|
289
285
|
finalPrice = finalPrice - extraDiscount;
|
|
290
|
-
console.log( finalPrice, 'fgvbh' );
|
|
291
286
|
// OriginalPrice = OriginalPrice + extra_discount
|
|
292
287
|
}
|
|
293
288
|
finalPrice = Math.ceil( finalPrice / 10 ) * 10; // for round off to 10 position
|
|
@@ -297,11 +292,10 @@ export const pricingInfo = async ( req, res ) => {
|
|
|
297
292
|
dollerpriceOriginal = ( ( OriginalPrice * 50 ) / 100 );
|
|
298
293
|
OriginalPrice = ( dollerpriceOriginal + OriginalPrice ) / 84;
|
|
299
294
|
}
|
|
300
|
-
res.sendSuccess( { OriginalPrice: Math.round( OriginalPrice ), price: Math.round( finalPrice ) } );
|
|
295
|
+
res.sendSuccess( { OriginalPrice: Math.round( OriginalPrice ), price: Math.round( finalPrice ), camaraCount: camaraCount } );
|
|
301
296
|
}
|
|
302
297
|
} );
|
|
303
298
|
} catch ( e ) {
|
|
304
|
-
console.log( 'pricingInfo=>', e );
|
|
305
299
|
logger.error( { error: e, function: 'pricingInfo' } );
|
|
306
300
|
return res.sendError( e, 500 );
|
|
307
301
|
}
|
|
@@ -327,7 +321,7 @@ export const updateSubscriptionOLD = async ( req, res ) => {
|
|
|
327
321
|
}
|
|
328
322
|
if ( element.type == 'trial' ) {
|
|
329
323
|
let params = {
|
|
330
|
-
user:
|
|
324
|
+
user: req.user._id, // need to login user id here
|
|
331
325
|
clientId: req.body.clientId,
|
|
332
326
|
name: element.productName,
|
|
333
327
|
description: 'Request for Trial',
|
|
@@ -353,7 +347,6 @@ export const updateSubscriptionOLD = async ( req, res ) => {
|
|
|
353
347
|
return res.sendError( 'Something went wrong', 500 );
|
|
354
348
|
}
|
|
355
349
|
} catch ( e ) {
|
|
356
|
-
console.log( e );
|
|
357
350
|
logger.error( { error: e, function: 'updateSubscription' } );
|
|
358
351
|
return res.sendError( e, 500 );
|
|
359
352
|
}
|
|
@@ -362,70 +355,57 @@ export const updateSubscriptionOLD = async ( req, res ) => {
|
|
|
362
355
|
export const updateSubscription = async ( req, res ) => {
|
|
363
356
|
try {
|
|
364
357
|
let requestBody = req.body;
|
|
365
|
-
if ( !
|
|
366
|
-
return res.sendError( '
|
|
358
|
+
if ( !requestBody?.products?.length ) {
|
|
359
|
+
return res.sendError( 'product is required', 400 );
|
|
367
360
|
}
|
|
368
|
-
|
|
369
|
-
let
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
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 );
|
|
361
|
+
|
|
362
|
+
let clientProducts = requestBody.client.planDetails.product;
|
|
363
|
+
for ( let item of requestBody.products ) {
|
|
364
|
+
let existsIndex = clientProducts.findIndex( ( ele ) => ele.productName == item.name );
|
|
365
|
+
if ( item.type == 'startTrial' && existsIndex == -1 ) {
|
|
366
|
+
let params = {
|
|
367
|
+
user: req.user._id, // need to login user id here
|
|
368
|
+
clientId: requestBody.clientId,
|
|
369
|
+
name: item.name,
|
|
370
|
+
description: 'Request for Trial',
|
|
371
|
+
category: 'Trial',
|
|
372
|
+
status: 'pending',
|
|
373
|
+
};
|
|
374
|
+
await clientRequestService.insert( params );
|
|
375
|
+
}
|
|
376
|
+
if ( item.type == 'subscription' ) {
|
|
377
|
+
if ( existsIndex == -1 ) {
|
|
378
|
+
clientProducts.push( {
|
|
379
|
+
productName: item.name,
|
|
380
|
+
subscribedDate: new Date(),
|
|
381
|
+
status: 'live',
|
|
382
|
+
} );
|
|
383
|
+
} else {
|
|
384
|
+
clientProducts[existsIndex].status = 'live';
|
|
385
|
+
clientProducts[existsIndex].subscribedDate = new Date();
|
|
408
386
|
}
|
|
409
387
|
}
|
|
410
388
|
}
|
|
411
389
|
|
|
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
390
|
let details = {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
391
|
+
subscriptionType: requestBody.subscriptionType,
|
|
392
|
+
subscriptionPeriod: requestBody.subscriptionPeriod,
|
|
393
|
+
storeCount: requestBody.storeCount,
|
|
394
|
+
totalCamera: requestBody.totalCamera,
|
|
395
|
+
totalStores: requestBody.totalStores,
|
|
396
|
+
storeSize: requestBody.storeSize,
|
|
397
|
+
product: clientProducts,
|
|
424
398
|
};
|
|
425
399
|
|
|
426
|
-
let
|
|
427
|
-
|
|
428
|
-
|
|
400
|
+
let data = {
|
|
401
|
+
planDetails: details,
|
|
402
|
+
price: requestBody.price,
|
|
403
|
+
priceType: requestBody.priceType,
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
let result = await paymentService.updateOne( { clientId: req.params.clientId }, data );
|
|
407
|
+
let storeProduct = clientProducts.map( ( item ) => item.productName );
|
|
408
|
+
await storeService.updateMany( { clientId: req.params.clientId, status: 'active' }, { product: storeProduct } );
|
|
429
409
|
|
|
430
410
|
if ( result.modifiedCount ) {
|
|
431
411
|
return res.sendSuccess( { message: 'Subscription Updated Successfully' } );
|
|
@@ -433,7 +413,6 @@ export const updateSubscription = async ( req, res ) => {
|
|
|
433
413
|
return res.sendError( 'Something went wrong', 500 );
|
|
434
414
|
}
|
|
435
415
|
} catch ( e ) {
|
|
436
|
-
console.log( e );
|
|
437
416
|
logger.error( { error: e, function: 'updateSubscription' } );
|
|
438
417
|
return res.sendError( e, 500 );
|
|
439
418
|
}
|
|
@@ -477,7 +456,6 @@ export const trialProductList = async ( req, res ) => {
|
|
|
477
456
|
} );
|
|
478
457
|
return res.sendSuccess( products );
|
|
479
458
|
} catch ( e ) {
|
|
480
|
-
console.log( 'trialRequest =>', e );
|
|
481
459
|
logger.error( { error: e, function: 'trialRequest' } );
|
|
482
460
|
return res.sendError( e, 500 );
|
|
483
461
|
}
|
|
@@ -490,18 +468,17 @@ export const unsubscribeProduct = async ( req, res ) => {
|
|
|
490
468
|
return res.sendSuccess( 'Request is Already initiated waiting for admin approval' );
|
|
491
469
|
}
|
|
492
470
|
let params = {
|
|
493
|
-
user:
|
|
471
|
+
user: req.user._id, // need to login user id here
|
|
494
472
|
clientId: req.body.clientId,
|
|
495
473
|
reason: req.body.reason,
|
|
496
474
|
description: req.body.description,
|
|
497
|
-
category: '
|
|
475
|
+
category: 'unsubscribe',
|
|
498
476
|
status: 'pending',
|
|
499
477
|
};
|
|
500
478
|
await clientRequestService.insert( params );
|
|
501
479
|
|
|
502
480
|
return res.sendSuccess( 'Request Send Successfully' );
|
|
503
481
|
} catch ( e ) {
|
|
504
|
-
console.log( 'unsubscribeProduct =>', e );
|
|
505
482
|
logger.error( { error: e, function: 'unsubscribeProduct' } );
|
|
506
483
|
return res.sendError( e, 500 );
|
|
507
484
|
}
|
|
@@ -514,7 +491,7 @@ export const trialExtendRequest = async ( req, res ) => {
|
|
|
514
491
|
return res.sendSuccess( 'Request is Already initiated waiting for admin approval' );
|
|
515
492
|
}
|
|
516
493
|
let params = {
|
|
517
|
-
user:
|
|
494
|
+
user: req.user._id, // need to login user id here
|
|
518
495
|
clientId: req.body.clientId,
|
|
519
496
|
name: req.body.product,
|
|
520
497
|
description: 'Request for extend Trial',
|
|
@@ -525,7 +502,6 @@ export const trialExtendRequest = async ( req, res ) => {
|
|
|
525
502
|
|
|
526
503
|
return res.sendSuccess( 'Request Send Successfully' );
|
|
527
504
|
} catch ( e ) {
|
|
528
|
-
console.log( 'trialExtendRequest =>', e );
|
|
529
505
|
logger.error( { error: e, function: 'trialExtendRequest' } );
|
|
530
506
|
return res.sendError( e, 500 );
|
|
531
507
|
}
|
|
@@ -539,7 +515,7 @@ export const trialRequest = async ( req, res ) => {
|
|
|
539
515
|
return res.sendSuccess( 'Request is Already initiated waiting for admin approval' );
|
|
540
516
|
}
|
|
541
517
|
let params = {
|
|
542
|
-
user:
|
|
518
|
+
user: req.user._id, // need to login user id here
|
|
543
519
|
clientId: req.body.clientId,
|
|
544
520
|
name: req.body.product,
|
|
545
521
|
description: 'Request for Trial',
|
|
@@ -550,7 +526,6 @@ export const trialRequest = async ( req, res ) => {
|
|
|
550
526
|
|
|
551
527
|
return res.sendSuccess( 'Request Send Successfully' );
|
|
552
528
|
} catch ( e ) {
|
|
553
|
-
console.log( 'trialExtendRequest =>', e );
|
|
554
529
|
logger.error( { error: e, function: 'trialExtendRequest' } );
|
|
555
530
|
return res.sendError( e, 500 );
|
|
556
531
|
}
|
|
@@ -574,7 +549,6 @@ export const invoiceDetails = async ( req, res ) => {
|
|
|
574
549
|
};
|
|
575
550
|
return res.sendSuccess( data );
|
|
576
551
|
} catch ( e ) {
|
|
577
|
-
console.log( 'invoiceDetails =>', e );
|
|
578
552
|
logger.error( { error: e, function: 'invoiceDetails' } );
|
|
579
553
|
return res.sendError( e, 500 );
|
|
580
554
|
}
|
|
@@ -602,7 +576,6 @@ export const updateInvoiceDetails = async ( req, res ) => {
|
|
|
602
576
|
return res.sendError( e );
|
|
603
577
|
} );
|
|
604
578
|
} catch ( e ) {
|
|
605
|
-
console.log( 'invoiceDetails =>', e );
|
|
606
579
|
logger.error( { error: e, function: 'invoiceDetails' } );
|
|
607
580
|
return res.sendError( e, 500 );
|
|
608
581
|
}
|
|
@@ -614,15 +587,68 @@ export const notificationList = async ( req, res ) => {
|
|
|
614
587
|
let query = {};
|
|
615
588
|
query.status = 'pending';
|
|
616
589
|
if ( req?.query?.clientId ) {
|
|
617
|
-
query.
|
|
590
|
+
query.clientId = req?.query?.clientId;
|
|
618
591
|
}
|
|
619
592
|
let notificationList = await clientRequestService.find( query, { createdAt: 0, updatedAt: 0 } );
|
|
593
|
+
query = [
|
|
594
|
+
{
|
|
595
|
+
$match: {
|
|
596
|
+
clientId: req.query.clientId,
|
|
597
|
+
status: 'active',
|
|
598
|
+
},
|
|
599
|
+
},
|
|
600
|
+
{ $unwind: '$planDetails.product' },
|
|
601
|
+
{
|
|
602
|
+
$match: {
|
|
603
|
+
'planDetails.product.status': 'trial',
|
|
604
|
+
},
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
$project: {
|
|
608
|
+
_id: 0,
|
|
609
|
+
product: '$planDetails.product',
|
|
610
|
+
currentPlan: '$planDetails.subscriptionType',
|
|
611
|
+
},
|
|
612
|
+
},
|
|
613
|
+
];
|
|
614
|
+
let getClientInfo = await paymentService.aggregate( query );
|
|
615
|
+
if ( getClientInfo.length ) {
|
|
616
|
+
getClientInfo.forEach( ( item ) => {
|
|
617
|
+
let [ firstWord, secondWord ] = item.product.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
618
|
+
firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
619
|
+
let startDate = dayjs( item.product.trialStartDate );
|
|
620
|
+
let endDate = dayjs( item.product.trialEndDate ).startOf( 'day' );
|
|
621
|
+
let date = dayjs().startOf( 'day' );
|
|
622
|
+
let days = date.diff( startDate, 'day' );
|
|
623
|
+
let totalDays = endDate.diff( startDate, 'day' );
|
|
624
|
+
let percentage = Math.round( ( days / totalDays )* 100 );
|
|
625
|
+
notificationList.push( {
|
|
626
|
+
product: item.product.productName,
|
|
627
|
+
name: `${firstWord} ${secondWord}`,
|
|
628
|
+
day: endDate.diff( date, 'day' ) + 1,
|
|
629
|
+
percentage: percentage,
|
|
630
|
+
category: 'trial product',
|
|
631
|
+
} );
|
|
632
|
+
} );
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
notificationList.forEach( ( item ) => {
|
|
636
|
+
if ( !item?.product && item.category == 'Trial' ) {
|
|
637
|
+
let [ firstWord, secondWord ] = item.name.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
638
|
+
firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
639
|
+
item.name = `${firstWord} ${secondWord}`;
|
|
640
|
+
}
|
|
641
|
+
} );
|
|
642
|
+
|
|
643
|
+
let data = {
|
|
644
|
+
notificationList,
|
|
645
|
+
currentPlan: getClientInfo[0]?.currentPlan || 'free',
|
|
646
|
+
};
|
|
620
647
|
if ( !notificationList.length ) {
|
|
621
648
|
return res.sendError( 'no data found', 204 );
|
|
622
649
|
}
|
|
623
|
-
return res.sendSuccess(
|
|
650
|
+
return res.sendSuccess( data );
|
|
624
651
|
} catch ( e ) {
|
|
625
|
-
console.log( 'approvalList =>', e );
|
|
626
652
|
logger.error( { error: e, function: 'approvalList' } );
|
|
627
653
|
return res.sendError( e, 500 );
|
|
628
654
|
}
|
|
@@ -635,7 +661,7 @@ export const trialApproval = async ( req, res ) => {
|
|
|
635
661
|
if ( !requestData ) {
|
|
636
662
|
return res.sendError( 'no data found', 204 );
|
|
637
663
|
}
|
|
638
|
-
requestData.status = '
|
|
664
|
+
requestData.status = 'completed';
|
|
639
665
|
requestData.save().then( async () => {
|
|
640
666
|
if ( req.body.type == 'approve' ) {
|
|
641
667
|
let clientProducts = await paymentService.findOne( { clientId: requestData.clientId, status: 'active' }, { planDetails: 1 } );
|
|
@@ -644,7 +670,6 @@ export const trialApproval = async ( req, res ) => {
|
|
|
644
670
|
}
|
|
645
671
|
let productIndex = clientProducts.planDetails.product.findIndex( ( item ) => item.productName == requestData.name );
|
|
646
672
|
if ( productIndex != -1 ) {
|
|
647
|
-
clientProducts.planDetails.product[productIndex].status =
|
|
648
673
|
clientProducts.planDetails.product[productIndex].status = 'trial';
|
|
649
674
|
clientProducts.planDetails.product[productIndex].trialStartDate = new Date();
|
|
650
675
|
clientProducts.planDetails.product[productIndex].trialEndDate = new Date( dayjs().add( 13, 'days' ).format( 'YYYY-MM-DD' ) );
|
|
@@ -658,11 +683,21 @@ export const trialApproval = async ( req, res ) => {
|
|
|
658
683
|
}
|
|
659
684
|
clientProducts.save();
|
|
660
685
|
await storeService.addremoveElement( { clientId: requestData.clientId, status: 'active' }, { $push: { product: requestData.name } } );
|
|
686
|
+
const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialInitiateEmail.hbs', 'utf8' );
|
|
687
|
+
const template = Handlebars.compile( templateHtml );
|
|
688
|
+
const html = template( { data: '' } );
|
|
689
|
+
let params = {
|
|
690
|
+
toEmail: 'sudha@tangotech.co.in',
|
|
691
|
+
mailSubject: 'test',
|
|
692
|
+
htmlBody: html,
|
|
693
|
+
attachment: '',
|
|
694
|
+
sourceEmail: appConfig.cloud.aws.ses.from,
|
|
695
|
+
};
|
|
696
|
+
sendEmailWithSES( params.toEmail, params.mailSubject, params.htmlBody, params.attachment, params.sourceEmail );
|
|
661
697
|
}
|
|
662
698
|
return res.sendSuccess( 'updated Successfully' );
|
|
663
699
|
} );
|
|
664
700
|
} catch ( e ) {
|
|
665
|
-
console.log( 'approvalList =>', e );
|
|
666
701
|
logger.error( { error: e, function: 'approvalList' } );
|
|
667
702
|
return res.sendError( e, 500 );
|
|
668
703
|
}
|
|
@@ -683,7 +718,7 @@ export const trialExtendRequestApproval = async ( req, res ) => {
|
|
|
683
718
|
clientDetails.save().then( async () => {
|
|
684
719
|
let requestData = await clientRequestService.findOne( { clientId: req.body.clientId, status: 'pending', name: req.body.product, category: 'TrialExtend' } );
|
|
685
720
|
if ( requestData ) {
|
|
686
|
-
requestData.status = '
|
|
721
|
+
requestData.status = 'completed';
|
|
687
722
|
requestData.save();
|
|
688
723
|
}
|
|
689
724
|
return res.sendSuccess( 'Trial Extended Successfully' );
|
|
@@ -691,7 +726,6 @@ export const trialExtendRequestApproval = async ( req, res ) => {
|
|
|
691
726
|
return res.sendError( e, 500 );
|
|
692
727
|
} );
|
|
693
728
|
} catch ( e ) {
|
|
694
|
-
console.log( 'trialExtendRequestApproval =>', e );
|
|
695
729
|
logger.error( { error: e, function: 'trialExtendRequestApproval' } );
|
|
696
730
|
return res.sendError( e, 500 );
|
|
697
731
|
}
|
|
@@ -712,7 +746,6 @@ export const productSubscribe = async ( req, res ) => {
|
|
|
712
746
|
} );
|
|
713
747
|
}
|
|
714
748
|
} );
|
|
715
|
-
console.log( req.body.product, 'product' );
|
|
716
749
|
let clientInfo = await paymentService.findOne( { clientId: req.body.clientId, status: 'active' }, { clientId: 1, planDetails: 1 } );
|
|
717
750
|
if ( !clientInfo ) {
|
|
718
751
|
return res.sendError( 'no data found', 204 );
|
|
@@ -724,7 +757,6 @@ export const productSubscribe = async ( req, res ) => {
|
|
|
724
757
|
if ( productList.includes( item.name ) && item.type =='unsubscribe' ) {
|
|
725
758
|
// let findIndex = product.findIndex( ( product ) => product.productName );
|
|
726
759
|
// product.splice( findIndex, 1 );
|
|
727
|
-
// console.log( clientInfo.clientId );
|
|
728
760
|
await storeService.addremoveElement( { clientId: clientInfo.clientId, status: 'active', product: { $in: item.name } }, { $pull: { product: item.name } } );
|
|
729
761
|
}
|
|
730
762
|
if ( !productList.includes( item.name ) && [ 'trial', 'subscription' ].includes( item.type ) ) {
|
|
@@ -743,16 +775,22 @@ export const productSubscribe = async ( req, res ) => {
|
|
|
743
775
|
} );
|
|
744
776
|
}
|
|
745
777
|
await storeService.addremoveElement( { clientId: clientInfo.clientId, status: 'active' }, { $push: { product: item.name } } );
|
|
778
|
+
} else {
|
|
779
|
+
let productIndex = product.findIndex( ( ele ) => ele.productName == item.name );
|
|
780
|
+
if ( productIndex != -1 ) {
|
|
781
|
+
if ( item.type == 'subscription' ) {
|
|
782
|
+
product[productIndex].subscribedDate = new Date();
|
|
783
|
+
product[productIndex].status = 'live';
|
|
784
|
+
}
|
|
785
|
+
}
|
|
746
786
|
}
|
|
747
787
|
}
|
|
748
788
|
product = product.filter( ( item ) => !removeProducts.includes( item.productName ) );
|
|
749
|
-
console.log( product, 'product' );
|
|
750
789
|
clientInfo.planDetails.product = product;
|
|
751
790
|
clientInfo.save().then( async () => {
|
|
752
791
|
} );
|
|
753
792
|
return res.sendSuccess( 'Product Subscribed Successfully' );
|
|
754
793
|
} catch ( e ) {
|
|
755
|
-
console.log( 'updateProductSubscribe =>', e );
|
|
756
794
|
logger.error( { error: e, function: 'updateProductSubscribe' } );
|
|
757
795
|
return res.sendError( e, 500 );
|
|
758
796
|
}
|
|
@@ -764,7 +802,7 @@ export const unsubscribeApproval = async ( req, res ) => {
|
|
|
764
802
|
if ( !requestData ) {
|
|
765
803
|
return res.sendError( 'no data found', 204 );
|
|
766
804
|
}
|
|
767
|
-
requestData.status = '
|
|
805
|
+
requestData.status = 'completed';
|
|
768
806
|
requestData.save().then( async () => {
|
|
769
807
|
if ( req.body.type == 'unsubscribe' ) {
|
|
770
808
|
let clientProducts = await paymentService.findOne( { clientId: requestData.clientId, status: 'active' }, { status: 1 } );
|
|
@@ -773,12 +811,11 @@ export const unsubscribeApproval = async ( req, res ) => {
|
|
|
773
811
|
}
|
|
774
812
|
clientProducts.status = 'deactive';
|
|
775
813
|
clientProducts.save();
|
|
776
|
-
await storeService.updateMany( { clientId:
|
|
814
|
+
await storeService.updateMany( { clientId: requestData.clientId }, { status: 'deactive' } );
|
|
777
815
|
}
|
|
778
816
|
return res.sendSuccess( 'updated Successfully' );
|
|
779
817
|
} );
|
|
780
818
|
} catch ( e ) {
|
|
781
|
-
console.log( 'subscribeApproval =>', e );
|
|
782
819
|
logger.error( { error: e, function: 'subscribeApproval' } );
|
|
783
820
|
return res.sendError( e, 500 );
|
|
784
821
|
}
|
|
@@ -814,9 +851,7 @@ export const productViewList = async ( req, res ) => {
|
|
|
814
851
|
if ( !clientProduct ) {
|
|
815
852
|
return res.sendError( 'no data found', 204 );
|
|
816
853
|
}
|
|
817
|
-
console.log( clientProduct.planDetails.product );
|
|
818
854
|
let productPrice = await basePricingService.findOne( { clientId: { $exists: false } }, { basePricing: 1 } );
|
|
819
|
-
console.log( storeProductCount, 'price' );
|
|
820
855
|
let products = [];
|
|
821
856
|
clientProduct.planDetails.product.forEach( ( item ) => {
|
|
822
857
|
let price;
|
|
@@ -846,7 +881,6 @@ export const productViewList = async ( req, res ) => {
|
|
|
846
881
|
// } );
|
|
847
882
|
return res.sendSuccess( products );
|
|
848
883
|
} catch ( e ) {
|
|
849
|
-
console.log( 'productViewList =>', e );
|
|
850
884
|
logger.error( { error: e, function: 'productViewList' } );
|
|
851
885
|
return res.sendError( e, 500 );
|
|
852
886
|
}
|
|
@@ -855,7 +889,7 @@ export const productViewList = async ( req, res ) => {
|
|
|
855
889
|
export const storeViewList = async ( req, res ) => {
|
|
856
890
|
try {
|
|
857
891
|
let limit = req.body?.limit || 10;
|
|
858
|
-
let offset = req.body.offset || 0;
|
|
892
|
+
let offset = ( req.body.offset - 1 ) || 0;
|
|
859
893
|
let skip = offset * limit;
|
|
860
894
|
let query = [
|
|
861
895
|
{
|
|
@@ -893,7 +927,7 @@ export const storeViewList = async ( req, res ) => {
|
|
|
893
927
|
query.push(
|
|
894
928
|
{
|
|
895
929
|
$match: {
|
|
896
|
-
|
|
930
|
+
storeId: { $in: req.body?.store },
|
|
897
931
|
},
|
|
898
932
|
},
|
|
899
933
|
);
|
|
@@ -925,10 +959,8 @@ export const storeViewList = async ( req, res ) => {
|
|
|
925
959
|
},
|
|
926
960
|
);
|
|
927
961
|
|
|
928
|
-
console.log( JSON.stringify( query ), 'query' );
|
|
929
962
|
|
|
930
963
|
let storeDetails = await storeService.aggregate( query );
|
|
931
|
-
console.log( storeDetails );
|
|
932
964
|
|
|
933
965
|
if ( !storeDetails[0].data.length ) {
|
|
934
966
|
return res.sendError( 'no data found', 204 );
|
|
@@ -940,7 +972,6 @@ export const storeViewList = async ( req, res ) => {
|
|
|
940
972
|
|
|
941
973
|
return res.sendSuccess( data );
|
|
942
974
|
} catch ( e ) {
|
|
943
|
-
console.log( 'storeViewList =>', e );
|
|
944
975
|
logger.error( { error: e, function: 'storeViewList' } );
|
|
945
976
|
return res.sendError( e, 500 );
|
|
946
977
|
}
|
|
@@ -957,11 +988,9 @@ export const storeLocationList = async ( req, res ) => {
|
|
|
957
988
|
} );
|
|
958
989
|
let location = storeDetails.filter( ( item ) => item.storeProfile.city != '' && item.storeProfile.city != null && typeof ( item.storeProfile.city ) != undefined ).map( ( item ) => item.storeProfile.city );
|
|
959
990
|
let productDetails = await basePricingService.findOne( { clientId: { $exists: false } }, { 'basePricing': 1, '_id': 0 } );
|
|
960
|
-
console.log( productDetails );
|
|
961
991
|
let product = productDetails.basePricing.map( ( item ) => item.productName );
|
|
962
992
|
return res.sendSuccess( { store, location, product } );
|
|
963
993
|
} catch ( e ) {
|
|
964
|
-
console.log( 'storeLocationList =>', e );
|
|
965
994
|
logger.error( { error: e, function: 'storeLocationList' } );
|
|
966
995
|
return res.sendError( e, 500 );
|
|
967
996
|
}
|
|
@@ -970,44 +999,98 @@ export const storeLocationList = async ( req, res ) => {
|
|
|
970
999
|
|
|
971
1000
|
export const addStoreProduct = async ( req, res ) => {
|
|
972
1001
|
try {
|
|
973
|
-
let storeDetails = await storeService.find( {
|
|
1002
|
+
let storeDetails = await storeService.find( { storeId: { $in: req.body.store }, clientId: req.body.clientId } );
|
|
1003
|
+
|
|
974
1004
|
if ( !storeDetails.length ) {
|
|
975
1005
|
return res.sendError( 'no data found', 204 );
|
|
976
1006
|
}
|
|
1007
|
+
let data = req.body.product;
|
|
1008
|
+
req.body.product = [];
|
|
1009
|
+
data.forEach( ( item ) => {
|
|
1010
|
+
if ( item.type != 'cancel' ) {
|
|
1011
|
+
let arr = item.name.split( ',' );
|
|
1012
|
+
arr.forEach( ( product ) => {
|
|
1013
|
+
req.body.product.push( {
|
|
1014
|
+
name: product,
|
|
1015
|
+
type: item.type,
|
|
1016
|
+
} );
|
|
1017
|
+
} );
|
|
1018
|
+
}
|
|
1019
|
+
} );
|
|
977
1020
|
let clientInfo = await paymentService.findOne( { clientId: req.body.clientId, status: 'active' }, { 'planDetails.product': 1 } );
|
|
978
1021
|
let productList = clientInfo.planDetails.product.map( ( product ) => product.productName );
|
|
979
1022
|
let clientProduct = [];
|
|
980
1023
|
let storeProduct = [];
|
|
1024
|
+
let removedProduct = [];
|
|
981
1025
|
clientProduct = clientInfo.planDetails.product;
|
|
982
1026
|
req.body.product.forEach( ( item ) => {
|
|
983
1027
|
if ( item.type != 'unsubscribe' ) {
|
|
984
1028
|
storeProduct.push( item.name );
|
|
985
1029
|
}
|
|
986
|
-
if (
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1030
|
+
if ( item.type == 'unsubscribe' ) {
|
|
1031
|
+
removedProduct.push( item.name );
|
|
1032
|
+
}
|
|
1033
|
+
if ( !productList.includes( item.name ) ) {
|
|
1034
|
+
let productExistsIndex = clientProduct.findIndex( ( product ) => {
|
|
1035
|
+
item.name == product.productName;
|
|
1036
|
+
} );
|
|
1037
|
+
if ( productExistsIndex != -1 ) {
|
|
1038
|
+
if ( item.type == 'trial' ) {
|
|
1039
|
+
clientProduct[productExistsIndex] = {
|
|
1040
|
+
productName: item.name,
|
|
1041
|
+
trialStartDate: new Date(),
|
|
1042
|
+
trialEndDate: new Date( dayjs().add( 13, 'days' ).format( 'YYYY-MM-DD' ) ),
|
|
1043
|
+
status: 'trial',
|
|
1044
|
+
};
|
|
1045
|
+
} else {
|
|
1046
|
+
clientProduct[productExistsIndex] = {
|
|
1047
|
+
productName: item.name,
|
|
1048
|
+
subscribedDate: new Date(),
|
|
1049
|
+
status: 'live',
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
1052
|
+
} else {
|
|
1053
|
+
if ( item.type == 'trial' ) {
|
|
1054
|
+
clientProduct.push( {
|
|
1055
|
+
productName: item.name,
|
|
1056
|
+
trialStartDate: new Date(),
|
|
1057
|
+
trialEndDate: new Date( dayjs().add( 13, 'days' ).format( 'YYYY-MM-DD' ) ),
|
|
1058
|
+
status: 'trial',
|
|
1059
|
+
} );
|
|
1060
|
+
}
|
|
1061
|
+
if ( item.type == 'subscription' ) {
|
|
1062
|
+
clientProduct.push( {
|
|
1063
|
+
productName: item.name,
|
|
1064
|
+
subscribedDate: new Date(),
|
|
1065
|
+
status: 'live',
|
|
1066
|
+
} );
|
|
1067
|
+
}
|
|
1001
1068
|
}
|
|
1002
1069
|
}
|
|
1003
1070
|
},
|
|
1004
1071
|
);
|
|
1005
1072
|
clientInfo.planDetails.product = clientProduct;
|
|
1006
1073
|
clientInfo.save();
|
|
1007
|
-
|
|
1074
|
+
storeDetails.forEach( async ( item ) => {
|
|
1075
|
+
let product;
|
|
1076
|
+
if ( item?.product?.length ) {
|
|
1077
|
+
product = item.product.concat( storeProduct );
|
|
1078
|
+
} else {
|
|
1079
|
+
product = storeProduct;
|
|
1080
|
+
}
|
|
1081
|
+
product = Array.from( new Set( product ) );
|
|
1082
|
+
if ( removedProduct.length ) {
|
|
1083
|
+
removedProduct.forEach( ( element ) => {
|
|
1084
|
+
let productIndex = product.findIndex( ( ele ) => ele == element );
|
|
1085
|
+
if ( productIndex != -1 ) {
|
|
1086
|
+
product.splice( productIndex, 1 );
|
|
1087
|
+
}
|
|
1088
|
+
} );
|
|
1089
|
+
}
|
|
1090
|
+
await storeService.updateOne( { storeId: item.storeId, clientId: req.body.clientId }, { product: product } );
|
|
1091
|
+
} );
|
|
1008
1092
|
return res.sendSuccess( 'product updated Successfully' );
|
|
1009
1093
|
} catch ( e ) {
|
|
1010
|
-
console.log( 'addStoreProduct => ', e );
|
|
1011
1094
|
logger.error( { error: e, function: 'addStoreProduct' } );
|
|
1012
1095
|
return res.sendError( e, 500 );
|
|
1013
1096
|
}
|
|
@@ -1016,8 +1099,11 @@ export const addStoreProduct = async ( req, res ) => {
|
|
|
1016
1099
|
|
|
1017
1100
|
export const invoiceList = async ( req, res ) => {
|
|
1018
1101
|
try {
|
|
1102
|
+
if ( req.body.export ) {
|
|
1103
|
+
req.body.limit = 10000;
|
|
1104
|
+
}
|
|
1019
1105
|
let limit = req.body.limit || 10;
|
|
1020
|
-
let offset = req.body.offset || 0;
|
|
1106
|
+
let offset = ( req.body.offset-1 ) || 0;
|
|
1021
1107
|
let skip = limit * offset;
|
|
1022
1108
|
let date;
|
|
1023
1109
|
let endDate;
|
|
@@ -1034,8 +1120,6 @@ export const invoiceList = async ( req, res ) => {
|
|
|
1034
1120
|
endDate= new Date( dayjs().endOf( 'month' ).format( 'YYYY-MM-DD' ) );
|
|
1035
1121
|
}
|
|
1036
1122
|
let query = [];
|
|
1037
|
-
console.log( date );
|
|
1038
|
-
console.log( endDate );
|
|
1039
1123
|
query = [
|
|
1040
1124
|
{
|
|
1041
1125
|
$match: {
|
|
@@ -1061,8 +1145,8 @@ export const invoiceList = async ( req, res ) => {
|
|
|
1061
1145
|
{
|
|
1062
1146
|
$facet: {
|
|
1063
1147
|
data: [
|
|
1064
|
-
{ $limit: limit },
|
|
1065
1148
|
{ $skip: skip },
|
|
1149
|
+
{ $limit: limit },
|
|
1066
1150
|
],
|
|
1067
1151
|
count: [
|
|
1068
1152
|
{ $count: 'count' },
|
|
@@ -1080,10 +1164,12 @@ export const invoiceList = async ( req, res ) => {
|
|
|
1080
1164
|
data: invoiceDetails[0].data,
|
|
1081
1165
|
count: invoiceDetails[0].count[0].count,
|
|
1082
1166
|
};
|
|
1083
|
-
|
|
1167
|
+
if ( !req.body.export ) {
|
|
1168
|
+
return res.sendSuccess( data );
|
|
1169
|
+
} else {
|
|
1170
|
+
download( invoiceDetails[0].data, res );
|
|
1171
|
+
}
|
|
1084
1172
|
} catch ( e ) {
|
|
1085
|
-
console.log( e );
|
|
1086
|
-
console.log( 'invoiceList =>', e );
|
|
1087
1173
|
logger.error( { error: e, function: 'invoiceList' } );
|
|
1088
1174
|
return res.sendError( e, 500 );
|
|
1089
1175
|
}
|
|
@@ -1186,7 +1272,6 @@ export const priceList = async ( req, res ) => {
|
|
|
1186
1272
|
};
|
|
1187
1273
|
return res.sendSuccess( result );
|
|
1188
1274
|
} catch ( e ) {
|
|
1189
|
-
console.log( e );
|
|
1190
1275
|
logger.error( { error: e, function: 'priceList' } );
|
|
1191
1276
|
return res.sendError( e, 500 );
|
|
1192
1277
|
}
|
|
@@ -1207,7 +1292,6 @@ export const pricingListUpdate = async ( req, res ) => {
|
|
|
1207
1292
|
delete item.lastIndex;
|
|
1208
1293
|
}
|
|
1209
1294
|
} );
|
|
1210
|
-
console.log( req.body.products, 'products' );
|
|
1211
1295
|
let getPriceInfo = await basePricingService.findOne( { clientId: { $exists: true }, clientId: req.body.clientId }, { standard: 1, step: 1 } );
|
|
1212
1296
|
let data = {
|
|
1213
1297
|
...( req.body.type == 'standard' ) ? { standard: req.body.products } : { step: req.body.products },
|
|
@@ -1226,7 +1310,6 @@ export const pricingListUpdate = async ( req, res ) => {
|
|
|
1226
1310
|
return res.sendSuccess( 'Pricig Updated Successfully' );
|
|
1227
1311
|
} );
|
|
1228
1312
|
} catch ( e ) {
|
|
1229
|
-
console.log( e );
|
|
1230
1313
|
logger.error( { error: e, function: 'addPricingList' } );
|
|
1231
1314
|
return res.sendError( e, 500 );
|
|
1232
1315
|
}
|
|
@@ -1245,7 +1328,6 @@ export const updatedRevisedPrice = async ( req, res ) => {
|
|
|
1245
1328
|
return res.sendSuccess( 'Credit notes Updated Successfully' );
|
|
1246
1329
|
} );
|
|
1247
1330
|
} catch ( e ) {
|
|
1248
|
-
console.log( 'updatedRevisedPrice =>', e );
|
|
1249
1331
|
logger.error( { error: e, function: 'updatedRevisedPrice' } );
|
|
1250
1332
|
return res.sendError( e, 500 );
|
|
1251
1333
|
}
|
|
@@ -1259,8 +1341,33 @@ export const unpaidInvoiceList = async ( req, res ) => {
|
|
|
1259
1341
|
}
|
|
1260
1342
|
return res.sendSuccess( invoiceDetails );
|
|
1261
1343
|
} catch ( e ) {
|
|
1262
|
-
console.log( 'unpaidInvoiceList =>', e );
|
|
1263
1344
|
logger.error( { error: e, function: 'unpaidInvoiceList' } );
|
|
1264
1345
|
return res.sendError( e, 500 );
|
|
1265
1346
|
}
|
|
1266
1347
|
};
|
|
1348
|
+
|
|
1349
|
+
|
|
1350
|
+
export const getStoreProducts = async ( req, res ) => {
|
|
1351
|
+
try {
|
|
1352
|
+
let storeProductDetails;
|
|
1353
|
+
if ( !req.body.store.length ) {
|
|
1354
|
+
storeProductDetails = await storeService.find( { clientId: req.body.clientId, status: 'active' } );
|
|
1355
|
+
} else {
|
|
1356
|
+
storeProductDetails = await storeService.find( { storeId: { $in: req.body.store }, clientId: req.body.clientId, status: 'active' } );
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
let product = new Set();
|
|
1360
|
+
storeProductDetails.forEach( ( item ) => {
|
|
1361
|
+
item.product.forEach( ( p ) => product.add( p ) );
|
|
1362
|
+
} );
|
|
1363
|
+
product = Array.from( product );
|
|
1364
|
+
if ( !product.length ) {
|
|
1365
|
+
return res.sendError( 'no data found', 204 );
|
|
1366
|
+
}
|
|
1367
|
+
return res.sendSuccess( product );
|
|
1368
|
+
} catch ( e ) {
|
|
1369
|
+
logger.error( { error: e, function: 'getStoreProducts' } );
|
|
1370
|
+
return res.sendError( e, 500 );
|
|
1371
|
+
}
|
|
1372
|
+
};
|
|
1373
|
+
|