@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.
Files changed (171) hide show
  1. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  2. package/dist_ts/00_commitinfo_data.js +9 -0
  3. package/dist_ts/classes.decoder.d.ts +40 -0
  4. package/dist_ts/classes.decoder.js +320 -0
  5. package/dist_ts/classes.encoder.d.ts +51 -0
  6. package/dist_ts/classes.encoder.js +293 -0
  7. package/dist_ts/classes.xinvoice.d.ts +136 -0
  8. package/dist_ts/classes.xinvoice.js +352 -0
  9. package/dist_ts/einvoice.d.ts +217 -0
  10. package/dist_ts/einvoice.js +505 -0
  11. package/dist_ts/errors.d.ts +121 -0
  12. package/dist_ts/errors.js +241 -0
  13. package/dist_ts/formats/base/base.decoder.d.ts +32 -0
  14. package/dist_ts/formats/base/base.decoder.js +52 -0
  15. package/dist_ts/formats/base/base.encoder.d.ts +13 -0
  16. package/dist_ts/formats/base/base.encoder.js +7 -0
  17. package/dist_ts/formats/base/base.validator.d.ts +44 -0
  18. package/dist_ts/formats/base/base.validator.js +39 -0
  19. package/dist_ts/formats/base.decoder.d.ts +19 -0
  20. package/dist_ts/formats/base.decoder.js +130 -0
  21. package/dist_ts/formats/base.validator.d.ts +44 -0
  22. package/dist_ts/formats/base.validator.js +39 -0
  23. package/dist_ts/formats/cii/cii.decoder.d.ts +61 -0
  24. package/dist_ts/formats/cii/cii.decoder.js +111 -0
  25. package/dist_ts/formats/cii/cii.encoder.d.ts +43 -0
  26. package/dist_ts/formats/cii/cii.encoder.js +48 -0
  27. package/dist_ts/formats/cii/cii.types.d.ts +31 -0
  28. package/dist_ts/formats/cii/cii.types.js +40 -0
  29. package/dist_ts/formats/cii/cii.validator.d.ts +56 -0
  30. package/dist_ts/formats/cii/cii.validator.js +146 -0
  31. package/dist_ts/formats/cii/facturx/facturx.decoder.d.ts +43 -0
  32. package/dist_ts/formats/cii/facturx/facturx.decoder.js +207 -0
  33. package/dist_ts/formats/cii/facturx/facturx.encoder.d.ts +82 -0
  34. package/dist_ts/formats/cii/facturx/facturx.encoder.js +400 -0
  35. package/dist_ts/formats/cii/facturx/facturx.types.d.ts +10 -0
  36. package/dist_ts/formats/cii/facturx/facturx.types.js +15 -0
  37. package/dist_ts/formats/cii/facturx/facturx.validator.d.ts +32 -0
  38. package/dist_ts/formats/cii/facturx/facturx.validator.js +138 -0
  39. package/dist_ts/formats/cii/zugferd/zugferd.decoder.d.ts +43 -0
  40. package/dist_ts/formats/cii/zugferd/zugferd.decoder.js +218 -0
  41. package/dist_ts/formats/cii/zugferd/zugferd.encoder.d.ts +97 -0
  42. package/dist_ts/formats/cii/zugferd/zugferd.encoder.js +550 -0
  43. package/dist_ts/formats/cii/zugferd/zugferd.types.d.ts +10 -0
  44. package/dist_ts/formats/cii/zugferd/zugferd.types.js +15 -0
  45. package/dist_ts/formats/cii/zugferd/zugferd.v1.decoder.d.ts +49 -0
  46. package/dist_ts/formats/cii/zugferd/zugferd.v1.decoder.js +229 -0
  47. package/dist_ts/formats/cii/zugferd/zugferd.validator.d.ts +16 -0
  48. package/dist_ts/formats/cii/zugferd/zugferd.validator.js +29 -0
  49. package/dist_ts/formats/decoder.factory.d.ts +15 -0
  50. package/dist_ts/formats/decoder.factory.js +46 -0
  51. package/dist_ts/formats/factories/decoder.factory.d.ts +13 -0
  52. package/dist_ts/formats/factories/decoder.factory.js +56 -0
  53. package/dist_ts/formats/factories/encoder.factory.d.ts +14 -0
  54. package/dist_ts/formats/factories/encoder.factory.js +40 -0
  55. package/dist_ts/formats/factories/validator.factory.d.ts +12 -0
  56. package/dist_ts/formats/factories/validator.factory.js +110 -0
  57. package/dist_ts/formats/factorx.decoder.d.ts +18 -0
  58. package/dist_ts/formats/factorx.decoder.js +178 -0
  59. package/dist_ts/formats/factorx.encoder.d.ts +51 -0
  60. package/dist_ts/formats/factorx.encoder.js +293 -0
  61. package/dist_ts/formats/facturx.decoder.d.ts +18 -0
  62. package/dist_ts/formats/facturx.decoder.js +210 -0
  63. package/dist_ts/formats/facturx.encoder.d.ts +51 -0
  64. package/dist_ts/formats/facturx.encoder.js +293 -0
  65. package/dist_ts/formats/facturx.validator.d.ts +67 -0
  66. package/dist_ts/formats/facturx.validator.js +266 -0
  67. package/dist_ts/formats/pdf/extractors/associated.extractor.d.ts +14 -0
  68. package/dist_ts/formats/pdf/extractors/associated.extractor.js +68 -0
  69. package/dist_ts/formats/pdf/extractors/base.extractor.d.ts +92 -0
  70. package/dist_ts/formats/pdf/extractors/base.extractor.js +319 -0
  71. package/dist_ts/formats/pdf/extractors/index.d.ts +4 -0
  72. package/dist_ts/formats/pdf/extractors/index.js +5 -0
  73. package/dist_ts/formats/pdf/extractors/standard.extractor.d.ts +13 -0
  74. package/dist_ts/formats/pdf/extractors/standard.extractor.js +74 -0
  75. package/dist_ts/formats/pdf/extractors/text.extractor.d.ts +45 -0
  76. package/dist_ts/formats/pdf/extractors/text.extractor.js +151 -0
  77. package/dist_ts/formats/pdf/pdf.embedder.d.ts +69 -0
  78. package/dist_ts/formats/pdf/pdf.embedder.js +183 -0
  79. package/dist_ts/formats/pdf/pdf.extractor.d.ts +49 -0
  80. package/dist_ts/formats/pdf/pdf.extractor.js +98 -0
  81. package/dist_ts/formats/pdf/robust-pdf.extractor.d.ts +40 -0
  82. package/dist_ts/formats/pdf/robust-pdf.extractor.js +324 -0
  83. package/dist_ts/formats/ubl/en16931.ubl.validator.d.ts +18 -0
  84. package/dist_ts/formats/ubl/en16931.ubl.validator.js +169 -0
  85. package/dist_ts/formats/ubl/generic/ubl.encoder.d.ts +151 -0
  86. package/dist_ts/formats/ubl/generic/ubl.encoder.js +892 -0
  87. package/dist_ts/formats/ubl/ubl.decoder.d.ts +61 -0
  88. package/dist_ts/formats/ubl/ubl.decoder.js +95 -0
  89. package/dist_ts/formats/ubl/ubl.encoder.d.ts +38 -0
  90. package/dist_ts/formats/ubl/ubl.encoder.js +46 -0
  91. package/dist_ts/formats/ubl/ubl.types.d.ts +16 -0
  92. package/dist_ts/formats/ubl/ubl.types.js +21 -0
  93. package/dist_ts/formats/ubl/ubl.validator.d.ts +50 -0
  94. package/dist_ts/formats/ubl/ubl.validator.js +112 -0
  95. package/dist_ts/formats/ubl/xrechnung/xrechnung.decoder.d.ts +34 -0
  96. package/dist_ts/formats/ubl/xrechnung/xrechnung.decoder.js +424 -0
  97. package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.d.ts +75 -0
  98. package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.js +555 -0
  99. package/dist_ts/formats/ubl/xrechnung.validator.d.ts +15 -0
  100. package/dist_ts/formats/ubl/xrechnung.validator.js +107 -0
  101. package/dist_ts/formats/ubl.validator.d.ts +82 -0
  102. package/dist_ts/formats/ubl.validator.js +306 -0
  103. package/dist_ts/formats/utils/format.detector.d.ts +62 -0
  104. package/dist_ts/formats/utils/format.detector.js +249 -0
  105. package/dist_ts/formats/validation/en16931.validator.d.ts +23 -0
  106. package/dist_ts/formats/validation/en16931.validator.js +119 -0
  107. package/dist_ts/formats/validator.factory.d.ts +18 -0
  108. package/dist_ts/formats/validator.factory.js +78 -0
  109. package/dist_ts/formats/xinvoice.decoder.d.ts +28 -0
  110. package/dist_ts/formats/xinvoice.decoder.js +332 -0
  111. package/dist_ts/formats/xinvoice.encoder.d.ts +19 -0
  112. package/dist_ts/formats/xinvoice.encoder.js +282 -0
  113. package/dist_ts/index.d.ts +51 -0
  114. package/dist_ts/index.js +90 -0
  115. package/dist_ts/interfaces/common.d.ts +79 -0
  116. package/dist_ts/interfaces/common.js +24 -0
  117. package/dist_ts/interfaces.d.ts +87 -0
  118. package/dist_ts/interfaces.js +23 -0
  119. package/dist_ts/plugins.d.ts +14 -0
  120. package/dist_ts/plugins.js +31 -0
  121. package/npmextra.json +35 -0
  122. package/package.json +71 -0
  123. package/readme.hints.md +1107 -0
  124. package/readme.howtofixtests.md +38 -0
  125. package/readme.literature.md +1 -0
  126. package/readme.md +998 -0
  127. package/readme.plan.md +481 -0
  128. package/ts/00_commitinfo_data.ts +8 -0
  129. package/ts/einvoice.ts +603 -0
  130. package/ts/errors.ts +341 -0
  131. package/ts/formats/base/base.decoder.ts +68 -0
  132. package/ts/formats/base/base.encoder.ts +14 -0
  133. package/ts/formats/base/base.validator.ts +64 -0
  134. package/ts/formats/cii/cii.decoder.ts +139 -0
  135. package/ts/formats/cii/cii.encoder.ts +64 -0
  136. package/ts/formats/cii/cii.types.ts +44 -0
  137. package/ts/formats/cii/cii.validator.ts +171 -0
  138. package/ts/formats/cii/facturx/facturx.decoder.ts +243 -0
  139. package/ts/formats/cii/facturx/facturx.encoder.ts +483 -0
  140. package/ts/formats/cii/facturx/facturx.types.ts +18 -0
  141. package/ts/formats/cii/facturx/facturx.validator.ts +180 -0
  142. package/ts/formats/cii/zugferd/zugferd.decoder.ts +256 -0
  143. package/ts/formats/cii/zugferd/zugferd.encoder.ts +661 -0
  144. package/ts/formats/cii/zugferd/zugferd.types.ts +18 -0
  145. package/ts/formats/cii/zugferd/zugferd.v1.decoder.ts +267 -0
  146. package/ts/formats/cii/zugferd/zugferd.validator.ts +31 -0
  147. package/ts/formats/factories/decoder.factory.ts +62 -0
  148. package/ts/formats/factories/encoder.factory.ts +47 -0
  149. package/ts/formats/factories/validator.factory.ts +134 -0
  150. package/ts/formats/pdf/extractors/associated.extractor.ts +78 -0
  151. package/ts/formats/pdf/extractors/base.extractor.ts +355 -0
  152. package/ts/formats/pdf/extractors/index.ts +4 -0
  153. package/ts/formats/pdf/extractors/standard.extractor.ts +86 -0
  154. package/ts/formats/pdf/extractors/text.extractor.ts +162 -0
  155. package/ts/formats/pdf/pdf.embedder.ts +242 -0
  156. package/ts/formats/pdf/pdf.extractor.ts +141 -0
  157. package/ts/formats/ubl/en16931.ubl.validator.ts +216 -0
  158. package/ts/formats/ubl/generic/ubl.encoder.ts +1041 -0
  159. package/ts/formats/ubl/ubl.decoder.ts +121 -0
  160. package/ts/formats/ubl/ubl.encoder.ts +63 -0
  161. package/ts/formats/ubl/ubl.types.ts +22 -0
  162. package/ts/formats/ubl/ubl.validator.ts +133 -0
  163. package/ts/formats/ubl/xrechnung/xrechnung.decoder.ts +471 -0
  164. package/ts/formats/ubl/xrechnung/xrechnung.encoder.ts +619 -0
  165. package/ts/formats/ubl/xrechnung.validator.ts +185 -0
  166. package/ts/formats/utils/format.detector.ts +306 -0
  167. package/ts/formats/validation/en16931.validator.ts +135 -0
  168. package/ts/index.ts +164 -0
  169. package/ts/interfaces/common.ts +90 -0
  170. package/ts/interfaces.ts +98 -0
  171. package/ts/plugins.ts +61 -0
@@ -0,0 +1,256 @@
1
+ import { CIIBaseDecoder } from '../cii.decoder.js';
2
+ import type { TInvoice, TCreditNote, TDebitNote } from '../../../interfaces/common.js';
3
+ import { business, finance } from '../../../plugins.js';
4
+ import { EN16931Validator } from '../../validation/en16931.validator.js';
5
+
6
+ /**
7
+ * Decoder for ZUGFeRD invoice format
8
+ */
9
+ export class ZUGFeRDDecoder extends CIIBaseDecoder {
10
+ /**
11
+ * Decodes a ZUGFeRD credit note
12
+ * @returns Promise resolving to a TCreditNote object
13
+ */
14
+ protected async decodeCreditNote(): Promise<TCreditNote> {
15
+ // Get common invoice data
16
+ const commonData = await this.extractCommonData();
17
+
18
+ // Create a credit note with the common data
19
+ return {
20
+ ...commonData,
21
+ accountingDocType: 'creditnote' as const
22
+ } as unknown as TCreditNote;
23
+ }
24
+
25
+ /**
26
+ * Decodes a ZUGFeRD debit note (invoice)
27
+ * @returns Promise resolving to a TDebitNote object
28
+ */
29
+ protected async decodeDebitNote(): Promise<TDebitNote> {
30
+ // Get common invoice data
31
+ const commonData = await this.extractCommonData();
32
+
33
+ // Create a debit note with the common data
34
+ return {
35
+ ...commonData,
36
+ accountingDocType: 'debitnote' as const
37
+ } as unknown as TDebitNote;
38
+ }
39
+
40
+ /**
41
+ * Extracts common invoice data from ZUGFeRD XML
42
+ * @returns Common invoice data
43
+ */
44
+ private async extractCommonData(): Promise<Partial<TInvoice>> {
45
+ // Extract invoice ID
46
+ const invoiceId = this.getText('//rsm:ExchangedDocument/ram:ID');
47
+
48
+ // Extract issue date
49
+ const issueDateStr = this.getText('//ram:IssueDateTime/udt:DateTimeString');
50
+ const issueDateFormat = this.getText('//ram:IssueDateTime/udt:DateTimeString/@format');
51
+ const issueDate = this.parseCIIDate(issueDateStr, issueDateFormat);
52
+
53
+ // Extract seller information
54
+ const seller = this.extractParty('//ram:SellerTradeParty');
55
+
56
+ // Extract buyer information
57
+ const buyer = this.extractParty('//ram:BuyerTradeParty');
58
+
59
+ // Extract items
60
+ const items = this.extractItems();
61
+
62
+ // Extract due date
63
+ const dueDateStr = this.getText('//ram:SpecifiedTradePaymentTerms/ram:DueDateDateTime/udt:DateTimeString');
64
+ const dueDate = dueDateStr ? new Date(dueDateStr).getTime() : Date.now();
65
+ const dueInDays = Math.round((dueDate - issueDate) / (1000 * 60 * 60 * 24));
66
+
67
+ // Extract currency
68
+ const currencyCode = this.getText('//ram:InvoiceCurrencyCode') || 'EUR';
69
+
70
+ // Extract total amount (not used in this implementation but could be useful)
71
+ // const totalAmount = this.getNumber('//ram:GrandTotalAmount');
72
+
73
+ // Extract notes
74
+ const allNotes = this.extractNotes();
75
+
76
+ // Extract subject and notes separately
77
+ // If we have notes, the first one might be the subject
78
+ let subject = `Invoice ${invoiceId}`;
79
+ let notes = [...allNotes];
80
+
81
+ // If the first note doesn't look like a payment term or other standard note,
82
+ // treat it as the subject
83
+ if (allNotes.length > 0 && !allNotes[0].toLowerCase().includes('due in') &&
84
+ !allNotes[0].toLowerCase().includes('payment')) {
85
+ subject = allNotes[0];
86
+ notes = allNotes.slice(1); // Remove subject from notes
87
+ }
88
+
89
+ // Check for reverse charge
90
+ const reverseCharge = this.exists('//ram:SpecifiedTradeAllowanceCharge/ram:ReasonCode[text()="62"]');
91
+
92
+ // Create the common invoice data
93
+ const invoiceData = {
94
+ type: 'accounting-doc' as const,
95
+ accountingDocType: 'invoice' as const,
96
+ id: invoiceId,
97
+ accountingDocId: invoiceId,
98
+ date: issueDate,
99
+ accountingDocStatus: 'issued' as const,
100
+ versionInfo: {
101
+ type: 'final' as const,
102
+ version: '1.0.0'
103
+ },
104
+ language: 'en',
105
+ incidenceId: invoiceId,
106
+ from: seller,
107
+ to: buyer,
108
+ subject: subject,
109
+ items: items,
110
+ dueInDays: dueInDays,
111
+ reverseCharge: reverseCharge,
112
+ currency: currencyCode as finance.TCurrency,
113
+ notes: notes,
114
+ deliveryDate: issueDate,
115
+ objectActions: []
116
+ };
117
+
118
+ // Validate mandatory EN16931 fields unless validation is skipped
119
+ if (!this.skipValidation) {
120
+ EN16931Validator.validateMandatoryFields(invoiceData);
121
+ }
122
+
123
+ return invoiceData;
124
+ }
125
+
126
+ /**
127
+ * Extracts party information from ZUGFeRD XML
128
+ * @param partyXPath XPath to the party node
129
+ * @returns Party information as TContact
130
+ */
131
+ private extractParty(partyXPath: string): business.TContact {
132
+ // Extract name
133
+ const name = this.getText(`${partyXPath}/ram:Name`);
134
+
135
+ // Extract address
136
+ const streetName = this.getText(`${partyXPath}/ram:PostalTradeAddress/ram:LineOne`);
137
+ const city = this.getText(`${partyXPath}/ram:PostalTradeAddress/ram:CityName`);
138
+ const postalCode = this.getText(`${partyXPath}/ram:PostalTradeAddress/ram:PostcodeCode`);
139
+ const country = this.getText(`${partyXPath}/ram:PostalTradeAddress/ram:CountryID`);
140
+
141
+ // Try to extract house number from street if possible
142
+ let houseNumber = '';
143
+ const streetParts = streetName.match(/^(.*?)\s+(\d+.*)$/);
144
+ if (streetParts) {
145
+ // If we can split into street name and house number
146
+ houseNumber = streetParts[2];
147
+ }
148
+
149
+ // Create address object
150
+ const address = {
151
+ streetName: streetName,
152
+ houseNumber: houseNumber,
153
+ city: city,
154
+ postalCode: postalCode,
155
+ countryCode: country
156
+ };
157
+
158
+ // Extract VAT ID
159
+ const vatId = this.getText(`${partyXPath}/ram:SpecifiedTaxRegistration/ram:ID[@schemeID="VA"]`) || '';
160
+
161
+ // Extract registration ID
162
+ const registrationId = this.getText(`${partyXPath}/ram:SpecifiedTaxRegistration/ram:ID[@schemeID="FC"]`) || '';
163
+
164
+ // Create contact object
165
+ return {
166
+ type: 'company',
167
+ name: name,
168
+ description: '',
169
+ address: address,
170
+ status: 'active',
171
+ foundedDate: this.createDefaultDate(),
172
+ registrationDetails: {
173
+ vatId: vatId,
174
+ registrationId: registrationId,
175
+ registrationName: ''
176
+ }
177
+ } as business.TContact;
178
+ }
179
+
180
+ /**
181
+ * Extracts invoice items from ZUGFeRD XML
182
+ * @returns Array of invoice items
183
+ */
184
+ private extractItems(): finance.TAccountingDocItem[] {
185
+ const items: finance.TAccountingDocItem[] = [];
186
+
187
+ // Get all item nodes
188
+ const itemNodes = this.select('//ram:IncludedSupplyChainTradeLineItem', this.doc);
189
+
190
+ // Process each item
191
+ if (Array.isArray(itemNodes)) {
192
+ for (let i = 0; i < itemNodes.length; i++) {
193
+ const itemNode = itemNodes[i];
194
+
195
+ // Extract item data
196
+ const name = this.getText('ram:SpecifiedTradeProduct/ram:Name', itemNode);
197
+ const articleNumber = this.getText('ram:SpecifiedTradeProduct/ram:SellerAssignedID', itemNode);
198
+ const unitQuantity = this.getNumber('ram:SpecifiedLineTradeDelivery/ram:BilledQuantity', itemNode);
199
+ const unitType = this.getText('ram:SpecifiedLineTradeDelivery/ram:BilledQuantity/@unitCode', itemNode) || 'EA';
200
+ const unitNetPrice = this.getNumber('ram:SpecifiedLineTradeAgreement/ram:NetPriceProductTradePrice/ram:ChargeAmount', itemNode);
201
+ const vatPercentage = this.getNumber('ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax/ram:RateApplicablePercent', itemNode);
202
+
203
+ // Create item object
204
+ items.push({
205
+ position: i + 1,
206
+ name: name,
207
+ articleNumber: articleNumber,
208
+ unitType: unitType,
209
+ unitQuantity: unitQuantity,
210
+ unitNetPrice: unitNetPrice,
211
+ vatPercentage: vatPercentage
212
+ });
213
+ }
214
+ }
215
+
216
+ return items;
217
+ }
218
+
219
+ /**
220
+ * Extracts notes from ZUGFeRD XML
221
+ * @returns Array of notes
222
+ */
223
+ private extractNotes(): string[] {
224
+ const notes: string[] = [];
225
+
226
+ // Get all note nodes
227
+ const noteNodes = this.select('//ram:IncludedNote', this.doc);
228
+
229
+ // Process each note
230
+ if (Array.isArray(noteNodes)) {
231
+ for (let i = 0; i < noteNodes.length; i++) {
232
+ const noteNode = noteNodes[i];
233
+ const noteText = this.getText('ram:Content', noteNode);
234
+
235
+ if (noteText) {
236
+ notes.push(noteText);
237
+ }
238
+ }
239
+ }
240
+
241
+ return notes;
242
+ }
243
+
244
+ /**
245
+ * Creates a default date for empty date fields
246
+ * @returns Default date as timestamp
247
+ */
248
+ private createDefaultDate(): any {
249
+ // Create a date object that will be compatible with TContact
250
+ return {
251
+ year: 2000,
252
+ month: 1,
253
+ day: 1
254
+ };
255
+ }
256
+ }