@awadheshs109/billing 1.0.30 → 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 +127 -47
- package/dist/index.d.ts +127 -47
- package/dist/index.js +937 -107
- package/dist/index.mjs +925 -107
- package/package.json +11 -7
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,6 +35,8 @@ __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,
|
|
29
41
|
VERSION: () => VERSION,
|
|
30
42
|
ValidationError: () => ValidationError,
|
|
@@ -119,13 +131,22 @@ var InvoiceCalculator = class {
|
|
|
119
131
|
0
|
|
120
132
|
);
|
|
121
133
|
const discountAmount = subtotal * (discount / 100);
|
|
122
|
-
const
|
|
123
|
-
const taxAmount =
|
|
134
|
+
const taxableAmount = subtotal - discountAmount;
|
|
135
|
+
const taxAmount = taxableAmount * (tax / 100);
|
|
136
|
+
const total = taxableAmount + taxAmount;
|
|
124
137
|
return {
|
|
125
|
-
subtotal
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
+
)
|
|
129
150
|
};
|
|
130
151
|
}
|
|
131
152
|
};
|
|
@@ -133,7 +154,7 @@ var InvoiceCalculator = class {
|
|
|
133
154
|
// src/core/billing.ts
|
|
134
155
|
var Billing = class {
|
|
135
156
|
static getVersion() {
|
|
136
|
-
return "
|
|
157
|
+
return "2.0.1";
|
|
137
158
|
}
|
|
138
159
|
};
|
|
139
160
|
Billing.calculateGST = calculateGST;
|
|
@@ -142,6 +163,14 @@ Billing.calculateDiscount = calculateDiscount;
|
|
|
142
163
|
Billing.formatCurrency = formatCurrency;
|
|
143
164
|
Billing.InvoiceCalculator = InvoiceCalculator;
|
|
144
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
|
+
|
|
145
174
|
// src/utils/date.ts
|
|
146
175
|
function formatDate(date = /* @__PURE__ */ new Date(), locale = "en-IN") {
|
|
147
176
|
return new Intl.DateTimeFormat(locale, {
|
|
@@ -165,135 +194,891 @@ function isValidGST(gst) {
|
|
|
165
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);
|
|
166
195
|
}
|
|
167
196
|
|
|
168
|
-
// src/
|
|
169
|
-
var
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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
|
+
}
|
|
174
236
|
};
|
|
175
237
|
|
|
176
|
-
// src/
|
|
177
|
-
var
|
|
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
|
-
|
|
207
|
-
|
|
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
|
+
};
|
|
208
281
|
}
|
|
209
282
|
};
|
|
210
283
|
|
|
211
|
-
// src/
|
|
212
|
-
var
|
|
213
|
-
static
|
|
214
|
-
return
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
${item.quantity},
|
|
219
|
-
${item.rate}`
|
|
220
|
-
)
|
|
221
|
-
].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
|
+
);
|
|
222
291
|
}
|
|
223
292
|
};
|
|
224
293
|
|
|
225
|
-
// src/exporters/
|
|
226
|
-
var
|
|
294
|
+
// src/exporters/csv-exporter.ts
|
|
295
|
+
var CsvExporter = class {
|
|
227
296
|
static generate(invoice) {
|
|
228
|
-
|
|
229
|
-
invoice,
|
|
230
|
-
|
|
231
|
-
|
|
297
|
+
const summary = InvoiceCalculator.summary(
|
|
298
|
+
invoice.items,
|
|
299
|
+
invoice.tax || 0,
|
|
300
|
+
invoice.discount || 0
|
|
232
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");
|
|
233
319
|
}
|
|
234
320
|
};
|
|
235
321
|
|
|
236
322
|
// src/templates/classic.template.ts
|
|
237
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("");
|
|
238
346
|
return `
|
|
239
|
-
|
|
240
|
-
|
|
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>
|
|
241
503
|
<body>
|
|
242
|
-
|
|
243
|
-
<div class="
|
|
244
|
-
|
|
245
|
-
<h1>INVOICE</h1>
|
|
246
|
-
|
|
504
|
+
<div class="receipt-container">
|
|
505
|
+
<div class="top-header">
|
|
247
506
|
<div>
|
|
248
|
-
|
|
249
|
-
|
|
507
|
+
<div class="company-name">
|
|
508
|
+
${invoice.company?.name || "Zentris Pvt Ltd"}
|
|
250
509
|
</div>
|
|
251
|
-
|
|
252
|
-
<h3>BILL TO</h3>
|
|
253
|
-
|
|
510
|
+
<div class="company-address">
|
|
254
511
|
<p>
|
|
255
|
-
${invoice.
|
|
256
|
-
<br/>
|
|
257
|
-
${invoice.customer.address}
|
|
512
|
+
${invoice.company?.address || "Mumbai, India"}
|
|
258
513
|
</p>
|
|
259
|
-
|
|
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">
|
|
260
556
|
<table>
|
|
261
|
-
|
|
262
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>
|
|
263
584
|
<th>Description</th>
|
|
585
|
+
<th>Qty</th>
|
|
586
|
+
<th>Rate</th>
|
|
264
587
|
<th>Amount</th>
|
|
265
588
|
</tr>
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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">
|
|
269
597
|
<tr>
|
|
270
|
-
<td
|
|
598
|
+
<td>Subtotal</td>
|
|
271
599
|
<td>
|
|
272
|
-
|
|
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)}
|
|
273
619
|
</td>
|
|
274
620
|
</tr>
|
|
275
|
-
`
|
|
276
|
-
).join("")}
|
|
277
|
-
|
|
278
621
|
</table>
|
|
279
|
-
|
|
280
|
-
<div>
|
|
281
|
-
Subtotal:
|
|
282
|
-
\u20B9${summary.subtotal}
|
|
283
622
|
</div>
|
|
284
|
-
|
|
285
|
-
<div>
|
|
286
|
-
Tax:
|
|
287
|
-
\u20B9${summary.tax}
|
|
288
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
|
+
}
|
|
289
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">
|
|
290
866
|
<div>
|
|
291
|
-
|
|
292
|
-
|
|
867
|
+
<div class="company-name">
|
|
868
|
+
${invoice.company?.name || "Zentris Pvt Ltd"}
|
|
293
869
|
</div>
|
|
294
|
-
|
|
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
|
|
295
1081
|
</div>
|
|
296
|
-
|
|
297
1082
|
</body>
|
|
298
1083
|
</html>
|
|
299
1084
|
`;
|
|
@@ -301,20 +1086,62 @@ Total:
|
|
|
301
1086
|
|
|
302
1087
|
// src/exporters/html-exporter.ts
|
|
303
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 {
|
|
304
1107
|
static generate(invoice) {
|
|
305
1108
|
const summary = InvoiceCalculator.summary(
|
|
306
1109
|
invoice.items,
|
|
307
|
-
invoice.tax,
|
|
308
|
-
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
|
|
309
1121
|
);
|
|
310
|
-
|
|
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);
|
|
311
1138
|
}
|
|
312
1139
|
};
|
|
313
1140
|
|
|
314
1141
|
// src/generators/invoice-generator.ts
|
|
315
1142
|
var InvoiceGenerator = class {
|
|
316
|
-
static
|
|
317
|
-
return
|
|
1143
|
+
static toHTML(invoice, options) {
|
|
1144
|
+
return HtmlExporter.generate(invoice, options);
|
|
318
1145
|
}
|
|
319
1146
|
static toCSV(invoice) {
|
|
320
1147
|
return CsvExporter.generate(invoice);
|
|
@@ -322,13 +1149,14 @@ var InvoiceGenerator = class {
|
|
|
322
1149
|
static toJSON(invoice) {
|
|
323
1150
|
return JsonExporter.generate(invoice);
|
|
324
1151
|
}
|
|
325
|
-
static
|
|
326
|
-
|
|
1152
|
+
static async toPDF(invoice, options) {
|
|
1153
|
+
const html = this.toHTML(invoice, options);
|
|
1154
|
+
return PdfExporter.generate(html);
|
|
327
1155
|
}
|
|
328
1156
|
};
|
|
329
1157
|
|
|
330
1158
|
// src/version.ts
|
|
331
|
-
var VERSION = "
|
|
1159
|
+
var VERSION = "2.0.1";
|
|
332
1160
|
// Annotate the CommonJS export names for ESM import in node:
|
|
333
1161
|
0 && (module.exports = {
|
|
334
1162
|
Billing,
|
|
@@ -336,6 +1164,8 @@ var VERSION = "1.1.0";
|
|
|
336
1164
|
InvoiceCalculator,
|
|
337
1165
|
InvoiceError,
|
|
338
1166
|
InvoiceGenerator,
|
|
1167
|
+
InvoiceNormalizer,
|
|
1168
|
+
InvoiceRenderer,
|
|
339
1169
|
TAX_RATES,
|
|
340
1170
|
VERSION,
|
|
341
1171
|
ValidationError,
|