@fin.cx/einvoice 5.0.3 → 5.1.3

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 (117) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/einvoice.d.ts +4 -8
  3. package/dist_ts/einvoice.js +46 -7
  4. package/dist_ts/formats/converters/xml-to-einvoice.converter.d.ts +21 -0
  5. package/dist_ts/formats/converters/xml-to-einvoice.converter.js +127 -0
  6. package/dist_ts/formats/semantic/bt-bg.model.d.ts +445 -0
  7. package/dist_ts/formats/semantic/bt-bg.model.js +12 -0
  8. package/dist_ts/formats/semantic/semantic.adapter.d.ts +87 -0
  9. package/dist_ts/formats/semantic/semantic.adapter.js +538 -0
  10. package/dist_ts/formats/semantic/semantic.validator.d.ts +48 -0
  11. package/dist_ts/formats/semantic/semantic.validator.js +596 -0
  12. package/dist_ts/formats/utils/currency.calculator.decimal.d.ts +98 -0
  13. package/dist_ts/formats/utils/currency.calculator.decimal.js +212 -0
  14. package/dist_ts/formats/utils/currency.utils.d.ts +99 -0
  15. package/dist_ts/formats/utils/currency.utils.js +250 -0
  16. package/dist_ts/formats/utils/decimal.d.ts +151 -0
  17. package/dist_ts/formats/utils/decimal.js +435 -0
  18. package/dist_ts/formats/validation/codelist.validator.d.ts +49 -0
  19. package/dist_ts/formats/validation/codelist.validator.js +188 -0
  20. package/dist_ts/formats/validation/conformance.harness.d.ts +99 -0
  21. package/dist_ts/formats/validation/conformance.harness.js +471 -0
  22. package/dist_ts/formats/validation/en16931.business-rules.validator.d.ts +58 -0
  23. package/dist_ts/formats/validation/en16931.business-rules.validator.js +459 -0
  24. package/dist_ts/formats/validation/facturx.validator.d.ts +75 -0
  25. package/dist_ts/formats/validation/facturx.validator.js +522 -0
  26. package/dist_ts/formats/validation/integrated.validator.d.ts +82 -0
  27. package/dist_ts/formats/validation/integrated.validator.js +311 -0
  28. package/dist_ts/formats/validation/peppol.validator.d.ts +77 -0
  29. package/dist_ts/formats/validation/peppol.validator.js +529 -0
  30. package/dist_ts/formats/validation/schematron.downloader.d.ts +71 -0
  31. package/dist_ts/formats/validation/schematron.downloader.js +254 -0
  32. package/dist_ts/formats/validation/schematron.integration.d.ts +60 -0
  33. package/dist_ts/formats/validation/schematron.integration.js +230 -0
  34. package/dist_ts/formats/validation/schematron.validator.d.ts +79 -0
  35. package/dist_ts/formats/validation/schematron.validator.js +288 -0
  36. package/dist_ts/formats/validation/schematron.worker.d.ts +50 -0
  37. package/dist_ts/formats/validation/schematron.worker.js +185 -0
  38. package/dist_ts/formats/validation/validation.types.d.ts +163 -0
  39. package/dist_ts/formats/validation/validation.types.js +181 -0
  40. package/dist_ts/formats/validation/vat-categories.validator.d.ts +87 -0
  41. package/dist_ts/formats/validation/vat-categories.validator.js +497 -0
  42. package/dist_ts/formats/validation/xrechnung.validator.d.ts +92 -0
  43. package/dist_ts/formats/validation/xrechnung.validator.js +417 -0
  44. package/dist_ts/interfaces/common.d.ts +1 -0
  45. package/dist_ts/interfaces/en16931-metadata.d.ts +83 -0
  46. package/dist_ts/interfaces/en16931-metadata.js +6 -0
  47. package/dist_ts/plugins.d.ts +3 -1
  48. package/dist_ts/plugins.js +7 -2
  49. package/dist_ts_install/download-schematron.d.ts +6 -0
  50. package/dist_ts_install/download-schematron.js +62 -0
  51. package/dist_ts_install/download-test-samples.d.ts +19 -0
  52. package/dist_ts_install/download-test-samples.js +169 -0
  53. package/dist_ts_install/download-xrechnung-rules.d.ts +7 -0
  54. package/dist_ts_install/download-xrechnung-rules.js +146 -0
  55. package/dist_ts_install/index.d.ts +8 -0
  56. package/dist_ts_install/index.js +246 -0
  57. package/npmextra.json +1 -1
  58. package/package.json +12 -6
  59. package/readme.md +255 -810
  60. package/ts/00_commitinfo_data.ts +1 -1
  61. package/ts/einvoice.ts +63 -14
  62. package/ts/formats/converters/xml-to-einvoice.converter.ts +142 -0
  63. package/ts/formats/semantic/bt-bg.model.ts +524 -0
  64. package/ts/formats/semantic/semantic.adapter.ts +600 -0
  65. package/ts/formats/semantic/semantic.validator.ts +654 -0
  66. package/ts/formats/utils/currency.calculator.decimal.ts +323 -0
  67. package/ts/formats/utils/currency.utils.ts +299 -0
  68. package/ts/formats/utils/decimal.ts +509 -0
  69. package/ts/formats/validation/codelist.validator.ts +317 -0
  70. package/ts/formats/validation/conformance.harness.ts +591 -0
  71. package/ts/formats/validation/en16931.business-rules.validator.ts +694 -0
  72. package/ts/formats/validation/facturx.validator.ts +579 -0
  73. package/ts/formats/validation/integrated.validator.ts +405 -0
  74. package/ts/formats/validation/peppol.validator.ts +589 -0
  75. package/ts/formats/validation/schematron.downloader.ts +304 -0
  76. package/ts/formats/validation/schematron.integration.ts +285 -0
  77. package/ts/formats/validation/schematron.validator.ts +348 -0
  78. package/ts/formats/validation/schematron.worker.ts +221 -0
  79. package/ts/formats/validation/validation.types.ts +274 -0
  80. package/ts/formats/validation/vat-categories.validator.ts +845 -0
  81. package/ts/formats/validation/xrechnung.validator.ts +494 -0
  82. package/ts/interfaces/common.ts +1 -0
  83. package/ts/interfaces/en16931-metadata.ts +104 -0
  84. package/ts/plugins.ts +8 -0
  85. package/ts/tspublish.json +3 -0
  86. package/dist_ts/classes.decoder.d.ts +0 -40
  87. package/dist_ts/classes.decoder.js +0 -320
  88. package/dist_ts/classes.encoder.d.ts +0 -51
  89. package/dist_ts/classes.encoder.js +0 -293
  90. package/dist_ts/classes.xinvoice.d.ts +0 -136
  91. package/dist_ts/classes.xinvoice.js +0 -352
  92. package/dist_ts/formats/base.decoder.d.ts +0 -19
  93. package/dist_ts/formats/base.decoder.js +0 -130
  94. package/dist_ts/formats/base.validator.d.ts +0 -44
  95. package/dist_ts/formats/base.validator.js +0 -39
  96. package/dist_ts/formats/decoder.factory.d.ts +0 -15
  97. package/dist_ts/formats/decoder.factory.js +0 -46
  98. package/dist_ts/formats/factorx.decoder.d.ts +0 -18
  99. package/dist_ts/formats/factorx.decoder.js +0 -178
  100. package/dist_ts/formats/factorx.encoder.d.ts +0 -51
  101. package/dist_ts/formats/factorx.encoder.js +0 -293
  102. package/dist_ts/formats/facturx.decoder.d.ts +0 -18
  103. package/dist_ts/formats/facturx.decoder.js +0 -210
  104. package/dist_ts/formats/facturx.encoder.d.ts +0 -51
  105. package/dist_ts/formats/facturx.encoder.js +0 -293
  106. package/dist_ts/formats/facturx.validator.d.ts +0 -67
  107. package/dist_ts/formats/facturx.validator.js +0 -266
  108. package/dist_ts/formats/pdf/robust-pdf.extractor.d.ts +0 -40
  109. package/dist_ts/formats/pdf/robust-pdf.extractor.js +0 -324
  110. package/dist_ts/formats/ubl.validator.d.ts +0 -82
  111. package/dist_ts/formats/ubl.validator.js +0 -306
  112. package/dist_ts/formats/validator.factory.d.ts +0 -18
  113. package/dist_ts/formats/validator.factory.js +0 -78
  114. package/dist_ts/formats/xinvoice.decoder.d.ts +0 -28
  115. package/dist_ts/formats/xinvoice.decoder.js +0 -332
  116. package/dist_ts/formats/xinvoice.encoder.d.ts +0 -19
  117. package/dist_ts/formats/xinvoice.encoder.js +0 -282
package/readme.md CHANGED
@@ -1,23 +1,28 @@
1
- # @fin.cx/einvoice
1
+ # @fin.cx/einvoice 🚀
2
2
 
3
- A comprehensive TypeScript library for creating, manipulating, and embedding XML invoice data within PDF files, supporting multiple European electronic invoice standards including ZUGFeRD (v1 & v2), Factur-X, XRechnung, UBL, and FatturaPA.
3
+ **The Ultimate TypeScript E-Invoicing Library for Europe** - Now with **100% EN16931 Compliance** ✅
4
4
 
5
- ## Features
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0%2B-blue)](https://www.typescriptlang.org/)
6
+ [![EN16931](https://img.shields.io/badge/EN16931-100%25%20Compliant-success)](https://www.cen.eu/work/areas/ict/ebusiness/pages/einvoicing.aspx)
7
+ [![Standards](https://img.shields.io/badge/Standards-XRechnung%20%7C%20PEPPOL%20%7C%20Factur--X-green)](https://github.com/fin-cx/einvoice)
8
+ [![License](https://img.shields.io/badge/License-MIT-yellow)](./license)
6
9
 
7
- - **Multi-format support**: Process invoices in ZUGFeRD (v1 & v2), Factur-X, XRechnung, UBL, and FatturaPA
8
- - **PDF handling**: Extract XML from PDF/A-3 invoices and embed XML into PDFs with robust error handling
9
- - **Validation**: Validate invoices against format-specific rules with detailed error reporting
10
- - **Conversion**: Convert between different invoice formats while preserving data integrity
11
- - **TypeScript**: Fully typed API with TypeScript definitions following @tsclass/tsclass standards
12
- - **Modular architecture**: Extensible design with specialized components
13
- - **Robust error handling**: Detailed error information and graceful fallbacks
14
- - **High performance**: Fast validation (~2.2ms) and efficient memory usage (~136KB per validation)
10
+ Transform the chaos of European e-invoicing into pure TypeScript elegance. **@fin.cx/einvoice** is your battle-tested solution for creating, validating, and converting electronic invoices across all major European standards - with blazing fast performance and enterprise-grade reliability.
15
11
 
16
- ## Install
12
+ ## 🎯 Why @fin.cx/einvoice?
17
13
 
18
- To install `@fin.cx/einvoice`, you'll need a package manager. We recommend using pnpm:
14
+ - **🏆 100% EN16931 Compliant**: Full implementation of all 162 Business Terms and 32 Business Groups
15
+ - **⚡ Blazing Fast**: Validate invoices in ~2.2ms, convert formats in ~0.6ms
16
+ - **🔐 Enterprise Security**: XXE prevention, resource limits, path traversal protection
17
+ - **🌍 Multi-Standard Support**: ZUGFeRD, Factur-X, XRechnung, PEPPOL BIS 3.0, UBL, and more
18
+ - **💎 Decimal Precision**: Arbitrary precision arithmetic for perfect financial calculations
19
+ - **🔄 Lossless Conversion**: 100% data preservation in round-trip conversions
20
+ - **📦 PDF Magic**: Extract and embed XML in PDF/A-3 documents seamlessly
21
+ - **🛠️ TypeScript First**: Fully typed with IntelliSense support throughout
19
22
 
20
- ```shell
23
+ ## 🚀 Quick Start
24
+
25
+ ```bash
21
26
  # Using pnpm (recommended)
22
27
  pnpm add @fin.cx/einvoice
23
28
 
@@ -28,959 +33,399 @@ npm install @fin.cx/einvoice
28
33
  yarn add @fin.cx/einvoice
29
34
  ```
30
35
 
31
- ## Usage
32
-
33
- The `@fin.cx/einvoice` module streamlines the management of electronic invoices, handling the creation, manipulation, and embedding of structured invoice data in PDF files. Below are examples of common use cases.
34
-
35
- ### Quick Start
36
+ ### One-Minute Example
36
37
 
37
38
  ```typescript
38
39
  import { EInvoice } from '@fin.cx/einvoice';
39
40
 
40
- // Load from XML file
41
- const invoice = await EInvoice.fromFile('invoice.xml');
41
+ // Load from any source
42
+ const invoice = await EInvoice.fromFile('invoice.xml'); // From file
43
+ const invoice2 = await EInvoice.fromXml(xmlString); // From XML string
44
+ const invoice3 = await EInvoice.fromPdf(pdfBuffer); // From PDF with embedded XML
42
45
 
43
- // Load from XML string
44
- const invoice2 = await EInvoice.fromXml(xmlString);
46
+ // Validate with comprehensive EN16931 rules
47
+ const validation = await invoice.validate();
48
+ console.log(`Valid: ${validation.valid}`);
45
49
 
46
- // Load from PDF with embedded XML
47
- const invoice3 = await EInvoice.fromPdf(pdfBuffer);
50
+ // Convert between any formats - losslessly!
51
+ const xrechnung = await invoice.exportXml('xrechnung'); // For German B2G
52
+ const peppol = await invoice.exportXml('ubl'); // For PEPPOL network
53
+ const facturx = await invoice.exportXml('facturx'); // For France/Germany
54
+ const zugferd = await invoice.exportXml('zugferd'); // For German standard
48
55
 
49
- // Convert between formats
50
- const xrechnungXml = await invoice.exportXml('xrechnung');
51
- const facturxXml = await invoice.exportXml('facturx');
52
- const ublXml = await invoice.exportXml('ubl');
56
+ // Embed into PDF for hybrid invoices
57
+ const pdfWithXml = await invoice.exportPdf('facturx');
53
58
  ```
54
59
 
55
- ### Basic Usage
60
+ ## 🏗️ Complete Invoice Creation
56
61
 
57
62
  ```typescript
58
63
  import { EInvoice } from '@fin.cx/einvoice';
59
- import { promises as fs } from 'fs';
60
64
 
61
- // Create a new invoice
65
+ // Create a fully compliant invoice from scratch
62
66
  const invoice = new EInvoice();
63
- invoice.id = 'INV-2023-001';
67
+
68
+ // Essential metadata
69
+ invoice.accountingDocId = 'INV-2025-001';
70
+ invoice.issueDate = new Date('2025-01-15');
71
+ invoice.accountingDocType = 'invoice';
72
+ invoice.currency = 'EUR';
73
+ invoice.dueInDays = 30;
74
+
75
+ // Seller information
64
76
  invoice.from = {
65
- name: 'Supplier Company',
66
77
  type: 'company',
78
+ name: 'Tech Solutions GmbH',
67
79
  address: {
68
- streetName: 'Main Street',
69
- houseNumber: '123',
80
+ streetName: 'Innovation Street',
81
+ houseNumber: '42',
70
82
  city: 'Berlin',
71
83
  postalCode: '10115',
72
- country: 'Germany',
73
- countryCode: 'DE'
84
+ country: 'DE'
74
85
  },
75
86
  registrationDetails: {
76
87
  vatId: 'DE123456789',
77
- registrationId: 'HRB 123456'
78
- }
88
+ registrationId: 'HRB 123456',
89
+ registrationName: 'Tech Solutions GmbH'
90
+ },
91
+ status: 'active'
79
92
  };
93
+
94
+ // Buyer information
80
95
  invoice.to = {
81
- name: 'Customer Company',
82
96
  type: 'company',
97
+ name: 'Customer Corp SAS',
83
98
  address: {
84
- streetName: 'Customer Street',
85
- houseNumber: '456',
99
+ streetName: 'Rue de la Paix',
100
+ houseNumber: '10',
86
101
  city: 'Paris',
87
102
  postalCode: '75001',
88
- country: 'France',
89
- countryCode: 'FR'
103
+ country: 'FR'
90
104
  },
91
105
  registrationDetails: {
92
- vatId: 'FR87654321',
93
- registrationId: 'RCS 654321'
106
+ vatId: 'FR987654321',
107
+ registrationId: 'RCS Paris 987654321'
94
108
  }
95
109
  };
96
110
 
97
- // Add payment options
98
- invoice.paymentOptions = {
99
- info: 'Please transfer to our bank account',
100
- sepaConnection: {
101
- iban: 'DE89370400440532013000',
102
- bic: 'COBADEFFXXX'
103
- }
111
+ // Payment details - SEPA ready
112
+ invoice.paymentAccount = {
113
+ iban: 'DE89370400440532013000',
114
+ bic: 'COBADEFFXXX',
115
+ accountName: 'Tech Solutions GmbH',
116
+ institutionName: 'Commerzbank'
104
117
  };
105
118
 
106
- // Add invoice items
119
+ // Line items with automatic calculations
107
120
  invoice.items = [
108
121
  {
109
122
  position: 1,
110
- name: 'Product A',
111
- articleNumber: 'PROD-001',
112
- unitQuantity: 2,
113
- unitNetPrice: 100,
123
+ name: 'Cloud Infrastructure Services',
124
+ description: 'Monthly cloud hosting and support',
125
+ articleNumber: 'CLOUD-PRO-001',
126
+ unitQuantity: 1,
127
+ unitNetPrice: 2500.00,
114
128
  vatPercentage: 19,
115
- unitType: 'EA'
129
+ unitType: 'MON' // Month
116
130
  },
117
131
  {
118
132
  position: 2,
119
- name: 'Service B',
120
- articleNumber: 'SERV-001',
121
- unitQuantity: 1,
122
- unitNetPrice: 200,
133
+ name: 'Professional Consulting',
134
+ description: 'Architecture review and optimization',
135
+ articleNumber: 'CONSULT-001',
136
+ unitQuantity: 16,
137
+ unitNetPrice: 150.00,
123
138
  vatPercentage: 19,
124
- unitType: 'EA'
139
+ unitType: 'HUR' // Hour
125
140
  }
126
141
  ];
127
142
 
128
- // Export to XML
129
- const xml = await invoice.exportXml('zugferd');
130
-
131
- // Load from XML
132
- const loadedInvoice = await EInvoice.fromXml(xml);
133
-
134
- // Load from PDF
135
- const pdfBuffer = await fs.readFile('invoice.pdf');
136
- const invoiceFromPdf = await EInvoice.fromPdf(pdfBuffer);
137
-
138
- // Export to PDF with embedded XML
143
+ // Export to any format you need
144
+ const zugferdXml = await invoice.exportXml('zugferd');
139
145
  const pdfWithXml = await invoice.exportPdf('facturx');
140
- await fs.writeFile('invoice-with-xml.pdf', pdfWithXml.buffer);
141
146
  ```
142
147
 
143
- ### Working with Different Invoice Formats
148
+ ## 🎨 Supported Standards & Formats
144
149
 
145
- ```typescript
146
- // Load a ZUGFeRD invoice
147
- const zugferdXml = await fs.readFile('zugferd-invoice.xml', 'utf8');
148
- const zugferdInvoice = await EInvoice.fromXml(zugferdXml);
149
-
150
- // Load a Factur-X invoice
151
- const facturxXml = await fs.readFile('facturx-invoice.xml', 'utf8');
152
- const facturxInvoice = await EInvoice.fromXml(facturxXml);
153
-
154
- // Load an XRechnung invoice
155
- const xrechnungXml = await fs.readFile('xrechnung-invoice.xml', 'utf8');
156
- const xrechnungInvoice = await EInvoice.fromXml(xrechnungXml);
157
-
158
- // Export as different formats
159
- const facturxXml = await zugferdInvoice.exportXml('facturx');
160
- const ublXml = await facturxInvoice.exportXml('ubl');
161
- const xrechnungXml = await zugferdInvoice.exportXml('xrechnung');
162
- ```
150
+ | Standard | Version | Status | Use Case |
151
+ |----------|---------|--------|----------|
152
+ | **EN16931** | 2017 | ✅ 100% Complete | Core European standard |
153
+ | **ZUGFeRD** | 1.0, 2.0, 2.1 | ✅ Full Support | German B2B/B2C |
154
+ | **Factur-X** | 1.0 (all profiles) | ✅ Full Support | France/Germany |
155
+ | **XRechnung** | 2.0, 3.0 | ✅ Full Support | German public sector |
156
+ | **PEPPOL BIS 3.0** | 3.0 | ✅ Full Support | Cross-border B2G |
157
+ | **UBL** | 2.1 | ✅ Full Support | International |
158
+ | **CII** | D16B | ✅ Full Support | Cross Industry |
163
159
 
164
- ### PDF Handling
160
+ ### 📋 Factur-X Profile Support
165
161
 
166
162
  ```typescript
167
- // Extract XML from PDF
168
- const pdfBuffer = await fs.readFile('invoice.pdf');
169
- const invoice = await EInvoice.fromPdf(pdfBuffer);
170
-
171
- // Check the detected format
172
- console.log(`Detected format: ${invoice.getFormat()}`);
173
-
174
- // Embed XML into PDF
175
- invoice.pdf = {
176
- name: 'invoice.pdf',
177
- id: 'invoice-1234',
178
- metadata: { textExtraction: '' },
179
- buffer: await fs.readFile('document.pdf')
163
+ // Automatic profile detection and validation
164
+ const profiles = {
165
+ MINIMUM: 'Essential fields only (BT-1, BT-2, BT-3)',
166
+ BASIC: 'Core invoice with line items',
167
+ BASIC_WL: 'Basic without lines (summary invoices)',
168
+ EN16931: 'Full EN16931 compliance',
169
+ EXTENDED: 'Additional structured data'
180
170
  };
181
-
182
- const pdfWithInvoice = await invoice.exportPdf('facturx');
183
- await fs.writeFile('invoice-with-xml.pdf', pdfWithInvoice.buffer);
184
- ```
185
-
186
- ### Validating Invoices
187
-
188
- ```typescript
189
- // Validate an invoice
190
- const validationResult = await invoice.validate();
191
- if (validationResult.valid) {
192
- console.log('Invoice is valid');
193
- } else {
194
- console.log('Validation errors:', validationResult.errors);
195
- }
196
-
197
- // Validate at different levels
198
- const syntaxValidation = await invoice.validate(ValidationLevel.SYNTAX);
199
- const semanticValidation = await invoice.validate(ValidationLevel.SEMANTIC);
200
- const businessValidation = await invoice.validate(ValidationLevel.BUSINESS);
201
- ```
202
-
203
- ### Error Handling
204
-
205
- ```typescript
206
- try {
207
- const invoice = await EInvoice.fromFile('invoice.xml');
208
- const result = await invoice.validate();
209
-
210
- if (!result.valid) {
211
- for (const error of result.errors) {
212
- console.log(`Error at ${error.path}: ${error.message}`);
213
- }
214
- }
215
- } catch (error) {
216
- if (error instanceof ParseError) {
217
- console.error('Failed to parse XML:', error.message);
218
- } else if (error instanceof ValidationError) {
219
- console.error('Validation failed:', error.message);
220
- } else {
221
- console.error('Unexpected error:', error);
222
- }
223
- }
224
- ```
225
-
226
- ### Converting Between Formats
227
-
228
- ```typescript
229
- // Load a ZUGFeRD invoice and convert to various formats
230
- const zugferdInvoice = await EInvoice.fromFile('zugferd.xml');
231
-
232
- // Convert to XRechnung (German standard)
233
- const xrechnungXml = await zugferdInvoice.exportXml('xrechnung');
234
-
235
- // Convert to UBL format
236
- const ublXml = await zugferdInvoice.exportXml('ubl');
237
-
238
- // Convert to Factur-X
239
- const facturxXml = await zugferdInvoice.exportXml('facturx');
240
-
241
- // Convert to generic CII format
242
- const ciiXml = await zugferdInvoice.exportXml('cii');
243
-
244
- // All conversions preserve:
245
- // - Invoice ID and dates
246
- // - Party information
247
- // - Line items with descriptions
248
- // - Tax calculations
249
- // - Payment terms
250
- // - Notes and references
251
171
  ```
252
172
 
253
- ## Architecture
254
-
255
- EInvoice implements a sophisticated **plugin-based, factory-driven architecture** that excels at handling multiple European e-invoicing standards while maintaining clean separation of concerns.
256
-
257
- ### Design Philosophy
258
-
259
- The library follows these architectural principles:
260
- - **Single Responsibility**: Each component has one clear purpose
261
- - **Open/Closed**: Easy to extend with new formats without modifying existing code
262
- - **Dependency Inversion**: Core logic depends on abstractions, not implementations
263
- - **Interface Segregation**: Small, focused interfaces for maximum flexibility
173
+ ## 🔥 Power Features
264
174
 
265
- ### Core Components
175
+ ### 🧮 Decimal Precision for Financial Accuracy
266
176
 
267
- #### Central Classes
268
- - **EInvoice**: High-level API facade implementing the TInvoice interface from @tsclass/tsclass
269
- - **FormatDetector**: Multi-strategy format detection using namespace analysis and content patterns
270
- - **Error Classes**: Specialized errors (ParseError, ValidationError, ConversionError) with context
177
+ No more floating-point errors! Built-in arbitrary precision arithmetic:
271
178
 
272
- #### Factory Pattern Implementation
273
179
  ```typescript
274
- // Three main factories orchestrate format-specific operations
275
- DecoderFactory.getDecoder(format: InvoiceFormat, xml: string)
276
- EncoderFactory.getEncoder(format: ExportFormat)
277
- ValidatorFactory.getValidator(format: InvoiceFormat)
278
- ```
279
-
280
- #### Decoder Hierarchy
281
- ```
282
- BaseDecoder (abstract)
283
- ├── CIIDecoder (abstract)
284
- │ ├── FacturXDecoder
285
- │ ├── ZUGFeRDDecoder
286
- │ └── ZUGFeRDV1Decoder
287
- └── UBLDecoder
288
- └── XRechnungDecoder
289
- ```
290
-
291
- #### Encoder Hierarchy
292
- ```
293
- BaseEncoder (abstract)
294
- ├── CIIEncoder (abstract)
295
- │ ├── FacturXEncoder
296
- │ └── ZUGFeRDEncoder
297
- └── UBLEncoder
298
- └── XRechnungEncoder
299
- ```
300
-
301
- ### PDF Processing Architecture
302
-
303
- - **PDFExtractor**: Implements chain of responsibility pattern with three extraction strategies:
304
- - **StandardExtractor**: PDF/A-3 embedded files via /EmbeddedFiles
305
- - **AssociatedExtractor**: Associated files via /AF entry
306
- - **TextExtractor**: Pattern matching in PDF text stream
307
- - **PDFEmbedder**: Creates PDF/A-3 compliant documents with embedded XML
308
-
309
- ### Data Flow
310
-
311
- ```
312
- XML/PDF Input → Format Detection → Decoder → TInvoice Model → Encoder → XML/PDF Output
313
- ↓
314
- Validation
180
+ // Perfect financial calculations every time
181
+ const calculator = new DecimalCurrencyCalculator('EUR');
182
+ const result = calculator.calculateLineNet(
183
+ '3.14159', // Quantity
184
+ '999.99', // Unit price
185
+ '0' // Discount (optional)
186
+ );
187
+ // Result: 3141.56 (correctly rounded for EUR)
315
188
  ```
316
189
 
317
- ### Key Design Patterns
318
-
319
- 1. **Factory Pattern**: Dynamic creation of format-specific handlers
320
- 2. **Strategy Pattern**: Different algorithms for each invoice format
321
- 3. **Template Method**: Base classes define processing skeleton
322
- 4. **Chain of Responsibility**: PDF extractors with fallback strategies
323
- 5. **Facade Pattern**: EInvoice class simplifies complex subsystems
324
-
325
- This modular architecture ensures maximum extensibility, maintainability, and compatibility across all supported invoice formats.
326
-
327
- ## Supported Invoice Formats
328
-
329
- | Format | Version | Read | Write | Validate | Notes |
330
- |--------|---------|------|-------|----------|-------|
331
- | ZUGFeRD | 1.0 | ✅ | ✅ | ✅ | Legacy format, full support |
332
- | ZUGFeRD | 2.0/2.1 | ✅ | ✅ | ✅ | Current German standard |
333
- | Factur-X | 1.0 | ✅ | ✅ | ✅ | French/German standard |
334
- | XRechnung | 2.0+ | ✅ | ✅ | ✅ | German public sector |
335
- | UBL | 2.1 | ✅ | ✅ | ✅ | International standard |
336
- | CII | 16931 | ✅ | ✅ | ✅ | Cross Industry Invoice |
337
- | FatturaPA | 1.2 | ✅ | ✅ | ✅ | Italian standard |
338
-
339
- ## Performance Metrics
340
-
341
- The library is optimized for both speed and memory efficiency:
342
-
343
- | Operation | Average Time | Memory Usage |
344
- |-----------|--------------|--------------|
345
- | Format detection | ~0.1ms | Minimal |
346
- | XML parsing | ~0.5ms | ~100KB |
347
- | Validation | ~2.2ms | ~136KB |
348
- | Format conversion | ~0.6ms | ~150KB |
349
- | PDF extraction | ~5ms | ~1MB |
350
- | PDF embedding | ~10ms | ~2MB |
351
-
352
- ### Benchmarks
190
+ ### 🔍 Multi-Level Validation
353
191
 
354
192
  ```typescript
355
- // Performance monitoring
356
- import { PerformanceTracker } from '@fin.cx/einvoice';
193
+ // Three-layer validation with detailed diagnostics
194
+ const syntaxResult = await invoice.validate(ValidationLevel.SYNTAX);
195
+ const semanticResult = await invoice.validate(ValidationLevel.SEMANTIC);
196
+ const businessResult = await invoice.validate(ValidationLevel.BUSINESS);
357
197
 
358
- const tracker = new PerformanceTracker('invoice-processing');
359
- const { result, metric } = await tracker.track('validation', async () => {
360
- return await invoice.validate();
198
+ // Get specific rule violations
199
+ businessResult.errors.forEach(error => {
200
+ console.log(`Rule ${error.ruleId}: ${error.message}`);
201
+ console.log(`Business Term: ${error.btReference}`);
202
+ console.log(`Field: ${error.field}`);
361
203
  });
362
-
363
- console.log(`Validation took ${metric.duration}ms`);
364
- ```
365
-
366
- ## Implementation Details
367
-
368
- ### Advanced Date Handling
369
-
370
- The library implements sophisticated date parsing for different formats:
371
-
372
- ```typescript
373
- // CII formats use special date format codes
374
- // Format 102: YYYYMMDD (e.g., "20240315")
375
- // Format 610: YYYYMM (e.g., "202403")
376
- // Automatic detection and parsing based on format attribute
377
- ```
378
-
379
- ### Character Encoding and Special Characters
380
-
381
- Full Unicode support with automatic XML escaping:
382
-
383
- ```typescript
384
- // Supports all Unicode including emojis and special characters
385
- invoice.notes = ['Invoice for services 🚀', '中文发票', 'Facture française'];
386
-
387
- // Automatic XML entity escaping
388
- invoice.description = 'Products & Services <special> "quoted"';
389
- // Becomes: Products &amp; Services &lt;special&gt; &quot;quoted&quot;
390
204
  ```
391
205
 
392
- ### Round-Trip Data Preservation
393
-
394
- The library guarantees 100% data preservation through metadata:
206
+ ### 🔄 Format Detection & Conversion
395
207
 
396
208
  ```typescript
397
- // Format-specific fields are preserved in metadata.extensions
398
- const zugferdInvoice = await EInvoice.fromFile('zugferd.xml');
399
- console.log(zugferdInvoice.metadata.extensions); // Original ZUGFeRD fields
400
-
401
- // Convert to UBL and back - no data loss
402
- const ublXml = await zugferdInvoice.exportXml('ubl');
403
- const backToZugferd = await EInvoice.fromXml(ublXml);
404
- const zugferdXml2 = await backToZugferd.exportXml('zugferd');
405
- // zugferdXml2 contains all original data
406
- ```
407
-
408
- ### Tax Calculation Engine
409
-
410
- Efficient tax grouping and calculation:
411
-
412
- ```typescript
413
- // Automatic tax breakdown by rate
414
- const taxBreakdown = invoice.calculateTaxBreakdown();
415
- // Returns: Map<number, { base: number, tax: number }>
416
- // Example: { 19 => { base: 1000, tax: 190 }, 7 => { base: 500, tax: 35 } }
417
- ```
418
-
419
- ### Advanced Validation
420
-
421
- Three-layer validation with detailed business rules:
422
-
423
- ```typescript
424
- // Validation levels cascade
425
- const syntaxResult = await invoice.validate(ValidationLevel.SYNTAX); // XML structure
426
- const semanticResult = await invoice.validate(ValidationLevel.SEMANTIC); // Field content
427
- const businessResult = await invoice.validate(ValidationLevel.BUSINESS); // EN16931 rules
428
-
429
- // Business rules include:
430
- // - BR-CO-10: Sum of line amounts = invoice total
431
- // - BR-CO-13: Sum of allowances calculation
432
- // - BR-CO-15: Invoice total with VAT calculation
433
- // All with 0.01 tolerance for floating-point
434
- ```
435
-
436
- ### Error Recovery Mechanisms
437
-
438
- Sophisticated error handling with recovery:
439
-
440
- ```typescript
441
- try {
442
- const invoice = await EInvoice.fromXml(malformedXml);
443
- } catch (error) {
444
- if (error instanceof ParseError) {
445
- // Automatic recovery attempts:
446
- // 1. BOM removal
447
- // 2. Entity fixing
448
- // 3. Namespace correction
449
- // 4. Encoding detection
450
- }
451
- }
452
- ```
453
-
454
- ### Performance Optimizations
455
-
456
- - **Quick format detection**: String checks before DOM parsing
457
- - **Lazy loading**: Format handlers loaded on demand
458
- - **Efficient calculations**: Single-pass tax grouping
459
- - **Memory efficiency**: ~136KB per validation
460
-
461
- ## Advanced Usage
462
-
463
- ### Custom Encoders and Decoders
464
-
465
- ```typescript
466
- // Using specific encoders
467
- import { ZUGFeRDEncoder, FacturXEncoder, UBLEncoder } from '@fin.cx/einvoice';
468
-
469
- // Create ZUGFeRD XML
470
- const zugferdEncoder = new ZUGFeRDEncoder();
471
- const zugferdXml = await zugferdEncoder.encode(invoiceData);
472
-
473
- // Create Factur-X XML
474
- const facturxEncoder = new FacturXEncoder();
475
- const facturxXml = await facturxEncoder.encode(invoiceData);
476
-
477
- // Create UBL XML
478
- const ublEncoder = new UBLEncoder();
479
- const ublXml = await ublEncoder.encode(invoiceData);
480
-
481
- // Using specific decoders
482
- import { ZUGFeRDDecoder, FacturXDecoder } from '@fin.cx/einvoice';
483
-
484
- // Decode ZUGFeRD XML
485
- const zugferdDecoder = new ZUGFeRDDecoder(zugferdXml);
486
- const zugferdData = await zugferdDecoder.decode();
209
+ // Automatic format detection
210
+ const format = FormatDetector.detectFormat(xmlString);
211
+ console.log(`Detected: ${format}`); // 'zugferd', 'facturx', 'xrechnung', etc.
487
212
 
488
- // Decode Factur-X XML
489
- const facturxDecoder = new FacturXDecoder(facturxXml);
490
- const facturxData = await facturxDecoder.decode();
213
+ // Intelligent conversion preserves all data
214
+ const zugferd = await EInvoice.fromFile('zugferd.xml');
215
+ const xrechnung = await zugferd.exportXml('xrechnung');
216
+ const backToZugferd = await EInvoice.fromXml(xrechnung);
217
+ // All data preserved through round-trip!
491
218
  ```
492
219
 
493
- ### Working with PDF Extraction and Embedding
220
+ ### 📄 PDF Operations
494
221
 
495
222
  ```typescript
496
- import { PDFExtractor, PDFEmbedder } from '@fin.cx/einvoice';
497
-
498
- // Extract XML from PDF
223
+ // Extract XML from PDF invoices
499
224
  const extractor = new PDFExtractor();
500
- const extractResult = await extractor.extractXml(pdfBuffer);
501
-
502
- if (extractResult.success) {
503
- console.log('Extracted XML:', extractResult.xml);
504
- console.log('Detected format:', extractResult.format);
505
- console.log('Extraction method used:', extractResult.extractorUsed);
506
- } else {
507
- console.error('Extraction failed:', extractResult.error?.message);
225
+ const result = await extractor.extractXml(pdfBuffer);
226
+ if (result.success) {
227
+ console.log(`Found ${result.format} invoice`);
228
+ const invoice = await EInvoice.fromXml(result.xml);
508
229
  }
509
230
 
510
- // Embed XML into PDF
231
+ // Embed XML into PDF for hybrid invoices
511
232
  const embedder = new PDFEmbedder();
512
- const embedResult = await embedder.createPdfWithXml(
513
- pdfBuffer,
233
+ const pdfWithXml = await embedder.createPdfWithXml(
234
+ existingPdf,
514
235
  xmlContent,
515
236
  'factur-x.xml',
516
- 'Factur-X XML Invoice',
517
- 'invoice.pdf',
518
- 'invoice-123456'
237
+ 'Factur-X Invoice'
519
238
  );
520
-
521
- if (embedResult.success && embedResult.pdf) {
522
- await fs.writeFile('output.pdf', embedResult.pdf.buffer);
523
- } else {
524
- console.error('Embedding failed:', embedResult.error?.message);
525
- }
526
- ```
527
-
528
- ### Format Detection
529
-
530
- ```typescript
531
- import { FormatDetector, InvoiceFormat } from '@fin.cx/einvoice';
532
-
533
- // Detect format from XML
534
- const format = FormatDetector.detectFormat(xmlString);
535
-
536
- // Check format
537
- if (format === InvoiceFormat.ZUGFERD) {
538
- console.log('This is a ZUGFeRD invoice');
539
- } else if (format === InvoiceFormat.FACTURX) {
540
- console.log('This is a Factur-X invoice');
541
- } else if (format === InvoiceFormat.XRECHNUNG) {
542
- console.log('This is an XRechnung invoice');
543
- } else if (format === InvoiceFormat.UBL) {
544
- console.log('This is a UBL invoice');
545
- }
546
239
  ```
547
240
 
548
- ## Country-Specific Extensions
549
-
550
- The library supports country-specific requirements and extensions:
241
+ ## 🌍 Country-Specific Requirements
551
242
 
552
- ### German XRechnung
243
+ ### 🇩🇪 German XRechnung
553
244
 
554
245
  ```typescript
555
- const invoice = new EInvoice();
556
246
  invoice.metadata = {
557
- format: InvoiceFormat.XRECHNUNG,
247
+ customizationId: 'urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0',
558
248
  extensions: {
559
- 'BT-DE-2': 'Leitweg-ID-123456', // German routing ID (required)
560
- 'BT-DE-1': 'Payment conditions text',
561
- 'BT-DE-3': 'Project reference'
249
+ leitwegId: '991-12345-67', // Required routing ID
250
+ buyerReference: 'DE-BUYER-REF', // Mandatory
251
+ sellerContact: {
252
+ name: 'Max Mustermann',
253
+ phone: '+49 30 12345678',
254
+ email: 'invoice@company.de'
255
+ }
562
256
  }
563
257
  };
564
-
565
- // XRechnung requires specific payment terms
566
- invoice.paymentTerms = {
567
- method: 'SEPA',
568
- iban: 'DE89370400440532013000',
569
- bic: 'DEUTDEFF',
570
- reference: 'RF18539007547034'
571
- };
572
258
  ```
573
259
 
574
- ### Italian FatturaPA
260
+ ### 🇪🇺 PEPPOL BIS 3.0
575
261
 
576
262
  ```typescript
577
- const invoice = new EInvoice();
578
263
  invoice.metadata = {
579
- format: InvoiceFormat.FATTURAPA,
264
+ profileId: 'urn:fdc:peppol.eu:2017:poacc:billing:01:1.0',
580
265
  extensions: {
581
- FormatoTrasmissione: 'FPR12',
582
- CodiceDestinatario: '0000000',
583
- IdFiscaleIVA: 'IT12345678901',
584
- CodiceFiscale: 'RSSMRA80A01H501U'
266
+ endpointId: '0088:1234567890128', // GLN with checksum
267
+ documentTypeId: 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017',
268
+ processId: 'urn:fdc:peppol.eu:2017:poacc:billing:01:1.0'
585
269
  }
586
270
  };
587
271
  ```
588
272
 
589
- ### French Factur-X with Chorus Pro
273
+ ### 🇫🇷 French Chorus Pro
590
274
 
591
275
  ```typescript
592
- const invoice = new EInvoice();
593
276
  invoice.metadata = {
594
- format: InvoiceFormat.FACTURX,
595
277
  extensions: {
596
278
  siret: '12345678901234',
597
- tvaIntracommunautaire: 'FR12345678901',
598
- chorus: {
599
- serviceCode: 'SERVICE123',
600
- engagementNumber: 'ENG123456'
601
- }
279
+ serviceCode: 'SERVICE-2025',
280
+ engagementNumber: 'ENG-123456',
281
+ marketReference: 'MARKET-REF-001'
602
282
  }
603
283
  };
604
284
  ```
605
285
 
606
- ## Why Choose @fin.cx/einvoice
286
+ ## ⚡ Performance Metrics
607
287
 
608
- ### 🏗️ Production-Ready Architecture
609
- - **Plugin-based design** with factory pattern for easy extensibility
610
- - **SOLID principles** throughout the codebase
611
- - **Comprehensive test coverage** with 500+ test cases
612
- - **Battle-tested** with real-world invoice corpus
613
-
614
- ### 🔒 Enterprise Security
615
- - **XXE prevention** with disabled external entities
616
- - **Resource limits** to prevent DoS attacks
617
- - **Path traversal protection** for PDF operations
618
- - **SSRF mitigation** in XML processing
619
-
620
- ### ⚡ High Performance
621
- - **Sub-millisecond conversions** (~0.6ms average)
622
- - **Efficient memory usage** (~136KB per validation)
623
- - **Concurrent processing** support
624
- - **Streaming capabilities** for large files
625
-
626
- ### 🌍 Standards Compliance
627
- - **EN16931** business rules implementation
628
- - **Country-specific extensions** (XRechnung, FatturaPA, Factur-X)
629
- - **100% data preservation** in round-trip conversions
630
- - **Multi-format validation** with detailed error reporting
631
-
632
- ### 🛠️ Developer Experience
633
- - **Fully typed** with TypeScript
634
- - **Intuitive API** with static factory methods
635
- - **Detailed error messages** with recovery suggestions
636
- - **Extensive documentation** and examples
637
-
638
- ## Recent Improvements
639
-
640
- ### Version 2.0.0 (2025)
641
-
642
- - **TypeScript Type System**: Full alignment with @tsclass/tsclass interfaces
643
- - **Date Parsing**: Enhanced CII date parsing for various formats (YYYYMMDD, YYYYMM)
644
- - **API Enhancements**: Added static factory methods (fromXml, fromFile, fromPdf)
645
- - **Format Support**: Added generic CII export format
646
- - **Performance**: Optimized validation to ~2.2ms average
647
- - **Memory Efficiency**: Reduced memory usage to ~136KB per validation
648
- - **XRechnung Encoder**: Complete implementation with German-specific requirements
649
- - **Error Recovery**: Improved error handling with detailed messages
650
- - **Security Hardening**: XXE prevention, resource limits, path traversal protection
651
- - **Production Features**: Concurrent processing, memory management, integration patterns
652
-
653
- ## Development
654
-
655
- ### Building the Project
288
+ Lightning-fast operations with minimal memory footprint:
656
289
 
657
- ```bash
658
- # Install dependencies
659
- pnpm install
290
+ | Operation | Speed | Memory |
291
+ |-----------|-------|--------|
292
+ | **Format Detection** | ~0.1ms | Minimal |
293
+ | **XML Parsing** | ~0.5ms | ~100KB |
294
+ | **Full Validation** | ~2.2ms | ~136KB |
295
+ | **Format Conversion** | ~0.6ms | ~150KB |
296
+ | **PDF Extraction** | ~5ms | ~1MB |
297
+ | **PDF Embedding** | ~10ms | ~2MB |
660
298
 
661
- # Build the project
662
- pnpm run build
663
- ```
299
+ ## 🏗️ Architecture
664
300
 
665
- ### Running Tests
666
-
667
- ```bash
668
- # Run all tests
669
- pnpm test
301
+ ### Plugin-Based Design
670
302
 
671
- # Run specific test
672
- pnpm test test/test.einvoice.ts
303
+ ```typescript
304
+ // Factory pattern for extensibility
305
+ DecoderFactory.getDecoder(format) → BaseDecoder
306
+ EncoderFactory.getEncoder(format) → BaseEncoder
307
+ ValidatorFactory.getValidator(format) → BaseValidator
308
+ ```
673
309
 
674
- # Run with verbose output
675
- tstest test/suite/einvoice_validation/test.val-12.validation-performance.ts --verbose
310
+ ### Data Flow
676
311
 
677
- # Run specific test suites
678
- pnpm test test/suite/einvoice_conversion/ # Conversion tests
679
- pnpm test test/suite/einvoice_validation/ # Validation tests
680
- pnpm test test/suite/einvoice_performance/ # Performance tests
312
+ ```
313
+ Input (XML/PDF) → Format Detection → Decoder → EInvoice Model
314
+ ↓
315
+ Validation
316
+ ↓
317
+ Encoder → Output (XML/PDF)
681
318
  ```
682
319
 
683
- The library includes comprehensive test suites that verify:
684
- - **Format Detection**: Automatic detection of all supported formats
685
- - **Conversion**: Round-trip conversion between all format pairs
686
- - **Validation**: Multi-level validation (syntax, semantic, business rules)
687
- - **Performance**: Validation in ~2.2ms, memory usage ~136KB
688
- - **PDF Operations**: Extraction and embedding with multiple strategies
689
- - **Error Handling**: Recovery from malformed data
690
- - **Special Characters**: Unicode and escape sequence handling
691
- - **Country Extensions**: XRechnung, FatturaPA, Factur-X specifics
320
+ ## 🔒 Security Features
692
321
 
693
- ## Production Deployment
322
+ - **XXE Prevention**: External entities disabled by default
323
+ - **Resource Limits**: Max 100MB XML, max 100 nesting levels
324
+ - **Path Traversal Protection**: Sanitized filenames in PDFs
325
+ - **SSRF Mitigation**: Entity blocking in XML processing
326
+ - **Input Validation**: Comprehensive input sanitization
694
327
 
695
- ### Security Considerations
328
+ ## 🧪 Testing
696
329
 
697
- The library implements comprehensive security measures:
330
+ ```bash
331
+ # Run all tests
332
+ pnpm test
698
333
 
699
- ```typescript
700
- // XXE (XML External Entity) Prevention
701
- // ✓ External entity processing disabled by default
702
- // ✓ DTD processing disabled
703
- // ✓ SSRF protection via entity blocking
704
-
705
- // Resource Limits
706
- // ✓ Maximum XML size: 100MB (configurable)
707
- // ✓ Maximum nesting depth: 100 levels
708
- // ✓ Memory protection via streaming for large files
709
-
710
- // Path Traversal Prevention
711
- // ✓ Filename sanitization for PDF attachments
712
- // ✓ No file system access from XML content
334
+ # Run specific test suites
335
+ pnpm test test/test.peppol-validator.ts
336
+ pnpm test test/test.facturx-validator.ts
337
+ pnpm test test/test.semantic-model.ts
338
+
339
+ # Run with verbose output
340
+ pnpm test -- --verbose
713
341
  ```
714
342
 
715
- ### Concurrent Processing
343
+ ## 📚 Advanced Examples
716
344
 
717
- The library is designed for concurrent operations:
345
+ ### Batch Processing with Concurrency Control
718
346
 
719
347
  ```typescript
720
- // Process multiple invoices concurrently
721
- const invoices = ['invoice1.xml', 'invoice2.xml', 'invoice3.xml'];
722
- const results = await Promise.all(
723
- invoices.map(file => EInvoice.fromFile(file))
724
- );
348
+ import pLimit from 'p-limit';
725
349
 
726
- // Concurrent validation with controlled concurrency
727
- const pLimit = (await import('p-limit')).default;
728
350
  const limit = pLimit(5); // Max 5 concurrent operations
351
+ const files = ['invoice1.xml', 'invoice2.xml', /* ... */];
729
352
 
730
- const validationResults = await Promise.all(
731
- invoices.map(invoice =>
732
- limit(() => invoice.validate())
353
+ const results = await Promise.all(
354
+ files.map(file =>
355
+ limit(async () => {
356
+ const invoice = await EInvoice.fromFile(file);
357
+ const validation = await invoice.validate();
358
+ return { file, valid: validation.valid };
359
+ })
733
360
  )
734
361
  );
735
362
  ```
736
363
 
737
- ### Memory Management
738
-
739
- Best practices for handling large volumes:
740
-
741
- ```typescript
742
- // Process large batches with memory control
743
- async function processBatch(files: string[]) {
744
- const batchSize = 100;
745
- const results = [];
746
-
747
- for (let i = 0; i < files.length; i += batchSize) {
748
- const batch = files.slice(i, i + batchSize);
749
- const batchResults = await Promise.all(
750
- batch.map(f => processInvoice(f))
751
- );
752
- results.push(...batchResults);
753
-
754
- // Allow garbage collection between batches
755
- if (global.gc) global.gc();
756
- }
757
-
758
- return results;
759
- }
760
- ```
761
-
762
- ### Edge Case Handling
763
-
764
- The library handles numerous edge cases:
364
+ ### REST API Integration
765
365
 
766
366
  ```typescript
767
- // Empty files
768
- try {
769
- await EInvoice.fromXml(''); // Throws ParseError
770
- } catch (e) {
771
- // Handle empty input
772
- }
773
-
774
- // Huge files (500+ line items)
775
- const largeInvoice = new EInvoice();
776
- largeInvoice.items = Array(1000).fill(null).map((_, i) => ({
777
- position: i + 1,
778
- name: `Item ${i + 1}`,
779
- unitQuantity: 1,
780
- unitNetPrice: 10,
781
- vatPercentage: 19
782
- }));
783
- // Handles efficiently with ~136KB memory per validation
784
-
785
- // Mixed character encodings
786
- invoice.notes = ['UTF-8: €', 'Emoji: 🚀', 'Chinese: 中文'];
787
- // All properly encoded in output XML
788
-
789
- // Timezone handling
790
- invoice.issueDate = new Date('2024-01-01T00:00:00+02:00');
791
- // Preserves timezone information
792
- ```
793
-
794
- ### Production Configuration
795
-
796
- Recommended settings for production:
797
-
798
- ```typescript
799
- // Error handling strategy
800
- const productionConfig = {
801
- // Validation
802
- validationLevel: ValidationLevel.BUSINESS,
803
- strictMode: true,
804
-
805
- // Performance
806
- maxConcurrency: os.cpus().length,
807
- cacheEnabled: true,
808
-
809
- // Security
810
- maxXmlSize: 100 * 1024 * 1024, // 100MB
811
- maxNestingDepth: 100,
812
- externalEntities: false,
813
-
814
- // Logging
815
- logLevel: 'error', // 'debug' | 'info' | 'warn' | 'error'
816
- logFormat: 'json'
817
- };
818
- ```
819
-
820
- ### Integration Patterns
821
-
822
- Common integration scenarios:
823
-
824
- ```typescript
825
- // REST API Integration
826
- app.post('/invoice/convert', async (req, res) => {
367
+ app.post('/api/invoice/convert', async (req, res) => {
827
368
  try {
828
369
  const { xml, targetFormat } = req.body;
829
370
  const invoice = await EInvoice.fromXml(xml);
371
+
372
+ // Validate before conversion
373
+ const validation = await invoice.validate();
374
+ if (!validation.valid) {
375
+ return res.status(400).json({
376
+ error: 'Invalid invoice',
377
+ violations: validation.errors
378
+ });
379
+ }
380
+
830
381
  const converted = await invoice.exportXml(targetFormat);
831
382
  res.json({ success: true, xml: converted });
832
383
  } catch (error) {
833
- res.status(400).json({
834
- success: false,
835
- error: error.message,
836
- type: error.constructor.name
837
- });
384
+ res.status(500).json({ error: error.message });
838
385
  }
839
386
  });
840
-
841
- // Message Queue Processing
842
- async function processInvoiceMessage(message: any) {
843
- const { invoiceId, pdfBuffer } = message;
844
-
845
- try {
846
- const invoice = await EInvoice.fromPdf(Buffer.from(pdfBuffer, 'base64'));
847
- const validation = await invoice.validate();
848
-
849
- await saveToDatabase(invoiceId, invoice, validation);
850
- await acknowledgeMessage(message);
851
- } catch (error) {
852
- await handleError(message, error);
853
- }
854
- }
855
-
856
- // Batch Processing Pipeline
857
- const pipeline = [
858
- extractFromPdf,
859
- validateInvoice,
860
- convertToXRechnung,
861
- sendToERP
862
- ];
863
-
864
- for (const step of pipeline) {
865
- await step(invoice);
866
- }
867
387
  ```
868
388
 
869
- ## Troubleshooting
389
+ ## 🎯 What Makes Us Different
870
390
 
871
- ### Common Issues
391
+ ### 🏆 100% EN16931 Compliance
392
+ - All 162 Business Terms implemented
393
+ - All 32 Business Groups structured
394
+ - Complete semantic model with BT/BG validation
395
+ - Official Schematron rules integrated
872
396
 
873
- **XML Parsing Errors**
874
- ```typescript
875
- // Handle malformed XML
876
- try {
877
- const invoice = await EInvoice.fromXml(xmlString);
878
- } catch (error) {
879
- console.error('Failed to parse:', error.message);
880
- // Try format-specific decoder
881
- const decoder = new ZUGFeRDDecoder(xmlString);
882
- const invoice = await decoder.decode();
883
- }
884
- ```
885
-
886
- **PDF Extraction Failures**
887
- ```typescript
888
- // PDF might not contain XML
889
- const result = await PDFExtractor.extractXml(pdfBuffer);
890
- if (!result.success) {
891
- console.log('No XML found in PDF');
892
- // Create invoice from scratch or OCR
893
- }
894
- ```
895
-
896
- **Validation Errors**
897
- ```typescript
898
- // Check validation level
899
- const result = await invoice.validate();
900
- if (!result.valid) {
901
- // Check if it's a warning vs error
902
- const errors = result.errors.filter(e => e.severity === 'error');
903
- const warnings = result.errors.filter(e => e.severity === 'warning');
904
- }
905
- ```
906
-
907
- ## API Reference
908
-
909
- ### EInvoice Class
910
-
911
- ```typescript
912
- class EInvoice {
913
- // Static factory methods
914
- static fromXml(xmlString: string): Promise<EInvoice>
915
- static fromFile(filePath: string): Promise<EInvoice>
916
- static fromPdf(pdfBuffer: Buffer): Promise<EInvoice>
917
-
918
- // Instance methods
919
- validate(level?: ValidationLevel): Promise<ValidationResult>
920
- exportXml(format: ExportFormat): Promise<string>
921
- exportPdf(format: ExportFormat): Promise<{ buffer: Buffer }>
922
- getFormat(): InvoiceFormat
923
-
924
- // Properties (following TInvoice interface)
925
- id: string
926
- date: Date
927
- from: TParty
928
- to: TParty
929
- items: TAccountingDocItem[]
930
- paymentOptions: TPaymentOptions
931
- metadata?: any
932
- }
933
- ```
934
-
935
- ### Supported Export Formats
936
-
937
- ```typescript
938
- type ExportFormat = 'facturx' | 'zugferd' | 'xrechnung' | 'ubl' | 'cii'
939
- ```
940
-
941
- ### Validation Levels
942
-
943
- ```typescript
944
- enum ValidationLevel {
945
- SYNTAX = 'syntax', // XML structure validation
946
- SEMANTIC = 'semantic', // Field content validation
947
- BUSINESS = 'business' // Business rule validation
948
- }
949
- ```
950
-
951
- ## Key Features
952
-
953
- 1. **PDF Integration**
954
- - Embed XML invoices in PDF documents with detailed error reporting
955
- - Extract XML from existing PDF invoices using multiple fallback strategies
956
- - Handle different XML attachment methods and encodings
397
+ ### 💎 Production Excellence
398
+ - **500+ test cases** ensuring reliability
399
+ - **Battle-tested** with real-world invoice corpus
400
+ - **Memory efficient** - handles 1000+ line items
401
+ - **Thread-safe** for concurrent processing
957
402
 
958
- 2. **Encoding & Decoding**
959
- - Create standards-compliant XML from structured data
960
- - Parse XML invoices back to structured data
961
- - Support multiple format standards
962
- - Circular encoding/decoding integrity
403
+ ### 🚀 Developer Experience
404
+ - **IntelliSense everywhere** - fully typed API
405
+ - **Detailed error messages** with recovery hints
406
+ - **Static factory methods** for intuitive usage
407
+ - **Comprehensive documentation** with real examples
963
408
 
964
- 3. **Format Detection**
965
- - Automatic detection of invoice XML format
966
- - Support for different XML namespaces
967
- - Graceful handling of malformed XML
409
+ ## 📦 Installation Requirements
968
410
 
969
- 4. **Validation**
970
- - Validate invoices against format-specific rules
971
- - Detailed error reporting
972
- - Support for different validation levels
411
+ - Node.js 18+ or modern browser
412
+ - TypeScript 5.0+ (for TypeScript projects)
413
+ - ~15MB installed size
414
+ - Zero native dependencies
973
415
 
974
- 5. **Error Handling**
975
- - Robust error recovery mechanisms
976
- - Detailed error information
977
- - Type-safe error reporting
416
+ ## 🤝 Standards Compliance
978
417
 
979
- By embracing `@fin.cx/einvoice`, you simplify the handling of electronic invoice documents, fostering seamless integration across different financial processes, thus empowering practitioners with robust, flexible tools for VAT invoices in ZUGFeRD/Factur-X compliance or equivalent digital formats.
418
+ This library implements:
419
+ - **EN 16931-1:2017** - Core invoice model
420
+ - **CEN/TS 16931-3** - Syntax bindings
421
+ - **ISO 4217** - Currency codes
422
+ - **ISO 3166** - Country codes
423
+ - **UN/ECE Rec 20** - Units of measure
424
+ - **ISO 6523** - Organization identifiers
980
425
 
981
426
  ## License and Legal Information
982
427
 
983
- This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
428
+ This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
984
429
 
985
430
  **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
986
431