tango-app-api-infra 3.0.45-dev → 3.0.47-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/src/controllers/clientInfra.controller.js +4 -8
- package/src/controllers/infra.controllers.js +59 -14
- package/src/controllers/userInfra.controller.js +55 -5
- package/src/hbs/invoice.hbs +38 -43
- package/src/services/userAssignedStore.service.js +26 -0
- package/app.js +0 -41
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-infra",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.47-dev",
|
|
4
4
|
"description": "infra",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"start": "nodemon --exec \"eslint --fix . && node
|
|
8
|
+
"start": "nodemon --exec \"eslint --fix . && node index.js\""
|
|
9
9
|
},
|
|
10
10
|
"engines": {
|
|
11
11
|
"node": ">=18.10.0"
|
|
@@ -251,7 +251,6 @@ export async function infraIssuesTable( req, res ) {
|
|
|
251
251
|
$match: {
|
|
252
252
|
$and: [
|
|
253
253
|
{ issueType: 'infra' },
|
|
254
|
-
{ status: { $ne: 'closed' } },
|
|
255
254
|
{ 'basicDetails.clientId': { $in: req.body.clientId } },
|
|
256
255
|
{ 'ticketDetails.issueStatus': 'identified' },
|
|
257
256
|
{ createdAt: { $gte: date.start } },
|
|
@@ -368,16 +367,13 @@ export async function infraIssuesTable( req, res ) {
|
|
|
368
367
|
const exportdata = [];
|
|
369
368
|
result.forEach( ( element ) => {
|
|
370
369
|
exportdata.push( {
|
|
370
|
+
'CREATED AT': element.createdAt,
|
|
371
371
|
'STORE ID': element.storeId,
|
|
372
372
|
'STORE NAME': element.storeName,
|
|
373
|
+
'SUB ISSUE': element.secondaryIssue,
|
|
374
|
+
'ISSUE IDENTIFIED ON': element.issueIdentifiedDate,
|
|
375
|
+
'ISSUE CLOSED ON': element.issueClosedDate,
|
|
373
376
|
'STATUS': element.status,
|
|
374
|
-
'CITY': element.city,
|
|
375
|
-
'STATE': element.state,
|
|
376
|
-
'COUNTRY': element.country,
|
|
377
|
-
'SPOC EMAIL': element.spocEmail,
|
|
378
|
-
'SPOC CONTACT': element.spocContact,
|
|
379
|
-
'DOWNTIME': element.downTime,
|
|
380
|
-
'STATUS DETAIL': element.statusDetail,
|
|
381
377
|
} );
|
|
382
378
|
} );
|
|
383
379
|
await download( exportdata, res );
|
|
@@ -20,6 +20,7 @@ export async function createTicket( req, res ) {
|
|
|
20
20
|
req.body.ticketId = 'TE_INF_' + new Date().valueOf();
|
|
21
21
|
req.body.ticketActivity = [ {
|
|
22
22
|
actionType: 'defaultInfra',
|
|
23
|
+
timeStamp: new Date(),
|
|
23
24
|
actionBy: 'Tango',
|
|
24
25
|
IdentifiedBy: 'Tango',
|
|
25
26
|
} ];
|
|
@@ -123,6 +124,7 @@ export async function updateStatus( req, res ) {
|
|
|
123
124
|
if ( req.body.status == 'inprogress' ) {
|
|
124
125
|
req.body.ticketActivity.push( {
|
|
125
126
|
actionType: 'statusChange',
|
|
127
|
+
timeStamp: new Date(),
|
|
126
128
|
actionBy: 'Tango',
|
|
127
129
|
IdentifiedBy: req.user.userName,
|
|
128
130
|
} );
|
|
@@ -136,6 +138,7 @@ export async function updateStatus( req, res ) {
|
|
|
136
138
|
if ( req.body.status == 'inprogress' ) {
|
|
137
139
|
req.body.ticketActivity.push( {
|
|
138
140
|
actionType: 'statusChange',
|
|
141
|
+
timeStamp: new Date(),
|
|
139
142
|
actionBy: 'User',
|
|
140
143
|
IdentifiedBy: req.user.userName,
|
|
141
144
|
} );
|
|
@@ -256,6 +259,7 @@ export async function updateInstallationTicket( req, res ) {
|
|
|
256
259
|
req.body.ticketActivity.push( {
|
|
257
260
|
actionType: req.body.actionType,
|
|
258
261
|
actionBy: actionBy,
|
|
262
|
+
timeStamp: new Date(),
|
|
259
263
|
IdentifiedBy: actionBy == 'Tango' ? actionBy : req.user.userName,
|
|
260
264
|
} );
|
|
261
265
|
updateValue = { ticketActivity: req.body.ticketActivity };
|
|
@@ -301,6 +305,7 @@ export async function AlertTicketReply( req, res ) {
|
|
|
301
305
|
req.body.ticketActivity.push( {
|
|
302
306
|
actionType: 'statusCheckReply',
|
|
303
307
|
actionBy: 'User',
|
|
308
|
+
timeStamp: new Date(),
|
|
304
309
|
statusCheckReply: req.body.statusCheckReply,
|
|
305
310
|
IdentifiedBy: req.user.userName,
|
|
306
311
|
hibernationDays: req.body.hibernationDays,
|
|
@@ -308,6 +313,7 @@ export async function AlertTicketReply( req, res ) {
|
|
|
308
313
|
req.body.ticketActivity.push( {
|
|
309
314
|
actionType: 'statusCheckMonitor',
|
|
310
315
|
IdentifiedBy: 'Tango',
|
|
316
|
+
timeStamp: new Date(),
|
|
311
317
|
actionBy: 'Tango',
|
|
312
318
|
} );
|
|
313
319
|
await updateOneTangoTicket( { ticketId: req.body.ticketId }, { 'ticketActivity': req.body.ticketActivity } );
|
|
@@ -516,8 +522,9 @@ export async function saveInfraEmailConfig( req, res ) {
|
|
|
516
522
|
}
|
|
517
523
|
}
|
|
518
524
|
export async function invoice( req, res ) {
|
|
525
|
+
let filename = `${req.body.clientName}-${req.body.invoiceNo}-${req.body.month}.pdf`;
|
|
519
526
|
let options = {
|
|
520
|
-
path:
|
|
527
|
+
path: `../../invoice/${filename}`,
|
|
521
528
|
format: 'A4', margin: {
|
|
522
529
|
top: '0.5in',
|
|
523
530
|
right: '0.5in',
|
|
@@ -529,7 +536,6 @@ export async function invoice( req, res ) {
|
|
|
529
536
|
|
|
530
537
|
const fileContent = readFileSync( join() + '/src/hbs/invoice.hbs', 'utf8' );
|
|
531
538
|
handlebars.registerHelper( 'ifKeyExists', function( context, key, options ) {
|
|
532
|
-
console.log( context, key, options );
|
|
533
539
|
if ( context.hasOwnProperty( key ) ) {
|
|
534
540
|
return options.fn( context ); // invoking as function
|
|
535
541
|
} else {
|
|
@@ -540,34 +546,73 @@ export async function invoice( req, res ) {
|
|
|
540
546
|
|
|
541
547
|
req.body.subtotal = 0;
|
|
542
548
|
for ( const [ index, item ] of req.body.product.entries() ) {
|
|
543
|
-
item.Amount = item.Price * item.Stores;
|
|
549
|
+
item.Amount = ( item.Price * item.Stores );
|
|
550
|
+
item.Price = ( item.Price ).toFixed( 2 );
|
|
544
551
|
item.index = index + 1;
|
|
545
552
|
req.body.subtotal += item.Amount;
|
|
546
|
-
item.
|
|
553
|
+
item.Amount = item.Amount.toFixed( 2 );
|
|
554
|
+
item.Amount = numberWithCommas( item.Amount );
|
|
555
|
+
item.HSNnumber = req.body.HSNnumber;
|
|
547
556
|
}
|
|
548
557
|
req.body.totaltax = 0;
|
|
549
558
|
if ( req.body.tax.length > 0 ) {
|
|
550
559
|
for ( let element of req.body.tax ) {
|
|
551
560
|
element.taxAmount = ( ( req.body.subtotal / 100 ) * element.value ).toFixed( 2 );
|
|
552
561
|
req.body.totaltax += Number( element.taxAmount );
|
|
562
|
+
element.taxAmount = numberWithCommas( element.taxAmount );
|
|
553
563
|
}
|
|
554
564
|
};
|
|
555
|
-
|
|
565
|
+
|
|
566
|
+
req.body.total = ( Number( req.body.totaltax ) + Number( req.body.subtotal ) ).toFixed( 2 );
|
|
567
|
+
req.body.amountwords = inWords( ( Math.round( req.body.total ) ) );
|
|
568
|
+
req.body.subtotal = ( req.body.subtotal ).toFixed( 2 );
|
|
569
|
+
|
|
570
|
+
req.body.subtotal = numberWithCommas( req.body.subtotal );
|
|
571
|
+
req.body.total = numberWithCommas( req.body.total );
|
|
556
572
|
|
|
557
573
|
const html = htmlContent( { ...req.body } );
|
|
558
574
|
|
|
559
575
|
let file = {
|
|
560
576
|
content: html,
|
|
561
577
|
};
|
|
562
|
-
|
|
578
|
+
function numberWithCommas( x ) {
|
|
579
|
+
return ( x.toString().replace( /,/g, '' ).replace( /\B(?=(\d{3})+(?!\d))/g, ',' ) );
|
|
580
|
+
}
|
|
563
581
|
htmlpdf.generatePdf( file, options ).then( async function( pdfBuffer ) {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
582
|
+
let mailSubject = `Invoice for ${req.body.month} - Tango/${req.body.clientName}`;
|
|
583
|
+
let mailbody = `<div>Dear Team,</div>
|
|
584
|
+
<div style="margin-top:10px">
|
|
585
|
+
Please find the attached Invoice for the month of ${req.body.month}.
|
|
586
|
+
</div>
|
|
587
|
+
<div style="margin-top:10px">
|
|
588
|
+
Best Regards,
|
|
589
|
+
</div>
|
|
590
|
+
<div style="margin-top:5px">
|
|
591
|
+
Finance
|
|
592
|
+
</div>`;
|
|
593
|
+
let commonmail = [ 'balaji@tangotech.co.in', 'rashmi@tangotech.co.in', 'aju@tangotech.co.in' ];
|
|
594
|
+
req.body.ccEmail = [ ...req.body.ccEmail, ...commonmail ];
|
|
595
|
+
let attachments = {
|
|
596
|
+
filename: `${filename}`,
|
|
597
|
+
content: pdfBuffer,
|
|
598
|
+
contentType: 'application/pdf', // e.g., 'application/pdf'
|
|
599
|
+
};
|
|
600
|
+
const result = await sendEmailWithSES( req.body.toEmail, req.body.ccEmail, mailSubject, mailbody, attachments, 'no-reply@tangotech.ai' );
|
|
601
|
+
res.sendSuccess( result );
|
|
572
602
|
} );
|
|
573
603
|
}
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
function inWords( num ) {
|
|
607
|
+
let a = [ '', 'one ', 'two ', 'three ', 'four ', 'five ', 'six ', 'seven ', 'eight ', 'nine ', 'ten ', 'eleven ', 'twelve ', 'thirteen ', 'fourteen ', 'fifteen ', 'sixteen ', 'seventeen ', 'eighteen ', 'nineteen ' ]; let b = [ '', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety' ];
|
|
608
|
+
if ( ( num = num.toString() ).length > 9 ) return 'overflow';
|
|
609
|
+
let n = ( '000000000' + num ).substr( -9 ).match( /^(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})$/ );
|
|
610
|
+
if ( !n ) return; let str = '';
|
|
611
|
+
str += ( n[1] != 0 ) ? ( a[Number( n[1] )] || b[n[1][0]] + ' ' + a[n[1][1]] ) + 'crore ' : '';
|
|
612
|
+
str += ( n[2] != 0 ) ? ( a[Number( n[2] )] || b[n[2][0]] + ' ' + a[n[2][1]] ) + 'lakh ' : '';
|
|
613
|
+
str += ( n[3] != 0 ) ? ( a[Number( n[3] )] || b[n[3][0]] + ' ' + a[n[3][1]] ) + 'thousand ' : '';
|
|
614
|
+
str += ( n[4] != 0 ) ? ( a[Number( n[4] )] || b[n[4][0]] + ' ' + a[n[4][1]] ) + 'hundred ' : '';
|
|
615
|
+
str += ( n[5] != 0 ) ? ( ( str != '' ) ? 'and ' : '' ) + ( a[Number( n[5] )] || b[n[5][0]] + ' ' + a[n[5][1]] ) : '';
|
|
616
|
+
|
|
617
|
+
return str.toLowerCase().split( ' ' ).map( ( word ) => word.charAt( 0 ).toUpperCase() + word.slice( 1 ) ).join( ' ' );
|
|
618
|
+
}
|
|
@@ -4,22 +4,72 @@ import { logger, download, getUTC } from 'tango-app-api-middleware';
|
|
|
4
4
|
import { findOneUser } from '../services/user.service.js';
|
|
5
5
|
import { aggregateStore } from '../services/store.service.js';
|
|
6
6
|
import { findOneGroup } from '../services/group.service.js';
|
|
7
|
-
|
|
7
|
+
import { findUserAssignedStore } from '../services/userAssignedStore.service.js';
|
|
8
8
|
import mongoose from 'mongoose';
|
|
9
9
|
import dayjs from 'dayjs';
|
|
10
10
|
|
|
11
11
|
export async function userTakeTicket( req, res ) {
|
|
12
12
|
try {
|
|
13
|
+
let assignedClients = [];
|
|
14
|
+
if ( req.user.role != 'superadmin' ) {
|
|
15
|
+
let userAssignedclient = await findUserAssignedStore( { userEmail: req.user.email }, { clientId: 1 } );
|
|
16
|
+
if ( userAssignedclient.length == 0 ) {
|
|
17
|
+
return res.sendError( 'No clients assigned for the user', 201 );
|
|
18
|
+
}
|
|
19
|
+
for ( let client of userAssignedclient ) {
|
|
20
|
+
assignedClients.push( client.clientId );
|
|
21
|
+
}
|
|
22
|
+
}
|
|
13
23
|
let userTicket = '';
|
|
14
24
|
if ( req.body.issueType == 'infra' ) {
|
|
15
|
-
|
|
25
|
+
let query = {
|
|
26
|
+
'status': { $ne: 'closed' },
|
|
27
|
+
'issueType': 'infra', 'ticketDetails.assigntoUser': true,
|
|
28
|
+
'ticketDetails.addressingUser': { $exists: false },
|
|
29
|
+
'ticketDetails.issueStatus': 'notidentified',
|
|
30
|
+
'ticketDetails.addressingClient': { $exists: false },
|
|
31
|
+
};
|
|
32
|
+
if ( assignedClients.length > 0 ) {
|
|
33
|
+
query =( { ...query, ...{ 'basicDetails.clientId': { $in: assignedClients } } } );
|
|
34
|
+
}
|
|
35
|
+
userTicket = await findOneTangoTicket( query );
|
|
36
|
+
|
|
16
37
|
if ( !userTicket ) {
|
|
17
|
-
|
|
38
|
+
let query = {
|
|
39
|
+
'status': { $ne: 'closed' },
|
|
40
|
+
'basicDetails.clientId': { $in: assignedClients },
|
|
41
|
+
'issueType': 'infra',
|
|
42
|
+
'ticketType': 'refreshticket',
|
|
43
|
+
'ticketDetails.refreshTicketStatus': 'notidentified',
|
|
44
|
+
};
|
|
45
|
+
if ( assignedClients.length > 0 ) {
|
|
46
|
+
query =( { ...query, ...{ 'basicDetails.clientId': { $in: assignedClients } } } );
|
|
47
|
+
}
|
|
48
|
+
userTicket = await findOneTangoTicket( query );
|
|
18
49
|
}
|
|
19
50
|
} else if ( req.body.issueType == 'installation' ) {
|
|
20
|
-
|
|
51
|
+
let query = {
|
|
52
|
+
'status': { $ne: 'closed' },
|
|
53
|
+
'issueType': 'installation',
|
|
54
|
+
'ticketDetails.addressingUser': { $exists: false },
|
|
55
|
+
'ticketDetails.issueStatus': 'notidentified',
|
|
56
|
+
'ticketDetails.addressingClient': { $exists: false },
|
|
57
|
+
};
|
|
58
|
+
if ( assignedClients.length > 0 ) {
|
|
59
|
+
query =( { ...query, ...{ 'basicDetails.clientId': { $in: assignedClients } } } );
|
|
60
|
+
}
|
|
61
|
+
userTicket = await findOneTangoTicket( query );
|
|
21
62
|
if ( !userTicket ) {
|
|
22
|
-
|
|
63
|
+
let query = {
|
|
64
|
+
'status': { $ne: 'closed' },
|
|
65
|
+
'issueType': 'installation',
|
|
66
|
+
'ticketType': 'refreshticket',
|
|
67
|
+
'ticketDetails.refreshTicketStatus': 'notidentified',
|
|
68
|
+
};
|
|
69
|
+
if ( assignedClients.length > 0 ) {
|
|
70
|
+
query =( { ...query, ...{ 'basicDetails.clientId': { $in: assignedClients } } } );
|
|
71
|
+
}
|
|
72
|
+
userTicket = await findOneTangoTicket( query );
|
|
23
73
|
}
|
|
24
74
|
}
|
|
25
75
|
if ( userTicket ) {
|
package/src/hbs/invoice.hbs
CHANGED
|
@@ -458,12 +458,12 @@
|
|
|
458
458
|
font-family: var(--text-md-medium-font-family, "Inter-Medium", sans-serif);
|
|
459
459
|
font-size: var(--text-md-medium-font-size, 16px);
|
|
460
460
|
line-height: var(--text-md-medium-line-height, 24px);
|
|
461
|
-
font-weight: var(--text-md-medium-font-weight,
|
|
461
|
+
font-weight: var(--text-md-medium-font-weight, 600);
|
|
462
462
|
position: relative;
|
|
463
463
|
}
|
|
464
464
|
|
|
465
465
|
.billing-address-given-by-the-client-flat-no-012-ground-floor-the-banyan-apartment-jsr-layout-j-p-nagar-9th-phase-alahalli-anjanapura-post-bengaluru-560062-karnataka-india {
|
|
466
|
-
color: var(--gray-
|
|
466
|
+
color: var(--gray-900, #344054);
|
|
467
467
|
text-align: left;
|
|
468
468
|
font-family: var(--text-md-regular-font-family, "Inter-Regular", sans-serif);
|
|
469
469
|
font-size: var(--text-md-regular-font-size, 16px);
|
|
@@ -620,7 +620,7 @@
|
|
|
620
620
|
color: var(--gray-800, #1d2939);
|
|
621
621
|
text-align: left;
|
|
622
622
|
font-family: var(--text-md-medium-font-family, "Inter-Medium", sans-serif);
|
|
623
|
-
font-size: var(--text-md-medium-font-size,
|
|
623
|
+
font-size: var(--text-md-medium-font-size, 14px);
|
|
624
624
|
line-height: var(--text-md-medium-line-height, 24px);
|
|
625
625
|
font-weight: var(--text-md-medium-font-weight, 500);
|
|
626
626
|
position: relative;
|
|
@@ -655,7 +655,7 @@
|
|
|
655
655
|
border-style: solid;
|
|
656
656
|
border-color: var(--gray-200, #eaecf0);
|
|
657
657
|
border-width: 0px 0px 1px 0px;
|
|
658
|
-
|
|
658
|
+
|
|
659
659
|
display: flex;
|
|
660
660
|
flex-direction: row;
|
|
661
661
|
gap: 0px;
|
|
@@ -688,7 +688,7 @@
|
|
|
688
688
|
border-style: solid;
|
|
689
689
|
border-color: var(--gray-200, #eaecf0);
|
|
690
690
|
border-width: 0px 0px 1px 0px;
|
|
691
|
-
|
|
691
|
+
|
|
692
692
|
display: flex;
|
|
693
693
|
flex-direction: column;
|
|
694
694
|
gap: 0px;
|
|
@@ -703,7 +703,7 @@
|
|
|
703
703
|
color: var(--gray-900, #101828);
|
|
704
704
|
text-align: left;
|
|
705
705
|
font-family: var(--text-md-medium-font-family, "Inter-Medium", sans-serif);
|
|
706
|
-
font-size: var(--text-md-medium-font-size,
|
|
706
|
+
font-size: var(--text-md-medium-font-size, 14px);
|
|
707
707
|
line-height: var(--text-md-medium-line-height, 24px);
|
|
708
708
|
font-weight: var(--text-md-medium-font-weight, 500);
|
|
709
709
|
position: relative;
|
|
@@ -713,8 +713,8 @@
|
|
|
713
713
|
color: var(--gray-500, #667085);
|
|
714
714
|
text-align: left;
|
|
715
715
|
font-family: var(--text-md-medium-font-family, "Inter-Medium", sans-serif);
|
|
716
|
-
font-size: var(--text-md-medium-font-size,
|
|
717
|
-
|
|
716
|
+
font-size: var(--text-md-medium-font-size, 14px);
|
|
717
|
+
|
|
718
718
|
font-weight: var(--text-md-medium-font-weight, 500);
|
|
719
719
|
position: relative;
|
|
720
720
|
width: 266px;
|
|
@@ -743,9 +743,9 @@
|
|
|
743
743
|
|
|
744
744
|
.text6 {
|
|
745
745
|
color: var(--gray-800, #1d2939);
|
|
746
|
-
text-align:
|
|
746
|
+
text-align: center;
|
|
747
747
|
font-family: var(--text-md-medium-font-family, "Inter-Medium", sans-serif);
|
|
748
|
-
font-size: var(--text-md-medium-font-size,
|
|
748
|
+
font-size: var(--text-md-medium-font-size, 14px);
|
|
749
749
|
line-height: var(--text-md-medium-line-height, 24px);
|
|
750
750
|
font-weight: var(--text-md-medium-font-weight, 500);
|
|
751
751
|
position: relative;
|
|
@@ -756,7 +756,7 @@
|
|
|
756
756
|
border-style: solid;
|
|
757
757
|
border-color: var(--gray-200, #eaecf0);
|
|
758
758
|
border-width: 0px 0px 1px 0px;
|
|
759
|
-
|
|
759
|
+
|
|
760
760
|
display: flex;
|
|
761
761
|
flex-direction: column;
|
|
762
762
|
gap: 0px;
|
|
@@ -769,7 +769,7 @@
|
|
|
769
769
|
|
|
770
770
|
.text7 {
|
|
771
771
|
color: var(--gray-900, #101828);
|
|
772
|
-
text-align:
|
|
772
|
+
text-align: center;
|
|
773
773
|
font-family: var(--text-md-medium-font-family, "Inter-Medium", sans-serif);
|
|
774
774
|
font-size: var(--text-md-medium-font-size, 16px);
|
|
775
775
|
line-height: var(--text-md-medium-line-height, 24px);
|
|
@@ -782,7 +782,7 @@
|
|
|
782
782
|
border-style: solid;
|
|
783
783
|
border-color: var(--gray-200, #eaecf0);
|
|
784
784
|
border-width: 0px 0px 1px 0px;
|
|
785
|
-
|
|
785
|
+
|
|
786
786
|
display: flex;
|
|
787
787
|
flex-direction: column;
|
|
788
788
|
gap: 0px;
|
|
@@ -798,7 +798,6 @@
|
|
|
798
798
|
border-style: solid;
|
|
799
799
|
border-color: var(--gray-200, #eaecf0);
|
|
800
800
|
border-width: 0px 0px 1px 0px;
|
|
801
|
-
padding: 16px 24px 16px 24px;
|
|
802
801
|
display: flex;
|
|
803
802
|
flex-direction: row;
|
|
804
803
|
gap: 0px;
|
|
@@ -811,7 +810,7 @@
|
|
|
811
810
|
|
|
812
811
|
.text8 {
|
|
813
812
|
color: var(--gray-900, #101828);
|
|
814
|
-
text-align:
|
|
813
|
+
text-align: center;
|
|
815
814
|
font-family: var(--text-md-medium-font-family, "Inter-Medium", sans-serif);
|
|
816
815
|
font-size: var(--text-md-medium-font-size, 16px);
|
|
817
816
|
line-height: var(--text-md-medium-line-height, 24px);
|
|
@@ -1226,17 +1225,15 @@
|
|
|
1226
1225
|
flex-shrink: 0;
|
|
1227
1226
|
position: relative;
|
|
1228
1227
|
}
|
|
1229
|
-
|
|
1230
1228
|
.authorized-signature {
|
|
1231
|
-
color: var(--
|
|
1232
|
-
text-align: left;
|
|
1229
|
+
color: var(--Gray-500, #667085);
|
|
1233
1230
|
font-family: var(--text-xl-semibold-font-family,
|
|
1234
1231
|
"Inter-SemiBold",
|
|
1235
|
-
sans-serif);
|
|
1236
|
-
font-size:
|
|
1237
|
-
|
|
1238
|
-
font-weight:
|
|
1239
|
-
|
|
1232
|
+
sans-serif) !important;
|
|
1233
|
+
font-size: 16px;
|
|
1234
|
+
font-style: normal;
|
|
1235
|
+
font-weight: 500;
|
|
1236
|
+
line-height: 24px;
|
|
1240
1237
|
}
|
|
1241
1238
|
|
|
1242
1239
|
.div {
|
|
@@ -1299,7 +1296,7 @@
|
|
|
1299
1296
|
<div class="frame-55">
|
|
1300
1297
|
<div class="frame-53">
|
|
1301
1298
|
<div class="tango-it-solutions-india-private-ltd">
|
|
1302
|
-
|
|
1299
|
+
TANGO IT SOLUTIONS INDIA PRIVATE LTD
|
|
1303
1300
|
</div>
|
|
1304
1301
|
</div>
|
|
1305
1302
|
<div class="frame-9158">
|
|
@@ -1372,9 +1369,7 @@
|
|
|
1372
1369
|
{{companyAddress}}
|
|
1373
1370
|
</div>
|
|
1374
1371
|
<div class="frame-562">
|
|
1375
|
-
|
|
1376
|
-
GSTIN 33AAFCI2595G1Z9
|
|
1377
|
-
</div> -->
|
|
1372
|
+
<div class="gstin-33-aafci-2595-g-1-z-9"> GSTIN {{GSTNumber}}</div>
|
|
1378
1373
|
</div>
|
|
1379
1374
|
</div>
|
|
1380
1375
|
</div>
|
|
@@ -1410,11 +1405,11 @@
|
|
|
1410
1405
|
<div class="text2">#</div>
|
|
1411
1406
|
</div>
|
|
1412
1407
|
</div>
|
|
1413
|
-
|
|
1408
|
+
{{#each product}}
|
|
1414
1409
|
<div class="table-cell">
|
|
1415
1410
|
<div class="text3">{{index}}</div>
|
|
1416
1411
|
</div>
|
|
1417
|
-
|
|
1412
|
+
{{/each}}
|
|
1418
1413
|
|
|
1419
1414
|
</div>
|
|
1420
1415
|
<div class="column">
|
|
@@ -1424,7 +1419,7 @@
|
|
|
1424
1419
|
</div>
|
|
1425
1420
|
</div>
|
|
1426
1421
|
{{#each product}}
|
|
1427
|
-
<div class="table-cell3" style="padding:
|
|
1422
|
+
<div class="table-cell3" style="padding:20px 24px 26px 24px;height:90px !important;">
|
|
1428
1423
|
<div class="text4">{{name}}</div>
|
|
1429
1424
|
<div class="text5">{{description}}</div>
|
|
1430
1425
|
</div>
|
|
@@ -1489,7 +1484,7 @@
|
|
|
1489
1484
|
<div class="table-cell6">
|
|
1490
1485
|
<div class="text8">{{currency}} {{Amount}}</div>
|
|
1491
1486
|
</div>
|
|
1492
|
-
|
|
1487
|
+
{{/each}}
|
|
1493
1488
|
|
|
1494
1489
|
</div>
|
|
1495
1490
|
</div>
|
|
@@ -1507,7 +1502,7 @@
|
|
|
1507
1502
|
<div class="text10">{{currency}} {{taxAmount}}</div>
|
|
1508
1503
|
</div>
|
|
1509
1504
|
</div>
|
|
1510
|
-
|
|
1505
|
+
{{/each }}
|
|
1511
1506
|
<!-- <div class="frame-2398">
|
|
1512
1507
|
<div class="text9">CGST (9%)</div>
|
|
1513
1508
|
<div class="frame-9157">
|
|
@@ -1523,14 +1518,14 @@
|
|
|
1523
1518
|
<div class="text12">{{currency}} {{total}}</div>
|
|
1524
1519
|
</div>
|
|
1525
1520
|
</div>
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1521
|
+
<div class="frame-23973">
|
|
1522
|
+
<div class="text11">Total In Words</div>
|
|
1523
|
+
<div class="frame-9157">
|
|
1524
|
+
<div class="text13">
|
|
1525
|
+
{{currencyName}} {{amountwords}} Only
|
|
1526
|
+
</div>
|
|
1527
|
+
</div>
|
|
1528
|
+
</div>
|
|
1534
1529
|
</div>
|
|
1535
1530
|
</div>
|
|
1536
1531
|
</div>
|
|
@@ -1555,7 +1550,7 @@
|
|
|
1555
1550
|
</div>
|
|
1556
1551
|
<div class="frame-532">
|
|
1557
1552
|
<div class="payment-type">Payment Type</div>
|
|
1558
|
-
<div class="virtual-acc">
|
|
1553
|
+
<div class="virtual-acc">{{paymentType}}</div>
|
|
1559
1554
|
</div>
|
|
1560
1555
|
</div>
|
|
1561
1556
|
<div class="frame-563">
|
|
@@ -1571,8 +1566,8 @@
|
|
|
1571
1566
|
</div>
|
|
1572
1567
|
</div>
|
|
1573
1568
|
<div class="frame-9161" style="margin-top:70px">
|
|
1574
|
-
<div class="authorized-signature">
|
|
1575
|
-
<div class="div">_________________________________</div>
|
|
1569
|
+
<div class="authorized-signature">This is a system generated invoice. No signature required</div>
|
|
1570
|
+
{{!-- <div class="div">_________________________________</div> --}}
|
|
1576
1571
|
</div>
|
|
1577
1572
|
</div>
|
|
1578
1573
|
</div>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
import userAssignedStoreModel from 'tango-api-schema/schema/userAssignedStore.model.js';
|
|
3
|
+
|
|
4
|
+
export async function countDocumentsUserAssignedStore( query ) {
|
|
5
|
+
return userAssignedStoreModel.countDocuments( query );
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export async function createAssignedStore( query ) {
|
|
9
|
+
return userAssignedStoreModel.create( query );
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function deleteManyuserAssignedStore( query ) {
|
|
13
|
+
return userAssignedStoreModel.deleteMany( query );
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function aggregateUserAssignedStore( query ) {
|
|
17
|
+
return userAssignedStoreModel.aggregate( query );
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function findUserAssignedStore( query, fields={} ) {
|
|
21
|
+
try {
|
|
22
|
+
return userAssignedStoreModel.find( query, fields );
|
|
23
|
+
} catch ( error ) {
|
|
24
|
+
return error;
|
|
25
|
+
}
|
|
26
|
+
}
|
package/app.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import express from 'express';
|
|
3
|
-
import { infraRouter, internalInfraRouter, userInfraRouter, storeInfraRouter, clientInfraRouter } from './index.js';
|
|
4
|
-
import dotenv from 'dotenv';
|
|
5
|
-
import responseMiddleware from './config/response/response.js';
|
|
6
|
-
import errorMiddleware from './config/response/error.js';
|
|
7
|
-
import { connectdb } from './config/database/database.js';
|
|
8
|
-
import pkg from 'body-parser';
|
|
9
|
-
import cors from 'cors';
|
|
10
|
-
const { json, urlencoded } = pkg;
|
|
11
|
-
import fileUpload from 'express-fileupload';
|
|
12
|
-
const env=dotenv.config();
|
|
13
|
-
const app = express();
|
|
14
|
-
const PORT = process.env.PORT || 3000;
|
|
15
|
-
app.use( fileUpload() );
|
|
16
|
-
|
|
17
|
-
if ( env.error ) {
|
|
18
|
-
logger.error( '.env not found' );
|
|
19
|
-
process.exit( 1 );
|
|
20
|
-
}
|
|
21
|
-
app.use( json( { limit: '500mb' } ) );
|
|
22
|
-
app.use(
|
|
23
|
-
urlencoded( {
|
|
24
|
-
extended: true,
|
|
25
|
-
} ),
|
|
26
|
-
);
|
|
27
|
-
app.use( cors() );
|
|
28
|
-
app.use( responseMiddleware );
|
|
29
|
-
app.use( errorMiddleware );
|
|
30
|
-
app.use( '/infra', infraRouter );
|
|
31
|
-
app.use( '/internalInfra', internalInfraRouter );
|
|
32
|
-
app.use( '/userInfra', userInfraRouter );
|
|
33
|
-
app.use( '/storeInfra', storeInfraRouter );
|
|
34
|
-
app.use( '/clientInfra', clientInfraRouter );
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
app.listen( PORT, () => {
|
|
38
|
-
console.log( `server is running on port= ${PORT} ` );
|
|
39
|
-
connectdb();
|
|
40
|
-
} );
|
|
41
|
-
|