@fin.cx/skr 1.1.0 → 1.2.0

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.
Files changed (46) hide show
  1. package/dist_ts/index.d.ts +6 -0
  2. package/dist_ts/index.js +7 -1
  3. package/dist_ts/plugins.d.ts +8 -1
  4. package/dist_ts/plugins.js +10 -2
  5. package/dist_ts/skr.api.d.ts +70 -0
  6. package/dist_ts/skr.api.js +348 -1
  7. package/dist_ts/skr.export.accounts.d.ts +53 -0
  8. package/dist_ts/skr.export.accounts.js +111 -0
  9. package/dist_ts/skr.export.balances.d.ts +59 -0
  10. package/dist_ts/skr.export.balances.js +205 -0
  11. package/dist_ts/skr.export.d.ts +110 -0
  12. package/dist_ts/skr.export.js +315 -0
  13. package/dist_ts/skr.export.ledger.d.ts +95 -0
  14. package/dist_ts/skr.export.ledger.js +164 -0
  15. package/dist_ts/skr.export.pdf.d.ts +82 -0
  16. package/dist_ts/skr.export.pdf.js +548 -0
  17. package/dist_ts/skr.invoice.adapter.d.ts +98 -0
  18. package/dist_ts/skr.invoice.adapter.js +476 -0
  19. package/dist_ts/skr.invoice.booking.d.ts +102 -0
  20. package/dist_ts/skr.invoice.booking.js +556 -0
  21. package/dist_ts/skr.invoice.entity.d.ts +287 -0
  22. package/dist_ts/skr.invoice.entity.js +2 -0
  23. package/dist_ts/skr.invoice.mapper.d.ts +69 -0
  24. package/dist_ts/skr.invoice.mapper.js +401 -0
  25. package/dist_ts/skr.invoice.storage.d.ts +140 -0
  26. package/dist_ts/skr.invoice.storage.js +529 -0
  27. package/dist_ts/skr.security.d.ts +65 -0
  28. package/dist_ts/skr.security.js +319 -0
  29. package/dist_ts/skr.types.d.ts +1 -0
  30. package/package.json +17 -12
  31. package/readme.md +207 -16
  32. package/ts/index.ts +6 -0
  33. package/ts/plugins.ts +22 -1
  34. package/ts/skr.api.ts +485 -0
  35. package/ts/skr.export.accounts.ts +154 -0
  36. package/ts/skr.export.balances.ts +270 -0
  37. package/ts/skr.export.ledger.ts +249 -0
  38. package/ts/skr.export.pdf.ts +601 -0
  39. package/ts/skr.export.ts +443 -0
  40. package/ts/skr.invoice.adapter.ts +581 -0
  41. package/ts/skr.invoice.booking.ts +738 -0
  42. package/ts/skr.invoice.entity.ts +351 -0
  43. package/ts/skr.invoice.mapper.ts +486 -0
  44. package/ts/skr.invoice.storage.ts +710 -0
  45. package/ts/skr.security.ts +405 -0
  46. package/ts/skr.types.ts +1 -0
@@ -0,0 +1,82 @@
1
+ import type { ITrialBalanceReport, IIncomeStatement, IBalanceSheet } from './skr.types.js';
2
+ export interface IPdfReportOptions {
3
+ companyName: string;
4
+ companyAddress?: string;
5
+ taxId?: string;
6
+ registrationNumber?: string;
7
+ fiscalYear: number;
8
+ dateFrom: Date;
9
+ dateTo: Date;
10
+ preparedBy?: string;
11
+ preparedDate?: Date;
12
+ }
13
+ export declare class PdfReportGenerator {
14
+ private exportPath;
15
+ private options;
16
+ private pdfInstance;
17
+ constructor(exportPath: string, options: IPdfReportOptions);
18
+ /**
19
+ * Initializes the PDF generator
20
+ */
21
+ initialize(): Promise<void>;
22
+ /**
23
+ * Generates the trial balance PDF report
24
+ */
25
+ generateTrialBalancePdf(report: ITrialBalanceReport): Promise<Buffer>;
26
+ /**
27
+ * Generates the income statement PDF report
28
+ */
29
+ generateIncomeStatementPdf(report: IIncomeStatement): Promise<Buffer>;
30
+ /**
31
+ * Generates the balance sheet PDF report
32
+ */
33
+ generateBalanceSheetPdf(report: IBalanceSheet): Promise<Buffer>;
34
+ /**
35
+ * Generates the comprehensive Jahresabschluss PDF
36
+ */
37
+ generateJahresabschlussPdf(trialBalance: ITrialBalanceReport, incomeStatement: IIncomeStatement, balanceSheet: IBalanceSheet): Promise<Buffer>;
38
+ /**
39
+ * Generates HTML for trial balance report
40
+ */
41
+ private generateTrialBalanceHtml;
42
+ /**
43
+ * Generates HTML for income statement report
44
+ */
45
+ private generateIncomeStatementHtml;
46
+ /**
47
+ * Generates HTML for balance sheet report
48
+ */
49
+ private generateBalanceSheetHtml;
50
+ /**
51
+ * Generates comprehensive Jahresabschluss HTML
52
+ */
53
+ private generateJahresabschlussHtml;
54
+ /**
55
+ * Generates the report header
56
+ */
57
+ private generateHeader;
58
+ /**
59
+ * Generates the report footer
60
+ */
61
+ private generateFooter;
62
+ /**
63
+ * Gets the base CSS styles for all reports
64
+ */
65
+ private getBaseStyles;
66
+ /**
67
+ * Formats number in German format (1.234,56)
68
+ */
69
+ private formatGermanNumber;
70
+ /**
71
+ * Formats date in German format (DD.MM.YYYY)
72
+ */
73
+ private formatGermanDate;
74
+ /**
75
+ * Saves a PDF report to the export directory
76
+ */
77
+ savePdfReport(filename: string, pdfBuffer: Buffer): Promise<string>;
78
+ /**
79
+ * Closes the PDF generator
80
+ */
81
+ close(): Promise<void>;
82
+ }
@@ -0,0 +1,548 @@
1
+ import * as plugins from './plugins.js';
2
+ import * as path from 'path';
3
+ export class PdfReportGenerator {
4
+ constructor(exportPath, options) {
5
+ this.pdfInstance = null;
6
+ this.exportPath = exportPath;
7
+ this.options = options;
8
+ }
9
+ /**
10
+ * Initializes the PDF generator
11
+ */
12
+ async initialize() {
13
+ this.pdfInstance = new plugins.smartpdf.SmartPdf();
14
+ await this.pdfInstance.start();
15
+ }
16
+ /**
17
+ * Generates the trial balance PDF report
18
+ */
19
+ async generateTrialBalancePdf(report) {
20
+ if (!this.pdfInstance) {
21
+ throw new Error('PDF generator not initialized');
22
+ }
23
+ const html = this.generateTrialBalanceHtml(report);
24
+ const pdfResult = await this.pdfInstance.getA4PdfResultForHtmlString(html);
25
+ return Buffer.from(pdfResult.buffer);
26
+ }
27
+ /**
28
+ * Generates the income statement PDF report
29
+ */
30
+ async generateIncomeStatementPdf(report) {
31
+ if (!this.pdfInstance) {
32
+ throw new Error('PDF generator not initialized');
33
+ }
34
+ const html = this.generateIncomeStatementHtml(report);
35
+ const pdfResult = await this.pdfInstance.getA4PdfResultForHtmlString(html);
36
+ return Buffer.from(pdfResult.buffer);
37
+ }
38
+ /**
39
+ * Generates the balance sheet PDF report
40
+ */
41
+ async generateBalanceSheetPdf(report) {
42
+ if (!this.pdfInstance) {
43
+ throw new Error('PDF generator not initialized');
44
+ }
45
+ const html = this.generateBalanceSheetHtml(report);
46
+ const pdfResult = await this.pdfInstance.getA4PdfResultForHtmlString(html);
47
+ return Buffer.from(pdfResult.buffer);
48
+ }
49
+ /**
50
+ * Generates the comprehensive Jahresabschluss PDF
51
+ */
52
+ async generateJahresabschlussPdf(trialBalance, incomeStatement, balanceSheet) {
53
+ if (!this.pdfInstance) {
54
+ throw new Error('PDF generator not initialized');
55
+ }
56
+ const html = this.generateJahresabschlussHtml(trialBalance, incomeStatement, balanceSheet);
57
+ const pdfResult = await this.pdfInstance.getA4PdfResultForHtmlString(html);
58
+ return Buffer.from(pdfResult.buffer);
59
+ }
60
+ /**
61
+ * Generates HTML for trial balance report
62
+ */
63
+ generateTrialBalanceHtml(report) {
64
+ const entries = report.entries || [];
65
+ const tableRows = entries.map(entry => `
66
+ <tr>
67
+ <td>${entry.accountNumber}</td>
68
+ <td>${entry.accountName}</td>
69
+ <td class="number">${this.formatGermanNumber(0)}</td>
70
+ <td class="number">${this.formatGermanNumber(entry.debitBalance)}</td>
71
+ <td class="number">${this.formatGermanNumber(entry.creditBalance)}</td>
72
+ <td class="number">${this.formatGermanNumber(entry.netBalance)}</td>
73
+ </tr>
74
+ `).join('');
75
+ return `
76
+ <!DOCTYPE html>
77
+ <html>
78
+ <head>
79
+ <meta charset="UTF-8">
80
+ <style>
81
+ ${this.getBaseStyles()}
82
+ </style>
83
+ </head>
84
+ <body>
85
+ ${this.generateHeader('Summen- und Saldenliste')}
86
+
87
+ <table class="report-table">
88
+ <thead>
89
+ <tr>
90
+ <th>Konto</th>
91
+ <th>Bezeichnung</th>
92
+ <th>Anfangssaldo</th>
93
+ <th>Soll</th>
94
+ <th>Haben</th>
95
+ <th>Saldo</th>
96
+ </tr>
97
+ </thead>
98
+ <tbody>
99
+ ${tableRows}
100
+ </tbody>
101
+ <tfoot>
102
+ <tr class="total-row">
103
+ <td colspan="3">Summe</td>
104
+ <td class="number">${this.formatGermanNumber(report.totalDebits)}</td>
105
+ <td class="number">${this.formatGermanNumber(report.totalCredits)}</td>
106
+ <td class="number">${this.formatGermanNumber(report.totalDebits - report.totalCredits)}</td>
107
+ </tr>
108
+ </tfoot>
109
+ </table>
110
+
111
+ ${this.generateFooter()}
112
+ </body>
113
+ </html>
114
+ `;
115
+ }
116
+ /**
117
+ * Generates HTML for income statement report
118
+ */
119
+ generateIncomeStatementHtml(report) {
120
+ const revenueRows = (report.revenue || []).map(entry => `
121
+ <tr>
122
+ <td>${entry.accountNumber}</td>
123
+ <td>${entry.accountName}</td>
124
+ <td class="number">${this.formatGermanNumber(entry.amount)}</td>
125
+ </tr>
126
+ `).join('');
127
+ const expenseRows = (report.expenses || []).map(entry => `
128
+ <tr>
129
+ <td>${entry.accountNumber}</td>
130
+ <td>${entry.accountName}</td>
131
+ <td class="number">${this.formatGermanNumber(entry.amount)}</td>
132
+ </tr>
133
+ `).join('');
134
+ return `
135
+ <!DOCTYPE html>
136
+ <html>
137
+ <head>
138
+ <meta charset="UTF-8">
139
+ <style>
140
+ ${this.getBaseStyles()}
141
+ </style>
142
+ </head>
143
+ <body>
144
+ ${this.generateHeader('Gewinn- und Verlustrechnung')}
145
+
146
+ <h2>Erträge</h2>
147
+ <table class="report-table">
148
+ <thead>
149
+ <tr>
150
+ <th>Konto</th>
151
+ <th>Bezeichnung</th>
152
+ <th>Betrag</th>
153
+ </tr>
154
+ </thead>
155
+ <tbody>
156
+ ${revenueRows}
157
+ </tbody>
158
+ <tfoot>
159
+ <tr class="subtotal-row">
160
+ <td colspan="2">Summe Erträge</td>
161
+ <td class="number">${this.formatGermanNumber(report.totalRevenue)}</td>
162
+ </tr>
163
+ </tfoot>
164
+ </table>
165
+
166
+ <h2>Aufwendungen</h2>
167
+ <table class="report-table">
168
+ <thead>
169
+ <tr>
170
+ <th>Konto</th>
171
+ <th>Bezeichnung</th>
172
+ <th>Betrag</th>
173
+ </tr>
174
+ </thead>
175
+ <tbody>
176
+ ${expenseRows}
177
+ </tbody>
178
+ <tfoot>
179
+ <tr class="subtotal-row">
180
+ <td colspan="2">Summe Aufwendungen</td>
181
+ <td class="number">${this.formatGermanNumber(report.totalExpenses)}</td>
182
+ </tr>
183
+ </tfoot>
184
+ </table>
185
+
186
+ <div class="result-section">
187
+ <h2>Ergebnis</h2>
188
+ <table class="summary-table">
189
+ <tr>
190
+ <td>Erträge</td>
191
+ <td class="number">${this.formatGermanNumber(report.totalRevenue)}</td>
192
+ </tr>
193
+ <tr>
194
+ <td>Aufwendungen</td>
195
+ <td class="number">- ${this.formatGermanNumber(report.totalExpenses)}</td>
196
+ </tr>
197
+ <tr class="total-row">
198
+ <td>${report.netIncome >= 0 ? 'Jahresüberschuss' : 'Jahresfehlbetrag'}</td>
199
+ <td class="number ${report.netIncome >= 0 ? 'positive' : 'negative'}">
200
+ ${this.formatGermanNumber(report.netIncome)}
201
+ </td>
202
+ </tr>
203
+ </table>
204
+ </div>
205
+
206
+ ${this.generateFooter()}
207
+ </body>
208
+ </html>
209
+ `;
210
+ }
211
+ /**
212
+ * Generates HTML for balance sheet report
213
+ */
214
+ generateBalanceSheetHtml(report) {
215
+ const assetRows = [...(report.assets.current || []), ...(report.assets.fixed || [])].map(entry => `
216
+ <tr>
217
+ <td>${entry.accountNumber}</td>
218
+ <td>${entry.accountName}</td>
219
+ <td class="number">${this.formatGermanNumber(entry.amount)}</td>
220
+ </tr>
221
+ `).join('');
222
+ const liabilityRows = [...(report.liabilities.current || []), ...(report.liabilities.longTerm || [])].map(entry => `
223
+ <tr>
224
+ <td>${entry.accountNumber}</td>
225
+ <td>${entry.accountName}</td>
226
+ <td class="number">${this.formatGermanNumber(entry.amount)}</td>
227
+ </tr>
228
+ `).join('');
229
+ const equityRows = (report.equity.entries || []).map(entry => `
230
+ <tr>
231
+ <td>${entry.accountNumber}</td>
232
+ <td>${entry.accountName}</td>
233
+ <td class="number">${this.formatGermanNumber(entry.amount)}</td>
234
+ </tr>
235
+ `).join('');
236
+ return `
237
+ <!DOCTYPE html>
238
+ <html>
239
+ <head>
240
+ <meta charset="UTF-8">
241
+ <style>
242
+ ${this.getBaseStyles()}
243
+ </style>
244
+ </head>
245
+ <body>
246
+ ${this.generateHeader('Bilanz')}
247
+
248
+ <div class="balance-sheet">
249
+ <div class="aktiva">
250
+ <h2>Aktiva</h2>
251
+ <table class="report-table">
252
+ <thead>
253
+ <tr>
254
+ <th>Konto</th>
255
+ <th>Bezeichnung</th>
256
+ <th>Betrag</th>
257
+ </tr>
258
+ </thead>
259
+ <tbody>
260
+ ${assetRows}
261
+ </tbody>
262
+ <tfoot>
263
+ <tr class="total-row">
264
+ <td colspan="2">Summe Aktiva</td>
265
+ <td class="number">${this.formatGermanNumber(report.assets.totalAssets)}</td>
266
+ </tr>
267
+ </tfoot>
268
+ </table>
269
+ </div>
270
+
271
+ <div class="passiva">
272
+ <h2>Passiva</h2>
273
+
274
+ <h3>Eigenkapital</h3>
275
+ <table class="report-table">
276
+ <tbody>
277
+ ${equityRows}
278
+ </tbody>
279
+ <tfoot>
280
+ <tr class="subtotal-row">
281
+ <td colspan="2">Summe Eigenkapital</td>
282
+ <td class="number">${this.formatGermanNumber(report.equity.totalEquity)}</td>
283
+ </tr>
284
+ </tfoot>
285
+ </table>
286
+
287
+ <h3>Fremdkapital</h3>
288
+ <table class="report-table">
289
+ <tbody>
290
+ ${liabilityRows}
291
+ </tbody>
292
+ <tfoot>
293
+ <tr class="subtotal-row">
294
+ <td colspan="2">Summe Fremdkapital</td>
295
+ <td class="number">${this.formatGermanNumber(report.liabilities.totalLiabilities)}</td>
296
+ </tr>
297
+ </tfoot>
298
+ </table>
299
+
300
+ <table class="summary-table">
301
+ <tr class="total-row">
302
+ <td>Summe Passiva</td>
303
+ <td class="number">${this.formatGermanNumber(report.liabilities.totalLiabilities + report.equity.totalEquity)}</td>
304
+ </tr>
305
+ </table>
306
+ </div>
307
+ </div>
308
+
309
+ ${this.generateFooter()}
310
+ </body>
311
+ </html>
312
+ `;
313
+ }
314
+ /**
315
+ * Generates comprehensive Jahresabschluss HTML
316
+ */
317
+ generateJahresabschlussHtml(trialBalance, incomeStatement, balanceSheet) {
318
+ return `
319
+ <!DOCTYPE html>
320
+ <html>
321
+ <head>
322
+ <meta charset="UTF-8">
323
+ <style>
324
+ ${this.getBaseStyles()}
325
+ .page-break { page-break-after: always; }
326
+ .cover-page {
327
+ display: flex;
328
+ flex-direction: column;
329
+ justify-content: center;
330
+ align-items: center;
331
+ height: 100vh;
332
+ text-align: center;
333
+ }
334
+ .cover-page h1 { font-size: 36px; margin-bottom: 20px; }
335
+ .cover-page h2 { font-size: 24px; margin-bottom: 40px; }
336
+ .toc { margin-top: 50px; }
337
+ .toc h2 { margin-bottom: 20px; }
338
+ .toc ul { list-style: none; padding: 0; }
339
+ .toc li { margin: 10px 0; font-size: 16px; }
340
+ </style>
341
+ </head>
342
+ <body>
343
+ <div class="cover-page">
344
+ <h1>Jahresabschluss</h1>
345
+ <h2>${this.options.companyName}</h2>
346
+ <p>Geschäftsjahr ${this.options.fiscalYear}</p>
347
+ <p>${this.formatGermanDate(this.options.dateFrom)} bis ${this.formatGermanDate(this.options.dateTo)}</p>
348
+
349
+ <div class="toc">
350
+ <h2>Inhalt</h2>
351
+ <ul>
352
+ <li>1. Bilanz</li>
353
+ <li>2. Gewinn- und Verlustrechnung</li>
354
+ <li>3. Summen- und Saldenliste</li>
355
+ </ul>
356
+ </div>
357
+ </div>
358
+
359
+ <div class="page-break"></div>
360
+ ${this.generateBalanceSheetHtml(balanceSheet)}
361
+
362
+ <div class="page-break"></div>
363
+ ${this.generateIncomeStatementHtml(incomeStatement)}
364
+
365
+ <div class="page-break"></div>
366
+ ${this.generateTrialBalanceHtml(trialBalance)}
367
+ </body>
368
+ </html>
369
+ `;
370
+ }
371
+ /**
372
+ * Generates the report header
373
+ */
374
+ generateHeader(reportTitle) {
375
+ return `
376
+ <div class="header">
377
+ <h1>${this.options.companyName}</h1>
378
+ ${this.options.companyAddress ? `<p>${this.options.companyAddress}</p>` : ''}
379
+ ${this.options.taxId ? `<p>Steuernummer: ${this.options.taxId}</p>` : ''}
380
+ ${this.options.registrationNumber ? `<p>Handelsregister: ${this.options.registrationNumber}</p>` : ''}
381
+ <hr>
382
+ <h2>${reportTitle}</h2>
383
+ <p>Periode: ${this.formatGermanDate(this.options.dateFrom)} bis ${this.formatGermanDate(this.options.dateTo)}</p>
384
+ </div>
385
+ `;
386
+ }
387
+ /**
388
+ * Generates the report footer
389
+ */
390
+ generateFooter() {
391
+ const preparedDate = this.options.preparedDate || new Date();
392
+ return `
393
+ <div class="footer">
394
+ <hr>
395
+ <p>Erstellt am: ${this.formatGermanDate(preparedDate)}</p>
396
+ ${this.options.preparedBy ? `<p>Erstellt von: ${this.options.preparedBy}</p>` : ''}
397
+ <p class="disclaimer">
398
+ Dieser Bericht wurde automatisch generiert und ist Teil des revisionssicheren
399
+ Jahresabschluss-Exports gemäß GoBD.
400
+ </p>
401
+ </div>
402
+ `;
403
+ }
404
+ /**
405
+ * Gets the base CSS styles for all reports
406
+ */
407
+ getBaseStyles() {
408
+ return `
409
+ body {
410
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
411
+ margin: 40px;
412
+ color: #333;
413
+ line-height: 1.6;
414
+ }
415
+ h1 { color: #2c3e50; margin-bottom: 10px; }
416
+ h2 { color: #34495e; margin-top: 30px; margin-bottom: 15px; }
417
+ h3 { color: #7f8c8d; margin-top: 20px; margin-bottom: 10px; }
418
+
419
+ .header {
420
+ text-align: center;
421
+ margin-bottom: 40px;
422
+ }
423
+
424
+ .footer {
425
+ margin-top: 50px;
426
+ text-align: center;
427
+ font-size: 12px;
428
+ color: #7f8c8d;
429
+ }
430
+
431
+ .disclaimer {
432
+ margin-top: 20px;
433
+ font-style: italic;
434
+ }
435
+
436
+ table {
437
+ width: 100%;
438
+ border-collapse: collapse;
439
+ margin: 20px 0;
440
+ }
441
+
442
+ th {
443
+ background-color: #34495e;
444
+ color: white;
445
+ padding: 10px;
446
+ text-align: left;
447
+ font-weight: 600;
448
+ }
449
+
450
+ td {
451
+ padding: 8px;
452
+ border-bottom: 1px solid #ecf0f1;
453
+ }
454
+
455
+ tbody tr:hover {
456
+ background-color: #f8f9fa;
457
+ }
458
+
459
+ .number {
460
+ text-align: right;
461
+ font-family: 'Courier New', monospace;
462
+ }
463
+
464
+ .total-row {
465
+ font-weight: bold;
466
+ background-color: #ecf0f1;
467
+ }
468
+
469
+ .subtotal-row {
470
+ font-weight: 600;
471
+ background-color: #f8f9fa;
472
+ }
473
+
474
+ .positive {
475
+ color: #27ae60;
476
+ }
477
+
478
+ .negative {
479
+ color: #e74c3c;
480
+ }
481
+
482
+ .result-section {
483
+ margin-top: 40px;
484
+ padding: 20px;
485
+ background-color: #f8f9fa;
486
+ border-radius: 5px;
487
+ }
488
+
489
+ .summary-table {
490
+ max-width: 500px;
491
+ margin: 20px auto;
492
+ }
493
+
494
+ .balance-sheet {
495
+ display: flex;
496
+ gap: 40px;
497
+ }
498
+
499
+ .aktiva, .passiva {
500
+ flex: 1;
501
+ }
502
+
503
+ @media print {
504
+ body { margin: 20px; }
505
+ .page-break { page-break-after: always; }
506
+ }
507
+ `;
508
+ }
509
+ /**
510
+ * Formats number in German format (1.234,56)
511
+ */
512
+ formatGermanNumber(value) {
513
+ return value.toLocaleString('de-DE', {
514
+ minimumFractionDigits: 2,
515
+ maximumFractionDigits: 2
516
+ });
517
+ }
518
+ /**
519
+ * Formats date in German format (DD.MM.YYYY)
520
+ */
521
+ formatGermanDate(date) {
522
+ return date.toLocaleDateString('de-DE', {
523
+ day: '2-digit',
524
+ month: '2-digit',
525
+ year: 'numeric'
526
+ });
527
+ }
528
+ /**
529
+ * Saves a PDF report to the export directory
530
+ */
531
+ async savePdfReport(filename, pdfBuffer) {
532
+ const reportsDir = path.join(this.exportPath, 'data', 'reports');
533
+ await plugins.smartfile.fs.ensureDir(reportsDir);
534
+ const filePath = path.join(reportsDir, filename);
535
+ await plugins.smartfile.memory.toFs(pdfBuffer, filePath);
536
+ return filePath;
537
+ }
538
+ /**
539
+ * Closes the PDF generator
540
+ */
541
+ async close() {
542
+ if (this.pdfInstance) {
543
+ await this.pdfInstance.stop();
544
+ this.pdfInstance = null;
545
+ }
546
+ }
547
+ }
548
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2tyLmV4cG9ydC5wZGYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9za3IuZXhwb3J0LnBkZi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQWU3QixNQUFNLE9BQU8sa0JBQWtCO0lBSzdCLFlBQVksVUFBa0IsRUFBRSxPQUEwQjtRQUZsRCxnQkFBVyxHQUFxQyxJQUFJLENBQUM7UUFHM0QsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDekIsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLFVBQVU7UUFDckIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDbkQsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxNQUEyQjtRQUM5RCxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sSUFBSSxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQztRQUNuRCxDQUFDO1FBRUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ25ELE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzRSxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxNQUF3QjtRQUM5RCxJQUFJLENBQUMs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