@awadheshs109/billing 1.0.29 → 2.0.12
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/README.md +136 -132
- package/dist/index.d.mts +128 -46
- package/dist/index.d.ts +128 -46
- package/dist/index.js +941 -106
- package/dist/index.mjs +928 -106
- package/package.json +14 -8
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -25,7 +35,10 @@ __export(index_exports, {
|
|
|
25
35
|
InvoiceCalculator: () => InvoiceCalculator,
|
|
26
36
|
InvoiceError: () => InvoiceError,
|
|
27
37
|
InvoiceGenerator: () => InvoiceGenerator,
|
|
38
|
+
InvoiceNormalizer: () => InvoiceNormalizer,
|
|
39
|
+
InvoiceRenderer: () => InvoiceRenderer,
|
|
28
40
|
TAX_RATES: () => TAX_RATES,
|
|
41
|
+
VERSION: () => VERSION,
|
|
29
42
|
ValidationError: () => ValidationError,
|
|
30
43
|
calculateDiscount: () => calculateDiscount,
|
|
31
44
|
calculateGST: () => calculateGST,
|
|
@@ -118,13 +131,22 @@ var InvoiceCalculator = class {
|
|
|
118
131
|
0
|
|
119
132
|
);
|
|
120
133
|
const discountAmount = subtotal * (discount / 100);
|
|
121
|
-
const
|
|
122
|
-
const taxAmount =
|
|
134
|
+
const taxableAmount = subtotal - discountAmount;
|
|
135
|
+
const taxAmount = taxableAmount * (tax / 100);
|
|
136
|
+
const total = taxableAmount + taxAmount;
|
|
123
137
|
return {
|
|
124
|
-
subtotal
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
138
|
+
subtotal: Number(
|
|
139
|
+
subtotal.toFixed(2)
|
|
140
|
+
),
|
|
141
|
+
taxAmount: Number(
|
|
142
|
+
taxAmount.toFixed(2)
|
|
143
|
+
),
|
|
144
|
+
discountAmount: Number(
|
|
145
|
+
discountAmount.toFixed(2)
|
|
146
|
+
),
|
|
147
|
+
total: Number(
|
|
148
|
+
total.toFixed(2)
|
|
149
|
+
)
|
|
128
150
|
};
|
|
129
151
|
}
|
|
130
152
|
};
|
|
@@ -132,7 +154,7 @@ var InvoiceCalculator = class {
|
|
|
132
154
|
// src/core/billing.ts
|
|
133
155
|
var Billing = class {
|
|
134
156
|
static getVersion() {
|
|
135
|
-
return "
|
|
157
|
+
return "2.0.1";
|
|
136
158
|
}
|
|
137
159
|
};
|
|
138
160
|
Billing.calculateGST = calculateGST;
|
|
@@ -141,6 +163,14 @@ Billing.calculateDiscount = calculateDiscount;
|
|
|
141
163
|
Billing.formatCurrency = formatCurrency;
|
|
142
164
|
Billing.InvoiceCalculator = InvoiceCalculator;
|
|
143
165
|
|
|
166
|
+
// src/constants/tax-rates.ts
|
|
167
|
+
var TAX_RATES = {
|
|
168
|
+
GST_5: 5,
|
|
169
|
+
GST_12: 12,
|
|
170
|
+
GST_18: 18,
|
|
171
|
+
GST_28: 28
|
|
172
|
+
};
|
|
173
|
+
|
|
144
174
|
// src/utils/date.ts
|
|
145
175
|
function formatDate(date = /* @__PURE__ */ new Date(), locale = "en-IN") {
|
|
146
176
|
return new Intl.DateTimeFormat(locale, {
|
|
@@ -164,135 +194,891 @@ function isValidGST(gst) {
|
|
|
164
194
|
return /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/i.test(gst);
|
|
165
195
|
}
|
|
166
196
|
|
|
167
|
-
// src/
|
|
168
|
-
var
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
197
|
+
// src/config/default-invoice-config.ts
|
|
198
|
+
var defaultInvoiceConfig = {
|
|
199
|
+
currency: "INR",
|
|
200
|
+
tax: 0,
|
|
201
|
+
discount: 0,
|
|
202
|
+
company: {
|
|
203
|
+
name: "",
|
|
204
|
+
address: "",
|
|
205
|
+
phone: ""
|
|
206
|
+
},
|
|
207
|
+
customer: {
|
|
208
|
+
name: "",
|
|
209
|
+
email: ""
|
|
210
|
+
},
|
|
211
|
+
features: {
|
|
212
|
+
showSellerGST: true,
|
|
213
|
+
showBuyerGST: true,
|
|
214
|
+
showPAN: true,
|
|
215
|
+
showTransport: true,
|
|
216
|
+
showEWay: true,
|
|
217
|
+
showBankDetails: true,
|
|
218
|
+
showTerms: true,
|
|
219
|
+
showSignature: true,
|
|
220
|
+
showSoftwareCredit: true,
|
|
221
|
+
showBranchDetails: true,
|
|
222
|
+
showPaymentDetails: true,
|
|
223
|
+
showPaymentTransactions: true,
|
|
224
|
+
showAmountWords: true
|
|
225
|
+
},
|
|
226
|
+
branding: {
|
|
227
|
+
showSoftwareCredit: true,
|
|
228
|
+
softwareCreditText: "Generated using Zentris Billing",
|
|
229
|
+
logoText: "ZENTRIS",
|
|
230
|
+
logoSubText: "Billing Engine"
|
|
231
|
+
},
|
|
232
|
+
theme: {
|
|
233
|
+
primaryColor: "#221b67",
|
|
234
|
+
accentColor: "#009688"
|
|
235
|
+
}
|
|
173
236
|
};
|
|
174
237
|
|
|
175
|
-
// src/
|
|
176
|
-
var
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
238
|
+
// src/normalizers/invoice-normalizer.ts
|
|
239
|
+
var InvoiceNormalizer = class {
|
|
240
|
+
static normalize(invoice) {
|
|
241
|
+
return {
|
|
242
|
+
...defaultInvoiceConfig,
|
|
243
|
+
...invoice,
|
|
244
|
+
items: invoice.items || [],
|
|
245
|
+
company: {
|
|
246
|
+
name: invoice.company?.name || defaultInvoiceConfig.company?.name || "",
|
|
247
|
+
address: invoice.company?.address || defaultInvoiceConfig.company?.address || "",
|
|
248
|
+
phone: invoice.company?.phone || defaultInvoiceConfig.company?.phone || "",
|
|
249
|
+
email: invoice.company?.email,
|
|
250
|
+
gstNumber: invoice.company?.gstNumber,
|
|
251
|
+
panNumber: invoice.company?.panNumber,
|
|
252
|
+
website: invoice.company?.website,
|
|
253
|
+
bankDetails: invoice.company?.bankDetails,
|
|
254
|
+
branches: invoice.company?.branches || []
|
|
255
|
+
},
|
|
256
|
+
customer: {
|
|
257
|
+
name: invoice.customer?.name || defaultInvoiceConfig.customer?.name || "",
|
|
258
|
+
email: invoice.customer?.email || defaultInvoiceConfig.customer?.email || "",
|
|
259
|
+
phone: invoice.customer?.phone,
|
|
260
|
+
gstNumber: invoice.customer?.gstNumber,
|
|
261
|
+
address: invoice.customer?.address
|
|
262
|
+
},
|
|
263
|
+
features: {
|
|
264
|
+
...defaultInvoiceConfig.features,
|
|
265
|
+
...invoice.features
|
|
266
|
+
},
|
|
267
|
+
branding: {
|
|
268
|
+
...defaultInvoiceConfig.branding,
|
|
269
|
+
...invoice.branding
|
|
270
|
+
},
|
|
271
|
+
theme: {
|
|
272
|
+
...defaultInvoiceConfig.theme,
|
|
273
|
+
...invoice.theme
|
|
274
|
+
},
|
|
275
|
+
payment: invoice.payment ? {
|
|
276
|
+
...invoice.payment,
|
|
277
|
+
transactions: invoice.payment.transactions || []
|
|
278
|
+
} : void 0,
|
|
279
|
+
terms: invoice.terms || []
|
|
280
|
+
};
|
|
207
281
|
}
|
|
208
282
|
};
|
|
209
283
|
|
|
210
|
-
// src/
|
|
211
|
-
var
|
|
212
|
-
static
|
|
213
|
-
return
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
${item.quantity},
|
|
218
|
-
${item.rate}`
|
|
219
|
-
)
|
|
220
|
-
].join("\n");
|
|
284
|
+
// src/renderers/invoice-renderer.ts
|
|
285
|
+
var InvoiceRenderer = class {
|
|
286
|
+
static renderHTML(invoice, summary, template) {
|
|
287
|
+
return template(
|
|
288
|
+
invoice,
|
|
289
|
+
summary
|
|
290
|
+
);
|
|
221
291
|
}
|
|
222
292
|
};
|
|
223
293
|
|
|
224
|
-
// src/exporters/
|
|
225
|
-
var
|
|
294
|
+
// src/exporters/csv-exporter.ts
|
|
295
|
+
var CsvExporter = class {
|
|
226
296
|
static generate(invoice) {
|
|
227
|
-
|
|
228
|
-
invoice,
|
|
229
|
-
|
|
230
|
-
|
|
297
|
+
const summary = InvoiceCalculator.summary(
|
|
298
|
+
invoice.items,
|
|
299
|
+
invoice.tax || 0,
|
|
300
|
+
invoice.discount || 0
|
|
231
301
|
);
|
|
302
|
+
const rows = [
|
|
303
|
+
`Invoice No,${invoice.invoiceNo}`,
|
|
304
|
+
`Date,${invoice.date}`,
|
|
305
|
+
`Customer,${invoice.customer.name}`,
|
|
306
|
+
`Payment Status,${invoice.payment?.status || "pending"}`,
|
|
307
|
+
"",
|
|
308
|
+
"Description,Quantity,Rate,Amount",
|
|
309
|
+
...invoice.items.map(
|
|
310
|
+
(item) => `${item.description},${item.quantity},${item.rate},${item.quantity * item.rate}`
|
|
311
|
+
),
|
|
312
|
+
"",
|
|
313
|
+
`Subtotal,,,${summary.subtotal}`,
|
|
314
|
+
`Tax Amount,,,${summary.taxAmount}`,
|
|
315
|
+
`Discount Amount,,,${summary.discountAmount}`,
|
|
316
|
+
`Grand Total,,,${summary.total}`
|
|
317
|
+
];
|
|
318
|
+
return rows.join("\n");
|
|
232
319
|
}
|
|
233
320
|
};
|
|
234
321
|
|
|
235
322
|
// src/templates/classic.template.ts
|
|
236
323
|
function classicInvoiceTemplate(invoice, summary) {
|
|
324
|
+
const currency = invoice.currency || "INR";
|
|
325
|
+
const items = invoice.items.map(
|
|
326
|
+
(item, index) => `
|
|
327
|
+
<tr>
|
|
328
|
+
<td>
|
|
329
|
+
${index + 1}
|
|
330
|
+
</td>
|
|
331
|
+
<td>
|
|
332
|
+
${item.description}
|
|
333
|
+
</td>
|
|
334
|
+
<td>
|
|
335
|
+
${item.quantity}
|
|
336
|
+
</td>
|
|
337
|
+
<td>
|
|
338
|
+
${Billing.formatCurrency(item.rate, currency)}
|
|
339
|
+
</td>
|
|
340
|
+
<td>
|
|
341
|
+
${Billing.formatCurrency(item.quantity * item.rate, currency)}
|
|
342
|
+
</td>
|
|
343
|
+
</tr>
|
|
344
|
+
`
|
|
345
|
+
).join("");
|
|
237
346
|
return `
|
|
238
|
-
|
|
239
|
-
|
|
347
|
+
<!DOCTYPE html>
|
|
348
|
+
<html lang="en">
|
|
349
|
+
<head>
|
|
350
|
+
<meta charset="UTF-8" />
|
|
351
|
+
<meta
|
|
352
|
+
name="viewport"
|
|
353
|
+
content="width=device-width, initial-scale=1.0"
|
|
354
|
+
/>
|
|
355
|
+
<title>
|
|
356
|
+
${invoice.type || "INVOICE"}
|
|
357
|
+
</title>
|
|
358
|
+
<style>
|
|
359
|
+
* {
|
|
360
|
+
box-sizing: border-box;
|
|
361
|
+
}
|
|
362
|
+
body {
|
|
363
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
364
|
+
background: #ffffff;
|
|
365
|
+
padding: 0;
|
|
366
|
+
margin: 0;
|
|
367
|
+
color: #222222;
|
|
368
|
+
-webkit-print-color-adjust: exact;
|
|
369
|
+
print-color-adjust: exact;
|
|
370
|
+
}
|
|
371
|
+
.receipt-container {
|
|
372
|
+
width: 100%;
|
|
373
|
+
max-width: 100%;
|
|
374
|
+
margin: auto;
|
|
375
|
+
background: #ffffff;
|
|
376
|
+
padding: 40px;
|
|
377
|
+
}
|
|
378
|
+
.top-header {
|
|
379
|
+
display: flex;
|
|
380
|
+
justify-content: space-between;
|
|
381
|
+
align-items: flex-start;
|
|
382
|
+
margin-bottom: 35px;
|
|
383
|
+
}
|
|
384
|
+
.company-name {
|
|
385
|
+
font-size: 28px;
|
|
386
|
+
font-weight: 700;
|
|
387
|
+
margin-bottom: 10px;
|
|
388
|
+
}
|
|
389
|
+
.company-address {
|
|
390
|
+
font-size: 13px;
|
|
391
|
+
line-height: 1.5;
|
|
392
|
+
}
|
|
393
|
+
.invoice-title {
|
|
394
|
+
font-size: 34px;
|
|
395
|
+
font-weight: 700;
|
|
396
|
+
letter-spacing: 1px;
|
|
397
|
+
}
|
|
398
|
+
.address-section {
|
|
399
|
+
display: grid;
|
|
400
|
+
grid-template-columns: 1fr 1fr 1fr;
|
|
401
|
+
gap: 25px;
|
|
402
|
+
margin-bottom: 30px;
|
|
403
|
+
}
|
|
404
|
+
.address-box h3 {
|
|
405
|
+
font-size: 16px;
|
|
406
|
+
margin-bottom: 8px;
|
|
407
|
+
}
|
|
408
|
+
.address-box p {
|
|
409
|
+
font-size: 13px;
|
|
410
|
+
line-height: 1.5;
|
|
411
|
+
}
|
|
412
|
+
.invoice-details td {
|
|
413
|
+
padding: 4px 0;
|
|
414
|
+
font-size: 13px;
|
|
415
|
+
}
|
|
416
|
+
.invoice-details td:first-child {
|
|
417
|
+
font-weight: 700;
|
|
418
|
+
padding-right: 10px;
|
|
419
|
+
}
|
|
420
|
+
.items-table {
|
|
421
|
+
width: 100%;
|
|
422
|
+
border-collapse: collapse;
|
|
423
|
+
margin-top: 15px;
|
|
424
|
+
}
|
|
425
|
+
.items-table th {
|
|
426
|
+
background: #f3f3f3;
|
|
427
|
+
padding: 10px;
|
|
428
|
+
border: 1px solid #cccccc;
|
|
429
|
+
font-size: 13px;
|
|
430
|
+
text-align: center;
|
|
431
|
+
}
|
|
432
|
+
.items-table td {
|
|
433
|
+
border: 1px solid #cccccc;
|
|
434
|
+
padding: 9px;
|
|
435
|
+
font-size: 12px;
|
|
436
|
+
line-height: 1.4;
|
|
437
|
+
word-break: break-word;
|
|
438
|
+
}
|
|
439
|
+
.items-table td:nth-child(1),
|
|
440
|
+
.items-table td:nth-child(3) {
|
|
441
|
+
text-align: center;
|
|
442
|
+
width: 60px;
|
|
443
|
+
}
|
|
444
|
+
.items-table td:nth-child(4),
|
|
445
|
+
.items-table td:nth-child(5) {
|
|
446
|
+
text-align: right;
|
|
447
|
+
width: 120px;
|
|
448
|
+
}
|
|
449
|
+
.total-wrapper {
|
|
450
|
+
display: flex;
|
|
451
|
+
justify-content: flex-end;
|
|
452
|
+
margin-top: 18px;
|
|
453
|
+
}
|
|
454
|
+
.total-box {
|
|
455
|
+
width: 320px;
|
|
456
|
+
}
|
|
457
|
+
.total-table td {
|
|
458
|
+
padding: 10px;
|
|
459
|
+
font-size: 14px;
|
|
460
|
+
}
|
|
461
|
+
.total-table td:last-child {
|
|
462
|
+
text-align: right;
|
|
463
|
+
}
|
|
464
|
+
.total-table tr:last-child td {
|
|
465
|
+
border: 1px solid #cccccc;
|
|
466
|
+
font-size: 24px;
|
|
467
|
+
font-weight: 700;
|
|
468
|
+
}
|
|
469
|
+
.notes {
|
|
470
|
+
margin-top: 35px;
|
|
471
|
+
}
|
|
472
|
+
.notes h3 {
|
|
473
|
+
margin-bottom: 10px;
|
|
474
|
+
font-size: 15px;
|
|
475
|
+
}
|
|
476
|
+
.notes p {
|
|
477
|
+
font-size: 12px;
|
|
478
|
+
line-height: 1.6;
|
|
479
|
+
}
|
|
480
|
+
.signature-section {
|
|
481
|
+
margin-top: 45px;
|
|
482
|
+
display: flex;
|
|
483
|
+
justify-content: flex-end;
|
|
484
|
+
}
|
|
485
|
+
.signature {
|
|
486
|
+
font-size: 34px;
|
|
487
|
+
font-family: cursive;
|
|
488
|
+
margin-bottom: 5px;
|
|
489
|
+
}
|
|
490
|
+
.signature-label {
|
|
491
|
+
border-top: 1px solid #222222;
|
|
492
|
+
padding-top: 5px;
|
|
493
|
+
font-size: 11px;
|
|
494
|
+
}
|
|
495
|
+
.footer {
|
|
496
|
+
margin-top: 40px;
|
|
497
|
+
text-align: center;
|
|
498
|
+
color: #777777;
|
|
499
|
+
font-size: 11px;
|
|
500
|
+
}
|
|
501
|
+
</style>
|
|
502
|
+
</head>
|
|
240
503
|
<body>
|
|
241
|
-
|
|
242
|
-
<div class="
|
|
243
|
-
|
|
244
|
-
<h1>INVOICE</h1>
|
|
245
|
-
|
|
504
|
+
<div class="receipt-container">
|
|
505
|
+
<div class="top-header">
|
|
246
506
|
<div>
|
|
247
|
-
|
|
248
|
-
|
|
507
|
+
<div class="company-name">
|
|
508
|
+
${invoice.company?.name || "Zentris Pvt Ltd"}
|
|
249
509
|
</div>
|
|
250
|
-
|
|
251
|
-
<h3>BILL TO</h3>
|
|
252
|
-
|
|
510
|
+
<div class="company-address">
|
|
253
511
|
<p>
|
|
254
|
-
${invoice.
|
|
255
|
-
<br/>
|
|
256
|
-
${invoice.customer.address}
|
|
512
|
+
${invoice.company?.address || "Mumbai, India"}
|
|
257
513
|
</p>
|
|
258
|
-
|
|
514
|
+
<p>
|
|
515
|
+
${invoice.company?.phone || "+91 9999999999"}
|
|
516
|
+
</p>
|
|
517
|
+
<p>
|
|
518
|
+
${invoice.company?.email || "support@zentris.com"}
|
|
519
|
+
</p>
|
|
520
|
+
<p>
|
|
521
|
+
GSTIN:
|
|
522
|
+
${invoice.company?.gstNumber || "27ABCDE1234F1Z5"}
|
|
523
|
+
</p>
|
|
524
|
+
</div>
|
|
525
|
+
</div>
|
|
526
|
+
<div class="invoice-title">
|
|
527
|
+
${invoice.type || "INVOICE"}
|
|
528
|
+
</div>
|
|
529
|
+
</div>
|
|
530
|
+
<div class="address-section">
|
|
531
|
+
<div class="address-box">
|
|
532
|
+
<h3>Seller</h3>
|
|
533
|
+
<p>
|
|
534
|
+
${invoice.company?.name || "Zentris Pvt Ltd"}
|
|
535
|
+
</p>
|
|
536
|
+
<p>
|
|
537
|
+
${invoice.company?.address || "Mumbai"}
|
|
538
|
+
</p>
|
|
539
|
+
</div>
|
|
540
|
+
<div class="address-box">
|
|
541
|
+
<h3>Buyer</h3>
|
|
542
|
+
<p>
|
|
543
|
+
${invoice.customer?.name || "Customer Name"}
|
|
544
|
+
</p>
|
|
545
|
+
<p>
|
|
546
|
+
${invoice.customer?.company || ""}
|
|
547
|
+
</p>
|
|
548
|
+
<p>
|
|
549
|
+
${invoice.customer?.address || "Customer Address"}
|
|
550
|
+
</p>
|
|
551
|
+
<p>
|
|
552
|
+
${invoice.customer?.phone || ""}
|
|
553
|
+
</p>
|
|
554
|
+
</div>
|
|
555
|
+
<div class="invoice-details">
|
|
259
556
|
<table>
|
|
260
|
-
|
|
261
557
|
<tr>
|
|
558
|
+
<td>Invoice Number</td>
|
|
559
|
+
<td>${invoice.invoiceNo || "INV-001"}</td>
|
|
560
|
+
</tr>
|
|
561
|
+
<tr>
|
|
562
|
+
<td>Date</td>
|
|
563
|
+
<td>${invoice.date || (/* @__PURE__ */ new Date()).toLocaleDateString()}</td>
|
|
564
|
+
</tr>
|
|
565
|
+
<tr>
|
|
566
|
+
<td>Due Date</td>
|
|
567
|
+
<td>${invoice.dueDate || ""}</td>
|
|
568
|
+
</tr>
|
|
569
|
+
<tr>
|
|
570
|
+
<td>Payment Mode</td>
|
|
571
|
+
<td>${invoice.payment?.mode || "Bank Transfer"}</td>
|
|
572
|
+
</tr>
|
|
573
|
+
<tr>
|
|
574
|
+
<td>Status</td>
|
|
575
|
+
<td>${invoice.payment?.status || "Pending"}</td>
|
|
576
|
+
</tr>
|
|
577
|
+
</table>
|
|
578
|
+
</div>
|
|
579
|
+
</div>
|
|
580
|
+
<table class="items-table">
|
|
581
|
+
<thead>
|
|
582
|
+
<tr>
|
|
583
|
+
<th>Number</th>
|
|
262
584
|
<th>Description</th>
|
|
585
|
+
<th>Qty</th>
|
|
586
|
+
<th>Rate</th>
|
|
263
587
|
<th>Amount</th>
|
|
264
588
|
</tr>
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
589
|
+
</thead>
|
|
590
|
+
<tbody>
|
|
591
|
+
${items}
|
|
592
|
+
</tbody>
|
|
593
|
+
</table>
|
|
594
|
+
<div class="total-wrapper">
|
|
595
|
+
<div class="total-box">
|
|
596
|
+
<table class="total-table">
|
|
268
597
|
<tr>
|
|
269
|
-
<td
|
|
598
|
+
<td>Subtotal</td>
|
|
270
599
|
<td>
|
|
271
|
-
|
|
600
|
+
${Billing.formatCurrency(summary.subtotal, currency)}
|
|
601
|
+
</td>
|
|
602
|
+
</tr>
|
|
603
|
+
<tr>
|
|
604
|
+
<td>Tax</td>
|
|
605
|
+
<td>
|
|
606
|
+
${Billing.formatCurrency(summary.taxAmount, currency)}
|
|
607
|
+
</td>
|
|
608
|
+
</tr>
|
|
609
|
+
<tr>
|
|
610
|
+
<td>Discount</td>
|
|
611
|
+
<td>
|
|
612
|
+
${Billing.formatCurrency(summary.discountAmount, currency)}
|
|
613
|
+
</td>
|
|
614
|
+
</tr>
|
|
615
|
+
<tr>
|
|
616
|
+
<td>Total</td>
|
|
617
|
+
<td>
|
|
618
|
+
${Billing.formatCurrency(summary.total, currency)}
|
|
272
619
|
</td>
|
|
273
620
|
</tr>
|
|
274
|
-
`
|
|
275
|
-
).join("")}
|
|
276
|
-
|
|
277
621
|
</table>
|
|
278
|
-
|
|
279
|
-
<div>
|
|
280
|
-
Subtotal:
|
|
281
|
-
\u20B9${summary.subtotal}
|
|
282
622
|
</div>
|
|
283
|
-
|
|
284
|
-
<div>
|
|
285
|
-
Tax:
|
|
286
|
-
\u20B9${summary.tax}
|
|
287
623
|
</div>
|
|
624
|
+
<div class="notes">
|
|
625
|
+
<h3>Terms and Conditions</h3>
|
|
626
|
+
<p>
|
|
627
|
+
${invoice.notes || "Payment due within 15 days. Thank you for your business."}
|
|
628
|
+
</p>
|
|
629
|
+
</div>
|
|
630
|
+
${invoice.signature ? `
|
|
631
|
+
<div class="signature-section">
|
|
632
|
+
<div class="signature-box">
|
|
633
|
+
<div class="signature">
|
|
634
|
+
${invoice.signature}
|
|
635
|
+
</div>
|
|
636
|
+
<div class="signature-label">
|
|
637
|
+
Authorized Signature
|
|
638
|
+
</div>
|
|
639
|
+
</div>
|
|
640
|
+
</div>
|
|
641
|
+
` : ""}
|
|
642
|
+
<div class="footer">
|
|
643
|
+
Generated using Zentris Billing
|
|
644
|
+
</div>
|
|
645
|
+
</div>
|
|
646
|
+
</body>
|
|
647
|
+
</html>
|
|
648
|
+
`;
|
|
649
|
+
}
|
|
288
650
|
|
|
651
|
+
// src/templates/classic.template2.ts
|
|
652
|
+
function classicInvoiceTemplate2(invoice, summary) {
|
|
653
|
+
const currency = invoice.currency || "INR";
|
|
654
|
+
const items = invoice.items.map(
|
|
655
|
+
(item, index) => `
|
|
656
|
+
<tr>
|
|
657
|
+
<td class="center">
|
|
658
|
+
${index + 1}
|
|
659
|
+
</td>
|
|
660
|
+
<td>
|
|
661
|
+
<b>${item.description}</b>
|
|
662
|
+
</td>
|
|
663
|
+
<td class="center">
|
|
664
|
+
${item.hsn || "8302"}
|
|
665
|
+
</td>
|
|
666
|
+
<td class="center">
|
|
667
|
+
${item.quantity}
|
|
668
|
+
</td>
|
|
669
|
+
<td class="right">
|
|
670
|
+
${Billing.formatCurrency(item.rate, currency)}
|
|
671
|
+
</td>
|
|
672
|
+
<td class="right">
|
|
673
|
+
${Billing.formatCurrency(item.quantity * item.rate, currency)}
|
|
674
|
+
</td>
|
|
675
|
+
</tr>
|
|
676
|
+
`
|
|
677
|
+
).join("");
|
|
678
|
+
return `
|
|
679
|
+
<!DOCTYPE html>
|
|
680
|
+
<html lang="en">
|
|
681
|
+
<head>
|
|
682
|
+
<meta charset="UTF-8"/>
|
|
683
|
+
<meta
|
|
684
|
+
name="viewport"
|
|
685
|
+
content="width=device-width, initial-scale=1.0"
|
|
686
|
+
/>
|
|
687
|
+
<title>
|
|
688
|
+
${invoice.type || "TAX INVOICE"}
|
|
689
|
+
</title>
|
|
690
|
+
<style>
|
|
691
|
+
*{
|
|
692
|
+
margin:0;
|
|
693
|
+
padding:0;
|
|
694
|
+
box-sizing:border-box;
|
|
695
|
+
font-family:Arial, Helvetica, sans-serif;
|
|
696
|
+
}
|
|
697
|
+
body{
|
|
698
|
+
background:#efefef;
|
|
699
|
+
padding:10px;
|
|
700
|
+
}
|
|
701
|
+
.invoice{
|
|
702
|
+
width:100%;
|
|
703
|
+
max-width:1000px;
|
|
704
|
+
margin:auto;
|
|
705
|
+
background:#fff;
|
|
706
|
+
border:2px solid #333;
|
|
707
|
+
color:#111;
|
|
708
|
+
}
|
|
709
|
+
table{
|
|
710
|
+
width:100%;
|
|
711
|
+
border-collapse:collapse;
|
|
712
|
+
}
|
|
713
|
+
td,th{
|
|
714
|
+
border:1px solid #333;
|
|
715
|
+
padding:4px 6px;
|
|
716
|
+
vertical-align:top;
|
|
717
|
+
font-size:12px;
|
|
718
|
+
}
|
|
719
|
+
.header{
|
|
720
|
+
padding:15px;
|
|
721
|
+
border-bottom:2px solid #333;
|
|
722
|
+
}
|
|
723
|
+
.top-flex{
|
|
724
|
+
display:flex;
|
|
725
|
+
justify-content:space-between;
|
|
726
|
+
align-items:flex-start;
|
|
727
|
+
}
|
|
728
|
+
.company-name{
|
|
729
|
+
font-size:32px;
|
|
730
|
+
font-weight:900;
|
|
731
|
+
color:#221b67;
|
|
732
|
+
line-height:1;
|
|
733
|
+
}
|
|
734
|
+
.green-strip{
|
|
735
|
+
background:#009688;
|
|
736
|
+
color:#fff;
|
|
737
|
+
font-size:13px;
|
|
738
|
+
font-weight:bold;
|
|
739
|
+
padding:6px 10px;
|
|
740
|
+
margin-top:8px;
|
|
741
|
+
display:inline-block;
|
|
742
|
+
}
|
|
743
|
+
.address{
|
|
744
|
+
margin-top:10px;
|
|
745
|
+
font-size:13px;
|
|
746
|
+
line-height:1.5;
|
|
747
|
+
}
|
|
748
|
+
.right-top{
|
|
749
|
+
text-align:right;
|
|
750
|
+
font-size:12px;
|
|
751
|
+
line-height:1.5;
|
|
752
|
+
}
|
|
753
|
+
.logo{
|
|
754
|
+
margin-top:10px;
|
|
755
|
+
font-size:28px;
|
|
756
|
+
font-weight:900;
|
|
757
|
+
color:#2a2a75;
|
|
758
|
+
}
|
|
759
|
+
.logo-sub{
|
|
760
|
+
font-size:10px;
|
|
761
|
+
letter-spacing:2px;
|
|
762
|
+
color:#999;
|
|
763
|
+
}
|
|
764
|
+
.invoice-title{
|
|
765
|
+
text-align:center;
|
|
766
|
+
font-size:18px;
|
|
767
|
+
font-weight:900;
|
|
768
|
+
}
|
|
769
|
+
.bold{
|
|
770
|
+
font-weight:bold;
|
|
771
|
+
}
|
|
772
|
+
.center{
|
|
773
|
+
text-align:center;
|
|
774
|
+
}
|
|
775
|
+
.right{
|
|
776
|
+
text-align:right;
|
|
777
|
+
}
|
|
778
|
+
.product-table th{
|
|
779
|
+
background:#f5f5f5;
|
|
780
|
+
font-size:11px;
|
|
781
|
+
}
|
|
782
|
+
.product-table td{
|
|
783
|
+
height:28px;
|
|
784
|
+
font-size:11px;
|
|
785
|
+
}
|
|
786
|
+
.total-row td{
|
|
787
|
+
font-size:15px;
|
|
788
|
+
font-weight:bold;
|
|
789
|
+
}
|
|
790
|
+
.amount-words{
|
|
791
|
+
padding:8px 12px;
|
|
792
|
+
font-size:12px;
|
|
793
|
+
line-height:1.6;
|
|
794
|
+
border-top:1px solid #333;
|
|
795
|
+
border-bottom:1px solid #333;
|
|
796
|
+
}
|
|
797
|
+
.tax-table th{
|
|
798
|
+
background:#f5f5f5;
|
|
799
|
+
}
|
|
800
|
+
.bank-details{
|
|
801
|
+
padding:8px;
|
|
802
|
+
line-height:1.7;
|
|
803
|
+
font-size:12px;
|
|
804
|
+
}
|
|
805
|
+
.qr{
|
|
806
|
+
width:100px;
|
|
807
|
+
height:100px;
|
|
808
|
+
border:3px solid #000;
|
|
809
|
+
margin:auto;
|
|
810
|
+
display:flex;
|
|
811
|
+
justify-content:center;
|
|
812
|
+
align-items:center;
|
|
813
|
+
font-size:12px;
|
|
814
|
+
font-weight:bold;
|
|
815
|
+
}
|
|
816
|
+
.certified{
|
|
817
|
+
text-align:center;
|
|
818
|
+
padding-top:10px;
|
|
819
|
+
font-size:11px;
|
|
820
|
+
font-weight:bold;
|
|
821
|
+
}
|
|
822
|
+
.company-sign{
|
|
823
|
+
text-align:center;
|
|
824
|
+
font-size:16px;
|
|
825
|
+
font-weight:bold;
|
|
826
|
+
padding:15px 0;
|
|
827
|
+
}
|
|
828
|
+
.computer-note{
|
|
829
|
+
text-align:center;
|
|
830
|
+
margin-top:60px;
|
|
831
|
+
transform:rotate(-10deg);
|
|
832
|
+
font-size:11px;
|
|
833
|
+
color:#333;
|
|
834
|
+
}
|
|
835
|
+
.terms{
|
|
836
|
+
padding:10px;
|
|
837
|
+
line-height:1.5;
|
|
838
|
+
font-size:11px;
|
|
839
|
+
}
|
|
840
|
+
.signature{
|
|
841
|
+
height:70px;
|
|
842
|
+
padding:10px;
|
|
843
|
+
font-weight:bold;
|
|
844
|
+
}
|
|
845
|
+
.footer{
|
|
846
|
+
padding:10px 0;
|
|
847
|
+
font-size:14px;
|
|
848
|
+
text-align:center;
|
|
849
|
+
}
|
|
850
|
+
@media print{
|
|
851
|
+
body{
|
|
852
|
+
background:#fff;
|
|
853
|
+
padding:0;
|
|
854
|
+
}
|
|
855
|
+
.invoice{
|
|
856
|
+
border:none;
|
|
857
|
+
max-width:100%;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
</style>
|
|
861
|
+
</head>
|
|
862
|
+
<body>
|
|
863
|
+
<div class="invoice">
|
|
864
|
+
<div class="header">
|
|
865
|
+
<div class="top-flex">
|
|
289
866
|
<div>
|
|
290
|
-
|
|
291
|
-
|
|
867
|
+
<div class="company-name">
|
|
868
|
+
${invoice.company?.name || "Zentris Pvt Ltd"}
|
|
292
869
|
</div>
|
|
293
|
-
|
|
870
|
+
<div class="green-strip">
|
|
871
|
+
Manufacturing & Software Billing Solutions
|
|
872
|
+
</div>
|
|
873
|
+
<div class="address">
|
|
874
|
+
${invoice.company?.address || "Mumbai, India"}
|
|
875
|
+
<br>
|
|
876
|
+
Phone:
|
|
877
|
+
${invoice.company?.phone || "+91 9999999999"}
|
|
878
|
+
<br>
|
|
879
|
+
Email:
|
|
880
|
+
${invoice.company?.email || "support@zentris.com"}
|
|
881
|
+
<br>
|
|
882
|
+
GSTIN:
|
|
883
|
+
${invoice.company?.gstNumber || "27ABCDE1234F1Z5"}
|
|
884
|
+
</div>
|
|
885
|
+
</div>
|
|
886
|
+
<div class="right-top">
|
|
887
|
+
Invoice:
|
|
888
|
+
${invoice.invoiceNo}
|
|
889
|
+
<br>
|
|
890
|
+
Date:
|
|
891
|
+
${invoice.date}
|
|
892
|
+
<br>
|
|
893
|
+
Due:
|
|
894
|
+
${invoice.dueDate || ""}
|
|
895
|
+
<div class="logo">
|
|
896
|
+
ZENTRIS
|
|
897
|
+
<div class="logo-sub">
|
|
898
|
+
BILLING ENGINE
|
|
899
|
+
</div>
|
|
900
|
+
</div>
|
|
901
|
+
</div>
|
|
902
|
+
</div>
|
|
903
|
+
</div>
|
|
904
|
+
<table>
|
|
905
|
+
<tr>
|
|
906
|
+
<td width="35%">
|
|
907
|
+
<span class="bold">
|
|
908
|
+
PAN :
|
|
909
|
+
</span>
|
|
910
|
+
${invoice.company?.panNumber || "ABCDE1234F"}
|
|
911
|
+
</td>
|
|
912
|
+
<td width="40%" class="invoice-title">
|
|
913
|
+
${invoice.type || "TAX INVOICE"}
|
|
914
|
+
</td>
|
|
915
|
+
<td width="25%" class="right bold">
|
|
916
|
+
ORIGINAL FOR RECIPIENT
|
|
917
|
+
</td>
|
|
918
|
+
</tr>
|
|
919
|
+
</table>
|
|
920
|
+
<table>
|
|
921
|
+
<tr>
|
|
922
|
+
<td width="40%" class="center bold">
|
|
923
|
+
Customer Detail
|
|
924
|
+
</td>
|
|
925
|
+
<td colspan="2"></td>
|
|
926
|
+
</tr>
|
|
927
|
+
<tr>
|
|
928
|
+
<td>
|
|
929
|
+
<b>M/S:</b>
|
|
930
|
+
${invoice.customer?.name}
|
|
931
|
+
<br><br>
|
|
932
|
+
<b>Company:</b>
|
|
933
|
+
${invoice.customer?.company || ""}
|
|
934
|
+
<br><br>
|
|
935
|
+
<b>Address:</b>
|
|
936
|
+
${invoice.customer?.address}
|
|
937
|
+
<br><br>
|
|
938
|
+
<b>Phone:</b>
|
|
939
|
+
${invoice.customer?.phone || ""}
|
|
940
|
+
<br><br>
|
|
941
|
+
<b>GSTIN:</b>
|
|
942
|
+
${invoice.customer?.gstNumber || ""}
|
|
943
|
+
</td>
|
|
944
|
+
<td width="30%">
|
|
945
|
+
<b>Payment Mode:</b>
|
|
946
|
+
${invoice.payment?.mode || "UPI"}
|
|
947
|
+
<br><br>
|
|
948
|
+
<b>Transport:</b>
|
|
949
|
+
${invoice.transport || "Blue Dart"}
|
|
950
|
+
<br><br>
|
|
951
|
+
<b>E-Way Bill:</b>
|
|
952
|
+
${invoice.eway || "78456378"}
|
|
953
|
+
</td>
|
|
954
|
+
<td width="30%">
|
|
955
|
+
<b>Status:</b>
|
|
956
|
+
${invoice.payment?.status || "Pending"}
|
|
957
|
+
</td>
|
|
958
|
+
</tr>
|
|
959
|
+
</table>
|
|
960
|
+
<table class="product-table">
|
|
961
|
+
<tr>
|
|
962
|
+
<th width="5%">
|
|
963
|
+
Sr
|
|
964
|
+
</th>
|
|
965
|
+
<th width="40%">
|
|
966
|
+
Description
|
|
967
|
+
</th>
|
|
968
|
+
<th width="13%">
|
|
969
|
+
HSN
|
|
970
|
+
</th>
|
|
971
|
+
<th width="13%">
|
|
972
|
+
Qty
|
|
973
|
+
</th>
|
|
974
|
+
<th width="14%">
|
|
975
|
+
Rate
|
|
976
|
+
</th>
|
|
977
|
+
<th width="15%">
|
|
978
|
+
Amount
|
|
979
|
+
</th>
|
|
980
|
+
</tr>
|
|
981
|
+
${items}
|
|
982
|
+
<tr class="total-row">
|
|
983
|
+
<td colspan="2" class="right">
|
|
984
|
+
TOTAL
|
|
985
|
+
</td>
|
|
986
|
+
<td></td>
|
|
987
|
+
<td class="center">
|
|
988
|
+
${invoice.items.length}
|
|
989
|
+
</td>
|
|
990
|
+
<td></td>
|
|
991
|
+
<td class="right">
|
|
992
|
+
${Billing.formatCurrency(summary.total, currency)}
|
|
993
|
+
</td>
|
|
994
|
+
</tr>
|
|
995
|
+
</table>
|
|
996
|
+
<div class="amount-words">
|
|
997
|
+
<b>Total in words:</b>
|
|
998
|
+
${invoice.amountWords || "Amount payable as per invoice"}
|
|
999
|
+
</div>
|
|
1000
|
+
<table class="tax-table">
|
|
1001
|
+
<tr>
|
|
1002
|
+
<th>
|
|
1003
|
+
Taxable
|
|
1004
|
+
</th>
|
|
1005
|
+
<th>
|
|
1006
|
+
Tax %
|
|
1007
|
+
</th>
|
|
1008
|
+
<th>
|
|
1009
|
+
Tax Amount
|
|
1010
|
+
</th>
|
|
1011
|
+
<th>
|
|
1012
|
+
Discount
|
|
1013
|
+
</th>
|
|
1014
|
+
<th>
|
|
1015
|
+
Grand Total
|
|
1016
|
+
</th>
|
|
1017
|
+
</tr>
|
|
1018
|
+
<tr>
|
|
1019
|
+
<td class="right">
|
|
1020
|
+
${summary.subtotal.toFixed(2)}
|
|
1021
|
+
</td>
|
|
1022
|
+
<td class="center">
|
|
1023
|
+
${invoice.tax || 0}%
|
|
1024
|
+
</td>
|
|
1025
|
+
<td class="right">
|
|
1026
|
+
${summary.taxAmount.toFixed(2)}
|
|
1027
|
+
</td>
|
|
1028
|
+
<td class="right">
|
|
1029
|
+
${summary.discountAmount.toFixed(2)}
|
|
1030
|
+
</td>
|
|
1031
|
+
<td class="right bold">
|
|
1032
|
+
${summary.total.toFixed(2)}
|
|
1033
|
+
</td>
|
|
1034
|
+
</tr>
|
|
1035
|
+
</table>
|
|
1036
|
+
<table>
|
|
1037
|
+
<tr>
|
|
1038
|
+
<td width="60%">
|
|
1039
|
+
<div class="bank-details">
|
|
1040
|
+
<b>Bank:</b>
|
|
1041
|
+
ICICI BANK
|
|
1042
|
+
<br>
|
|
1043
|
+
<b>Account:</b>
|
|
1044
|
+
2715500356
|
|
1045
|
+
<br>
|
|
1046
|
+
<b>IFSC:</b>
|
|
1047
|
+
ICIC000045
|
|
1048
|
+
<br>
|
|
1049
|
+
<b>UPI:</b>
|
|
1050
|
+
zentris@icici
|
|
1051
|
+
</div>
|
|
1052
|
+
</td>
|
|
1053
|
+
<td width="40%" class="center">
|
|
1054
|
+
<div class="qr">
|
|
1055
|
+
QR CODE
|
|
1056
|
+
</div>
|
|
1057
|
+
<div style="margin-top:8px;">
|
|
1058
|
+
Pay using UPI
|
|
1059
|
+
</div>
|
|
1060
|
+
</td>
|
|
1061
|
+
</tr>
|
|
1062
|
+
</table>
|
|
1063
|
+
<div class="terms">
|
|
1064
|
+
<b>Terms & Conditions</b>
|
|
1065
|
+
<br><br>
|
|
1066
|
+
Payment due within 15 days.
|
|
1067
|
+
<br>
|
|
1068
|
+
Goods once sold will not be taken back.
|
|
1069
|
+
<br>
|
|
1070
|
+
Subject to Mumbai jurisdiction.
|
|
1071
|
+
</div>
|
|
1072
|
+
<div class="company-sign">
|
|
1073
|
+
For
|
|
1074
|
+
${invoice.company?.name || "Zentris Pvt Ltd"}
|
|
1075
|
+
<br><br>
|
|
1076
|
+
${invoice.signature || "Authorised Signatory"}
|
|
1077
|
+
</div>
|
|
1078
|
+
</div>
|
|
1079
|
+
<div class="footer">
|
|
1080
|
+
Generated using Zentris Billing
|
|
294
1081
|
</div>
|
|
295
|
-
|
|
296
1082
|
</body>
|
|
297
1083
|
</html>
|
|
298
1084
|
`;
|
|
@@ -300,20 +1086,62 @@ Total:
|
|
|
300
1086
|
|
|
301
1087
|
// src/exporters/html-exporter.ts
|
|
302
1088
|
var HtmlExporter = class {
|
|
1089
|
+
static generate(invoice, options) {
|
|
1090
|
+
const normalizedInvoice = InvoiceNormalizer.normalize(invoice);
|
|
1091
|
+
const summary = InvoiceCalculator.summary(
|
|
1092
|
+
normalizedInvoice.items,
|
|
1093
|
+
normalizedInvoice.tax || 0,
|
|
1094
|
+
normalizedInvoice.discount || 0
|
|
1095
|
+
);
|
|
1096
|
+
const template = options?.template === "gst" ? classicInvoiceTemplate2 : classicInvoiceTemplate;
|
|
1097
|
+
return InvoiceRenderer.renderHTML(
|
|
1098
|
+
normalizedInvoice,
|
|
1099
|
+
summary,
|
|
1100
|
+
template
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
1103
|
+
};
|
|
1104
|
+
|
|
1105
|
+
// src/exporters/json-exporter.ts
|
|
1106
|
+
var JsonExporter = class {
|
|
303
1107
|
static generate(invoice) {
|
|
304
1108
|
const summary = InvoiceCalculator.summary(
|
|
305
1109
|
invoice.items,
|
|
306
|
-
invoice.tax,
|
|
307
|
-
invoice.discount
|
|
1110
|
+
invoice.tax || 0,
|
|
1111
|
+
invoice.discount || 0
|
|
1112
|
+
);
|
|
1113
|
+
return JSON.stringify(
|
|
1114
|
+
{
|
|
1115
|
+
invoice,
|
|
1116
|
+
summary,
|
|
1117
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1118
|
+
},
|
|
1119
|
+
null,
|
|
1120
|
+
2
|
|
308
1121
|
);
|
|
309
|
-
|
|
1122
|
+
}
|
|
1123
|
+
};
|
|
1124
|
+
|
|
1125
|
+
// src/exporters/pdf-exporter.ts
|
|
1126
|
+
var import_puppeteer = __toESM(require("puppeteer"));
|
|
1127
|
+
var PdfExporter = class {
|
|
1128
|
+
static async generate(html) {
|
|
1129
|
+
const browser = await import_puppeteer.default.launch({ headless: true });
|
|
1130
|
+
const page = await browser.newPage();
|
|
1131
|
+
await page.setContent(html, { waitUntil: "networkidle0" });
|
|
1132
|
+
const pdfBuffer = await page.pdf({
|
|
1133
|
+
format: "A4",
|
|
1134
|
+
printBackground: true
|
|
1135
|
+
});
|
|
1136
|
+
await browser.close();
|
|
1137
|
+
return Buffer.from(pdfBuffer);
|
|
310
1138
|
}
|
|
311
1139
|
};
|
|
312
1140
|
|
|
313
1141
|
// src/generators/invoice-generator.ts
|
|
314
1142
|
var InvoiceGenerator = class {
|
|
315
|
-
static
|
|
316
|
-
return
|
|
1143
|
+
static toHTML(invoice, options) {
|
|
1144
|
+
return HtmlExporter.generate(invoice, options);
|
|
317
1145
|
}
|
|
318
1146
|
static toCSV(invoice) {
|
|
319
1147
|
return CsvExporter.generate(invoice);
|
|
@@ -321,10 +1149,14 @@ var InvoiceGenerator = class {
|
|
|
321
1149
|
static toJSON(invoice) {
|
|
322
1150
|
return JsonExporter.generate(invoice);
|
|
323
1151
|
}
|
|
324
|
-
static
|
|
325
|
-
|
|
1152
|
+
static async toPDF(invoice, options) {
|
|
1153
|
+
const html = this.toHTML(invoice, options);
|
|
1154
|
+
return PdfExporter.generate(html);
|
|
326
1155
|
}
|
|
327
1156
|
};
|
|
1157
|
+
|
|
1158
|
+
// src/version.ts
|
|
1159
|
+
var VERSION = "2.0.1";
|
|
328
1160
|
// Annotate the CommonJS export names for ESM import in node:
|
|
329
1161
|
0 && (module.exports = {
|
|
330
1162
|
Billing,
|
|
@@ -332,7 +1164,10 @@ var InvoiceGenerator = class {
|
|
|
332
1164
|
InvoiceCalculator,
|
|
333
1165
|
InvoiceError,
|
|
334
1166
|
InvoiceGenerator,
|
|
1167
|
+
InvoiceNormalizer,
|
|
1168
|
+
InvoiceRenderer,
|
|
335
1169
|
TAX_RATES,
|
|
1170
|
+
VERSION,
|
|
336
1171
|
ValidationError,
|
|
337
1172
|
calculateDiscount,
|
|
338
1173
|
calculateGST,
|