@fin.cx/einvoice 5.0.2
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/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/classes.decoder.d.ts +40 -0
- package/dist_ts/classes.decoder.js +320 -0
- package/dist_ts/classes.encoder.d.ts +51 -0
- package/dist_ts/classes.encoder.js +293 -0
- package/dist_ts/classes.xinvoice.d.ts +136 -0
- package/dist_ts/classes.xinvoice.js +352 -0
- package/dist_ts/einvoice.d.ts +217 -0
- package/dist_ts/einvoice.js +505 -0
- package/dist_ts/errors.d.ts +121 -0
- package/dist_ts/errors.js +241 -0
- package/dist_ts/formats/base/base.decoder.d.ts +32 -0
- package/dist_ts/formats/base/base.decoder.js +52 -0
- package/dist_ts/formats/base/base.encoder.d.ts +13 -0
- package/dist_ts/formats/base/base.encoder.js +7 -0
- package/dist_ts/formats/base/base.validator.d.ts +44 -0
- package/dist_ts/formats/base/base.validator.js +39 -0
- package/dist_ts/formats/base.decoder.d.ts +19 -0
- package/dist_ts/formats/base.decoder.js +130 -0
- package/dist_ts/formats/base.validator.d.ts +44 -0
- package/dist_ts/formats/base.validator.js +39 -0
- package/dist_ts/formats/cii/cii.decoder.d.ts +61 -0
- package/dist_ts/formats/cii/cii.decoder.js +111 -0
- package/dist_ts/formats/cii/cii.encoder.d.ts +43 -0
- package/dist_ts/formats/cii/cii.encoder.js +48 -0
- package/dist_ts/formats/cii/cii.types.d.ts +31 -0
- package/dist_ts/formats/cii/cii.types.js +40 -0
- package/dist_ts/formats/cii/cii.validator.d.ts +56 -0
- package/dist_ts/formats/cii/cii.validator.js +146 -0
- package/dist_ts/formats/cii/facturx/facturx.decoder.d.ts +43 -0
- package/dist_ts/formats/cii/facturx/facturx.decoder.js +207 -0
- package/dist_ts/formats/cii/facturx/facturx.encoder.d.ts +82 -0
- package/dist_ts/formats/cii/facturx/facturx.encoder.js +400 -0
- package/dist_ts/formats/cii/facturx/facturx.types.d.ts +10 -0
- package/dist_ts/formats/cii/facturx/facturx.types.js +15 -0
- package/dist_ts/formats/cii/facturx/facturx.validator.d.ts +32 -0
- package/dist_ts/formats/cii/facturx/facturx.validator.js +138 -0
- package/dist_ts/formats/cii/zugferd/zugferd.decoder.d.ts +43 -0
- package/dist_ts/formats/cii/zugferd/zugferd.decoder.js +218 -0
- package/dist_ts/formats/cii/zugferd/zugferd.encoder.d.ts +97 -0
- package/dist_ts/formats/cii/zugferd/zugferd.encoder.js +550 -0
- package/dist_ts/formats/cii/zugferd/zugferd.types.d.ts +10 -0
- package/dist_ts/formats/cii/zugferd/zugferd.types.js +15 -0
- package/dist_ts/formats/cii/zugferd/zugferd.v1.decoder.d.ts +49 -0
- package/dist_ts/formats/cii/zugferd/zugferd.v1.decoder.js +229 -0
- package/dist_ts/formats/cii/zugferd/zugferd.validator.d.ts +16 -0
- package/dist_ts/formats/cii/zugferd/zugferd.validator.js +29 -0
- package/dist_ts/formats/decoder.factory.d.ts +15 -0
- package/dist_ts/formats/decoder.factory.js +46 -0
- package/dist_ts/formats/factories/decoder.factory.d.ts +13 -0
- package/dist_ts/formats/factories/decoder.factory.js +56 -0
- package/dist_ts/formats/factories/encoder.factory.d.ts +14 -0
- package/dist_ts/formats/factories/encoder.factory.js +40 -0
- package/dist_ts/formats/factories/validator.factory.d.ts +12 -0
- package/dist_ts/formats/factories/validator.factory.js +110 -0
- package/dist_ts/formats/factorx.decoder.d.ts +18 -0
- package/dist_ts/formats/factorx.decoder.js +178 -0
- package/dist_ts/formats/factorx.encoder.d.ts +51 -0
- package/dist_ts/formats/factorx.encoder.js +293 -0
- package/dist_ts/formats/facturx.decoder.d.ts +18 -0
- package/dist_ts/formats/facturx.decoder.js +210 -0
- package/dist_ts/formats/facturx.encoder.d.ts +51 -0
- package/dist_ts/formats/facturx.encoder.js +293 -0
- package/dist_ts/formats/facturx.validator.d.ts +67 -0
- package/dist_ts/formats/facturx.validator.js +266 -0
- package/dist_ts/formats/pdf/extractors/associated.extractor.d.ts +14 -0
- package/dist_ts/formats/pdf/extractors/associated.extractor.js +68 -0
- package/dist_ts/formats/pdf/extractors/base.extractor.d.ts +92 -0
- package/dist_ts/formats/pdf/extractors/base.extractor.js +319 -0
- package/dist_ts/formats/pdf/extractors/index.d.ts +4 -0
- package/dist_ts/formats/pdf/extractors/index.js +5 -0
- package/dist_ts/formats/pdf/extractors/standard.extractor.d.ts +13 -0
- package/dist_ts/formats/pdf/extractors/standard.extractor.js +74 -0
- package/dist_ts/formats/pdf/extractors/text.extractor.d.ts +45 -0
- package/dist_ts/formats/pdf/extractors/text.extractor.js +151 -0
- package/dist_ts/formats/pdf/pdf.embedder.d.ts +69 -0
- package/dist_ts/formats/pdf/pdf.embedder.js +183 -0
- package/dist_ts/formats/pdf/pdf.extractor.d.ts +49 -0
- package/dist_ts/formats/pdf/pdf.extractor.js +98 -0
- package/dist_ts/formats/pdf/robust-pdf.extractor.d.ts +40 -0
- package/dist_ts/formats/pdf/robust-pdf.extractor.js +324 -0
- package/dist_ts/formats/ubl/en16931.ubl.validator.d.ts +18 -0
- package/dist_ts/formats/ubl/en16931.ubl.validator.js +169 -0
- package/dist_ts/formats/ubl/generic/ubl.encoder.d.ts +151 -0
- package/dist_ts/formats/ubl/generic/ubl.encoder.js +892 -0
- package/dist_ts/formats/ubl/ubl.decoder.d.ts +61 -0
- package/dist_ts/formats/ubl/ubl.decoder.js +95 -0
- package/dist_ts/formats/ubl/ubl.encoder.d.ts +38 -0
- package/dist_ts/formats/ubl/ubl.encoder.js +46 -0
- package/dist_ts/formats/ubl/ubl.types.d.ts +16 -0
- package/dist_ts/formats/ubl/ubl.types.js +21 -0
- package/dist_ts/formats/ubl/ubl.validator.d.ts +50 -0
- package/dist_ts/formats/ubl/ubl.validator.js +112 -0
- package/dist_ts/formats/ubl/xrechnung/xrechnung.decoder.d.ts +34 -0
- package/dist_ts/formats/ubl/xrechnung/xrechnung.decoder.js +424 -0
- package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.d.ts +75 -0
- package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.js +555 -0
- package/dist_ts/formats/ubl/xrechnung.validator.d.ts +15 -0
- package/dist_ts/formats/ubl/xrechnung.validator.js +107 -0
- package/dist_ts/formats/ubl.validator.d.ts +82 -0
- package/dist_ts/formats/ubl.validator.js +306 -0
- package/dist_ts/formats/utils/format.detector.d.ts +62 -0
- package/dist_ts/formats/utils/format.detector.js +249 -0
- package/dist_ts/formats/validation/en16931.validator.d.ts +23 -0
- package/dist_ts/formats/validation/en16931.validator.js +119 -0
- package/dist_ts/formats/validator.factory.d.ts +18 -0
- package/dist_ts/formats/validator.factory.js +78 -0
- package/dist_ts/formats/xinvoice.decoder.d.ts +28 -0
- package/dist_ts/formats/xinvoice.decoder.js +332 -0
- package/dist_ts/formats/xinvoice.encoder.d.ts +19 -0
- package/dist_ts/formats/xinvoice.encoder.js +282 -0
- package/dist_ts/index.d.ts +51 -0
- package/dist_ts/index.js +90 -0
- package/dist_ts/interfaces/common.d.ts +79 -0
- package/dist_ts/interfaces/common.js +24 -0
- package/dist_ts/interfaces.d.ts +87 -0
- package/dist_ts/interfaces.js +23 -0
- package/dist_ts/plugins.d.ts +14 -0
- package/dist_ts/plugins.js +31 -0
- package/npmextra.json +35 -0
- package/package.json +71 -0
- package/readme.hints.md +1107 -0
- package/readme.howtofixtests.md +38 -0
- package/readme.literature.md +1 -0
- package/readme.md +998 -0
- package/readme.plan.md +481 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/einvoice.ts +603 -0
- package/ts/errors.ts +341 -0
- package/ts/formats/base/base.decoder.ts +68 -0
- package/ts/formats/base/base.encoder.ts +14 -0
- package/ts/formats/base/base.validator.ts +64 -0
- package/ts/formats/cii/cii.decoder.ts +139 -0
- package/ts/formats/cii/cii.encoder.ts +64 -0
- package/ts/formats/cii/cii.types.ts +44 -0
- package/ts/formats/cii/cii.validator.ts +171 -0
- package/ts/formats/cii/facturx/facturx.decoder.ts +243 -0
- package/ts/formats/cii/facturx/facturx.encoder.ts +483 -0
- package/ts/formats/cii/facturx/facturx.types.ts +18 -0
- package/ts/formats/cii/facturx/facturx.validator.ts +180 -0
- package/ts/formats/cii/zugferd/zugferd.decoder.ts +256 -0
- package/ts/formats/cii/zugferd/zugferd.encoder.ts +661 -0
- package/ts/formats/cii/zugferd/zugferd.types.ts +18 -0
- package/ts/formats/cii/zugferd/zugferd.v1.decoder.ts +267 -0
- package/ts/formats/cii/zugferd/zugferd.validator.ts +31 -0
- package/ts/formats/factories/decoder.factory.ts +62 -0
- package/ts/formats/factories/encoder.factory.ts +47 -0
- package/ts/formats/factories/validator.factory.ts +134 -0
- package/ts/formats/pdf/extractors/associated.extractor.ts +78 -0
- package/ts/formats/pdf/extractors/base.extractor.ts +355 -0
- package/ts/formats/pdf/extractors/index.ts +4 -0
- package/ts/formats/pdf/extractors/standard.extractor.ts +86 -0
- package/ts/formats/pdf/extractors/text.extractor.ts +162 -0
- package/ts/formats/pdf/pdf.embedder.ts +242 -0
- package/ts/formats/pdf/pdf.extractor.ts +141 -0
- package/ts/formats/ubl/en16931.ubl.validator.ts +216 -0
- package/ts/formats/ubl/generic/ubl.encoder.ts +1041 -0
- package/ts/formats/ubl/ubl.decoder.ts +121 -0
- package/ts/formats/ubl/ubl.encoder.ts +63 -0
- package/ts/formats/ubl/ubl.types.ts +22 -0
- package/ts/formats/ubl/ubl.validator.ts +133 -0
- package/ts/formats/ubl/xrechnung/xrechnung.decoder.ts +471 -0
- package/ts/formats/ubl/xrechnung/xrechnung.encoder.ts +619 -0
- package/ts/formats/ubl/xrechnung.validator.ts +185 -0
- package/ts/formats/utils/format.detector.ts +306 -0
- package/ts/formats/validation/en16931.validator.ts +135 -0
- package/ts/index.ts +164 -0
- package/ts/interfaces/common.ts +90 -0
- package/ts/interfaces.ts +98 -0
- package/ts/plugins.ts +61 -0
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { business, finance } from './plugins.js';
|
|
3
|
+
import { InvoiceFormat, ValidationLevel } from './interfaces/common.js';
|
|
4
|
+
// Import error classes
|
|
5
|
+
import { EInvoiceError, EInvoiceParsingError, EInvoiceValidationError, EInvoicePDFError, EInvoiceFormatError, ErrorContext } from './errors.js';
|
|
6
|
+
// Import factories
|
|
7
|
+
import { DecoderFactory } from './formats/factories/decoder.factory.js';
|
|
8
|
+
import { EncoderFactory } from './formats/factories/encoder.factory.js';
|
|
9
|
+
import { ValidatorFactory } from './formats/factories/validator.factory.js';
|
|
10
|
+
// Import PDF utilities
|
|
11
|
+
import { PDFEmbedder } from './formats/pdf/pdf.embedder.js';
|
|
12
|
+
import { PDFExtractor } from './formats/pdf/pdf.extractor.js';
|
|
13
|
+
// Import format detector
|
|
14
|
+
import { FormatDetector } from './formats/utils/format.detector.js';
|
|
15
|
+
/**
|
|
16
|
+
* Main class for working with electronic invoices.
|
|
17
|
+
* Supports various invoice formats including Factur-X, ZUGFeRD, UBL, and XRechnung
|
|
18
|
+
* Extends the TInvoice interface for seamless integration with existing systems
|
|
19
|
+
*/
|
|
20
|
+
export class EInvoice {
|
|
21
|
+
/**
|
|
22
|
+
* Creates an EInvoice instance from XML string
|
|
23
|
+
* @param xmlString XML string to parse
|
|
24
|
+
* @returns EInvoice instance
|
|
25
|
+
*/
|
|
26
|
+
static async fromXml(xmlString) {
|
|
27
|
+
const invoice = new EInvoice();
|
|
28
|
+
await invoice.fromXmlString(xmlString);
|
|
29
|
+
return invoice;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Creates an EInvoice instance from file
|
|
33
|
+
* @param filePath Path to the file
|
|
34
|
+
* @returns EInvoice instance
|
|
35
|
+
*/
|
|
36
|
+
static async fromFile(filePath) {
|
|
37
|
+
const invoice = new EInvoice();
|
|
38
|
+
await invoice.fromFile(filePath);
|
|
39
|
+
return invoice;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Creates an EInvoice instance from PDF
|
|
43
|
+
* @param pdfBuffer PDF buffer
|
|
44
|
+
* @returns EInvoice instance
|
|
45
|
+
*/
|
|
46
|
+
static async fromPdf(pdfBuffer) {
|
|
47
|
+
const invoice = new EInvoice();
|
|
48
|
+
if (typeof pdfBuffer === 'string') {
|
|
49
|
+
// If given a file path
|
|
50
|
+
await invoice.fromPdfFile(pdfBuffer);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// If given a buffer, extract XML and parse it
|
|
54
|
+
const extractResult = await invoice.pdfExtractor.extractXml(pdfBuffer);
|
|
55
|
+
if (!extractResult.success || !extractResult.xml) {
|
|
56
|
+
throw new EInvoicePDFError('No invoice XML found in PDF', 'extract');
|
|
57
|
+
}
|
|
58
|
+
await invoice.fromXmlString(extractResult.xml);
|
|
59
|
+
}
|
|
60
|
+
return invoice;
|
|
61
|
+
}
|
|
62
|
+
// Backward compatibility properties
|
|
63
|
+
get invoiceId() { return this.accountingDocId; }
|
|
64
|
+
set invoiceId(value) { this.accountingDocId = value; }
|
|
65
|
+
get invoiceType() {
|
|
66
|
+
return this.accountingDocType === 'invoice' ? 'invoice' :
|
|
67
|
+
this.accountingDocType === 'creditnote' ? 'creditnote' : 'debitnote';
|
|
68
|
+
}
|
|
69
|
+
set invoiceType(value) {
|
|
70
|
+
this.accountingDocType = 'invoice'; // Always set to invoice for TInvoice type
|
|
71
|
+
}
|
|
72
|
+
// Computed properties for convenience
|
|
73
|
+
get issueDate() {
|
|
74
|
+
return new Date(this.date);
|
|
75
|
+
}
|
|
76
|
+
set issueDate(value) {
|
|
77
|
+
this.date = value.getTime();
|
|
78
|
+
}
|
|
79
|
+
get totalNet() {
|
|
80
|
+
return this.calculateTotalNet();
|
|
81
|
+
}
|
|
82
|
+
get totalVat() {
|
|
83
|
+
return this.calculateTotalVat();
|
|
84
|
+
}
|
|
85
|
+
get totalGross() {
|
|
86
|
+
return this.totalNet + this.totalVat;
|
|
87
|
+
}
|
|
88
|
+
get taxBreakdown() {
|
|
89
|
+
return this.calculateTaxBreakdown();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Creates a new EInvoice instance
|
|
93
|
+
* @param options Configuration options
|
|
94
|
+
*/
|
|
95
|
+
constructor(options) {
|
|
96
|
+
// TInvoice interface properties - accounting document structure
|
|
97
|
+
this.type = 'accounting-doc';
|
|
98
|
+
this.accountingDocType = 'invoice';
|
|
99
|
+
this.accountingDocId = '';
|
|
100
|
+
this.accountingDocStatus = 'issued';
|
|
101
|
+
// Business envelope properties
|
|
102
|
+
this.id = '';
|
|
103
|
+
this.date = Date.now();
|
|
104
|
+
this.status = 'issued';
|
|
105
|
+
this.subject = '';
|
|
106
|
+
this.versionInfo = {
|
|
107
|
+
type: 'draft',
|
|
108
|
+
version: '1.0.0'
|
|
109
|
+
};
|
|
110
|
+
// Additional envelope properties
|
|
111
|
+
this.incidenceId = '';
|
|
112
|
+
this.language = 'en';
|
|
113
|
+
this.objectActions = [];
|
|
114
|
+
this.pdf = null;
|
|
115
|
+
this.pdfAttachments = null;
|
|
116
|
+
this.accentColor = null;
|
|
117
|
+
this.logoUrl = null;
|
|
118
|
+
// Accounting document specific properties
|
|
119
|
+
this.items = [];
|
|
120
|
+
this.dueInDays = 30;
|
|
121
|
+
this.reverseCharge = false;
|
|
122
|
+
this.currency = 'EUR';
|
|
123
|
+
this.notes = [];
|
|
124
|
+
this.xmlString = '';
|
|
125
|
+
this.detectedFormat = InvoiceFormat.UNKNOWN;
|
|
126
|
+
this.validationErrors = [];
|
|
127
|
+
this.options = {
|
|
128
|
+
validateOnLoad: false,
|
|
129
|
+
validationLevel: ValidationLevel.SYNTAX
|
|
130
|
+
};
|
|
131
|
+
// PDF utilities
|
|
132
|
+
this.pdfEmbedder = new PDFEmbedder();
|
|
133
|
+
this.pdfExtractor = new PDFExtractor();
|
|
134
|
+
// Initialize empty contact objects
|
|
135
|
+
this.from = this.createEmptyContact();
|
|
136
|
+
this.to = this.createEmptyContact();
|
|
137
|
+
// Apply options if provided
|
|
138
|
+
if (options) {
|
|
139
|
+
this.options = { ...this.options, ...options };
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Creates an empty TContact object
|
|
144
|
+
*/
|
|
145
|
+
createEmptyContact() {
|
|
146
|
+
return {
|
|
147
|
+
type: 'company',
|
|
148
|
+
name: '',
|
|
149
|
+
description: '',
|
|
150
|
+
address: {
|
|
151
|
+
streetName: '',
|
|
152
|
+
houseNumber: '',
|
|
153
|
+
city: '',
|
|
154
|
+
postalCode: '',
|
|
155
|
+
country: ''
|
|
156
|
+
},
|
|
157
|
+
registrationDetails: {
|
|
158
|
+
vatId: '',
|
|
159
|
+
registrationId: '',
|
|
160
|
+
registrationName: ''
|
|
161
|
+
},
|
|
162
|
+
status: 'active',
|
|
163
|
+
foundedDate: {
|
|
164
|
+
year: new Date().getFullYear(),
|
|
165
|
+
month: new Date().getMonth() + 1,
|
|
166
|
+
day: new Date().getDate()
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Exports the invoice as XML in the specified format
|
|
172
|
+
* @param format The export format
|
|
173
|
+
* @returns XML string
|
|
174
|
+
*/
|
|
175
|
+
async exportXml(format) {
|
|
176
|
+
return this.toXmlString(format);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Loads invoice data from XML (alias for fromXmlString)
|
|
180
|
+
* @param xmlString The XML string to parse
|
|
181
|
+
* @returns The EInvoice instance for chaining
|
|
182
|
+
*/
|
|
183
|
+
async loadXml(xmlString) {
|
|
184
|
+
return this.fromXmlString(xmlString);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Loads invoice data from an XML string
|
|
188
|
+
* @param xmlString The XML string to parse
|
|
189
|
+
* @returns The EInvoice instance for chaining
|
|
190
|
+
*/
|
|
191
|
+
async fromXmlString(xmlString) {
|
|
192
|
+
try {
|
|
193
|
+
this.xmlString = xmlString;
|
|
194
|
+
// Detect format
|
|
195
|
+
this.detectedFormat = FormatDetector.detectFormat(xmlString);
|
|
196
|
+
if (this.detectedFormat === InvoiceFormat.UNKNOWN) {
|
|
197
|
+
throw new EInvoiceFormatError('Unknown invoice format', { sourceFormat: 'unknown' });
|
|
198
|
+
}
|
|
199
|
+
// Get appropriate decoder
|
|
200
|
+
const decoder = DecoderFactory.createDecoder(xmlString, !this.options.validateOnLoad);
|
|
201
|
+
const invoice = await decoder.decode();
|
|
202
|
+
// Map the decoded invoice to our properties
|
|
203
|
+
this.mapFromTInvoice(invoice);
|
|
204
|
+
// Validate if requested
|
|
205
|
+
if (this.options.validateOnLoad) {
|
|
206
|
+
await this.validate(this.options.validationLevel);
|
|
207
|
+
}
|
|
208
|
+
return this;
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
if (error instanceof EInvoiceError) {
|
|
212
|
+
throw error;
|
|
213
|
+
}
|
|
214
|
+
throw new EInvoiceParsingError(`Failed to parse XML: ${error.message}`, {}, error);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Loads invoice data from a file
|
|
219
|
+
* @param filePath Path to the file to load
|
|
220
|
+
* @returns The EInvoice instance for chaining
|
|
221
|
+
*/
|
|
222
|
+
async fromFile(filePath) {
|
|
223
|
+
try {
|
|
224
|
+
const fileBuffer = await plugins.fs.readFile(filePath);
|
|
225
|
+
// Check if it's a PDF
|
|
226
|
+
if (filePath.toLowerCase().endsWith('.pdf') || fileBuffer.subarray(0, 4).toString() === '%PDF') {
|
|
227
|
+
return this.fromPdfFile(filePath);
|
|
228
|
+
}
|
|
229
|
+
// Otherwise treat as XML
|
|
230
|
+
const xmlString = fileBuffer.toString('utf-8');
|
|
231
|
+
return this.fromXmlString(xmlString);
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
throw new EInvoiceError(`Failed to load file: ${error.message}`, 'FILE_LOAD_ERROR', { filePath });
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Loads invoice data from a PDF file
|
|
239
|
+
* @param filePath Path to the PDF file
|
|
240
|
+
* @returns The EInvoice instance for chaining
|
|
241
|
+
*/
|
|
242
|
+
async fromPdfFile(filePath) {
|
|
243
|
+
try {
|
|
244
|
+
const pdfBuffer = await plugins.fs.readFile(filePath);
|
|
245
|
+
const extractResult = await this.pdfExtractor.extractXml(pdfBuffer);
|
|
246
|
+
const extractedXml = extractResult.success ? extractResult.xml : null;
|
|
247
|
+
if (!extractedXml) {
|
|
248
|
+
throw new EInvoicePDFError('No invoice XML found in PDF', 'extract', { filePath });
|
|
249
|
+
}
|
|
250
|
+
// Store the PDF for later use
|
|
251
|
+
this.pdf = {
|
|
252
|
+
name: plugins.path.basename(filePath),
|
|
253
|
+
id: plugins.crypto.createHash('md5').update(pdfBuffer).digest('hex'),
|
|
254
|
+
buffer: new Uint8Array(pdfBuffer),
|
|
255
|
+
metadata: {
|
|
256
|
+
textExtraction: '',
|
|
257
|
+
format: 'PDF/A-3',
|
|
258
|
+
embeddedXml: {
|
|
259
|
+
filename: 'factur-x.xml',
|
|
260
|
+
description: 'Factur-X Invoice'
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
return this.fromXmlString(extractedXml);
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
if (error instanceof EInvoiceError) {
|
|
268
|
+
throw error;
|
|
269
|
+
}
|
|
270
|
+
throw new EInvoicePDFError(`Failed to extract invoice from PDF: ${error.message}`, 'extract', {}, error);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Maps data from a TInvoice to this EInvoice instance
|
|
275
|
+
*/
|
|
276
|
+
mapFromTInvoice(invoice) {
|
|
277
|
+
// Map all properties from the decoded invoice
|
|
278
|
+
Object.assign(this, invoice);
|
|
279
|
+
// Ensure backward compatibility
|
|
280
|
+
if (!this.id && this.accountingDocId) {
|
|
281
|
+
this.id = this.accountingDocId;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Maps this EInvoice instance to a TInvoice
|
|
286
|
+
*/
|
|
287
|
+
mapToTInvoice() {
|
|
288
|
+
const invoice = {
|
|
289
|
+
type: 'accounting-doc',
|
|
290
|
+
accountingDocType: this.accountingDocType,
|
|
291
|
+
accountingDocId: this.accountingDocId || this.id,
|
|
292
|
+
accountingDocStatus: this.accountingDocStatus,
|
|
293
|
+
id: this.id,
|
|
294
|
+
date: this.date,
|
|
295
|
+
status: this.status,
|
|
296
|
+
subject: this.subject,
|
|
297
|
+
versionInfo: this.versionInfo,
|
|
298
|
+
from: this.from,
|
|
299
|
+
to: this.to,
|
|
300
|
+
legalContact: this.legalContact,
|
|
301
|
+
incidenceId: this.incidenceId,
|
|
302
|
+
language: this.language,
|
|
303
|
+
objectActions: this.objectActions,
|
|
304
|
+
items: this.items,
|
|
305
|
+
dueInDays: this.dueInDays,
|
|
306
|
+
reverseCharge: this.reverseCharge,
|
|
307
|
+
currency: this.currency,
|
|
308
|
+
notes: this.notes,
|
|
309
|
+
periodOfPerformance: this.periodOfPerformance,
|
|
310
|
+
deliveryDate: this.deliveryDate,
|
|
311
|
+
buyerReference: this.buyerReference,
|
|
312
|
+
electronicAddress: this.electronicAddress,
|
|
313
|
+
paymentOptions: this.paymentOptions,
|
|
314
|
+
relatedDocuments: this.relatedDocuments,
|
|
315
|
+
printResult: this.printResult
|
|
316
|
+
};
|
|
317
|
+
// Preserve metadata for enhanced spec compliance
|
|
318
|
+
if (this.metadata) {
|
|
319
|
+
invoice.metadata = this.metadata;
|
|
320
|
+
}
|
|
321
|
+
return invoice;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Exports the invoice to an XML string in the specified format
|
|
325
|
+
* @param format The target format
|
|
326
|
+
* @returns The XML string
|
|
327
|
+
*/
|
|
328
|
+
async toXmlString(format) {
|
|
329
|
+
try {
|
|
330
|
+
const encoder = EncoderFactory.createEncoder(format);
|
|
331
|
+
const invoice = this.mapToTInvoice();
|
|
332
|
+
// Import EN16931Validator dynamically to avoid circular dependency
|
|
333
|
+
const { EN16931Validator } = await import('./formats/validation/en16931.validator.js');
|
|
334
|
+
// Validate mandatory fields before encoding
|
|
335
|
+
EN16931Validator.validateMandatoryFields(invoice);
|
|
336
|
+
return await encoder.encode(invoice);
|
|
337
|
+
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
throw new EInvoiceFormatError(`Failed to encode to ${format}: ${error.message}`, { targetFormat: format });
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Validates the invoice
|
|
344
|
+
* @param level The validation level to use
|
|
345
|
+
* @returns The validation result
|
|
346
|
+
*/
|
|
347
|
+
async validate(level = ValidationLevel.BUSINESS) {
|
|
348
|
+
try {
|
|
349
|
+
const format = this.detectedFormat || InvoiceFormat.UNKNOWN;
|
|
350
|
+
if (format === InvoiceFormat.UNKNOWN) {
|
|
351
|
+
throw new EInvoiceValidationError('Cannot validate: format unknown', []);
|
|
352
|
+
}
|
|
353
|
+
const validator = ValidatorFactory.createValidator(this.xmlString);
|
|
354
|
+
const result = validator.validate(level);
|
|
355
|
+
this.validationErrors = result.errors;
|
|
356
|
+
return result;
|
|
357
|
+
}
|
|
358
|
+
catch (error) {
|
|
359
|
+
if (error instanceof EInvoiceError) {
|
|
360
|
+
throw error;
|
|
361
|
+
}
|
|
362
|
+
throw new EInvoiceValidationError(`Validation failed: ${error.message}`, [], { validationLevel: level });
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Embeds the invoice XML into a PDF
|
|
367
|
+
* @param pdfBuffer The PDF buffer to embed into
|
|
368
|
+
* @param format The format to use for embedding
|
|
369
|
+
* @returns The PDF buffer with embedded XML
|
|
370
|
+
*/
|
|
371
|
+
async embedInPdf(pdfBuffer, format = 'facturx') {
|
|
372
|
+
try {
|
|
373
|
+
const xmlString = await this.toXmlString(format);
|
|
374
|
+
const embedResult = await this.pdfEmbedder.embedXml(pdfBuffer, xmlString, 'invoice.xml', `${format} Invoice`);
|
|
375
|
+
if (!embedResult.success) {
|
|
376
|
+
throw new EInvoicePDFError('Failed to embed XML in PDF', 'embed', { format });
|
|
377
|
+
}
|
|
378
|
+
return embedResult.data;
|
|
379
|
+
}
|
|
380
|
+
catch (error) {
|
|
381
|
+
throw new EInvoicePDFError(`Failed to embed XML in PDF: ${error.message}`, 'embed', { format }, error);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Saves the invoice to a file
|
|
386
|
+
* @param filePath The path to save to
|
|
387
|
+
* @param format The format to save in
|
|
388
|
+
*/
|
|
389
|
+
async saveToFile(filePath, format) {
|
|
390
|
+
try {
|
|
391
|
+
// Determine format from file extension if not provided
|
|
392
|
+
if (!format && filePath.toLowerCase().endsWith('.xml')) {
|
|
393
|
+
format = this.detectedFormat === InvoiceFormat.UBL ? 'ubl' :
|
|
394
|
+
this.detectedFormat === InvoiceFormat.ZUGFERD ? 'zugferd' :
|
|
395
|
+
this.detectedFormat === InvoiceFormat.FACTURX ? 'facturx' :
|
|
396
|
+
'xrechnung';
|
|
397
|
+
}
|
|
398
|
+
if (filePath.toLowerCase().endsWith('.pdf')) {
|
|
399
|
+
// Save as PDF with embedded XML
|
|
400
|
+
if (!this.pdf) {
|
|
401
|
+
throw new EInvoiceError('No PDF available to save', 'NO_PDF_ERROR');
|
|
402
|
+
}
|
|
403
|
+
const pdfWithXml = await this.embedInPdf(Buffer.from(this.pdf.buffer), format);
|
|
404
|
+
await plugins.fs.writeFile(filePath, pdfWithXml);
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
// Save as XML
|
|
408
|
+
const xmlString = await this.toXmlString(format || 'xrechnung');
|
|
409
|
+
await plugins.fs.writeFile(filePath, xmlString, 'utf-8');
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
catch (error) {
|
|
413
|
+
if (error instanceof EInvoiceError) {
|
|
414
|
+
throw error;
|
|
415
|
+
}
|
|
416
|
+
throw new EInvoiceError(`Failed to save file: ${error.message}`, 'FILE_SAVE_ERROR', { filePath });
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Gets the validation errors
|
|
421
|
+
* @returns Array of validation errors
|
|
422
|
+
*/
|
|
423
|
+
getValidationErrors() {
|
|
424
|
+
return this.validationErrors;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Checks if the invoice is valid
|
|
428
|
+
* @returns True if valid, false otherwise
|
|
429
|
+
*/
|
|
430
|
+
isValid() {
|
|
431
|
+
return this.validationErrors.length === 0;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Gets the detected format
|
|
435
|
+
* @returns The detected invoice format
|
|
436
|
+
*/
|
|
437
|
+
getFormat() {
|
|
438
|
+
return this.detectedFormat;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Gets the original XML string
|
|
442
|
+
* @returns The XML string
|
|
443
|
+
*/
|
|
444
|
+
getXml() {
|
|
445
|
+
return this.xmlString;
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Calculates the total net amount
|
|
449
|
+
*/
|
|
450
|
+
calculateTotalNet() {
|
|
451
|
+
return this.items.reduce((sum, item) => {
|
|
452
|
+
return sum + (item.unitQuantity * item.unitNetPrice);
|
|
453
|
+
}, 0);
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Calculates the total VAT amount
|
|
457
|
+
*/
|
|
458
|
+
calculateTotalVat() {
|
|
459
|
+
return this.items.reduce((sum, item) => {
|
|
460
|
+
const net = item.unitQuantity * item.unitNetPrice;
|
|
461
|
+
return sum + (net * item.vatPercentage / 100);
|
|
462
|
+
}, 0);
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Calculates tax breakdown by rate
|
|
466
|
+
*/
|
|
467
|
+
calculateTaxBreakdown() {
|
|
468
|
+
const breakdown = new Map();
|
|
469
|
+
this.items.forEach(item => {
|
|
470
|
+
const net = item.unitQuantity * item.unitNetPrice;
|
|
471
|
+
const tax = net * item.vatPercentage / 100;
|
|
472
|
+
const current = breakdown.get(item.vatPercentage) || { net: 0, tax: 0 };
|
|
473
|
+
breakdown.set(item.vatPercentage, {
|
|
474
|
+
net: current.net + net,
|
|
475
|
+
tax: current.tax + tax
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
return Array.from(breakdown.entries()).map(([rate, amounts]) => ({
|
|
479
|
+
taxPercent: rate,
|
|
480
|
+
netAmount: amounts.net,
|
|
481
|
+
taxAmount: amounts.tax
|
|
482
|
+
}));
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Creates a new invoice item
|
|
486
|
+
*/
|
|
487
|
+
createItem(data) {
|
|
488
|
+
return {
|
|
489
|
+
position: data.position || this.items.length + 1,
|
|
490
|
+
name: data.name || '',
|
|
491
|
+
articleNumber: data.articleNumber,
|
|
492
|
+
unitType: data.unitType || 'unit',
|
|
493
|
+
unitQuantity: data.unitQuantity || 1,
|
|
494
|
+
unitNetPrice: data.unitNetPrice || 0,
|
|
495
|
+
vatPercentage: data.vatPercentage || 0
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Adds an item to the invoice
|
|
500
|
+
*/
|
|
501
|
+
addItem(item) {
|
|
502
|
+
this.items.push(this.createItem(item));
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWludm9pY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9laW52b2ljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUVqRCxPQUFPLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBR3hFLHVCQUF1QjtBQUN2QixPQUFPLEVBQ0wsYUFBYSxFQUNiLG9CQUFvQixFQUNwQix1QkFBdUIsRUFDdkIsZ0JBQWdCLEVBQ2hCLG1CQUFtQixFQUNuQixZQUFZLEVBQ2IsTUFBTSxhQUFhLENBQUM7QUFFckIsbUJBQW1CO0FBQ25CLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUN4RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDeEUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFFNUUsdUJBQXVCO0FBQ3ZCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFFOUQseUJBQXlCO0FBQ3pCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUVwRTs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLFFBQVE7SUFDbkI7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQWlCO1FBQzNDLE1BQU0sT0FBTyxHQUFHLElBQUksUUFBUSxFQUFFLENBQUM7UUFDL0IsTUFBTSxPQUFPLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3ZDLE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksTUFBTSxDQUFDLEtBQUss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
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all EInvoice-related errors
|
|
3
|
+
*/
|
|
4
|
+
export declare class EInvoiceError extends Error {
|
|
5
|
+
code: string;
|
|
6
|
+
details?: any;
|
|
7
|
+
cause?: Error;
|
|
8
|
+
constructor(message: string, code: string, details?: any, cause?: Error);
|
|
9
|
+
/**
|
|
10
|
+
* Returns a detailed error message including cause if available
|
|
11
|
+
*/
|
|
12
|
+
getDetailedMessage(): string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Error thrown when XML parsing fails
|
|
16
|
+
*/
|
|
17
|
+
export declare class EInvoiceParsingError extends EInvoiceError {
|
|
18
|
+
line?: number;
|
|
19
|
+
column?: number;
|
|
20
|
+
xmlSnippet?: string;
|
|
21
|
+
constructor(message: string, details?: {
|
|
22
|
+
line?: number;
|
|
23
|
+
column?: number;
|
|
24
|
+
xmlSnippet?: string;
|
|
25
|
+
format?: string;
|
|
26
|
+
}, cause?: Error);
|
|
27
|
+
/**
|
|
28
|
+
* Returns a user-friendly error message with location information
|
|
29
|
+
*/
|
|
30
|
+
getLocationMessage(): string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Error thrown when validation fails
|
|
34
|
+
*/
|
|
35
|
+
export declare class EInvoiceValidationError extends EInvoiceError {
|
|
36
|
+
validationErrors: Array<{
|
|
37
|
+
code: string;
|
|
38
|
+
message: string;
|
|
39
|
+
location?: string;
|
|
40
|
+
severity?: 'error' | 'warning';
|
|
41
|
+
}>;
|
|
42
|
+
constructor(message: string, validationErrors: Array<{
|
|
43
|
+
code: string;
|
|
44
|
+
message: string;
|
|
45
|
+
location?: string;
|
|
46
|
+
severity?: 'error' | 'warning';
|
|
47
|
+
}>, details?: any);
|
|
48
|
+
/**
|
|
49
|
+
* Returns a formatted validation report
|
|
50
|
+
*/
|
|
51
|
+
getValidationReport(): string;
|
|
52
|
+
/**
|
|
53
|
+
* Gets validation errors by severity
|
|
54
|
+
*/
|
|
55
|
+
getErrorsBySeverity(severity: 'error' | 'warning'): typeof this.validationErrors;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Error thrown during PDF operations
|
|
59
|
+
*/
|
|
60
|
+
export declare class EInvoicePDFError extends EInvoiceError {
|
|
61
|
+
operation: 'extract' | 'embed' | 'create' | 'validate';
|
|
62
|
+
pdfInfo?: {
|
|
63
|
+
filename?: string;
|
|
64
|
+
size?: number;
|
|
65
|
+
pageCount?: number;
|
|
66
|
+
};
|
|
67
|
+
constructor(message: string, operation: 'extract' | 'embed' | 'create' | 'validate', details?: any, cause?: Error);
|
|
68
|
+
/**
|
|
69
|
+
* Returns recovery suggestions based on the operation
|
|
70
|
+
*/
|
|
71
|
+
getRecoverySuggestions(): string[];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Error thrown for format-specific issues
|
|
75
|
+
*/
|
|
76
|
+
export declare class EInvoiceFormatError extends EInvoiceError {
|
|
77
|
+
sourceFormat?: string;
|
|
78
|
+
targetFormat?: string;
|
|
79
|
+
unsupportedFeatures?: string[];
|
|
80
|
+
constructor(message: string, details: {
|
|
81
|
+
sourceFormat?: string;
|
|
82
|
+
targetFormat?: string;
|
|
83
|
+
unsupportedFeatures?: string[];
|
|
84
|
+
conversionPath?: string;
|
|
85
|
+
}, cause?: Error);
|
|
86
|
+
/**
|
|
87
|
+
* Returns a compatibility report
|
|
88
|
+
*/
|
|
89
|
+
getCompatibilityReport(): string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Error recovery helper class
|
|
93
|
+
*/
|
|
94
|
+
export declare class ErrorRecovery {
|
|
95
|
+
/**
|
|
96
|
+
* Attempts to recover from a parsing error by cleaning the XML
|
|
97
|
+
*/
|
|
98
|
+
static attemptXMLRecovery(xmlString: string, error: EInvoiceParsingError): Promise<{
|
|
99
|
+
success: boolean;
|
|
100
|
+
cleanedXml?: string;
|
|
101
|
+
message: string;
|
|
102
|
+
}>;
|
|
103
|
+
/**
|
|
104
|
+
* Provides partial data extraction on validation failure
|
|
105
|
+
*/
|
|
106
|
+
static extractPartialData(xmlString: string, format: string): {
|
|
107
|
+
success: boolean;
|
|
108
|
+
partialData?: any;
|
|
109
|
+
message: string;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Error context builder for detailed error information
|
|
114
|
+
*/
|
|
115
|
+
export declare class ErrorContext {
|
|
116
|
+
private context;
|
|
117
|
+
add(key: string, value: any): this;
|
|
118
|
+
addTimestamp(): this;
|
|
119
|
+
addEnvironment(): this;
|
|
120
|
+
build(): Record<string, any>;
|
|
121
|
+
}
|