@fin.cx/einvoice 5.0.3 → 5.1.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 (116) 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/package.json +9 -3
  58. package/readme.md +255 -810
  59. package/ts/00_commitinfo_data.ts +1 -1
  60. package/ts/einvoice.ts +63 -14
  61. package/ts/formats/converters/xml-to-einvoice.converter.ts +142 -0
  62. package/ts/formats/semantic/bt-bg.model.ts +524 -0
  63. package/ts/formats/semantic/semantic.adapter.ts +600 -0
  64. package/ts/formats/semantic/semantic.validator.ts +654 -0
  65. package/ts/formats/utils/currency.calculator.decimal.ts +323 -0
  66. package/ts/formats/utils/currency.utils.ts +299 -0
  67. package/ts/formats/utils/decimal.ts +509 -0
  68. package/ts/formats/validation/codelist.validator.ts +317 -0
  69. package/ts/formats/validation/conformance.harness.ts +591 -0
  70. package/ts/formats/validation/en16931.business-rules.validator.ts +694 -0
  71. package/ts/formats/validation/facturx.validator.ts +579 -0
  72. package/ts/formats/validation/integrated.validator.ts +405 -0
  73. package/ts/formats/validation/peppol.validator.ts +589 -0
  74. package/ts/formats/validation/schematron.downloader.ts +304 -0
  75. package/ts/formats/validation/schematron.integration.ts +285 -0
  76. package/ts/formats/validation/schematron.validator.ts +348 -0
  77. package/ts/formats/validation/schematron.worker.ts +221 -0
  78. package/ts/formats/validation/validation.types.ts +274 -0
  79. package/ts/formats/validation/vat-categories.validator.ts +845 -0
  80. package/ts/formats/validation/xrechnung.validator.ts +494 -0
  81. package/ts/interfaces/common.ts +1 -0
  82. package/ts/interfaces/en16931-metadata.ts +104 -0
  83. package/ts/plugins.ts +8 -0
  84. package/ts/tspublish.json +3 -0
  85. package/dist_ts/classes.decoder.d.ts +0 -40
  86. package/dist_ts/classes.decoder.js +0 -320
  87. package/dist_ts/classes.encoder.d.ts +0 -51
  88. package/dist_ts/classes.encoder.js +0 -293
  89. package/dist_ts/classes.xinvoice.d.ts +0 -136
  90. package/dist_ts/classes.xinvoice.js +0 -352
  91. package/dist_ts/formats/base.decoder.d.ts +0 -19
  92. package/dist_ts/formats/base.decoder.js +0 -130
  93. package/dist_ts/formats/base.validator.d.ts +0 -44
  94. package/dist_ts/formats/base.validator.js +0 -39
  95. package/dist_ts/formats/decoder.factory.d.ts +0 -15
  96. package/dist_ts/formats/decoder.factory.js +0 -46
  97. package/dist_ts/formats/factorx.decoder.d.ts +0 -18
  98. package/dist_ts/formats/factorx.decoder.js +0 -178
  99. package/dist_ts/formats/factorx.encoder.d.ts +0 -51
  100. package/dist_ts/formats/factorx.encoder.js +0 -293
  101. package/dist_ts/formats/facturx.decoder.d.ts +0 -18
  102. package/dist_ts/formats/facturx.decoder.js +0 -210
  103. package/dist_ts/formats/facturx.encoder.d.ts +0 -51
  104. package/dist_ts/formats/facturx.encoder.js +0 -293
  105. package/dist_ts/formats/facturx.validator.d.ts +0 -67
  106. package/dist_ts/formats/facturx.validator.js +0 -266
  107. package/dist_ts/formats/pdf/robust-pdf.extractor.d.ts +0 -40
  108. package/dist_ts/formats/pdf/robust-pdf.extractor.js +0 -324
  109. package/dist_ts/formats/ubl.validator.d.ts +0 -82
  110. package/dist_ts/formats/ubl.validator.js +0 -306
  111. package/dist_ts/formats/validator.factory.d.ts +0 -18
  112. package/dist_ts/formats/validator.factory.js +0 -78
  113. package/dist_ts/formats/xinvoice.decoder.d.ts +0 -28
  114. package/dist_ts/formats/xinvoice.decoder.js +0 -332
  115. package/dist_ts/formats/xinvoice.encoder.d.ts +0 -19
  116. package/dist_ts/formats/xinvoice.encoder.js +0 -282
@@ -0,0 +1,522 @@
1
+ /**
2
+ * Factur-X validator for profile-specific compliance
3
+ * Implements validation for MINIMUM, BASIC, EN16931, and EXTENDED profiles
4
+ */
5
+ /**
6
+ * Factur-X Profile definitions
7
+ */
8
+ export var FacturXProfile;
9
+ (function (FacturXProfile) {
10
+ FacturXProfile["MINIMUM"] = "MINIMUM";
11
+ FacturXProfile["BASIC"] = "BASIC";
12
+ FacturXProfile["BASIC_WL"] = "BASIC_WL";
13
+ FacturXProfile["EN16931"] = "EN16931";
14
+ FacturXProfile["EXTENDED"] = "EXTENDED";
15
+ })(FacturXProfile || (FacturXProfile = {}));
16
+ /**
17
+ * Factur-X Validator
18
+ * Validates invoices according to Factur-X profile specifications
19
+ */
20
+ export class FacturXValidator {
21
+ constructor() {
22
+ /**
23
+ * Profile requirements mapping
24
+ */
25
+ this.profileRequirements = {
26
+ [FacturXProfile.MINIMUM]: {
27
+ mandatory: [
28
+ 'accountingDocId', // BT-1: Invoice number
29
+ 'issueDate', // BT-2: Invoice issue date
30
+ 'accountingDocType', // BT-3: Invoice type code
31
+ 'currency', // BT-5: Invoice currency code
32
+ 'from.name', // BT-27: Seller name
33
+ 'from.vatNumber', // BT-31: Seller VAT identifier
34
+ 'to.name', // BT-44: Buyer name
35
+ 'totalInvoiceAmount', // BT-112: Invoice total amount with VAT
36
+ 'totalNetAmount', // BT-109: Invoice total amount without VAT
37
+ 'totalVatAmount', // BT-110: Invoice total VAT amount
38
+ ],
39
+ optional: []
40
+ },
41
+ [FacturXProfile.BASIC]: {
42
+ mandatory: [
43
+ // All MINIMUM fields plus:
44
+ 'accountingDocId',
45
+ 'issueDate',
46
+ 'accountingDocType',
47
+ 'currency',
48
+ 'from.name',
49
+ 'from.vatNumber',
50
+ 'from.address', // BT-35: Seller postal address
51
+ 'from.country', // BT-40: Seller country code
52
+ 'to.name',
53
+ 'to.address', // BT-50: Buyer postal address
54
+ 'to.country', // BT-55: Buyer country code
55
+ 'items', // BG-25: Invoice line items
56
+ 'items[].name', // BT-153: Item name
57
+ 'items[].unitQuantity', // BT-129: Invoiced quantity
58
+ 'items[].unitNetPrice', // BT-146: Item net price
59
+ 'items[].vatPercentage', // BT-152: Invoiced item VAT rate
60
+ 'totalInvoiceAmount',
61
+ 'totalNetAmount',
62
+ 'totalVatAmount',
63
+ 'dueDate', // BT-9: Payment due date
64
+ ],
65
+ optional: [
66
+ 'metadata.buyerReference', // BT-10: Buyer reference
67
+ 'metadata.purchaseOrderReference', // BT-13: Purchase order reference
68
+ 'metadata.salesOrderReference', // BT-14: Sales order reference
69
+ 'metadata.contractReference', // BT-12: Contract reference
70
+ 'projectReference', // BT-11: Project reference
71
+ ]
72
+ },
73
+ [FacturXProfile.BASIC_WL]: {
74
+ // Basic without lines - for summary invoices
75
+ mandatory: [
76
+ 'accountingDocId',
77
+ 'issueDate',
78
+ 'accountingDocType',
79
+ 'currency',
80
+ 'from.name',
81
+ 'from.vatNumber',
82
+ 'from.address',
83
+ 'from.country',
84
+ 'to.name',
85
+ 'to.address',
86
+ 'to.country',
87
+ 'totalInvoiceAmount',
88
+ 'totalNetAmount',
89
+ 'totalVatAmount',
90
+ 'dueDate',
91
+ // No items required
92
+ ],
93
+ optional: [
94
+ 'metadata.buyerReference',
95
+ 'metadata.purchaseOrderReference',
96
+ 'metadata.contractReference',
97
+ ]
98
+ },
99
+ [FacturXProfile.EN16931]: {
100
+ // Full EN16931 compliance - all mandatory fields from the standard
101
+ mandatory: [
102
+ // Document level
103
+ 'accountingDocId',
104
+ 'issueDate',
105
+ 'accountingDocType',
106
+ 'currency',
107
+ 'metadata.buyerReference',
108
+ // Seller information
109
+ 'from.name',
110
+ 'from.address',
111
+ 'from.city',
112
+ 'from.postalCode',
113
+ 'from.country',
114
+ 'from.vatNumber',
115
+ // Buyer information
116
+ 'to.name',
117
+ 'to.address',
118
+ 'to.city',
119
+ 'to.postalCode',
120
+ 'to.country',
121
+ // Line items
122
+ 'items',
123
+ 'items[].name',
124
+ 'items[].unitQuantity',
125
+ 'items[].unitType',
126
+ 'items[].unitNetPrice',
127
+ 'items[].vatPercentage',
128
+ // Totals
129
+ 'totalInvoiceAmount',
130
+ 'totalNetAmount',
131
+ 'totalVatAmount',
132
+ 'dueDate',
133
+ ],
134
+ optional: [
135
+ // All other EN16931 fields
136
+ 'metadata.purchaseOrderReference',
137
+ 'metadata.salesOrderReference',
138
+ 'metadata.contractReference',
139
+ 'metadata.deliveryDate',
140
+ 'metadata.paymentTerms',
141
+ 'metadata.paymentMeans',
142
+ 'to.vatNumber',
143
+ 'to.legalRegistration',
144
+ 'items[].articleNumber',
145
+ 'items[].description',
146
+ 'paymentAccount',
147
+ ]
148
+ },
149
+ [FacturXProfile.EXTENDED]: {
150
+ // Extended profile allows all fields
151
+ mandatory: [
152
+ // Same as EN16931 core
153
+ 'accountingDocId',
154
+ 'issueDate',
155
+ 'accountingDocType',
156
+ 'currency',
157
+ 'from.name',
158
+ 'from.vatNumber',
159
+ 'to.name',
160
+ 'totalInvoiceAmount',
161
+ ],
162
+ optional: [
163
+ // All fields are allowed in EXTENDED profile
164
+ ]
165
+ }
166
+ };
167
+ }
168
+ /**
169
+ * Singleton pattern for validator instance
170
+ */
171
+ static create() {
172
+ if (!FacturXValidator.instance) {
173
+ FacturXValidator.instance = new FacturXValidator();
174
+ }
175
+ return FacturXValidator.instance;
176
+ }
177
+ /**
178
+ * Main validation entry point for Factur-X
179
+ */
180
+ validateFacturX(invoice, profile) {
181
+ const results = [];
182
+ // Detect profile if not provided
183
+ const detectedProfile = profile || this.detectProfile(invoice);
184
+ // Skip if not a Factur-X invoice
185
+ if (!detectedProfile) {
186
+ return results;
187
+ }
188
+ // Validate according to profile
189
+ results.push(...this.validateProfileRequirements(invoice, detectedProfile));
190
+ results.push(...this.validateProfileSpecificRules(invoice, detectedProfile));
191
+ // Add profile-specific business rules
192
+ if (detectedProfile === FacturXProfile.MINIMUM) {
193
+ results.push(...this.validateMinimumProfile(invoice));
194
+ }
195
+ else if (detectedProfile === FacturXProfile.BASIC || detectedProfile === FacturXProfile.BASIC_WL) {
196
+ results.push(...this.validateBasicProfile(invoice, detectedProfile));
197
+ }
198
+ else if (detectedProfile === FacturXProfile.EN16931) {
199
+ results.push(...this.validateEN16931Profile(invoice));
200
+ }
201
+ else if (detectedProfile === FacturXProfile.EXTENDED) {
202
+ results.push(...this.validateExtendedProfile(invoice));
203
+ }
204
+ return results;
205
+ }
206
+ /**
207
+ * Detect Factur-X profile from invoice metadata
208
+ */
209
+ detectProfile(invoice) {
210
+ const profileId = invoice.metadata?.profileId || '';
211
+ const customizationId = invoice.metadata?.customizationId || '';
212
+ const format = invoice.metadata?.format;
213
+ // Check if it's a Factur-X invoice
214
+ if (!format?.includes('facturx') && !profileId.includes('facturx') &&
215
+ !customizationId.includes('facturx') && !profileId.includes('zugferd')) {
216
+ return null;
217
+ }
218
+ // Detect specific profile
219
+ const profileLower = profileId.toLowerCase();
220
+ const customLower = customizationId.toLowerCase();
221
+ if (profileLower.includes('minimum') || customLower.includes('minimum')) {
222
+ return FacturXProfile.MINIMUM;
223
+ }
224
+ else if (profileLower.includes('basic_wl') || customLower.includes('basicwl')) {
225
+ return FacturXProfile.BASIC_WL;
226
+ }
227
+ else if (profileLower.includes('basic') || customLower.includes('basic')) {
228
+ return FacturXProfile.BASIC;
229
+ }
230
+ else if (profileLower.includes('en16931') || customLower.includes('en16931') ||
231
+ profileLower.includes('comfort') || customLower.includes('comfort')) {
232
+ return FacturXProfile.EN16931;
233
+ }
234
+ else if (profileLower.includes('extended') || customLower.includes('extended')) {
235
+ return FacturXProfile.EXTENDED;
236
+ }
237
+ // Default to BASIC if format is Factur-X but profile unclear
238
+ return FacturXProfile.BASIC;
239
+ }
240
+ /**
241
+ * Validate field requirements for a specific profile
242
+ */
243
+ validateProfileRequirements(invoice, profile) {
244
+ const results = [];
245
+ const requirements = this.profileRequirements[profile];
246
+ // Check mandatory fields
247
+ for (const field of requirements.mandatory) {
248
+ const value = this.getFieldValue(invoice, field);
249
+ if (value === undefined || value === null || value === '') {
250
+ results.push({
251
+ ruleId: `FX-${profile}-M01`,
252
+ severity: 'error',
253
+ message: `Field '${field}' is mandatory for Factur-X ${profile} profile`,
254
+ field: field,
255
+ source: 'FACTURX'
256
+ });
257
+ }
258
+ }
259
+ // Check forbidden fields (if any)
260
+ if (requirements.forbidden) {
261
+ for (const field of requirements.forbidden) {
262
+ const value = this.getFieldValue(invoice, field);
263
+ if (value !== undefined && value !== null) {
264
+ results.push({
265
+ ruleId: `FX-${profile}-F01`,
266
+ severity: 'error',
267
+ message: `Field '${field}' is not allowed in Factur-X ${profile} profile`,
268
+ field: field,
269
+ value: value,
270
+ source: 'FACTURX'
271
+ });
272
+ }
273
+ }
274
+ }
275
+ return results;
276
+ }
277
+ /**
278
+ * Get field value from invoice using dot notation
279
+ */
280
+ getFieldValue(invoice, fieldPath) {
281
+ // Handle special calculated fields
282
+ if (fieldPath === 'totalInvoiceAmount') {
283
+ return invoice.totalGross || invoice.totalInvoiceAmount;
284
+ }
285
+ if (fieldPath === 'totalNetAmount') {
286
+ return invoice.totalNet || invoice.totalNetAmount;
287
+ }
288
+ if (fieldPath === 'totalVatAmount') {
289
+ return invoice.totalVat || invoice.totalVatAmount;
290
+ }
291
+ if (fieldPath === 'dueDate') {
292
+ // Check for dueInDays which is used in EInvoice
293
+ if (invoice.dueInDays !== undefined && invoice.dueInDays !== null) {
294
+ return true; // Has payment terms
295
+ }
296
+ return invoice.dueDate;
297
+ }
298
+ const parts = fieldPath.split('.');
299
+ let value = invoice;
300
+ for (const part of parts) {
301
+ if (part.includes('[')) {
302
+ // Array field like items[]
303
+ const fieldName = part.substring(0, part.indexOf('['));
304
+ const arrayField = part.substring(part.indexOf('[') + 1, part.indexOf(']'));
305
+ if (!value[fieldName] || !Array.isArray(value[fieldName])) {
306
+ return undefined;
307
+ }
308
+ if (arrayField === '') {
309
+ // Check if array exists and has items
310
+ return value[fieldName].length > 0 ? value[fieldName] : undefined;
311
+ }
312
+ else {
313
+ // Check specific field in array items
314
+ return value[fieldName].every((item) => item[arrayField] !== undefined);
315
+ }
316
+ }
317
+ else {
318
+ value = value?.[part];
319
+ }
320
+ }
321
+ return value;
322
+ }
323
+ /**
324
+ * Profile-specific validation rules
325
+ */
326
+ validateProfileSpecificRules(invoice, profile) {
327
+ const results = [];
328
+ // Validate according to profile level
329
+ switch (profile) {
330
+ case FacturXProfile.MINIMUM:
331
+ // MINIMUM requires at least gross amounts
332
+ // Check both calculated totals and direct properties (for test compatibility)
333
+ const totalGross = invoice.totalGross || invoice.totalInvoiceAmount;
334
+ if (!totalGross || totalGross <= 0) {
335
+ results.push({
336
+ ruleId: 'FX-MIN-01',
337
+ severity: 'error',
338
+ message: 'MINIMUM profile requires positive total invoice amount',
339
+ field: 'totalInvoiceAmount',
340
+ value: totalGross,
341
+ source: 'FACTURX'
342
+ });
343
+ }
344
+ break;
345
+ case FacturXProfile.BASIC:
346
+ case FacturXProfile.BASIC_WL:
347
+ // BASIC requires VAT breakdown
348
+ const totalVat = invoice.totalVat;
349
+ if (!invoice.metadata?.extensions?.taxDetails && totalVat > 0) {
350
+ results.push({
351
+ ruleId: 'FX-BAS-01',
352
+ severity: 'warning',
353
+ message: 'BASIC profile should include VAT breakdown when VAT is present',
354
+ field: 'metadata.extensions.taxDetails',
355
+ source: 'FACTURX'
356
+ });
357
+ }
358
+ break;
359
+ case FacturXProfile.EN16931:
360
+ // EN16931 requires full compliance - additional checks handled by EN16931 validator
361
+ if (!invoice.metadata?.buyerReference && !invoice.metadata?.extensions?.purchaseOrderReference) {
362
+ results.push({
363
+ ruleId: 'FX-EN-01',
364
+ severity: 'error',
365
+ message: 'EN16931 profile requires either buyer reference or purchase order reference',
366
+ field: 'metadata.buyerReference',
367
+ source: 'FACTURX'
368
+ });
369
+ }
370
+ break;
371
+ }
372
+ return results;
373
+ }
374
+ /**
375
+ * Validate MINIMUM profile specific rules
376
+ */
377
+ validateMinimumProfile(invoice) {
378
+ const results = [];
379
+ // MINIMUM profile allows only essential fields
380
+ // Check that complex structures are not present
381
+ if (invoice.items && invoice.items.length > 0) {
382
+ // Lines are optional but if present must be minimal
383
+ invoice.items.forEach((item, index) => {
384
+ if (item.allowances || item.charges) {
385
+ results.push({
386
+ ruleId: 'FX-MIN-02',
387
+ severity: 'warning',
388
+ message: `Line ${index + 1}: MINIMUM profile should not include line allowances/charges`,
389
+ field: `items[${index}]`,
390
+ source: 'FACTURX'
391
+ });
392
+ }
393
+ });
394
+ }
395
+ return results;
396
+ }
397
+ /**
398
+ * Validate BASIC profile specific rules
399
+ */
400
+ validateBasicProfile(invoice, profile) {
401
+ const results = [];
402
+ // BASIC requires line items (except BASIC_WL)
403
+ // Only check for line items in BASIC profile, not BASIC_WL
404
+ if (profile === FacturXProfile.BASIC) {
405
+ if (!invoice.items || invoice.items.length === 0) {
406
+ results.push({
407
+ ruleId: 'FX-BAS-02',
408
+ severity: 'error',
409
+ message: 'BASIC profile requires at least one invoice line item',
410
+ field: 'items',
411
+ source: 'FACTURX'
412
+ });
413
+ }
414
+ }
415
+ // Payment information should be present
416
+ if (!invoice.dueInDays && invoice.dueInDays !== 0) {
417
+ results.push({
418
+ ruleId: 'FX-BAS-03',
419
+ severity: 'warning',
420
+ message: 'BASIC profile should include payment terms (due in days)',
421
+ field: 'dueInDays',
422
+ source: 'FACTURX'
423
+ });
424
+ }
425
+ return results;
426
+ }
427
+ /**
428
+ * Validate EN16931 profile specific rules
429
+ */
430
+ validateEN16931Profile(invoice) {
431
+ const results = [];
432
+ // EN16931 requires complete address information
433
+ const fromAny = invoice.from;
434
+ const toAny = invoice.to;
435
+ if (!fromAny?.city || !fromAny?.postalCode) {
436
+ results.push({
437
+ ruleId: 'FX-EN-02',
438
+ severity: 'error',
439
+ message: 'EN16931 profile requires complete seller address including city and postal code',
440
+ field: 'from.address',
441
+ source: 'FACTURX'
442
+ });
443
+ }
444
+ if (!toAny?.city || !toAny?.postalCode) {
445
+ results.push({
446
+ ruleId: 'FX-EN-03',
447
+ severity: 'error',
448
+ message: 'EN16931 profile requires complete buyer address including city and postal code',
449
+ field: 'to.address',
450
+ source: 'FACTURX'
451
+ });
452
+ }
453
+ // Line items must have unit type
454
+ if (invoice.items) {
455
+ invoice.items.forEach((item, index) => {
456
+ if (!item.unitType) {
457
+ results.push({
458
+ ruleId: 'FX-EN-04',
459
+ severity: 'error',
460
+ message: `Line ${index + 1}: EN16931 profile requires unit of measure`,
461
+ field: `items[${index}].unitType`,
462
+ source: 'FACTURX'
463
+ });
464
+ }
465
+ });
466
+ }
467
+ return results;
468
+ }
469
+ /**
470
+ * Validate EXTENDED profile specific rules
471
+ */
472
+ validateExtendedProfile(invoice) {
473
+ const results = [];
474
+ // EXTENDED profile is most permissive - mainly check for data consistency
475
+ if (invoice.metadata?.extensions) {
476
+ // Extended profile can include additional structured data
477
+ // Validate that extended data is well-formed
478
+ const extensions = invoice.metadata.extensions;
479
+ if (extensions.attachments && Array.isArray(extensions.attachments)) {
480
+ extensions.attachments.forEach((attachment, index) => {
481
+ if (!attachment.filename || !attachment.mimeType) {
482
+ results.push({
483
+ ruleId: 'FX-EXT-01',
484
+ severity: 'warning',
485
+ message: `Attachment ${index + 1}: Should include filename and MIME type`,
486
+ field: `metadata.extensions.attachments[${index}]`,
487
+ source: 'FACTURX'
488
+ });
489
+ }
490
+ });
491
+ }
492
+ }
493
+ return results;
494
+ }
495
+ /**
496
+ * Get profile display name
497
+ */
498
+ getProfileDisplayName(profile) {
499
+ const names = {
500
+ [FacturXProfile.MINIMUM]: 'Factur-X MINIMUM',
501
+ [FacturXProfile.BASIC]: 'Factur-X BASIC',
502
+ [FacturXProfile.BASIC_WL]: 'Factur-X BASIC WL',
503
+ [FacturXProfile.EN16931]: 'Factur-X EN16931',
504
+ [FacturXProfile.EXTENDED]: 'Factur-X EXTENDED'
505
+ };
506
+ return names[profile];
507
+ }
508
+ /**
509
+ * Get profile compliance level (for reporting)
510
+ */
511
+ getProfileComplianceLevel(profile) {
512
+ const levels = {
513
+ [FacturXProfile.MINIMUM]: 1,
514
+ [FacturXProfile.BASIC_WL]: 2,
515
+ [FacturXProfile.BASIC]: 3,
516
+ [FacturXProfile.EN16931]: 4,
517
+ [FacturXProfile.EXTENDED]: 5
518
+ };
519
+ return levels[profile];
520
+ }
521
+ }
522
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdHVyeC52YWxpZGF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9mb3JtYXRzL3ZhbGlkYXRpb24vZmFjdHVyeC52YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBS0g7O0dBRUc7QUFDSCxNQUFNLENBQU4sSUFBWSxjQU1YO0FBTkQsV0FBWSxjQUFjO0lBQ3hCLHFDQUFtQixDQUFBO0lBQ25CLGlDQUFlLENBQUE7SUFDZix1Q0FBcUIsQ0FBQTtJQUNyQixxQ0FBbUIsQ0FBQTtJQUNuQix1Q0FBcUIsQ0FBQTtBQUN2QixDQUFDLEVBTlcsY0FBYyxLQUFkLGNBQWMsUUFNekI7QUFXRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sZ0JBQWdCO0lBQTdCO1FBR0U7O1dBRUc7UUFDSyx3QkFBbUIsR0FBZ0Q7WUFDekUsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ3hCLFNBQVMsRUFBRTtvQkFDVCxpQkFBaUIsRUFBTyx1QkFBdUI7b0JBQy9DLFdBQVcsRUFBWSwyQkFBMkI7b0JBQ2xELG1CQUFtQixFQUFJLDBCQUEwQjtvQkFDakQsVUFBVSxFQUFhLDhCQUE4QjtvQkFDckQsV0FBVyxFQUFZLHFCQUFxQjtvQkFDNUMsZ0JBQWdCLEVBQU8sK0JBQStCO29CQUN0RCxTQUFTLEVBQWMsb0JBQW9CO29CQUMzQyxvQkFBb0IsRUFBRyx3Q0FBd0M7b0JBQy9ELGdCQUFnQixFQUFPLDJDQUEyQztvQkFDbEUsZ0JBQWdCLEVBQU8sbUNBQW1DO2lCQUMzRDtnQkFDRCxRQUFRLEVBQUUsRUFBRTthQUNiO1lBRUQsQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQ3RCLFNBQVMsRUFBRTtvQkFDVCwyQkFBMkI7b0JBQzNCLGlCQUFpQjtvQkFDakIsV0FBVztvQkFDWCxtQkFBbUI7b0JBQ25CLFVBQVU7b0JBQ1YsV0FBVztvQkFDWCxnQkFBZ0I7b0JBQ2hCLGNBQWMsRUFBUywr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
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Main integrated validator combining all validation capabilities
3
+ * Orchestrates TypeScript validators, Schematron, and profile-specific rules
4
+ */
5
+ import type { ValidationOptions, ValidationReport } from './validation.types.js';
6
+ import type { EInvoice } from '../../einvoice.js';
7
+ /**
8
+ * Main validator that combines all validation capabilities
9
+ */
10
+ export declare class MainValidator {
11
+ private integratedValidator;
12
+ private xrechnungValidator;
13
+ private peppolValidator;
14
+ private facturxValidator;
15
+ private businessRulesValidator;
16
+ private codeListValidator;
17
+ private schematronEnabled;
18
+ constructor();
19
+ /**
20
+ * Initialize Schematron validation for better coverage
21
+ */
22
+ initializeSchematron(profile?: 'EN16931' | 'PEPPOL' | 'XRECHNUNG'): Promise<void>;
23
+ /**
24
+ * Validate an invoice with all available validators
25
+ */
26
+ validate(invoice: EInvoice, xmlContent?: string, options?: ValidationOptions): Promise<ValidationReport>;
27
+ /**
28
+ * Detect profile from invoice metadata
29
+ */
30
+ private detectProfile;
31
+ /**
32
+ * Check if invoice is XRechnung
33
+ */
34
+ private isXRechnungInvoice;
35
+ /**
36
+ * Check if invoice is PEPPOL
37
+ */
38
+ private isPeppolInvoice;
39
+ /**
40
+ * Check if invoice is Factur-X
41
+ */
42
+ private isFacturXInvoice;
43
+ /**
44
+ * Detect format from XML content
45
+ */
46
+ private detectFormat;
47
+ /**
48
+ * Remove duplicate validation results
49
+ */
50
+ private deduplicateResults;
51
+ /**
52
+ * Estimate total rules for coverage calculation
53
+ */
54
+ private estimateTotalRules;
55
+ /**
56
+ * Validate with automatic format and profile detection
57
+ */
58
+ validateAuto(invoice: EInvoice, xmlContent?: string): Promise<ValidationReport>;
59
+ /**
60
+ * Get validation capabilities
61
+ */
62
+ getCapabilities(): {
63
+ schematron: boolean;
64
+ xrechnung: boolean;
65
+ peppol: boolean;
66
+ facturx: boolean;
67
+ calculations: boolean;
68
+ codeLists: boolean;
69
+ };
70
+ /**
71
+ * Format validation report as text
72
+ */
73
+ formatReport(report: ValidationReport): string;
74
+ }
75
+ /**
76
+ * Create a pre-configured validator instance
77
+ */
78
+ export declare function createValidator(options?: {
79
+ profile?: 'EN16931' | 'PEPPOL' | 'XRECHNUNG';
80
+ enableSchematron?: boolean;
81
+ }): Promise<MainValidator>;
82
+ export type { ValidationReport, ValidationResult, ValidationOptions } from './validation.types.js';