tango-app-api-payment-subscription 3.0.11-dev → 3.0.12-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 CHANGED
@@ -36,6 +36,7 @@ module.exports = {
36
36
  'no-unused-vars': 'error',
37
37
  'new-cap': [ 'error', { 'newIsCap': true, 'capIsNew': false } ],
38
38
  'prefer-const': 'off',
39
+ 'no-console': 'error',
39
40
  },
40
41
  };
41
42
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-payment-subscription",
3
- "version": "3.0.11-dev",
3
+ "version": "3.0.12-dev",
4
4
  "description": "paymentSubscription",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -1,4 +1,4 @@
1
- import { logger } from 'tango-app-api-middleware';
1
+ import { logger, download } 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';
@@ -30,7 +30,6 @@ export const addBilling = async ( req, res ) => {
30
30
  return res.sendError( 'Something Went Wrong', 500 );
31
31
  }
32
32
  } catch ( e ) {
33
- console.log( e );
34
33
  logger.error( { error: e, function: 'addBilling' } );
35
34
  return res.sendError( e, 500 );
36
35
  }
@@ -68,7 +67,7 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
68
67
  return res.sendError( 'no data found', 204 );
69
68
  }
70
69
  let storeCount = await storeService.count( { clientId: clientInfo[0].clientId } );
71
- let tangoProducts = [ 'tangoTraffic', 'tangoZone', 'tangoSOP', 'prioritySupport' ];
70
+ let tangoProducts = [ 'tangoTraffic', 'tangoZone', 'tangoSop', 'prioritySupport' ];
72
71
  let activeProducts = clientInfo[0].planDetails.product;
73
72
  let liveProducts = [];
74
73
  let trialProducts = [];
@@ -106,7 +105,7 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
106
105
  case 'tangoZone':
107
106
  element.aliseProductName = 'Tango Zone';
108
107
  break;
109
- case 'tangoSOP':
108
+ case 'tangoSop':
110
109
  element.aliseProductName = 'Tango SOP';
111
110
  break;
112
111
  case 'prioritySupport':
@@ -191,7 +190,6 @@ export const clientBillingSubscriptionInfo = async ( req, res, next ) => {
191
190
 
192
191
  return res.sendSuccess( data );
193
192
  } catch ( e ) {
194
- console.log( e );
195
193
  logger.error( { error: e, function: 'billingInfo' } );
196
194
  return res.sendError( e, 500 );
197
195
  }
@@ -231,7 +229,6 @@ export const pricingInfo = async ( req, res ) => {
231
229
  input.products.forEach( async ( element, index ) => {
232
230
  let getProduct = productList.find( ( item ) => item.productName == element );
233
231
  let camaraPerSqft = getProduct.camaraPerStores.filter( ( data ) => data.sqft == input.camaraPerSqft );
234
- console.log( camaraPerSqft, 'rest' );
235
232
  let basicprice = Math.round( getProduct.basePrice * ( camaraPerSqft[0].camaraCount ) );
236
233
  productDiscounts.push( getProduct.discoutPercentage );
237
234
  let stage = 0;
@@ -263,31 +260,25 @@ export const pricingInfo = async ( req, res ) => {
263
260
  let discountprice = Math.round( basicprice * Math.pow( 0.9, stage ) );
264
261
  dummy.push( discountprice );
265
262
  OriginalPrice = OriginalPrice + discountprice;
266
- // console.log("====>", OriginalPrice);
267
263
  finalPrice = finalPrice + discountprice;
268
264
  camaraArray.push( Number( Math.ceil( camaraPerSqft[0].camaraCount ) ) );
265
+ let camaraCount = Math.max( ...camaraArray );
269
266
  if ( dummy.length == input.products.length ) {
270
267
  if ( input.products.length > 1 ) {
271
268
  // for extra product to add maximum discount
272
269
  let maxProductDiscounts = Math.max( ...productDiscounts );
273
270
  let addtionalDiscount = ( finalPrice * maxProductDiscounts ) / 100;
274
- console.log( 'addtional product discount', addtionalDiscount );
275
271
  finalPrice = finalPrice - addtionalDiscount;
276
- console.log( finalPrice, 'test' );
277
272
  // OriginalPrice = OriginalPrice + addtionalDiscount
278
273
  }
279
274
  if ( input.planName == 'quarterly' ) {
280
275
  let extraDiscount = ( finalPrice * 10 ) / 100;
281
- console.log( 'halfyearly extraDiscount', extraDiscount );
282
276
  finalPrice = finalPrice - extraDiscount;
283
- console.log( finalPrice, 'rtyu' );
284
277
  // OriginalPrice = OriginalPrice + extra_discount
285
278
  }
286
279
  if ( input.planName == 'annual' ) {
287
280
  let extraDiscount = ( finalPrice * 20 ) / 100;
288
- console.log( 'yearly extraDiscount', extraDiscount );
289
281
  finalPrice = finalPrice - extraDiscount;
290
- console.log( finalPrice, 'fgvbh' );
291
282
  // OriginalPrice = OriginalPrice + extra_discount
292
283
  }
293
284
  finalPrice = Math.ceil( finalPrice / 10 ) * 10; // for round off to 10 position
@@ -297,11 +288,10 @@ export const pricingInfo = async ( req, res ) => {
297
288
  dollerpriceOriginal = ( ( OriginalPrice * 50 ) / 100 );
298
289
  OriginalPrice = ( dollerpriceOriginal + OriginalPrice ) / 84;
299
290
  }
300
- res.sendSuccess( { OriginalPrice: Math.round( OriginalPrice ), price: Math.round( finalPrice ) } );
291
+ res.sendSuccess( { OriginalPrice: Math.round( OriginalPrice ), price: Math.round( finalPrice ), camaraCount: camaraCount } );
301
292
  }
302
293
  } );
303
294
  } catch ( e ) {
304
- console.log( 'pricingInfo=>', e );
305
295
  logger.error( { error: e, function: 'pricingInfo' } );
306
296
  return res.sendError( e, 500 );
307
297
  }
@@ -353,7 +343,6 @@ export const updateSubscriptionOLD = async ( req, res ) => {
353
343
  return res.sendError( 'Something went wrong', 500 );
354
344
  }
355
345
  } catch ( e ) {
356
- console.log( e );
357
346
  logger.error( { error: e, function: 'updateSubscription' } );
358
347
  return res.sendError( e, 500 );
359
348
  }
@@ -362,70 +351,100 @@ export const updateSubscriptionOLD = async ( req, res ) => {
362
351
  export const updateSubscription = async ( req, res ) => {
363
352
  try {
364
353
  let requestBody = req.body;
365
- if ( !req?.body?.currentPlanInfo ) {
366
- return res.sendError( 'Plan info detail is required', 400 );
354
+ if ( !requestBody?.products?.length ) {
355
+ return res.sendError( 'product is required', 400 );
367
356
  }
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 );
357
+
358
+ let clientProducts = requestBody.client.planDetails.product;
359
+ for ( let item of requestBody.products ) {
360
+ let existsIndex = clientProducts.findIndex( ( ele ) => ele.productName == item.name );
361
+ if ( item.type == 'startTrial' && existsIndex == -1 ) {
362
+ let params = {
363
+ user: '65e966e12b1991393cf8ce30', // need to login user id here
364
+ clientId: requestBody.clientId,
365
+ name: item.name,
366
+ description: 'Request for Trial',
367
+ category: 'Trial',
368
+ status: 'pending',
369
+ };
370
+ await clientRequestService.insert( params );
371
+ }
372
+ if ( item.type == 'subscription' ) {
373
+ if ( existsIndex == -1 ) {
374
+ clientProducts.push( {
375
+ productName: item.name,
376
+ subscribedDate: new Date(),
377
+ status: 'live',
378
+ } );
379
+ } else {
380
+ clientProducts[existsIndex].status = 'live';
381
+ clientProducts[existsIndex].subscribedDate = new Date();
408
382
  }
409
383
  }
410
384
  }
411
385
 
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
386
  let details = {
421
- planDetails: requestBody.currentPlanInfo,
422
- price: price,
423
- priceType: priceType,
387
+ subscriptionType: requestBody.subscriptionType,
388
+ subscriptionPeriod: requestBody.subscriptionPeriod,
389
+ storeCount: requestBody.storeCount,
390
+ totalCamera: requestBody.totalCamera,
391
+ totalStores: requestBody.totalStores,
392
+ storeSize: requestBody.storeSize,
393
+ product: clientProducts,
424
394
  };
425
395
 
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 } );
396
+ // for ( let i = 0; i < requestBody.product.length; i++ ) {
397
+ // if ( requestBody.currentPlanInfo.product[i].status == 'live' && requestBody.currentPlanInfo.product[i].active == true ) {};
398
+ // if ( requestBody.currentPlanInfo.product[i].status == 'trial' && requestBody.currentPlanInfo.product[i].active == true ) {
399
+ // if ( requestBody.currentPlanInfo.product[i].confirmation == 'subscribenow' ) {
400
+ // requestBody.currentPlanInfo.product[i].subscribedDate = new Date();
401
+ // requestBody.currentPlanInfo.product[i].status = 'live';
402
+ // requestBody.currentPlanInfo.product[i].trialStartDate = requestBody.currentPlanInfo.product[i]?.trialStartDate || '';
403
+ // requestBody.currentPlanInfo.product[i].trialEndDate = requestBody.currentPlanInfo.product[i]?.trialEndDate || '';
404
+ // }
405
+ // };
406
+ // if ( requestBody.currentPlanInfo.product[i].active == true && !requestBody.currentPlanInfo.product[i].hasOwnProperty( 'status' ) ) {
407
+ // if ( requestBody.currentPlanInfo.product[i].confirmation == 'subscribenow' ) {
408
+ // requestBody.currentPlanInfo.product[i].subscribedDate = new Date();
409
+ // requestBody.currentPlanInfo.product[i].status = 'live';
410
+ // requestBody.currentPlanInfo.product[i].trialStartDate = requestBody.currentPlanInfo.product[i]?.trialStartDate || '';
411
+ // requestBody.currentPlanInfo.product[i].trialEndDate = requestBody.currentPlanInfo.product[i]?.trialEndDate || '';
412
+ // }
413
+ // if ( requestBody.currentPlanInfo.product[i].confirmation == 'starttrail' ) {
414
+ // requestBody.currentPlanInfo.product[i].status = 'trial';
415
+ // let params = {
416
+ // user: '65e966e12b1991393cf8ce30', // need to login user id here
417
+ // clientId: requestBody.clientId,
418
+ // name: requestBody.currentPlanInfo.product[i].productName,
419
+ // description: 'Request for Trial',
420
+ // category: 'Trial',
421
+ // status: 'pending',
422
+ // };
423
+ // await clientRequestService.insert( params );
424
+ // }
425
+ // if ( requestBody.currentPlanInfo.product[i].confirmation == 'doitlater' ) {
426
+ // // need to do price changes
427
+ // requestBody.currentPlanInfo.product.splice( i, 1 );
428
+ // }
429
+ // }
430
+ // }
431
+
432
+ // for ( let j = 0; j < requestBody.currentPlanInfo.product.length; j++ ) {
433
+ // delete requestBody.currentPlanInfo.product[j]?.aliseProductName;
434
+ // delete requestBody.currentPlanInfo.product[j]?.toolTip;
435
+ // delete requestBody.currentPlanInfo.product[j]?.active;
436
+ // delete requestBody.currentPlanInfo.product[j]?.confirmation;
437
+ // }
438
+
439
+ let data = {
440
+ planDetails: details,
441
+ price: requestBody.price,
442
+ priceType: requestBody.priceType,
443
+ };
444
+
445
+ let result = await paymentService.updateOne( { clientId: req.params.clientId }, data );
446
+ let storeProduct = clientProducts.map( ( item ) => item.productName );
447
+ await storeService.updateMany( { clientId: req.params.clientId, status: 'active' }, { product: storeProduct } );
429
448
 
430
449
  if ( result.modifiedCount ) {
431
450
  return res.sendSuccess( { message: 'Subscription Updated Successfully' } );
@@ -433,7 +452,6 @@ export const updateSubscription = async ( req, res ) => {
433
452
  return res.sendError( 'Something went wrong', 500 );
434
453
  }
435
454
  } catch ( e ) {
436
- console.log( e );
437
455
  logger.error( { error: e, function: 'updateSubscription' } );
438
456
  return res.sendError( e, 500 );
439
457
  }
@@ -477,7 +495,6 @@ export const trialProductList = async ( req, res ) => {
477
495
  } );
478
496
  return res.sendSuccess( products );
479
497
  } catch ( e ) {
480
- console.log( 'trialRequest =>', e );
481
498
  logger.error( { error: e, function: 'trialRequest' } );
482
499
  return res.sendError( e, 500 );
483
500
  }
@@ -494,14 +511,13 @@ export const unsubscribeProduct = async ( req, res ) => {
494
511
  clientId: req.body.clientId,
495
512
  reason: req.body.reason,
496
513
  description: req.body.description,
497
- category: 'Request for unsubscribe',
514
+ category: 'unsubscribe',
498
515
  status: 'pending',
499
516
  };
500
517
  await clientRequestService.insert( params );
501
518
 
502
519
  return res.sendSuccess( 'Request Send Successfully' );
503
520
  } catch ( e ) {
504
- console.log( 'unsubscribeProduct =>', e );
505
521
  logger.error( { error: e, function: 'unsubscribeProduct' } );
506
522
  return res.sendError( e, 500 );
507
523
  }
@@ -525,7 +541,6 @@ export const trialExtendRequest = async ( req, res ) => {
525
541
 
526
542
  return res.sendSuccess( 'Request Send Successfully' );
527
543
  } catch ( e ) {
528
- console.log( 'trialExtendRequest =>', e );
529
544
  logger.error( { error: e, function: 'trialExtendRequest' } );
530
545
  return res.sendError( e, 500 );
531
546
  }
@@ -550,7 +565,6 @@ export const trialRequest = async ( req, res ) => {
550
565
 
551
566
  return res.sendSuccess( 'Request Send Successfully' );
552
567
  } catch ( e ) {
553
- console.log( 'trialExtendRequest =>', e );
554
568
  logger.error( { error: e, function: 'trialExtendRequest' } );
555
569
  return res.sendError( e, 500 );
556
570
  }
@@ -574,7 +588,6 @@ export const invoiceDetails = async ( req, res ) => {
574
588
  };
575
589
  return res.sendSuccess( data );
576
590
  } catch ( e ) {
577
- console.log( 'invoiceDetails =>', e );
578
591
  logger.error( { error: e, function: 'invoiceDetails' } );
579
592
  return res.sendError( e, 500 );
580
593
  }
@@ -602,7 +615,6 @@ export const updateInvoiceDetails = async ( req, res ) => {
602
615
  return res.sendError( e );
603
616
  } );
604
617
  } catch ( e ) {
605
- console.log( 'invoiceDetails =>', e );
606
618
  logger.error( { error: e, function: 'invoiceDetails' } );
607
619
  return res.sendError( e, 500 );
608
620
  }
@@ -614,15 +626,68 @@ export const notificationList = async ( req, res ) => {
614
626
  let query = {};
615
627
  query.status = 'pending';
616
628
  if ( req?.query?.clientId ) {
617
- query.client = req?.query?.clientId;
629
+ query.clientId = req?.query?.clientId;
618
630
  }
619
631
  let notificationList = await clientRequestService.find( query, { createdAt: 0, updatedAt: 0 } );
632
+ query = [
633
+ {
634
+ $match: {
635
+ clientId: req.query.clientId,
636
+ status: 'active',
637
+ },
638
+ },
639
+ { $unwind: '$planDetails.product' },
640
+ {
641
+ $match: {
642
+ 'planDetails.product.status': 'trial',
643
+ },
644
+ },
645
+ {
646
+ $project: {
647
+ _id: 0,
648
+ product: '$planDetails.product',
649
+ currentPlan: '$planDetails.subscriptionType',
650
+ },
651
+ },
652
+ ];
653
+ let getClientInfo = await paymentService.aggregate( query );
654
+ if ( getClientInfo.length ) {
655
+ getClientInfo.forEach( ( item ) => {
656
+ let [ firstWord, secondWord ] = item.product.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
657
+ firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
658
+ let startDate = dayjs( item.product.trialStartDate );
659
+ let endDate = dayjs( item.product.trialEndDate ).startOf( 'day' );
660
+ let date = dayjs().startOf( 'day' );
661
+ let days = date.diff( startDate, 'day' );
662
+ let totalDays = endDate.diff( startDate, 'day' );
663
+ let percentage = Math.round( ( days / totalDays )* 100 );
664
+ notificationList.push( {
665
+ product: item.product.productName,
666
+ name: `${firstWord} ${secondWord}`,
667
+ day: endDate.diff( date, 'day' ) + 1,
668
+ percentage: percentage,
669
+ category: 'trial product',
670
+ } );
671
+ } );
672
+ }
673
+
674
+ notificationList.forEach( ( item ) => {
675
+ if ( !item?.product && item.category == 'Trial' ) {
676
+ let [ firstWord, secondWord ] = item.name.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
677
+ firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
678
+ item.name = `${firstWord} ${secondWord}`;
679
+ }
680
+ } );
681
+
682
+ let data = {
683
+ notificationList,
684
+ currentPlan: getClientInfo[0]?.currentPlan || 'free',
685
+ };
620
686
  if ( !notificationList.length ) {
621
687
  return res.sendError( 'no data found', 204 );
622
688
  }
623
- return res.sendSuccess( notificationList );
689
+ return res.sendSuccess( data );
624
690
  } catch ( e ) {
625
- console.log( 'approvalList =>', e );
626
691
  logger.error( { error: e, function: 'approvalList' } );
627
692
  return res.sendError( e, 500 );
628
693
  }
@@ -635,7 +700,7 @@ export const trialApproval = async ( req, res ) => {
635
700
  if ( !requestData ) {
636
701
  return res.sendError( 'no data found', 204 );
637
702
  }
638
- requestData.status = 'complete';
703
+ requestData.status = 'completed';
639
704
  requestData.save().then( async () => {
640
705
  if ( req.body.type == 'approve' ) {
641
706
  let clientProducts = await paymentService.findOne( { clientId: requestData.clientId, status: 'active' }, { planDetails: 1 } );
@@ -644,7 +709,6 @@ export const trialApproval = async ( req, res ) => {
644
709
  }
645
710
  let productIndex = clientProducts.planDetails.product.findIndex( ( item ) => item.productName == requestData.name );
646
711
  if ( productIndex != -1 ) {
647
- clientProducts.planDetails.product[productIndex].status =
648
712
  clientProducts.planDetails.product[productIndex].status = 'trial';
649
713
  clientProducts.planDetails.product[productIndex].trialStartDate = new Date();
650
714
  clientProducts.planDetails.product[productIndex].trialEndDate = new Date( dayjs().add( 13, 'days' ).format( 'YYYY-MM-DD' ) );
@@ -662,7 +726,6 @@ export const trialApproval = async ( req, res ) => {
662
726
  return res.sendSuccess( 'updated Successfully' );
663
727
  } );
664
728
  } catch ( e ) {
665
- console.log( 'approvalList =>', e );
666
729
  logger.error( { error: e, function: 'approvalList' } );
667
730
  return res.sendError( e, 500 );
668
731
  }
@@ -683,7 +746,7 @@ export const trialExtendRequestApproval = async ( req, res ) => {
683
746
  clientDetails.save().then( async () => {
684
747
  let requestData = await clientRequestService.findOne( { clientId: req.body.clientId, status: 'pending', name: req.body.product, category: 'TrialExtend' } );
685
748
  if ( requestData ) {
686
- requestData.status = 'complete';
749
+ requestData.status = 'completed';
687
750
  requestData.save();
688
751
  }
689
752
  return res.sendSuccess( 'Trial Extended Successfully' );
@@ -691,7 +754,6 @@ export const trialExtendRequestApproval = async ( req, res ) => {
691
754
  return res.sendError( e, 500 );
692
755
  } );
693
756
  } catch ( e ) {
694
- console.log( 'trialExtendRequestApproval =>', e );
695
757
  logger.error( { error: e, function: 'trialExtendRequestApproval' } );
696
758
  return res.sendError( e, 500 );
697
759
  }
@@ -712,7 +774,6 @@ export const productSubscribe = async ( req, res ) => {
712
774
  } );
713
775
  }
714
776
  } );
715
- console.log( req.body.product, 'product' );
716
777
  let clientInfo = await paymentService.findOne( { clientId: req.body.clientId, status: 'active' }, { clientId: 1, planDetails: 1 } );
717
778
  if ( !clientInfo ) {
718
779
  return res.sendError( 'no data found', 204 );
@@ -724,7 +785,6 @@ export const productSubscribe = async ( req, res ) => {
724
785
  if ( productList.includes( item.name ) && item.type =='unsubscribe' ) {
725
786
  // let findIndex = product.findIndex( ( product ) => product.productName );
726
787
  // product.splice( findIndex, 1 );
727
- // console.log( clientInfo.clientId );
728
788
  await storeService.addremoveElement( { clientId: clientInfo.clientId, status: 'active', product: { $in: item.name } }, { $pull: { product: item.name } } );
729
789
  }
730
790
  if ( !productList.includes( item.name ) && [ 'trial', 'subscription' ].includes( item.type ) ) {
@@ -743,16 +803,22 @@ export const productSubscribe = async ( req, res ) => {
743
803
  } );
744
804
  }
745
805
  await storeService.addremoveElement( { clientId: clientInfo.clientId, status: 'active' }, { $push: { product: item.name } } );
806
+ } else {
807
+ let productIndex = product.findIndex( ( ele ) => ele.productName == item.name );
808
+ if ( productIndex != -1 ) {
809
+ if ( item.type == 'subscription' ) {
810
+ product[productIndex].subscribedDate = new Date();
811
+ product[productIndex].status = 'live';
812
+ }
813
+ }
746
814
  }
747
815
  }
748
816
  product = product.filter( ( item ) => !removeProducts.includes( item.productName ) );
749
- console.log( product, 'product' );
750
817
  clientInfo.planDetails.product = product;
751
818
  clientInfo.save().then( async () => {
752
819
  } );
753
820
  return res.sendSuccess( 'Product Subscribed Successfully' );
754
821
  } catch ( e ) {
755
- console.log( 'updateProductSubscribe =>', e );
756
822
  logger.error( { error: e, function: 'updateProductSubscribe' } );
757
823
  return res.sendError( e, 500 );
758
824
  }
@@ -764,7 +830,7 @@ export const unsubscribeApproval = async ( req, res ) => {
764
830
  if ( !requestData ) {
765
831
  return res.sendError( 'no data found', 204 );
766
832
  }
767
- requestData.status = 'complete';
833
+ requestData.status = 'completed';
768
834
  requestData.save().then( async () => {
769
835
  if ( req.body.type == 'unsubscribe' ) {
770
836
  let clientProducts = await paymentService.findOne( { clientId: requestData.clientId, status: 'active' }, { status: 1 } );
@@ -773,12 +839,11 @@ export const unsubscribeApproval = async ( req, res ) => {
773
839
  }
774
840
  clientProducts.status = 'deactive';
775
841
  clientProducts.save();
776
- await storeService.updateMany( { clientId: clientInfo.clientId }, { status: 'deactive' } );
842
+ await storeService.updateMany( { clientId: requestData.clientId }, { status: 'deactive' } );
777
843
  }
778
844
  return res.sendSuccess( 'updated Successfully' );
779
845
  } );
780
846
  } catch ( e ) {
781
- console.log( 'subscribeApproval =>', e );
782
847
  logger.error( { error: e, function: 'subscribeApproval' } );
783
848
  return res.sendError( e, 500 );
784
849
  }
@@ -814,9 +879,7 @@ export const productViewList = async ( req, res ) => {
814
879
  if ( !clientProduct ) {
815
880
  return res.sendError( 'no data found', 204 );
816
881
  }
817
- console.log( clientProduct.planDetails.product );
818
882
  let productPrice = await basePricingService.findOne( { clientId: { $exists: false } }, { basePricing: 1 } );
819
- console.log( storeProductCount, 'price' );
820
883
  let products = [];
821
884
  clientProduct.planDetails.product.forEach( ( item ) => {
822
885
  let price;
@@ -846,7 +909,6 @@ export const productViewList = async ( req, res ) => {
846
909
  // } );
847
910
  return res.sendSuccess( products );
848
911
  } catch ( e ) {
849
- console.log( 'productViewList =>', e );
850
912
  logger.error( { error: e, function: 'productViewList' } );
851
913
  return res.sendError( e, 500 );
852
914
  }
@@ -855,7 +917,7 @@ export const productViewList = async ( req, res ) => {
855
917
  export const storeViewList = async ( req, res ) => {
856
918
  try {
857
919
  let limit = req.body?.limit || 10;
858
- let offset = req.body.offset || 0;
920
+ let offset = ( req.body.offset - 1 ) || 0;
859
921
  let skip = offset * limit;
860
922
  let query = [
861
923
  {
@@ -893,7 +955,7 @@ export const storeViewList = async ( req, res ) => {
893
955
  query.push(
894
956
  {
895
957
  $match: {
896
- storeName: { $in: req.body?.store },
958
+ storeId: { $in: req.body?.store },
897
959
  },
898
960
  },
899
961
  );
@@ -925,10 +987,8 @@ export const storeViewList = async ( req, res ) => {
925
987
  },
926
988
  );
927
989
 
928
- console.log( JSON.stringify( query ), 'query' );
929
990
 
930
991
  let storeDetails = await storeService.aggregate( query );
931
- console.log( storeDetails );
932
992
 
933
993
  if ( !storeDetails[0].data.length ) {
934
994
  return res.sendError( 'no data found', 204 );
@@ -940,7 +1000,6 @@ export const storeViewList = async ( req, res ) => {
940
1000
 
941
1001
  return res.sendSuccess( data );
942
1002
  } catch ( e ) {
943
- console.log( 'storeViewList =>', e );
944
1003
  logger.error( { error: e, function: 'storeViewList' } );
945
1004
  return res.sendError( e, 500 );
946
1005
  }
@@ -957,11 +1016,9 @@ export const storeLocationList = async ( req, res ) => {
957
1016
  } );
958
1017
  let location = storeDetails.filter( ( item ) => item.storeProfile.city != '' && item.storeProfile.city != null && typeof ( item.storeProfile.city ) != undefined ).map( ( item ) => item.storeProfile.city );
959
1018
  let productDetails = await basePricingService.findOne( { clientId: { $exists: false } }, { 'basePricing': 1, '_id': 0 } );
960
- console.log( productDetails );
961
1019
  let product = productDetails.basePricing.map( ( item ) => item.productName );
962
1020
  return res.sendSuccess( { store, location, product } );
963
1021
  } catch ( e ) {
964
- console.log( 'storeLocationList =>', e );
965
1022
  logger.error( { error: e, function: 'storeLocationList' } );
966
1023
  return res.sendError( e, 500 );
967
1024
  }
@@ -970,44 +1027,98 @@ export const storeLocationList = async ( req, res ) => {
970
1027
 
971
1028
  export const addStoreProduct = async ( req, res ) => {
972
1029
  try {
973
- let storeDetails = await storeService.find( { storeName: { $in: req.body.store }, clientId: req.body.clientId } );
1030
+ let storeDetails = await storeService.find( { storeId: { $in: req.body.store }, clientId: req.body.clientId } );
1031
+
974
1032
  if ( !storeDetails.length ) {
975
1033
  return res.sendError( 'no data found', 204 );
976
1034
  }
1035
+ let data = req.body.product;
1036
+ req.body.product = [];
1037
+ data.forEach( ( item ) => {
1038
+ if ( item.type != 'cancel' ) {
1039
+ let arr = item.name.split( ',' );
1040
+ arr.forEach( ( product ) => {
1041
+ req.body.product.push( {
1042
+ name: product,
1043
+ type: item.type,
1044
+ } );
1045
+ } );
1046
+ }
1047
+ } );
977
1048
  let clientInfo = await paymentService.findOne( { clientId: req.body.clientId, status: 'active' }, { 'planDetails.product': 1 } );
978
1049
  let productList = clientInfo.planDetails.product.map( ( product ) => product.productName );
979
1050
  let clientProduct = [];
980
1051
  let storeProduct = [];
1052
+ let removedProduct = [];
981
1053
  clientProduct = clientInfo.planDetails.product;
982
1054
  req.body.product.forEach( ( item ) => {
983
1055
  if ( item.type != 'unsubscribe' ) {
984
1056
  storeProduct.push( item.name );
985
1057
  }
986
- if ( !productList.includes( item ) ) {
987
- if ( item.type == 'trial' ) {
988
- clientProduct.push( {
989
- productName: item.name,
990
- trialStartDate: new Date(),
991
- trialEndDate: new Date( dayjs().add( 13, 'days' ).format( 'YYYY-MM-DD' ) ),
992
- status: 'trial',
993
- } );
994
- }
995
- if ( item.type == 'subscribe' ) {
996
- clientProduct.push( {
997
- productName: item.name,
998
- subscribedDate: new Date(),
999
- status: 'live',
1000
- } );
1058
+ if ( item.type == 'unsubscribe' ) {
1059
+ removedProduct.push( item.name );
1060
+ }
1061
+ if ( !productList.includes( item.name ) ) {
1062
+ let productExistsIndex = clientProduct.findIndex( ( product ) => {
1063
+ item.name == product.productName;
1064
+ } );
1065
+ if ( productExistsIndex != -1 ) {
1066
+ if ( item.type == 'trial' ) {
1067
+ clientProduct[productExistsIndex] = {
1068
+ productName: item.name,
1069
+ trialStartDate: new Date(),
1070
+ trialEndDate: new Date( dayjs().add( 13, 'days' ).format( 'YYYY-MM-DD' ) ),
1071
+ status: 'trial',
1072
+ };
1073
+ } else {
1074
+ clientProduct[productExistsIndex] = {
1075
+ productName: item.name,
1076
+ subscribedDate: new Date(),
1077
+ status: 'live',
1078
+ };
1079
+ }
1080
+ } else {
1081
+ if ( item.type == 'trial' ) {
1082
+ clientProduct.push( {
1083
+ productName: item.name,
1084
+ trialStartDate: new Date(),
1085
+ trialEndDate: new Date( dayjs().add( 13, 'days' ).format( 'YYYY-MM-DD' ) ),
1086
+ status: 'trial',
1087
+ } );
1088
+ }
1089
+ if ( item.type == 'subscription' ) {
1090
+ clientProduct.push( {
1091
+ productName: item.name,
1092
+ subscribedDate: new Date(),
1093
+ status: 'live',
1094
+ } );
1095
+ }
1001
1096
  }
1002
1097
  }
1003
1098
  },
1004
1099
  );
1005
1100
  clientInfo.planDetails.product = clientProduct;
1006
1101
  clientInfo.save();
1007
- await storeService.addremoveElement( { storeName: { $in: req.body.store }, clientId: req.body.clientId }, { $push: { product: { $each: storeProduct } } } );
1102
+ storeDetails.forEach( async ( item ) => {
1103
+ let product;
1104
+ if ( item?.product?.length ) {
1105
+ product = item.product.concat( storeProduct );
1106
+ } else {
1107
+ product = storeProduct;
1108
+ }
1109
+ product = Array.from( new Set( product ) );
1110
+ if ( removedProduct.length ) {
1111
+ removedProduct.forEach( ( element ) => {
1112
+ let productIndex = product.findIndex( ( ele ) => ele == element );
1113
+ if ( productIndex != -1 ) {
1114
+ product.splice( productIndex, 1 );
1115
+ }
1116
+ } );
1117
+ }
1118
+ await storeService.updateOne( { storeId: item.storeId, clientId: req.body.clientId }, { product: product } );
1119
+ } );
1008
1120
  return res.sendSuccess( 'product updated Successfully' );
1009
1121
  } catch ( e ) {
1010
- console.log( 'addStoreProduct => ', e );
1011
1122
  logger.error( { error: e, function: 'addStoreProduct' } );
1012
1123
  return res.sendError( e, 500 );
1013
1124
  }
@@ -1016,8 +1127,11 @@ export const addStoreProduct = async ( req, res ) => {
1016
1127
 
1017
1128
  export const invoiceList = async ( req, res ) => {
1018
1129
  try {
1130
+ if ( req.body.export ) {
1131
+ req.body.limit = 10000;
1132
+ }
1019
1133
  let limit = req.body.limit || 10;
1020
- let offset = req.body.offset || 0;
1134
+ let offset = ( req.body.offset-1 ) || 0;
1021
1135
  let skip = limit * offset;
1022
1136
  let date;
1023
1137
  let endDate;
@@ -1034,8 +1148,6 @@ export const invoiceList = async ( req, res ) => {
1034
1148
  endDate= new Date( dayjs().endOf( 'month' ).format( 'YYYY-MM-DD' ) );
1035
1149
  }
1036
1150
  let query = [];
1037
- console.log( date );
1038
- console.log( endDate );
1039
1151
  query = [
1040
1152
  {
1041
1153
  $match: {
@@ -1061,8 +1173,8 @@ export const invoiceList = async ( req, res ) => {
1061
1173
  {
1062
1174
  $facet: {
1063
1175
  data: [
1064
- { $limit: limit },
1065
1176
  { $skip: skip },
1177
+ { $limit: limit },
1066
1178
  ],
1067
1179
  count: [
1068
1180
  { $count: 'count' },
@@ -1080,10 +1192,12 @@ export const invoiceList = async ( req, res ) => {
1080
1192
  data: invoiceDetails[0].data,
1081
1193
  count: invoiceDetails[0].count[0].count,
1082
1194
  };
1083
- return res.sendSuccess( data );
1195
+ if ( !req.body.export ) {
1196
+ return res.sendSuccess( data );
1197
+ } else {
1198
+ download( invoiceDetails[0].data, res );
1199
+ }
1084
1200
  } catch ( e ) {
1085
- console.log( e );
1086
- console.log( 'invoiceList =>', e );
1087
1201
  logger.error( { error: e, function: 'invoiceList' } );
1088
1202
  return res.sendError( e, 500 );
1089
1203
  }
@@ -1186,7 +1300,6 @@ export const priceList = async ( req, res ) => {
1186
1300
  };
1187
1301
  return res.sendSuccess( result );
1188
1302
  } catch ( e ) {
1189
- console.log( e );
1190
1303
  logger.error( { error: e, function: 'priceList' } );
1191
1304
  return res.sendError( e, 500 );
1192
1305
  }
@@ -1207,7 +1320,6 @@ export const pricingListUpdate = async ( req, res ) => {
1207
1320
  delete item.lastIndex;
1208
1321
  }
1209
1322
  } );
1210
- console.log( req.body.products, 'products' );
1211
1323
  let getPriceInfo = await basePricingService.findOne( { clientId: { $exists: true }, clientId: req.body.clientId }, { standard: 1, step: 1 } );
1212
1324
  let data = {
1213
1325
  ...( req.body.type == 'standard' ) ? { standard: req.body.products } : { step: req.body.products },
@@ -1226,7 +1338,6 @@ export const pricingListUpdate = async ( req, res ) => {
1226
1338
  return res.sendSuccess( 'Pricig Updated Successfully' );
1227
1339
  } );
1228
1340
  } catch ( e ) {
1229
- console.log( e );
1230
1341
  logger.error( { error: e, function: 'addPricingList' } );
1231
1342
  return res.sendError( e, 500 );
1232
1343
  }
@@ -1245,7 +1356,6 @@ export const updatedRevisedPrice = async ( req, res ) => {
1245
1356
  return res.sendSuccess( 'Credit notes Updated Successfully' );
1246
1357
  } );
1247
1358
  } catch ( e ) {
1248
- console.log( 'updatedRevisedPrice =>', e );
1249
1359
  logger.error( { error: e, function: 'updatedRevisedPrice' } );
1250
1360
  return res.sendError( e, 500 );
1251
1361
  }
@@ -1259,8 +1369,32 @@ export const unpaidInvoiceList = async ( req, res ) => {
1259
1369
  }
1260
1370
  return res.sendSuccess( invoiceDetails );
1261
1371
  } catch ( e ) {
1262
- console.log( 'unpaidInvoiceList =>', e );
1263
1372
  logger.error( { error: e, function: 'unpaidInvoiceList' } );
1264
1373
  return res.sendError( e, 500 );
1265
1374
  }
1266
1375
  };
1376
+
1377
+
1378
+ export const getStoreProducts = async ( req, res ) => {
1379
+ try {
1380
+ let storeProductDetails;
1381
+ if ( !req.body.store.length ) {
1382
+ storeProductDetails = await storeService.find( { clientId: req.body.clientId, status: 'active' } );
1383
+ } else {
1384
+ storeProductDetails = await storeService.find( { storeId: { $in: req.body.store }, clientId: req.body.clientId, status: 'active' } );
1385
+ }
1386
+
1387
+ let product = new Set();
1388
+ storeProductDetails.forEach( ( item ) => {
1389
+ item.product.forEach( ( p ) => product.add( p ) );
1390
+ } );
1391
+ product = Array.from( product );
1392
+ if ( !product.length ) {
1393
+ return res.sendError( 'no data found', 204 );
1394
+ }
1395
+ return res.sendSuccess( product );
1396
+ } catch ( e ) {
1397
+ logger.error( { error: e, function: 'getStoreProducts' } );
1398
+ return res.sendError( e, 500 );
1399
+ }
1400
+ };
@@ -63,7 +63,7 @@ export const validateTrialandUnsubscribeParams = {
63
63
  export const validateTrialExtendRequestParams = {
64
64
  body: joi.object( {
65
65
  clientId: joi.string().required(),
66
- days: joi.string().required(),
66
+ days: joi.number().required(),
67
67
  product: joi.string().required(),
68
68
  } ),
69
69
  };
@@ -86,8 +86,9 @@ export const validateStoreViewParams = {
86
86
  export const validateAddStoreProductParams = {
87
87
  body: joi.object( {
88
88
  clientId: joi.string().required(),
89
- store: joi.array().required(),
89
+ store: joi.array().required().empty(),
90
90
  product: joi.array().required(),
91
+ selectAll: joi.boolean().optional(),
91
92
  } ),
92
93
  };
93
94
 
@@ -101,6 +102,7 @@ export const validateInvoiceParams = {
101
102
  sortColumn: joi.string().optional(),
102
103
  sortBy: joi.number().optional(),
103
104
  clientId: joi.string().required(),
105
+ export: joi.boolean().optional(),
104
106
  } ),
105
107
  };
106
108
 
@@ -127,3 +129,25 @@ export const validatePriceListParams = {
127
129
  clientId: joi.string().required(),
128
130
  } ),
129
131
  };
132
+
133
+ export const validateStoreProductsParams = {
134
+ body: joi.object( {
135
+ clientId: joi.string().required(),
136
+ store: joi.array().required().empty(),
137
+ } ),
138
+ };
139
+
140
+ export const validateUpdateSubscriptionSchema = {
141
+ body: joi.object( {
142
+ clientId: joi.string().required(),
143
+ price: joi.number().required(),
144
+ priceType: joi.string().required(),
145
+ subscriptionType: joi.string().required(),
146
+ subscriptionPeriod: joi.string().required(),
147
+ storeCount: joi.number().required(),
148
+ totalCamera: joi.number().required(),
149
+ totalStores: joi.string().required(),
150
+ storeSize: joi.string().required(),
151
+ products: joi.array().required(),
152
+ } ),
153
+ };
@@ -12,7 +12,7 @@ paymentSubscriptionRouter.get( '/clientBillingSubscriptionInfo/:clientId', isAll
12
12
 
13
13
  paymentSubscriptionRouter.post( '/basePricing', validate( validationDtos.validateProducts ), paymentController.pricingInfo );
14
14
 
15
- paymentSubscriptionRouter.put( '/update/subscription/:clientId', isAllowedSessionHandler, validate( validationDtos.validateBrandParams ), validateClient, paymentController.updateSubscription );
15
+ paymentSubscriptionRouter.put( '/update/subscription/:clientId', isAllowedSessionHandler, validate( validationDtos.validateUpdateSubscriptionSchema ), validateClient, paymentController.updateSubscription );
16
16
 
17
17
  paymentSubscriptionRouter.get( '/getTrialProducts', isAllowedSessionHandler, validate( validationDtos.validateStoreParams ), paymentController.trialProductList );
18
18
 
@@ -54,4 +54,6 @@ paymentSubscriptionRouter.post( '/creditNotes', isAllowedSessionHandler, validat
54
54
 
55
55
  paymentSubscriptionRouter.get( '/creditNotes/invoiceList/:clientId', isAllowedSessionHandler, validate( validationDtos.validateBrandParams ), paymentController.unpaidInvoiceList );
56
56
 
57
+ paymentSubscriptionRouter.post( '/admin/getStoreProducts', isAllowedSessionHandler, validate( validationDtos.validateStoreProductsParams ), paymentController.getStoreProducts );
58
+
57
59
 
@@ -19,3 +19,7 @@ export const updateMany = ( query = {}, record = {} ) => {
19
19
  export const addremoveElement = ( query = {}, record ={} ) => {
20
20
  return model.storeModel.updateMany( query, record );
21
21
  };
22
+
23
+ export const updateOne = ( query = {}, record ={} ) => {
24
+ return model.storeModel.updateOne( query, { $set: record } );
25
+ };
@@ -22,7 +22,6 @@ export const validateClient = async ( req, res, next ) => {
22
22
  req.body.client = clientDetails;
23
23
  next();
24
24
  } catch ( e ) {
25
- console.log( 'validateClient =>', e );
26
25
  logger.error( { error: e, function: 'validateClient' } );
27
26
  res.sendError( e, 500 );
28
27
  }
package/script-new.js DELETED
@@ -1,376 +0,0 @@
1
- const fs = require( 'fs' );
2
- const path = require( 'path' );
3
- const { execSync } = require( 'child_process' );
4
- // Define folder structure
5
- const createProjectStructure = async ( folderName ) => {
6
- const folders = [
7
- `src`,
8
- `src/controllers`,
9
- `src/routes`,
10
- `config`,
11
- `config/database`,
12
- `config/logger`,
13
- `config/env`,
14
- ];
15
-
16
- // Create folders
17
- folders.forEach( ( folder ) => {
18
- const folderPath = path.join( __dirname, folder );
19
- fs.mkdirSync( folderPath, { recursive: true } );
20
- } );
21
-
22
- // Create index.js file
23
- const indexjsContent = `
24
-
25
- import { ${folderName}router } from './src/routes/${folderName}.routes.js';
26
-
27
- export { ${folderName}router };
28
-
29
- `;
30
- fs.writeFileSync(
31
- path.join( __dirname, `/`, 'index.js' ),
32
- indexjsContent,
33
- );
34
-
35
- // Create app.js file
36
- const appContent = `
37
- import express from 'express';
38
- import { ${folderName}router } from './index.js';
39
-
40
- import dotenv from 'dotenv';
41
- import { logger } from 'tango-app-api-middleware';
42
- import { connectdb } from './config/database/database.js';
43
-
44
- const env=dotenv.config();
45
-
46
- const app = express();
47
- const PORT = process.env.PORT || 3000;
48
-
49
-
50
-
51
-
52
- if ( env.error ) {
53
- logger.error( '.env not found' );
54
- process.exit( 1 );
55
- }
56
-
57
-
58
- app.use('/api', ${folderName}Router);
59
-
60
- app.listen(PORT, () => {
61
- console.log(\`server is running on port= \${PORT} \`);
62
- connectdb();
63
- });
64
-
65
- `;
66
- fs.writeFileSync(
67
- path.join( __dirname, `/`, 'app.js' ),
68
- appContent,
69
- );
70
-
71
- // Create route.js file
72
- const appJsContent = `
73
- import express from 'express';
74
-
75
- export const ${folderName}router = express.Router();
76
-
77
- ${folderName}router.get('/', (req, res) => {
78
- res.send('Hello, world!');
79
- });
80
-
81
-
82
- `;
83
- fs.writeFileSync(
84
- path.join( __dirname, `/src/routes`, `${folderName}.routes.js` ),
85
- appJsContent,
86
- );
87
-
88
- // Create package.json file
89
- const packageJsonContent = `
90
- {
91
- "name": "${folderName}",
92
- "version": "1.0.0",
93
- "description": "${folderName}",
94
- "main": "app.js",
95
- "type": "module",
96
- "scripts": {
97
- "start": "nodemon --exec \\"eslint --fix . && node app.js\\""
98
- },
99
- "engines": {
100
- "node": ">=18.10.0"
101
- },
102
- "author": "praveenraj",
103
- "license": "ISC"
104
-
105
- }
106
- `;
107
- fs.writeFileSync(
108
- path.join( __dirname, 'package.json' ),
109
- packageJsonContent,
110
- );
111
-
112
- // Create .eslintrc.js file
113
- const eslintrcContent = `
114
- module.exports = {
115
- 'env': {
116
- 'es2021': true,
117
- 'node': true,
118
- },
119
- 'extends': 'google',
120
- 'overrides': [
121
- {
122
- 'env': {
123
- 'node': true,
124
- },
125
- 'files': [
126
- '.eslintrc.{js,cjs}',
127
- ],
128
- 'parserOptions': {
129
- 'sourceType': 'script',
130
- },
131
- },
132
- ],
133
- 'parserOptions': {
134
- 'ecmaVersion': 'latest',
135
- 'sourceType': 'module',
136
- },
137
- 'rules': {
138
- 'linebreak-style': [ 'error', 'windows' ],
139
- 'require-jsdoc': 'off',
140
- 'arrow-spacing': 'error',
141
- 'key-spacing': [ 'error', { 'beforeColon': false, 'afterColon': true } ],
142
- 'object-curly-spacing': [ 'error', 'always' ],
143
- 'space-in-parens': [ 'error', 'always' ],
144
- 'keyword-spacing': 'error',
145
- 'array-bracket-spacing': [ 'error', 'always' ],
146
- 'spaced-comment': [ 'error', 'always' ],
147
- 'max-len': [ 'error', { 'code': 700 } ],
148
- 'no-unused-vars': 'error',
149
- 'new-cap': [ 'error', { 'newIsCap': true, 'capIsNew': false } ],
150
- 'prefer-const': 'off',
151
- },
152
- };
153
-
154
- `;
155
- fs.writeFileSync(
156
- path.join( __dirname, '.eslintrc.cjs' ),
157
- eslintrcContent,
158
- );
159
-
160
- // Create .env file
161
- const envContent = `
162
- PORT=3005
163
- AWS_ACCESS_KEY_ID=AKIAQSSPN5BZSDAZHWB2
164
- AWS_SECRET_ACCESS_KEY=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
165
-
166
- mongo_username= tangoeye
167
- mongo_password= SUTONQosEUijJKWC
168
-
169
- ELASTIC_CLOUD_ID=
170
- ELASTIC_USERNAME=
171
- ELASTIC_PASSWORD=
172
- ELASTIC_NODE=
173
-
174
- `;
175
- fs.writeFileSync( path.join( __dirname, '.env' ), envContent );
176
-
177
- // Create database.js file
178
- const databaseContent = `
179
- import appConfig from '../../config/env/env.js';
180
- import mongoose from 'mongoose';
181
- import { logger } from 'tango-app-api-middleware';
182
-
183
- export function getConnection() {
184
- appConfig.database.mongo.username = process.env.mongo_username;
185
- appConfig.database.mongo.password = process.env.mongo_password;
186
-
187
- const options = {
188
- useNewUrlParser: true,
189
- useUnifiedTopology: true,
190
- };
191
- let connectionString;
192
-
193
- if (appConfig.database.mongo.authSource) {
194
- connectionString = \`\${appConfig.database.mongo.hostname}/\${appConfig.database.mongo.name}?\${appConfig.database.mongo.authSource}\`;
195
- }
196
-
197
- if (appConfig.database.mongo.username && appConfig.database.mongo.password) {
198
- connectionString = \`\${appConfig.database.mongo.username}:\${appConfig.database.mongo.password}@\${appConfig.database.mongo.hostname}/\${appConfig.database.mongo.name}\`;
199
- } else {
200
- connectionString = \`\${appConfig.database.mongo.hostname}/\${appConfig.database.mongo.name}\`;
201
- }
202
- if (appConfig.database.mongo.authSource) {
203
- connectionString = \`mongodb+srv://\${connectionString}\`;
204
- } else {
205
- connectionString = \`mongodb://\${connectionString}\`;
206
- }
207
- return { uri: \`\${connectionString}\`, options };
208
- }
209
-
210
- export function connectdb() {
211
- const db = getConnection();
212
- // Establish Connection
213
- mongoose.connect(db.uri, db.options);
214
-
215
- // Mongoose Events
216
- mongoose.connection.on('connected', () => {
217
- logger.info('Mongoose connected with MongoDB: ' + new Date().toISOString());
218
- });
219
-
220
- // Event: Disconnected
221
- mongoose.connection.on('disconnected', () => {
222
- logger.log('MongoDB Connection Closed: ' + new Date().toISOString());
223
- });
224
-
225
- // Event: Error
226
- mongoose.connection.on('error', (error) => {
227
- logger.error(error);
228
- });
229
- }
230
- `;
231
-
232
- fs.writeFileSync(
233
- path.join( __dirname, `/config/database`, `database.js` ),
234
-
235
- databaseContent,
236
- );
237
-
238
- // Create logger.js file
239
- const loggerContent = `
240
- import winston from 'winston';
241
- import DailyRotateFile from 'winston-daily-rotate-file';
242
-
243
- export const logger = winston.createLogger( {
244
- level: 'info',
245
- format: winston.format.combine(
246
- winston.format.errors( { stack: true } ),
247
- winston.format.timestamp(),
248
- winston.format.prettyPrint(),
249
- winston.format.colorize(),
250
- ),
251
- transports: [
252
- new DailyRotateFile( {
253
- filename: \`error-%DATE%.log\`,
254
- dirname: \`storage/logs/\`,
255
- datePattern: 'YYYY-MM-DD',
256
- zippedArchive: true,
257
- maxFiles: '2d',
258
- maxSize: '2g',
259
- level: 'error',
260
- } ),
261
- new DailyRotateFile( {
262
- filename: \`application-%DATE%.log\`,
263
- dirname: \`storage/logs/\`,
264
- datePattern: 'YYYY-MM-DD',
265
- zippedArchive: true,
266
- maxFiles: '2d',
267
- maxSize: '2g',
268
- } ),
269
- ],
270
- } );
271
-
272
-
273
- `;
274
- fs.writeFileSync(
275
- path.join( __dirname, `/config/logger`, `logger.js` ),
276
-
277
- loggerContent,
278
- );
279
- console.log( `Folder structure for ${folderName} created successfully.` );
280
-
281
- // Create database.js file
282
- const envjsContent = `
283
- const appConfig = {
284
- app: {
285
- environment: 'development',
286
- },
287
- api: {
288
- version: [ 'v3' ],
289
- },
290
- url: {
291
- admin: '',
292
- audit: '',
293
- },
294
- database: {
295
- mongo: {
296
- hostname: 'serverlessinstance-1.o0iqto1.mongodb.net',
297
- name: 'tango-api-uat',
298
- },
299
- postgre: {},
300
- },
301
- cloud: {
302
- aws: {
303
- region: 'ap-south-1',
304
- secertManager: 'tango-api-dev',
305
- sqs: {
306
- url: '',
307
- },
308
- bucket: {
309
- name: '',
310
- },
311
- version: 'v4',
312
- },
313
- elasticSearch: {
314
- cloud: {
315
- id: process.env.ELASTIC_CLOUD_ID,
316
- },
317
- auth: {
318
- username: process.env.ELASTIC_USERNAME,
319
- password: process.env.ELASTIC_PASSWORD,
320
- },
321
- // node: process.env.ELASTIC_NODE,
322
- },
323
- },
324
-
325
- };
326
-
327
- export default appConfig;
328
-
329
- `;
330
-
331
- fs.writeFileSync(
332
- path.join( __dirname, `/config/env`, `env.js` ),
333
- envjsContent,
334
- );
335
-
336
- // Install specific dependencies
337
- console.log( 'Installing dependencies...', {
338
- cwd: path.join( __dirname ),
339
- } );
340
- try {
341
- const gitignoreContent = [
342
- 'node_modules/',
343
- 'package-lock.json',
344
- 'storage/',
345
- 'config/',
346
- 'app.js',
347
- '.env',
348
- ].join( '\r\n' ); // Use Windows-style line endings
349
-
350
- // Write content to .gitignore
351
- fs.writeFileSync( path.join( __dirname, '.gitignore' ), gitignoreContent );
352
-
353
- // Install npm dependencies
354
- const npmCommand = 'npm install express mongodb aws-sdk nodemon tango-api-schema winston winston-daily-rotate-file dotenv';
355
- execSync( npmCommand, { cwd: path.join( __dirname ), stdio: 'inherit' } );
356
-
357
- console.log( 'Dependencies installed successfully.' );
358
- } catch ( error ) {
359
- console.error( 'Error occurred while installing dependencies:', error );
360
- }
361
-
362
- // Install specific dependencies as devDependencies
363
- console.log( 'Installing devDependencies...' );
364
- try {
365
- await execSync(
366
- ' npm install --save-dev eslint eslint-config-google eslint-config-semistandard eslint-config-standard eslint-plugin-import eslint-plugin-promise',
367
- { cwd: path.join( __dirname ) },
368
- );
369
- console.log( 'devDependencies installed successfully.' );
370
- } catch ( error ) {
371
- console.error( 'Error occurred while installing devDependencies:', error );
372
- }
373
- };
374
-
375
- // Usage: node createProjectStructure.js myapi
376
- createProjectStructure( process.argv[2] );