@fin.cx/skr 1.0.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 (54) 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 +354 -3
  7. package/dist_ts/skr.classes.journalentry.d.ts +1 -0
  8. package/dist_ts/skr.classes.journalentry.js +55 -15
  9. package/dist_ts/skr.classes.ledger.d.ts +4 -0
  10. package/dist_ts/skr.classes.ledger.js +72 -1
  11. package/dist_ts/skr.classes.reports.js +56 -22
  12. package/dist_ts/skr.export.accounts.d.ts +53 -0
  13. package/dist_ts/skr.export.accounts.js +111 -0
  14. package/dist_ts/skr.export.balances.d.ts +59 -0
  15. package/dist_ts/skr.export.balances.js +205 -0
  16. package/dist_ts/skr.export.d.ts +110 -0
  17. package/dist_ts/skr.export.js +315 -0
  18. package/dist_ts/skr.export.ledger.d.ts +95 -0
  19. package/dist_ts/skr.export.ledger.js +164 -0
  20. package/dist_ts/skr.export.pdf.d.ts +82 -0
  21. package/dist_ts/skr.export.pdf.js +548 -0
  22. package/dist_ts/skr.invoice.adapter.d.ts +98 -0
  23. package/dist_ts/skr.invoice.adapter.js +476 -0
  24. package/dist_ts/skr.invoice.booking.d.ts +102 -0
  25. package/dist_ts/skr.invoice.booking.js +556 -0
  26. package/dist_ts/skr.invoice.entity.d.ts +287 -0
  27. package/dist_ts/skr.invoice.entity.js +2 -0
  28. package/dist_ts/skr.invoice.mapper.d.ts +69 -0
  29. package/dist_ts/skr.invoice.mapper.js +401 -0
  30. package/dist_ts/skr.invoice.storage.d.ts +140 -0
  31. package/dist_ts/skr.invoice.storage.js +529 -0
  32. package/dist_ts/skr.security.d.ts +65 -0
  33. package/dist_ts/skr.security.js +319 -0
  34. package/dist_ts/skr.types.d.ts +1 -0
  35. package/package.json +18 -12
  36. package/readme.md +461 -132
  37. package/ts/index.ts +6 -0
  38. package/ts/plugins.ts +22 -1
  39. package/ts/skr.api.ts +489 -2
  40. package/ts/skr.classes.journalentry.ts +63 -14
  41. package/ts/skr.classes.ledger.ts +85 -0
  42. package/ts/skr.classes.reports.ts +64 -21
  43. package/ts/skr.export.accounts.ts +154 -0
  44. package/ts/skr.export.balances.ts +270 -0
  45. package/ts/skr.export.ledger.ts +249 -0
  46. package/ts/skr.export.pdf.ts +601 -0
  47. package/ts/skr.export.ts +443 -0
  48. package/ts/skr.invoice.adapter.ts +581 -0
  49. package/ts/skr.invoice.booking.ts +738 -0
  50. package/ts/skr.invoice.entity.ts +351 -0
  51. package/ts/skr.invoice.mapper.ts +486 -0
  52. package/ts/skr.invoice.storage.ts +710 -0
  53. package/ts/skr.security.ts +405 -0
  54. package/ts/skr.types.ts +1 -0
@@ -0,0 +1,53 @@
1
+ import type { IAccountData, TSKRType } from './skr.types.js';
2
+ export interface IAccountDataExport extends IAccountData {
3
+ parentAccount?: string;
4
+ defaultTaxCode?: string;
5
+ activeFrom?: Date | string;
6
+ activeTo?: Date | string;
7
+ }
8
+ export interface IAccountExportRow {
9
+ account_code: string;
10
+ name: string;
11
+ type: string;
12
+ class: number;
13
+ parent?: string;
14
+ skr_set: TSKRType;
15
+ tax_code_default?: string;
16
+ active_from?: string;
17
+ active_to?: string;
18
+ description?: string;
19
+ is_active: boolean;
20
+ }
21
+ export declare class AccountsExporter {
22
+ private exportPath;
23
+ private accounts;
24
+ constructor(exportPath: string);
25
+ /**
26
+ * Adds an account to the export
27
+ */
28
+ addAccount(account: IAccountDataExport): void;
29
+ /**
30
+ * Exports accounts to CSV format
31
+ */
32
+ exportToCSV(): Promise<void>;
33
+ /**
34
+ * Exports accounts to JSON format (alternative)
35
+ */
36
+ exportToJSON(): Promise<void>;
37
+ /**
38
+ * Escapes CSV values
39
+ */
40
+ private escapeCSV;
41
+ /**
42
+ * Formats a date to ISO date string
43
+ */
44
+ private formatDate;
45
+ /**
46
+ * Gets the number of accounts
47
+ */
48
+ getAccountCount(): number;
49
+ /**
50
+ * Clears the accounts list
51
+ */
52
+ clear(): void;
53
+ }
@@ -0,0 +1,111 @@
1
+ import * as plugins from './plugins.js';
2
+ import * as path from 'path';
3
+ export class AccountsExporter {
4
+ constructor(exportPath) {
5
+ this.accounts = [];
6
+ this.exportPath = exportPath;
7
+ }
8
+ /**
9
+ * Adds an account to the export
10
+ */
11
+ addAccount(account) {
12
+ const exportRow = {
13
+ account_code: account.accountNumber,
14
+ name: account.accountName,
15
+ type: account.accountType,
16
+ class: account.accountClass,
17
+ parent: account.parentAccount,
18
+ skr_set: account.skrType,
19
+ tax_code_default: account.defaultTaxCode,
20
+ active_from: account.activeFrom ? this.formatDate(account.activeFrom) : undefined,
21
+ active_to: account.activeTo ? this.formatDate(account.activeTo) : undefined,
22
+ description: account.description,
23
+ is_active: account.isActive !== false
24
+ };
25
+ this.accounts.push(exportRow);
26
+ }
27
+ /**
28
+ * Exports accounts to CSV format
29
+ */
30
+ async exportToCSV() {
31
+ const csvPath = path.join(this.exportPath, 'data', 'accounting', 'accounts.csv');
32
+ await plugins.smartfile.fs.ensureDir(path.dirname(csvPath));
33
+ // Create CSV header
34
+ const headers = [
35
+ 'account_code',
36
+ 'name',
37
+ 'type',
38
+ 'class',
39
+ 'parent',
40
+ 'skr_set',
41
+ 'tax_code_default',
42
+ 'active_from',
43
+ 'active_to',
44
+ 'description',
45
+ 'is_active'
46
+ ];
47
+ let csvContent = headers.join(',') + '\n';
48
+ // Add account rows
49
+ for (const account of this.accounts) {
50
+ const row = [
51
+ this.escapeCSV(account.account_code),
52
+ this.escapeCSV(account.name),
53
+ this.escapeCSV(account.type),
54
+ account.class.toString(),
55
+ this.escapeCSV(account.parent || ''),
56
+ this.escapeCSV(account.skr_set),
57
+ this.escapeCSV(account.tax_code_default || ''),
58
+ this.escapeCSV(account.active_from || ''),
59
+ this.escapeCSV(account.active_to || ''),
60
+ this.escapeCSV(account.description || ''),
61
+ account.is_active.toString()
62
+ ];
63
+ csvContent += row.join(',') + '\n';
64
+ }
65
+ await plugins.smartfile.memory.toFs(csvContent, csvPath);
66
+ }
67
+ /**
68
+ * Exports accounts to JSON format (alternative)
69
+ */
70
+ async exportToJSON() {
71
+ const jsonPath = path.join(this.exportPath, 'data', 'accounting', 'accounts.json');
72
+ await plugins.smartfile.fs.ensureDir(path.dirname(jsonPath));
73
+ const jsonData = {
74
+ schema_version: '1.0',
75
+ export_date: new Date().toISOString(),
76
+ accounts: this.accounts
77
+ };
78
+ await plugins.smartfile.memory.toFs(JSON.stringify(jsonData, null, 2), jsonPath);
79
+ }
80
+ /**
81
+ * Escapes CSV values
82
+ */
83
+ escapeCSV(value) {
84
+ if (value.includes(',') || value.includes('"') || value.includes('\n')) {
85
+ return `"${value.replace(/"/g, '""')}"`;
86
+ }
87
+ return value;
88
+ }
89
+ /**
90
+ * Formats a date to ISO date string
91
+ */
92
+ formatDate(date) {
93
+ if (typeof date === 'string') {
94
+ return date.split('T')[0];
95
+ }
96
+ return date.toISOString().split('T')[0];
97
+ }
98
+ /**
99
+ * Gets the number of accounts
100
+ */
101
+ getAccountCount() {
102
+ return this.accounts.length;
103
+ }
104
+ /**
105
+ * Clears the accounts list
106
+ */
107
+ clear() {
108
+ this.accounts = [];
109
+ }
110
+ }
111
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2tyLmV4cG9ydC5hY2NvdW50cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3Nrci5leHBvcnQuYWNjb3VudHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUF5QjdCLE1BQU0sT0FBTyxnQkFBZ0I7SUFJM0IsWUFBWSxVQUFrQjtRQUZ0QixhQUFRLEdBQXdCLEVBQUUsQ0FBQztRQUd6QyxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztJQUMvQixDQUFDO0lBRUQ7O09BRUc7SUFDSSxVQUFVLENBQUMsT0FBMkI7UUFDM0MsTUFBTSxTQUFTLEdBQXNCO1lBQ25DLFlBQVksRUFBRSxPQUFPLENBQUMsYUFBYTtZQUNuQyxJQUFJLEVBQUUsT0FBTyxDQUFDLFdBQVc7WUFDekIsSUFBSSxFQUFFLE9BQU8sQ0FBQyxXQUFXO1lBQ3pCLEtBQUssRUFBRSxPQUFPLENBQUMsWUFBWTtZQUMzQixNQUFNLEVBQUUsT0FBTyxDQUFDLGFBQWE7WUFDN0IsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO1lBQ3hCLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxjQUFjO1lBQ3hDLFdBQVcsRUFBRSxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztZQUNqRixTQUFTLEVBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7WUFDM0UsV0FBVyxFQUFFLE9BQU8sQ0FBQyxXQUFXO1lBQ2hDLFNBQVMsRUFBRSxPQUFPLENBQUMsUUFBUSxLQUFLLEtBQUs7U0FDdEMsQ0FBQztRQUVGLElBQUksQ0FBQyxRQUFR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
@@ -0,0 +1,59 @@
1
+ import type { IAccountBalance } from './skr.types.js';
2
+ export interface IAccountBalanceExport extends IAccountBalance {
3
+ openingBalance?: number;
4
+ transactionCount?: number;
5
+ }
6
+ export interface IBalanceExportRow {
7
+ account_code: string;
8
+ account_name: string;
9
+ fiscal_year: number;
10
+ period?: string;
11
+ opening_balance: string;
12
+ closing_balance: string;
13
+ debit_sum: string;
14
+ credit_sum: string;
15
+ balance: string;
16
+ transaction_count: number;
17
+ }
18
+ export declare class BalancesExporter {
19
+ private exportPath;
20
+ private balances;
21
+ private fiscalYear;
22
+ constructor(exportPath: string, fiscalYear: number);
23
+ /**
24
+ * Adds a balance entry to the export
25
+ */
26
+ addBalance(accountCode: string, accountName: string, balance: IAccountBalanceExport, period?: string): void;
27
+ /**
28
+ * Exports balances to CSV format
29
+ */
30
+ exportToCSV(): Promise<void>;
31
+ /**
32
+ * Exports trial balance (Summen- und Saldenliste)
33
+ */
34
+ exportTrialBalance(): Promise<void>;
35
+ /**
36
+ * Exports balances to JSON format
37
+ */
38
+ exportToJSON(): Promise<void>;
39
+ /**
40
+ * Generates balance summary for specific account classes
41
+ */
42
+ exportClassSummary(): Promise<void>;
43
+ /**
44
+ * Escapes CSV values
45
+ */
46
+ private escapeCSV;
47
+ /**
48
+ * Formats number in German format (1.234,56)
49
+ */
50
+ private formatGermanNumber;
51
+ /**
52
+ * Gets the number of balance entries
53
+ */
54
+ getBalanceCount(): number;
55
+ /**
56
+ * Clears the balances list
57
+ */
58
+ clear(): void;
59
+ }
@@ -0,0 +1,205 @@
1
+ import * as plugins from './plugins.js';
2
+ import * as path from 'path';
3
+ export class BalancesExporter {
4
+ constructor(exportPath, fiscalYear) {
5
+ this.balances = [];
6
+ this.exportPath = exportPath;
7
+ this.fiscalYear = fiscalYear;
8
+ }
9
+ /**
10
+ * Adds a balance entry to the export
11
+ */
12
+ addBalance(accountCode, accountName, balance, period) {
13
+ const exportRow = {
14
+ account_code: accountCode,
15
+ account_name: accountName,
16
+ fiscal_year: this.fiscalYear,
17
+ period: period,
18
+ opening_balance: (balance.openingBalance || 0).toFixed(2),
19
+ closing_balance: balance.balance.toFixed(2),
20
+ debit_sum: balance.debitTotal.toFixed(2),
21
+ credit_sum: balance.creditTotal.toFixed(2),
22
+ balance: balance.balance.toFixed(2),
23
+ transaction_count: balance.transactionCount || 0
24
+ };
25
+ this.balances.push(exportRow);
26
+ }
27
+ /**
28
+ * Exports balances to CSV format
29
+ */
30
+ async exportToCSV() {
31
+ const csvPath = path.join(this.exportPath, 'data', 'accounting', 'balances.csv');
32
+ await plugins.smartfile.fs.ensureDir(path.dirname(csvPath));
33
+ // Create CSV header
34
+ const headers = [
35
+ 'account_code',
36
+ 'account_name',
37
+ 'fiscal_year',
38
+ 'period',
39
+ 'opening_balance',
40
+ 'closing_balance',
41
+ 'debit_sum',
42
+ 'credit_sum',
43
+ 'balance',
44
+ 'transaction_count'
45
+ ];
46
+ let csvContent = headers.join(',') + '\n';
47
+ // Sort balances by account code
48
+ this.balances.sort((a, b) => a.account_code.localeCompare(b.account_code));
49
+ // Add balance rows
50
+ for (const balance of this.balances) {
51
+ const row = [
52
+ this.escapeCSV(balance.account_code),
53
+ this.escapeCSV(balance.account_name),
54
+ balance.fiscal_year.toString(),
55
+ this.escapeCSV(balance.period || ''),
56
+ balance.opening_balance,
57
+ balance.closing_balance,
58
+ balance.debit_sum,
59
+ balance.credit_sum,
60
+ balance.balance,
61
+ balance.transaction_count.toString()
62
+ ];
63
+ csvContent += row.join(',') + '\n';
64
+ }
65
+ await plugins.smartfile.memory.toFs(csvContent, csvPath);
66
+ }
67
+ /**
68
+ * Exports trial balance (Summen- und Saldenliste)
69
+ */
70
+ async exportTrialBalance() {
71
+ const csvPath = path.join(this.exportPath, 'data', 'accounting', 'trial_balance.csv');
72
+ await plugins.smartfile.fs.ensureDir(path.dirname(csvPath));
73
+ // Create CSV header for trial balance
74
+ const headers = [
75
+ 'Konto',
76
+ 'Bezeichnung',
77
+ 'Anfangssaldo',
78
+ 'Soll',
79
+ 'Haben',
80
+ 'Saldo',
81
+ 'Endsaldo'
82
+ ];
83
+ let csvContent = headers.join(',') + '\n';
84
+ // Add rows with German formatting
85
+ for (const balance of this.balances) {
86
+ const row = [
87
+ this.escapeCSV(balance.account_code),
88
+ this.escapeCSV(balance.account_name),
89
+ this.formatGermanNumber(parseFloat(balance.opening_balance)),
90
+ this.formatGermanNumber(parseFloat(balance.debit_sum)),
91
+ this.formatGermanNumber(parseFloat(balance.credit_sum)),
92
+ this.formatGermanNumber(parseFloat(balance.debit_sum) - parseFloat(balance.credit_sum)),
93
+ this.formatGermanNumber(parseFloat(balance.closing_balance))
94
+ ];
95
+ csvContent += row.join(',') + '\n';
96
+ }
97
+ // Add totals row
98
+ const totalDebit = this.balances.reduce((sum, b) => sum + parseFloat(b.debit_sum), 0);
99
+ const totalCredit = this.balances.reduce((sum, b) => sum + parseFloat(b.credit_sum), 0);
100
+ csvContent += '\n';
101
+ csvContent += [
102
+ 'SUMME',
103
+ '',
104
+ '',
105
+ this.formatGermanNumber(totalDebit),
106
+ this.formatGermanNumber(totalCredit),
107
+ this.formatGermanNumber(totalDebit - totalCredit),
108
+ ''
109
+ ].join(',') + '\n';
110
+ await plugins.smartfile.memory.toFs(csvContent, csvPath);
111
+ }
112
+ /**
113
+ * Exports balances to JSON format
114
+ */
115
+ async exportToJSON() {
116
+ const jsonPath = path.join(this.exportPath, 'data', 'accounting', 'balances.json');
117
+ await plugins.smartfile.fs.ensureDir(path.dirname(jsonPath));
118
+ const jsonData = {
119
+ schema_version: '1.0',
120
+ export_date: new Date().toISOString(),
121
+ fiscal_year: this.fiscalYear,
122
+ balances: this.balances,
123
+ totals: {
124
+ total_debit: this.balances.reduce((sum, b) => sum + parseFloat(b.debit_sum), 0).toFixed(2),
125
+ total_credit: this.balances.reduce((sum, b) => sum + parseFloat(b.credit_sum), 0).toFixed(2),
126
+ account_count: this.balances.length
127
+ }
128
+ };
129
+ await plugins.smartfile.memory.toFs(JSON.stringify(jsonData, null, 2), jsonPath);
130
+ }
131
+ /**
132
+ * Generates balance summary for specific account classes
133
+ */
134
+ async exportClassSummary() {
135
+ const csvPath = path.join(this.exportPath, 'data', 'accounting', 'class_summary.csv');
136
+ await plugins.smartfile.fs.ensureDir(path.dirname(csvPath));
137
+ // Group balances by account class (first digit of account code)
138
+ const classSummary = {};
139
+ for (const balance of this.balances) {
140
+ const accountClass = balance.account_code.charAt(0);
141
+ if (!classSummary[accountClass]) {
142
+ classSummary[accountClass] = { debit: 0, credit: 0, balance: 0 };
143
+ }
144
+ classSummary[accountClass].debit += parseFloat(balance.debit_sum);
145
+ classSummary[accountClass].credit += parseFloat(balance.credit_sum);
146
+ classSummary[accountClass].balance += parseFloat(balance.balance);
147
+ }
148
+ // Create CSV
149
+ let csvContent = 'Kontenklasse,Bezeichnung,Soll,Haben,Saldo\n';
150
+ const classNames = {
151
+ '0': 'Anlagevermögen',
152
+ '1': 'Umlaufvermögen',
153
+ '2': 'Eigenkapital',
154
+ '3': 'Fremdkapital',
155
+ '4': 'Betriebliche Erträge',
156
+ '5': 'Materialaufwand',
157
+ '6': 'Betriebsaufwand',
158
+ '7': 'Weitere Aufwendungen',
159
+ '8': 'Erträge',
160
+ '9': 'Abschlusskonten'
161
+ };
162
+ for (const [classNum, summary] of Object.entries(classSummary)) {
163
+ const row = [
164
+ classNum,
165
+ this.escapeCSV(classNames[classNum] || `Klasse ${classNum}`),
166
+ this.formatGermanNumber(summary.debit),
167
+ this.formatGermanNumber(summary.credit),
168
+ this.formatGermanNumber(summary.balance)
169
+ ];
170
+ csvContent += row.join(',') + '\n';
171
+ }
172
+ await plugins.smartfile.memory.toFs(csvContent, csvPath);
173
+ }
174
+ /**
175
+ * Escapes CSV values
176
+ */
177
+ escapeCSV(value) {
178
+ if (value.includes(',') || value.includes('"') || value.includes('\n')) {
179
+ return `"${value.replace(/"/g, '""')}"`;
180
+ }
181
+ return value;
182
+ }
183
+ /**
184
+ * Formats number in German format (1.234,56)
185
+ */
186
+ formatGermanNumber(value) {
187
+ return value.toLocaleString('de-DE', {
188
+ minimumFractionDigits: 2,
189
+ maximumFractionDigits: 2
190
+ });
191
+ }
192
+ /**
193
+ * Gets the number of balance entries
194
+ */
195
+ getBalanceCount() {
196
+ return this.balances.length;
197
+ }
198
+ /**
199
+ * Clears the balances list
200
+ */
201
+ clear() {
202
+ this.balances = [];
203
+ }
204
+ }
205
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2tyLmV4cG9ydC5iYWxhbmNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3Nrci5leHBvcnQuYmFsYW5jZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFzQjdCLE1BQU0sT0FBTyxnQkFBZ0I7SUFLM0IsWUFBWSxVQUFrQixFQUFFLFVBQWtCO1FBSDFDLGFBQVEsR0FBd0IsRUFBRSxDQUFDO1FBSXpDLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO0lBQy9CLENBQUM7SUFFRDs7T0FFRztJQUNJLFVBQVUsQ0FDZixXQUFtQixFQUNuQixXQUFtQixFQUNuQixPQUE4QixFQUM5QixNQUFlO1FBRWYsTUFBTSxTQUFTLEdBQXNCO1lBQ25DLFlBQVksRUFBRSxXQUFXO1lBQ3pCLFlBQVksRUFBRSxXQUFXO1lBQ3pCLFdBQVcsRUFBRSxJQUFJLENBQUMsVUFBVTtZQUM1QixNQUFNLEVBQUUsTUFBTTtZQUNkLGVBQWUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxjQUFjLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUN6RCxlQUFlLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQzNDLFNBQVMsRUFBRSxPQUFPLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDeEMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUMxQyxPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQ25DLGlCQUFpQixFQUFFLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDO1NBQ2pELENBQUM7UUFF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
@@ -0,0 +1,110 @@
1
+ import type { TSKRType } from './skr.types.js';
2
+ export interface IExportOptions {
3
+ exportPath: string;
4
+ fiscalYear: number;
5
+ dateFrom: Date;
6
+ dateTo: Date;
7
+ includeDocuments?: boolean;
8
+ generatePdfReports?: boolean;
9
+ signExport?: boolean;
10
+ timestampExport?: boolean;
11
+ companyInfo?: {
12
+ name: string;
13
+ taxId: string;
14
+ registrationNumber?: string;
15
+ address?: string;
16
+ };
17
+ }
18
+ export interface IExportMetadata {
19
+ exportVersion: string;
20
+ exportTimestamp: string;
21
+ generator: {
22
+ name: string;
23
+ version: string;
24
+ };
25
+ company?: {
26
+ name: string;
27
+ taxId: string;
28
+ registrationNumber?: string;
29
+ address?: string;
30
+ };
31
+ fiscalYear: number;
32
+ dateRange: {
33
+ from: string;
34
+ to: string;
35
+ };
36
+ skrType: TSKRType;
37
+ schemaVersion: string;
38
+ crypto: {
39
+ digestAlgorithms: string[];
40
+ signatureType?: string;
41
+ timestampPolicy?: string;
42
+ merkleTree: boolean;
43
+ };
44
+ options: {
45
+ packagedAs: 'bagit';
46
+ compression: 'none' | 'deflate';
47
+ deduplication: boolean;
48
+ };
49
+ }
50
+ export interface IBagItManifest {
51
+ [filePath: string]: string;
52
+ }
53
+ export interface IDocumentIndex {
54
+ contentHash: string;
55
+ sizeBytes: number;
56
+ mimeType: string;
57
+ createdAt: string;
58
+ originalFilename?: string;
59
+ pdfaAvailable: boolean;
60
+ zugferdXml?: string;
61
+ retentionClass: string;
62
+ }
63
+ export declare class SkrExport {
64
+ private logger;
65
+ private options;
66
+ private exportDir;
67
+ private manifest;
68
+ private tagManifest;
69
+ constructor(options: IExportOptions);
70
+ /**
71
+ * Creates the BagIt directory structure for the export
72
+ */
73
+ createBagItStructure(): Promise<void>;
74
+ /**
75
+ * Creates the bagit.txt declaration file
76
+ */
77
+ private createBagItDeclaration;
78
+ /**
79
+ * Creates the README.txt file with Verfahrensdokumentation
80
+ */
81
+ private createReadme;
82
+ /**
83
+ * Creates the export metadata JSON file
84
+ */
85
+ createExportMetadata(skrType: TSKRType): Promise<void>;
86
+ /**
87
+ * Creates JSON schemas for the export data structures
88
+ */
89
+ createSchemas(): Promise<void>;
90
+ /**
91
+ * Writes the BagIt manifest files
92
+ */
93
+ writeManifests(): Promise<void>;
94
+ /**
95
+ * Calculates SHA-256 hash of a file
96
+ */
97
+ private hashFile;
98
+ /**
99
+ * Stores a document in content-addressed storage
100
+ */
101
+ storeDocument(content: Buffer, originalFilename?: string): Promise<string>;
102
+ /**
103
+ * Creates a Merkle tree from all file hashes
104
+ */
105
+ createMerkleTree(): Promise<string>;
106
+ /**
107
+ * Validates the BagIt structure
108
+ */
109
+ validateBagIt(): Promise<boolean>;
110
+ }