tango-app-api-payment-subscription 3.1.12 → 3.1.13

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.1.12",
3
+ "version": "3.1.13",
4
4
  "description": "paymentSubscription",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -26,7 +26,7 @@
26
26
  "nodemon": "^3.1.0",
27
27
  "swagger-ui-express": "^5.0.0",
28
28
  "tango-api-schema": "^2.0.131",
29
- "tango-app-api-middleware": "^3.1.19",
29
+ "tango-app-api-middleware": "^3.1.26",
30
30
  "winston": "^3.12.0",
31
31
  "winston-daily-rotate-file": "^5.0.0"
32
32
  },
@@ -1,7 +1,10 @@
1
1
  import { download, logger } from 'tango-app-api-middleware';
2
2
  import { aggregate } from '../services/store.service.js';
3
- import { aggregatebilling, create, deleteOne, find, findOne, updateMany, updateOne } from '../services/billing.service.js';
3
+ import * as invoice from '../services/invoice.service.js';
4
+ import { aggregatebilling, countDocuments, create, deleteOne, find, findOne, updateMany, updateOne } from '../services/billing.service.js';
4
5
  import mongoose from 'mongoose';
6
+ import { findOneAccount } from '../services/paymentAccount.service.js';
7
+ import dayjs from 'dayjs';
5
8
 
6
9
 
7
10
  export const subscribedStoreList = async ( req, res ) => {
@@ -308,6 +311,8 @@ export const deleteBillingGroup = async ( req, res ) => {
308
311
 
309
312
  export const getBillingGroups = async ( req, res ) => {
310
313
  try {
314
+ const allGroups = await countDocuments( { clientId: req.body.clientId } );
315
+
311
316
  const matchStage = {
312
317
  $match: {
313
318
  clientId: req.body.clientId,
@@ -434,6 +439,7 @@ export const getBillingGroups = async ( req, res ) => {
434
439
  await download( exportResult, res );
435
440
  return;
436
441
  }
442
+ groupList[0].pageInfo['total'] = allGroups;
437
443
 
438
444
  return res.sendSuccess( groupList[0] );
439
445
  } catch ( error ) {
@@ -442,4 +448,238 @@ export const getBillingGroups = async ( req, res ) => {
442
448
  }
443
449
  };
444
450
 
451
+ export const getVirtualAccount = async ( req, res ) => {
452
+ try {
453
+ const account = await findOneAccount( { clientId: req.query.clientId }, { accountNumber: 1, ifsc: 1, branch: 1, paymentType: 1, _id: 0 } );
454
+
455
+ if ( !account ) {
456
+ return res.sendError( 'No data found', 204 );
457
+ }
458
+
459
+ return res.sendSuccess( account );
460
+ } catch ( error ) {
461
+ logger.error( { error: error, function: 'getVirtualAccount' } );
462
+ return res.sendError( error, 500 );
463
+ }
464
+ };
465
+
466
+
467
+ export const getInvoices = async ( req, res ) => {
468
+ try {
469
+ const allInvoices = await invoice.count( { clientId: req.body.clientId } );
470
+
471
+ const matchStage = {
472
+ $match: {
473
+ clientId: req.body.clientId,
474
+ },
475
+ };
476
+
477
+ let filterStartDate = '';
478
+ let filterEndDate = '';
479
+
480
+ if ( req.body?.filter && req.body.filter == 'current' ) {
481
+ filterStartDate = new Date( dayjs().startOf( 'month' ).format( 'YYYY-MM-DD' ) );
482
+ filterEndDate = new Date( dayjs().endOf( 'month' ).format( 'YYYY-MM-DD' ) );
483
+ }
484
+ if ( req.body?.filter && req.body.filter == 'prev' ) {
485
+ filterStartDate = new Date( dayjs().subtract( 1, 'month' ).startOf( 'month' ).format( 'YYYY-MM-DD' ) );
486
+ filterEndDate = new Date( dayjs().subtract( 1, 'month' ).endOf( 'month' ).format( 'YYYY-MM-DD' ) );
487
+ }
488
+ if ( req.body?.filter && req.body.filter == 'last' ) {
489
+ filterStartDate = new Date( dayjs().subtract( 2, 'month' ).startOf( 'month' ).format( 'YYYY-MM-DD' ) );
490
+ filterEndDate = new Date( dayjs().endOf( 'month' ).format( 'YYYY-MM-DD' ) );
491
+ }
492
+
493
+ if ( req.body?.filter ) {
494
+ matchStage.$match['$and'] = [
495
+ { billingDate: { $gte: filterStartDate } },
496
+ { billingDate: { $lte: filterEndDate } },
497
+ ];
498
+ }
499
+
500
+ if ( req.body.searchValue ) {
501
+ matchStage.$match.$or = [
502
+ {
503
+ invoice: {
504
+ $regex: req.body.searchValue,
505
+ $options: 'i',
506
+ },
507
+ },
508
+ ];
509
+ }
510
+
511
+
512
+ const pipeline = [
513
+ matchStage,
514
+ {
515
+ $project: {
516
+ '_id': 1,
517
+ 'invoice': 1,
518
+ 'billingDate': 1,
519
+ 'totalAmount': 1,
520
+ 'stores': 1,
521
+ 'paymentStatus': 1,
522
+ 'paymentTerm': 1,
523
+ 'products.productName': 1,
524
+ },
525
+ },
526
+ ];
527
+
528
+ if ( req.body?.sortColumn && req.body?.sortBy ) {
529
+ pipeline.push(
530
+ {
531
+ $addFields: {
532
+ sortField: {
533
+ $toLower: `$${req.body.sortColumn}`,
534
+ },
535
+ },
536
+ },
537
+ {
538
+ $sort: {
539
+ [req.body.sortColumn]: req.body.sortBy,
540
+ },
541
+ },
542
+ );
543
+ }
544
+
545
+ pipeline.push(
546
+ {
547
+ $project: {
548
+ sortField: 0,
549
+ },
550
+ },
551
+
552
+ );
553
+
554
+ const facetStage = {
555
+ $facet: {
556
+ data: [
557
+ {
558
+ $skip: ( ( req.body.offset - 1 ) * req.body.limit ),
559
+ },
560
+ {
561
+ $limit: ( req.body.limit ),
562
+ },
563
+ ],
564
+ pageInfo: [
565
+ {
566
+ $count: 'count',
567
+ },
568
+ ],
569
+ },
570
+ };
571
+
572
+ if ( req.body?.isExport ) {
573
+ facetStage.$facet.data = [];
574
+ }
575
+
576
+ pipeline.push( facetStage );
577
+
578
+ pipeline.push( {
579
+ $unwind: {
580
+ path: '$pageInfo',
581
+ },
582
+ } );
583
+
584
+ const invoiceList = await invoice.aggregate( pipeline );
585
+
586
+
587
+ if ( !invoiceList[0] ) {
588
+ return res.sendError( 'No data found', 204 );
589
+ }
590
+
591
+ function transformData( data ) {
592
+ const result = [];
593
+ const groups = {};
594
+
595
+ data.forEach( ( invoiceData ) => {
596
+ if ( invoiceData.paymentStatus === 'unpaid' ) {
597
+ const currentDate = dayjs();
598
+ const givenDate = dayjs( invoiceData.billingDate );
599
+ const daysDifference = currentDate.diff( givenDate, 'day' );
600
+ if ( daysDifference <= invoiceData.paymentTerm && daysDifference >= 0 ) {
601
+ invoiceData.paymentStatus = 'due';
602
+ } else {
603
+ invoiceData.paymentStatus = 'unpaid';
604
+ }
605
+ }
606
+ invoiceData.products = invoiceData.products.map( ( product ) => product.productName );
607
+ const tempProduct = new Set();
608
+ invoiceData.products.forEach( ( product ) => {
609
+ tempProduct.add( product );
610
+ } );
611
+ invoiceData.products = Array.from( tempProduct );
612
+
613
+ const billingDate = invoiceData.billingDate;
614
+
615
+ if ( !groups[billingDate] ) {
616
+ groups[billingDate] = {
617
+ summary: `Summary - ${dayjs( billingDate ).format( 'MMM YYYY' )}`,
618
+ products: new Set(),
619
+ stores: 0,
620
+ totalAmount: 0,
621
+ billingDate: billingDate,
622
+ invoices: [],
623
+ paymentStatus: invoiceData.paymentStatus,
624
+ };
625
+ }
626
+
627
+ groups[billingDate].invoices.push( invoiceData );
628
+ groups[billingDate].stores += invoiceData.stores;
629
+ groups[billingDate].totalAmount += invoiceData.totalAmount;
630
+
631
+ if ( invoiceData.paymentStatus === 'unpaid' ) {
632
+ const currentDate = dayjs();
633
+ const givenDate = dayjs( invoiceData.billingDate );
634
+ const daysDifference = currentDate.diff( givenDate, 'day' );
635
+ if ( daysDifference <= invoiceData.paymentTerm && daysDifference >= 0 ) {
636
+ groups[billingDate].paymentStatus = 'due';
637
+ } else {
638
+ groups[billingDate].paymentStatus = 'unpaid';
639
+ }
640
+ }
641
+
642
+ invoiceData.products.forEach( ( product ) => {
643
+ groups[billingDate].products.add( product );
644
+ } );
645
+ } );
646
+
647
+
648
+ // eslint-disable-next-line guard-for-in
649
+ for ( const billingDate in groups ) {
650
+ const group = groups[billingDate];
651
+ group.products = Array.from( group.products );
652
+ result.push( group );
653
+ }
654
+
655
+ return result;
656
+ }
657
+
658
+ invoiceList[0].data = transformData( invoiceList[0].data );
659
+
660
+
661
+ if ( req.body.isExport ) {
662
+ const exportResult = [];
663
+ for ( let invoice of invoiceList[0].data ) {
664
+ exportResult.push( {
665
+ 'Invoice': invoice.invoice||'',
666
+ 'Billing date': invoice.billingDate||'',
667
+ 'Total amount': invoice.totalAmount||'',
668
+ 'Store count': invoice.stores || '',
669
+ 'Status': invoice.paymentStatus||'',
670
+ 'Products': invoice.products.length ? invoice.products.join( ', ' ) : '',
671
+ } );
672
+ }
673
+ await download( exportResult, res );
674
+ return;
675
+ }
676
+ invoiceList[0].pageInfo['total'] = allInvoices;
677
+
678
+ return res.sendSuccess( invoiceList[0] );
679
+ } catch ( error ) {
680
+ logger.error( { error: error, function: 'subscribedStoreList' } );
681
+ return res.sendError( error, 500 );
682
+ }
683
+ };
684
+
445
685
 
@@ -1,8 +1,7 @@
1
- import { aggregatebilling } from '../services/billing.service.js';
2
1
  import * as invoiceService from '../services/invoice.service.js';
3
2
  import * as dailyPricingService from '../services/dailyPrice.service.js';
4
3
  import * as clientService from '../services/clientPayment.services.js';
5
- // import * as basePricingService from '../services/basePrice.service.js';
4
+ import * as billingService from '../services/billing.service.js';
6
5
  import dayjs from 'dayjs';
7
6
 
8
7
 
@@ -14,7 +13,7 @@ import htmlpdf from 'html-pdf-node';
14
13
  export async function createInvoice( req, res ) {
15
14
  try {
16
15
  for ( let client of req.body.clientList ) {
17
- let invoiceGroup = await aggregatebilling( [
16
+ let invoiceGroup = await billingService.aggregatebilling( [
18
17
  {
19
18
  $match: {
20
19
  clientId: client,
@@ -32,7 +31,6 @@ export async function createInvoice( req, res ) {
32
31
 
33
32
  let address = group.addressLineOne + group.addressLineTwo + group.city + ',' + group.state + ',' + group.country + ' -' + group.pinCode;
34
33
 
35
-
36
34
  const currentMonthDays = dayjs().daysInMonth();
37
35
  let products = await dailyPricingService.aggregate( [
38
36
  {
@@ -44,6 +42,17 @@ export async function createInvoice( req, res ) {
44
42
  $sort: { dateISO: -1 },
45
43
  },
46
44
  { $limit: 1 },
45
+ {
46
+ $project: {
47
+ stores: {
48
+ $filter: {
49
+ input: '$stores',
50
+ as: 'item',
51
+ cond: { $in: [ '$$item.storeId', group.stores ] },
52
+ },
53
+ },
54
+ },
55
+ },
47
56
  {
48
57
  $unwind: {
49
58
  path: '$stores',
@@ -63,6 +72,11 @@ export async function createInvoice( req, res ) {
63
72
  workingDays: '$stores.products.workingdays',
64
73
  },
65
74
  },
75
+ {
76
+ $match: {
77
+ workingDays: { $gt: 0 },
78
+ },
79
+ },
66
80
  {
67
81
  $group: {
68
82
  _id: {
@@ -244,6 +258,8 @@ export async function createInvoice( req, res ) {
244
258
  );
245
259
  }
246
260
  let data = {
261
+ groupName: group.groupName,
262
+ groupId: group._id,
247
263
  invoice: `INV-${Finacialyear}-${invoiceNo}`,
248
264
  products: products,
249
265
  status: 'pending',
@@ -332,6 +348,7 @@ export async function invoiceDownload( req, res ) {
332
348
  dueDate,
333
349
  };
334
350
  const currentMonthDays = dayjs().daysInMonth();
351
+ let getgroup = await billingService.findOne( { _id: invoiceInfo.groupId } );
335
352
  let annuxureData = await dailyPricingService.aggregate( [
336
353
  {
337
354
  $match: {
@@ -342,6 +359,17 @@ export async function invoiceDownload( req, res ) {
342
359
  $sort: { dateISO: -1 },
343
360
  },
344
361
  { $limit: 1 },
362
+ {
363
+ $project: {
364
+ stores: {
365
+ $filter: {
366
+ input: '$stores',
367
+ as: 'item',
368
+ cond: { $in: [ '$$item.storeId', getgroup.stores ] },
369
+ },
370
+ },
371
+ },
372
+ },
345
373
  {
346
374
  $unwind: {
347
375
  path: '$stores',
@@ -0,0 +1,18 @@
1
+
2
+ import { createOrder } from 'tango-app-api-middleware';
3
+
4
+
5
+ export const generateOrder = async ( req, res ) => {
6
+ try {
7
+ const order = await createOrder( { amount: req.body.amount, currency: req.body.currency } );
8
+
9
+ if ( !order ) {
10
+ return res.sendError( 'Failed to generate order id', 500 );
11
+ }
12
+
13
+ return res.sendSuccess( order );
14
+ } catch ( error ) {
15
+ logger.error( { error: error, function: 'getVirtualAccount' } );
16
+ return res.sendError( error, 500 );
17
+ }
18
+ };
@@ -10,6 +10,8 @@ import * as invoiceService from '../services/invoice.service.js';
10
10
  import * as userService from '../services/user.service.js';
11
11
  import * as dailyPriceService from '../services/dailyPrice.service.js';
12
12
  import * as cameraService from '../services/camera.service.js';
13
+ import * as billingService from '../services/billing.service.js';
14
+
13
15
  import dayjs from 'dayjs';
14
16
  import Handlebars from 'handlebars';
15
17
  import fs from 'fs';
@@ -2014,18 +2016,18 @@ export const invoiceList = async ( req, res ) => {
2014
2016
  item.billingDate = dayjs( item.billingDate ).format( 'DD MMM, YYYY' );
2015
2017
  if ( item.products?.length > 0 ) {
2016
2018
  let newProducts = [];
2017
- // for ( let productIndex = 0; productIndex < item.products.length; productIndex++ ) {
2018
- // let [ firstWord, secondWord ] = item.products[productIndex]?.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
2019
- // firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
2020
- // item.products[productIndex].productName = firstWord + ' ' + secondWord;
2021
- // newProducts.push( item.products[productIndex]?.productName );
2022
- // }
2023
2019
  for ( let productIndex = 0; productIndex < item.products.length; productIndex++ ) {
2024
- let [ firstWord, secondWord ] = item.products[productIndex]?.product?.product.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
2020
+ let [ firstWord, secondWord ] = item.products[productIndex]?.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
2025
2021
  firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
2026
- item.products[productIndex].product.product = firstWord + ' ' + secondWord;
2027
- newProducts.push( item.products[productIndex]?.product?.product );
2022
+ item.products[productIndex].productName = firstWord + ' ' + secondWord;
2023
+ newProducts.push( item.products[productIndex]?.productName );
2028
2024
  }
2025
+ // for ( let productIndex = 0; productIndex < item.products.length; productIndex++ ) {
2026
+ // let [ firstWord, secondWord ] = item.products[productIndex]?.product?.product.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
2027
+ // firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
2028
+ // item.products[productIndex].product.product = firstWord + ' ' + secondWord;
2029
+ // newProducts.push( item.products[productIndex]?.product?.product );
2030
+ // }
2029
2031
  item.productList = newProducts;
2030
2032
  }
2031
2033
  } );
@@ -3060,7 +3062,7 @@ export const dailyPricingInsert = async ( req, res ) => {
3060
3062
  let query = [
3061
3063
  {
3062
3064
  $match: {
3063
- clientId: requestClient[clientIndex],
3065
+ clientId: getClient.clientId,
3064
3066
  },
3065
3067
  },
3066
3068
  { $unwind: '$stores' },
@@ -3085,7 +3087,21 @@ export const dailyPricingInsert = async ( req, res ) => {
3085
3087
  let dailyData = await dailyPriceService.aggregate( query );
3086
3088
  let cameraDetails = await cameraService.find( { storeId: getStore[storeIndex].storeId, clientId: requestClient[clientIndex], isActivated: true, isUp: true }, { streamName: 1 } );
3087
3089
  let firstDate = dayjs( getStore[storeIndex]?.edge?.firstFileDate ).format( 'YYYY-MM-DD' );
3088
- let workingdays = ( firstDate < requestData.date && getStore[storeIndex]?.status == 'active' && dailyData[0]?.dateString != dayjs( requestData.date, 'YYYY-MM-DD' ).format( 'YYYY-MM-DD' ) ) ? ( dailyData.length && dailyData[0]?.stores?.daysDifference ) ? ( dailyData[0]?.stores?.daysDifference + 1 ) : 1 : dailyData[0]?.stores?.daysDifference ? dailyData[0]?.stores?.daysDifference : 0;
3090
+ let workingdays;
3091
+ if ( firstDate < requestData.date && getStore[storeIndex]?.status == 'active' &&
3092
+ dailyData[0]?.dateString != dayjs( requestData.date, 'YYYY-MM-DD' ).format( 'YYYY-MM-DD' ) ) {
3093
+ if ( dailyData.length && dailyData[0]?.stores?.daysDifference ) {
3094
+ workingdays = dailyData[0]?.stores?.daysDifference + 1;
3095
+ } else {
3096
+ workingdays = 1;
3097
+ }
3098
+ } else {
3099
+ if ( dailyData[0]?.stores?.daysDifference ) {
3100
+ workingdays = dailyData[0]?.stores?.daysDifference;
3101
+ } else {
3102
+ workingdays = 0;
3103
+ }
3104
+ }
3089
3105
  let priceDetails = getClient.priceType == 'standard' ? getBaseprice.standard : getBaseprice.step;
3090
3106
  for ( let storeProductIndex = 0; storeProductIndex < getStore[storeIndex].product.length; storeProductIndex++ ) {
3091
3107
  let productDetails;
@@ -3189,6 +3205,7 @@ export const dailyPricingInsertV1 = async ( req, res ) => {
3189
3205
  for ( let i=1; i<requestData.days; i++ ) {
3190
3206
  dayList.push( dayjs( requestData.date ).add( i, 'day' ).format( 'YYYY-MM-DD' ) );
3191
3207
  }
3208
+
3192
3209
  if ( requestData && requestClient.length > 0 ) {
3193
3210
  for ( let i=0; i<dayList.length; i++ ) {
3194
3211
  requestData.date = dayList[i];
@@ -3202,12 +3219,12 @@ export const dailyPricingInsertV1 = async ( req, res ) => {
3202
3219
  for ( let storeIndex = 0; storeIndex < getStore.length; storeIndex++ ) {
3203
3220
  let productList = [];
3204
3221
  if ( getBaseprice ) {
3205
- await axios.get( `${JSON.parse( process.env.URL ).oldapidomain}/processedDayData/getDailyData?clientId=${requestClient[clientIndex]}&storeId=${getStore[storeIndex].storeId}&date=${requestData.date}`, { headers: { Authorization: 'Bearer d47433f8-9a33-47c7-ba43-1a0fbac28f66' } } ).then( async ( response ) => {
3222
+ await axios.get( `https://api.tangoeye.in/v1/processedDayData/getDailyData?clientId=${requestClient[clientIndex]}&storeId=${getStore[storeIndex].storeId}&date=${requestData.date}`, { headers: { Authorization: 'Bearer d47433f8-9a33-47c7-ba43-1a0fbac28f66' } } ).then( async ( response ) => {
3206
3223
  let processedFileDate = response.data?.data?.firstFileDate || null;
3207
3224
  let query = [
3208
3225
  {
3209
3226
  $match: {
3210
- clientId: requestClient[clientIndex],
3227
+ clientId: getClient.clientId,
3211
3228
  },
3212
3229
  },
3213
3230
  { $unwind: '$stores' },
@@ -3232,7 +3249,21 @@ export const dailyPricingInsertV1 = async ( req, res ) => {
3232
3249
  let dailyData = await dailyPriceService.aggregate( query );
3233
3250
  let cameraDetails = await cameraService.find( { storeId: getStore[storeIndex].storeId, clientId: requestClient[clientIndex], isActivated: true, isUp: true }, { streamName: 1 } );
3234
3251
  let firstDate = dayjs( getStore[storeIndex]?.edge?.firstFileDate ).format( 'YYYY-MM-DD' );
3235
- let workingdays = ( firstDate < requestData.date && getStore[storeIndex]?.status == 'active' && dailyData[0]?.dateString != dayjs( requestData.date, 'YYYY-MM-DD' ).format( 'YYYY-MM-DD' ) ) ? ( dailyData.length && dailyData[0]?.stores?.daysDifference ) ? ( dailyData[0]?.stores?.daysDifference + 1 ) : 1 : dailyData[0]?.stores?.daysDifference ? dailyData[0]?.stores?.daysDifference : 0;
3252
+ let workingdays;
3253
+ if ( firstDate < requestData.date && getStore[storeIndex]?.status == 'active' &&
3254
+ dailyData[0]?.dateString != dayjs( requestData.date, 'YYYY-MM-DD' ).format( 'YYYY-MM-DD' ) ) {
3255
+ if ( dailyData.length && dailyData[0]?.stores?.daysDifference ) {
3256
+ workingdays = dailyData[0]?.stores?.daysDifference + 1;
3257
+ } else {
3258
+ workingdays = 1;
3259
+ }
3260
+ } else {
3261
+ if ( dailyData[0]?.stores?.daysDifference ) {
3262
+ workingdays = dailyData[0]?.stores?.daysDifference;
3263
+ } else {
3264
+ workingdays = 0;
3265
+ }
3266
+ }
3236
3267
  let priceDetails = getClient.priceType == 'standard' ? getBaseprice.standard : getBaseprice.step;
3237
3268
  for ( let storeProductIndex = 0; storeProductIndex < getStore[storeIndex].product.length; storeProductIndex++ ) {
3238
3269
  let productDetails;
@@ -3276,13 +3307,14 @@ export const dailyPricingInsertV1 = async ( req, res ) => {
3276
3307
  },
3277
3308
  );
3278
3309
  if ( storeIndex == getStore.length - 1 ) {
3310
+ let activestores = storeList.filter( ( store ) => store.status=='active' );
3279
3311
  let params = {
3280
3312
  clientId: requestClient[clientIndex],
3281
3313
  stores: storeList,
3282
3314
  dateISO: new Date( requestData.date ),
3283
3315
  accountType: getClient?.planDetails?.subscriptionType,
3284
3316
  status: getClient?.status,
3285
- activeStores: getStore?.length,
3317
+ activeStores: activestores?.length,
3286
3318
  brandName: getClient?.clientName,
3287
3319
  proRate: getClient?.paymentInvoice?.proRate,
3288
3320
  dateString: dayjs( requestData.date, 'YYYY-MM-DD' ).format( 'YYYY-MM-DD' ),
@@ -3676,3 +3708,34 @@ function convertTitleCase( data ) {
3676
3708
  }
3677
3709
 
3678
3710
 
3711
+ export async function createDefaultbillings( req, res ) {
3712
+ let clientlist = await paymentService.find( { 'status': 'active' } );
3713
+
3714
+ for ( let client of clientlist ) {
3715
+ let storeslist = await storeService.find( { clientId: client.clientId }, { storeId: 1 } );
3716
+ storeslist = storeslist.map( ( a ) => a.storeId );
3717
+ let payload = {
3718
+ clientId: client.clientId,
3719
+ registeredCompanyName: client.billingDetails.companyName,
3720
+ gst: client.billingDetails.gstNumber,
3721
+ addressLineOne: client.billingDetails.billingAddress,
3722
+ placeOfSupply: client.billingDetails.PlaceOfSupply,
3723
+ stores: storeslist,
3724
+ currency: client.paymentInvoice.currencyType,
3725
+ generateInvoiceTo: [ ...client.paymentInvoice.invoiceCC, ...client.paymentInvoice.invoiceCC.invoiceTo?client.paymentInvoice.invoiceCC.invoiceTo:[] ],
3726
+ isPrimary: true,
3727
+
3728
+ };
3729
+ await billingService.create( payload );
3730
+ }
3731
+ }
3732
+
3733
+
3734
+ export async function planDetails( req, res ) {
3735
+ try {
3736
+
3737
+ } catch ( error ) {
3738
+ logger.error( { error: error, function: 'planDetails' } );
3739
+ return res.sendError( error, 500 );
3740
+ }
3741
+ }
@@ -378,3 +378,26 @@ export const billingGroupBody = joi.object( {
378
378
  export const billingGroupSchema = {
379
379
  body: billingGroupBody,
380
380
  };
381
+
382
+ export const getVirtualAccountQuery = {
383
+ clientId: joi.string().required(),
384
+ };
385
+
386
+ export const getVirtualAccountSchema = {
387
+ query: getVirtualAccountQuery,
388
+ };
389
+
390
+ export const getInvoiceBody = joi.object( {
391
+ limit: joi.number().required(),
392
+ offset: joi.number().required(),
393
+ clientId: joi.string().required(),
394
+ sortColumn: joi.string().optional(),
395
+ sortBy: joi.number().optional(),
396
+ searchValue: joi.string().optional(),
397
+ isExport: joi.boolean().optional(),
398
+ filter: joi.string().optional(),
399
+ } );
400
+
401
+ export const getInvoiceSchema = {
402
+ body: getInvoiceBody,
403
+ };
@@ -1,8 +1,8 @@
1
1
  import express from 'express';
2
2
  export const billingRouter = express.Router();
3
3
  import { authorize, isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
4
- import { createBillingGroup, deleteBillingGroup, getAllBillingGroups, getBillingGroups, subscribedStoreList, updateBillingGroup } from '../controllers/billing.controllers.js';
5
- import { billingGroupSchema, createBillingGroupsSchema, deleteBillingGroupsSchema, getBillingGroupsSchema, subscribedStoreListSchema, updateBillingGroupsSchema } from '../dtos/validation.dtos.js';
4
+ import { createBillingGroup, deleteBillingGroup, getAllBillingGroups, getBillingGroups, getInvoices, getVirtualAccount, subscribedStoreList, updateBillingGroup } from '../controllers/billing.controllers.js';
5
+ import { billingGroupSchema, createBillingGroupsSchema, deleteBillingGroupsSchema, getBillingGroupsSchema, getInvoiceSchema, getVirtualAccountSchema, subscribedStoreListSchema, updateBillingGroupsSchema } from '../dtos/validation.dtos.js';
6
6
 
7
7
 
8
8
  billingRouter.post( '/get-subscribed-store-list', isAllowedSessionHandler, authorize( {
@@ -41,3 +41,15 @@ billingRouter.post( '/get-billing-groups', isAllowedSessionHandler, authorize( {
41
41
  ],
42
42
  } ), validate( billingGroupSchema ), getBillingGroups );
43
43
 
44
+ billingRouter.get( '/get-virtual-account', isAllowedSessionHandler, authorize( {
45
+ userType: [ 'tango' ], access: [
46
+ { featureName: 'settings', name: 'paymentSubscriptions', permissions: [ 'isView' ] },
47
+ ],
48
+ } ), validate( getVirtualAccountSchema ), getVirtualAccount );
49
+
50
+ billingRouter.post( '/get-invoices', isAllowedSessionHandler, authorize( {
51
+ userType: [ 'tango' ], access: [
52
+ { featureName: 'settings', name: 'paymentSubscriptions', permissions: [ 'isView' ] },
53
+ ],
54
+ } ), validate( getInvoiceSchema ), getInvoices );
55
+
@@ -0,0 +1,11 @@
1
+ import express from 'express';
2
+ export const paymentRouter = express.Router();
3
+ import { authorize, isAllowedSessionHandler } from 'tango-app-api-middleware';
4
+ import { generateOrder } from '../controllers/payment.controller.js';
5
+
6
+
7
+ paymentRouter.post( '/generate-order', isAllowedSessionHandler, authorize( {
8
+ userType: [ 'tango' ], access: [
9
+ { featureName: 'settings', name: 'paymentSubscriptions', permissions: [ 'isView' ] },
10
+ ],
11
+ } ), generateOrder );
@@ -165,4 +165,7 @@ paymentSubscriptionRouter.get( '/notificationList', isAllowedSessionHandler, val
165
165
  paymentSubscriptionRouter.put( '/notification/update/:notificationId', isAllowedSessionHandler, validate( validationDtos.validateId ), paymentController.updateNotification );
166
166
  paymentSubscriptionRouter.put( '/pushNotification/update/:notificationId', isAllowedSessionHandler, validate( validationDtos.validateId ), paymentController.updatePushNotification );
167
167
  paymentSubscriptionRouter.post( '/updateRemind/:notificationId', isAllowedSessionHandler, validate( validationDtos.validateId ), paymentController.updateRemind );
168
+ paymentSubscriptionRouter.post( '/createDefaultbillings', paymentController.createDefaultbillings );
169
+ paymentSubscriptionRouter.post( '/planDetails', isAllowedSessionHandler, paymentController.planDetails );
170
+
168
171
 
@@ -28,3 +28,7 @@ export const updateMany = ( query, record ) => {
28
28
  return model.billingModel.updateMany( query, record );
29
29
  };
30
30
 
31
+ export const countDocuments = ( query = {}, options = {} ) => {
32
+ return model.billingModel.countDocuments( query, options );
33
+ };
34
+
@@ -0,0 +1,7 @@
1
+
2
+
3
+ import model from 'tango-api-schema';
4
+
5
+ export const findOneAccount = ( query = {}, record = {} ) => {
6
+ return model.paymentAccountModel.findOne( query, record );
7
+ };