@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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/einvoice.d.ts +4 -8
- package/dist_ts/einvoice.js +46 -7
- package/dist_ts/formats/converters/xml-to-einvoice.converter.d.ts +21 -0
- package/dist_ts/formats/converters/xml-to-einvoice.converter.js +127 -0
- package/dist_ts/formats/semantic/bt-bg.model.d.ts +445 -0
- package/dist_ts/formats/semantic/bt-bg.model.js +12 -0
- package/dist_ts/formats/semantic/semantic.adapter.d.ts +87 -0
- package/dist_ts/formats/semantic/semantic.adapter.js +538 -0
- package/dist_ts/formats/semantic/semantic.validator.d.ts +48 -0
- package/dist_ts/formats/semantic/semantic.validator.js +596 -0
- package/dist_ts/formats/utils/currency.calculator.decimal.d.ts +98 -0
- package/dist_ts/formats/utils/currency.calculator.decimal.js +212 -0
- package/dist_ts/formats/utils/currency.utils.d.ts +99 -0
- package/dist_ts/formats/utils/currency.utils.js +250 -0
- package/dist_ts/formats/utils/decimal.d.ts +151 -0
- package/dist_ts/formats/utils/decimal.js +435 -0
- package/dist_ts/formats/validation/codelist.validator.d.ts +49 -0
- package/dist_ts/formats/validation/codelist.validator.js +188 -0
- package/dist_ts/formats/validation/conformance.harness.d.ts +99 -0
- package/dist_ts/formats/validation/conformance.harness.js +471 -0
- package/dist_ts/formats/validation/en16931.business-rules.validator.d.ts +58 -0
- package/dist_ts/formats/validation/en16931.business-rules.validator.js +459 -0
- package/dist_ts/formats/validation/facturx.validator.d.ts +75 -0
- package/dist_ts/formats/validation/facturx.validator.js +522 -0
- package/dist_ts/formats/validation/integrated.validator.d.ts +82 -0
- package/dist_ts/formats/validation/integrated.validator.js +311 -0
- package/dist_ts/formats/validation/peppol.validator.d.ts +77 -0
- package/dist_ts/formats/validation/peppol.validator.js +529 -0
- package/dist_ts/formats/validation/schematron.downloader.d.ts +71 -0
- package/dist_ts/formats/validation/schematron.downloader.js +254 -0
- package/dist_ts/formats/validation/schematron.integration.d.ts +60 -0
- package/dist_ts/formats/validation/schematron.integration.js +230 -0
- package/dist_ts/formats/validation/schematron.validator.d.ts +79 -0
- package/dist_ts/formats/validation/schematron.validator.js +288 -0
- package/dist_ts/formats/validation/schematron.worker.d.ts +50 -0
- package/dist_ts/formats/validation/schematron.worker.js +185 -0
- package/dist_ts/formats/validation/validation.types.d.ts +163 -0
- package/dist_ts/formats/validation/validation.types.js +181 -0
- package/dist_ts/formats/validation/vat-categories.validator.d.ts +87 -0
- package/dist_ts/formats/validation/vat-categories.validator.js +497 -0
- package/dist_ts/formats/validation/xrechnung.validator.d.ts +92 -0
- package/dist_ts/formats/validation/xrechnung.validator.js +417 -0
- package/dist_ts/interfaces/common.d.ts +1 -0
- package/dist_ts/interfaces/en16931-metadata.d.ts +83 -0
- package/dist_ts/interfaces/en16931-metadata.js +6 -0
- package/dist_ts/plugins.d.ts +3 -1
- package/dist_ts/plugins.js +7 -2
- package/dist_ts_install/download-schematron.d.ts +6 -0
- package/dist_ts_install/download-schematron.js +62 -0
- package/dist_ts_install/download-test-samples.d.ts +19 -0
- package/dist_ts_install/download-test-samples.js +169 -0
- package/dist_ts_install/download-xrechnung-rules.d.ts +7 -0
- package/dist_ts_install/download-xrechnung-rules.js +146 -0
- package/dist_ts_install/index.d.ts +8 -0
- package/dist_ts_install/index.js +246 -0
- package/package.json +9 -3
- package/readme.md +255 -810
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/einvoice.ts +63 -14
- package/ts/formats/converters/xml-to-einvoice.converter.ts +142 -0
- package/ts/formats/semantic/bt-bg.model.ts +524 -0
- package/ts/formats/semantic/semantic.adapter.ts +600 -0
- package/ts/formats/semantic/semantic.validator.ts +654 -0
- package/ts/formats/utils/currency.calculator.decimal.ts +323 -0
- package/ts/formats/utils/currency.utils.ts +299 -0
- package/ts/formats/utils/decimal.ts +509 -0
- package/ts/formats/validation/codelist.validator.ts +317 -0
- package/ts/formats/validation/conformance.harness.ts +591 -0
- package/ts/formats/validation/en16931.business-rules.validator.ts +694 -0
- package/ts/formats/validation/facturx.validator.ts +579 -0
- package/ts/formats/validation/integrated.validator.ts +405 -0
- package/ts/formats/validation/peppol.validator.ts +589 -0
- package/ts/formats/validation/schematron.downloader.ts +304 -0
- package/ts/formats/validation/schematron.integration.ts +285 -0
- package/ts/formats/validation/schematron.validator.ts +348 -0
- package/ts/formats/validation/schematron.worker.ts +221 -0
- package/ts/formats/validation/validation.types.ts +274 -0
- package/ts/formats/validation/vat-categories.validator.ts +845 -0
- package/ts/formats/validation/xrechnung.validator.ts +494 -0
- package/ts/interfaces/common.ts +1 -0
- package/ts/interfaces/en16931-metadata.ts +104 -0
- package/ts/plugins.ts +8 -0
- package/ts/tspublish.json +3 -0
- package/dist_ts/classes.decoder.d.ts +0 -40
- package/dist_ts/classes.decoder.js +0 -320
- package/dist_ts/classes.encoder.d.ts +0 -51
- package/dist_ts/classes.encoder.js +0 -293
- package/dist_ts/classes.xinvoice.d.ts +0 -136
- package/dist_ts/classes.xinvoice.js +0 -352
- package/dist_ts/formats/base.decoder.d.ts +0 -19
- package/dist_ts/formats/base.decoder.js +0 -130
- package/dist_ts/formats/base.validator.d.ts +0 -44
- package/dist_ts/formats/base.validator.js +0 -39
- package/dist_ts/formats/decoder.factory.d.ts +0 -15
- package/dist_ts/formats/decoder.factory.js +0 -46
- package/dist_ts/formats/factorx.decoder.d.ts +0 -18
- package/dist_ts/formats/factorx.decoder.js +0 -178
- package/dist_ts/formats/factorx.encoder.d.ts +0 -51
- package/dist_ts/formats/factorx.encoder.js +0 -293
- package/dist_ts/formats/facturx.decoder.d.ts +0 -18
- package/dist_ts/formats/facturx.decoder.js +0 -210
- package/dist_ts/formats/facturx.encoder.d.ts +0 -51
- package/dist_ts/formats/facturx.encoder.js +0 -293
- package/dist_ts/formats/facturx.validator.d.ts +0 -67
- package/dist_ts/formats/facturx.validator.js +0 -266
- package/dist_ts/formats/pdf/robust-pdf.extractor.d.ts +0 -40
- package/dist_ts/formats/pdf/robust-pdf.extractor.js +0 -324
- package/dist_ts/formats/ubl.validator.d.ts +0 -82
- package/dist_ts/formats/ubl.validator.js +0 -306
- package/dist_ts/formats/validator.factory.d.ts +0 -18
- package/dist_ts/formats/validator.factory.js +0 -78
- package/dist_ts/formats/xinvoice.decoder.d.ts +0 -28
- package/dist_ts/formats/xinvoice.decoder.js +0 -332
- package/dist_ts/formats/xinvoice.encoder.d.ts +0 -19
- package/dist_ts/formats/xinvoice.encoder.js +0 -282
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import { CurrencyCalculator } from '../utils/currency.utils.js';
|
|
3
|
+
/**
|
|
4
|
+
* VAT Category codes according to UNCL5305
|
|
5
|
+
*/
|
|
6
|
+
export var VATCategory;
|
|
7
|
+
(function (VATCategory) {
|
|
8
|
+
VATCategory["S"] = "S";
|
|
9
|
+
VATCategory["Z"] = "Z";
|
|
10
|
+
VATCategory["E"] = "E";
|
|
11
|
+
VATCategory["AE"] = "AE";
|
|
12
|
+
VATCategory["K"] = "K";
|
|
13
|
+
VATCategory["G"] = "G";
|
|
14
|
+
VATCategory["O"] = "O";
|
|
15
|
+
VATCategory["L"] = "L";
|
|
16
|
+
VATCategory["M"] = "M"; // Tax for production, services and importation in Ceuta and Melilla
|
|
17
|
+
})(VATCategory || (VATCategory = {}));
|
|
18
|
+
/**
|
|
19
|
+
* Comprehensive VAT Category Rules Validator
|
|
20
|
+
* Implements all EN16931 VAT category-specific business rules
|
|
21
|
+
*/
|
|
22
|
+
export class VATCategoriesValidator {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.results = [];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Validate VAT categories according to EN16931
|
|
28
|
+
*/
|
|
29
|
+
validate(invoice) {
|
|
30
|
+
this.results = [];
|
|
31
|
+
// Initialize currency calculator if currency is available
|
|
32
|
+
if (invoice.currency) {
|
|
33
|
+
this.currencyCalculator = new CurrencyCalculator(invoice.currency);
|
|
34
|
+
}
|
|
35
|
+
// Group items by VAT category
|
|
36
|
+
const itemsByCategory = this.groupItemsByVATCategory(invoice.items || []);
|
|
37
|
+
const breakdownsByCategory = this.groupBreakdownsByCategory(invoice.taxBreakdown || []);
|
|
38
|
+
// Validate each VAT category
|
|
39
|
+
this.validateStandardRate(itemsByCategory.get('S'), breakdownsByCategory.get('S'), invoice);
|
|
40
|
+
this.validateZeroRated(itemsByCategory.get('Z'), breakdownsByCategory.get('Z'), invoice);
|
|
41
|
+
this.validateExempt(itemsByCategory.get('E'), breakdownsByCategory.get('E'), invoice);
|
|
42
|
+
this.validateReverseCharge(itemsByCategory.get('AE'), breakdownsByCategory.get('AE'), invoice);
|
|
43
|
+
this.validateIntraCommunity(itemsByCategory.get('K'), breakdownsByCategory.get('K'), invoice);
|
|
44
|
+
this.validateExport(itemsByCategory.get('G'), breakdownsByCategory.get('G'), invoice);
|
|
45
|
+
this.validateOutOfScope(itemsByCategory.get('O'), breakdownsByCategory.get('O'), invoice);
|
|
46
|
+
// Cross-category validation
|
|
47
|
+
this.validateCrossCategoryRules(invoice, itemsByCategory, breakdownsByCategory);
|
|
48
|
+
return this.results;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Validate Standard Rate VAT (BR-S-*)
|
|
52
|
+
*/
|
|
53
|
+
validateStandardRate(items, breakdown, invoice) {
|
|
54
|
+
if (!items || items.length === 0)
|
|
55
|
+
return;
|
|
56
|
+
// BR-S-01: Invoice with standard rated items must have standard rated breakdown
|
|
57
|
+
if (!breakdown) {
|
|
58
|
+
this.addError('BR-S-01', 'Invoice with standard rated items must have a standard rated VAT breakdown', 'taxBreakdown');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// BR-S-02: Standard rate VAT category taxable amount
|
|
62
|
+
const expectedTaxable = this.calculateTaxableAmount(items);
|
|
63
|
+
if (!this.areAmountsEqual(breakdown.netAmount, expectedTaxable)) {
|
|
64
|
+
this.addError('BR-S-02', `Standard rate VAT taxable amount mismatch`, 'taxBreakdown.netAmount', breakdown.netAmount, expectedTaxable);
|
|
65
|
+
}
|
|
66
|
+
// BR-S-03: Standard rate VAT category tax amount
|
|
67
|
+
const rate = breakdown.taxPercent || 0;
|
|
68
|
+
const expectedTax = this.calculateVATAmount(expectedTaxable, rate);
|
|
69
|
+
if (!this.areAmountsEqual(breakdown.taxAmount, expectedTax)) {
|
|
70
|
+
this.addError('BR-S-03', `Standard rate VAT tax amount mismatch`, 'taxBreakdown.taxAmount', breakdown.taxAmount, expectedTax);
|
|
71
|
+
}
|
|
72
|
+
// BR-S-04: Standard rate VAT category code must be "S"
|
|
73
|
+
if (breakdown.categoryCode && breakdown.categoryCode !== 'S') {
|
|
74
|
+
this.addError('BR-S-04', 'Standard rate VAT category code must be "S"', 'taxBreakdown.categoryCode', breakdown.categoryCode, 'S');
|
|
75
|
+
}
|
|
76
|
+
// BR-S-05: Standard rate VAT rate must be greater than zero
|
|
77
|
+
if (rate <= 0) {
|
|
78
|
+
this.addError('BR-S-05', 'Standard rate VAT rate must be greater than zero', 'taxBreakdown.taxPercent', rate, '> 0');
|
|
79
|
+
}
|
|
80
|
+
// BR-S-08: No exemption reason for standard rate
|
|
81
|
+
if (breakdown.exemptionReason) {
|
|
82
|
+
this.addError('BR-S-08', 'Standard rate VAT must not have an exemption reason', 'taxBreakdown.exemptionReason');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Validate Zero Rated VAT (BR-Z-*)
|
|
87
|
+
*/
|
|
88
|
+
validateZeroRated(items, breakdown, invoice) {
|
|
89
|
+
if (!items || items.length === 0)
|
|
90
|
+
return;
|
|
91
|
+
// BR-Z-01: Invoice with zero rated items must have zero rated breakdown
|
|
92
|
+
if (!breakdown) {
|
|
93
|
+
this.addError('BR-Z-01', 'Invoice with zero rated items must have a zero rated VAT breakdown', 'taxBreakdown');
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// BR-Z-02: Zero rate VAT category taxable amount
|
|
97
|
+
const expectedTaxable = this.calculateTaxableAmount(items);
|
|
98
|
+
if (!this.areAmountsEqual(breakdown.netAmount, expectedTaxable)) {
|
|
99
|
+
this.addError('BR-Z-02', 'Zero rate VAT taxable amount mismatch', 'taxBreakdown.netAmount', breakdown.netAmount, expectedTaxable);
|
|
100
|
+
}
|
|
101
|
+
// BR-Z-03: Zero rate VAT tax amount must be zero
|
|
102
|
+
if (breakdown.taxAmount !== 0) {
|
|
103
|
+
this.addError('BR-Z-03', 'Zero rate VAT tax amount must be zero', 'taxBreakdown.taxAmount', breakdown.taxAmount, 0);
|
|
104
|
+
}
|
|
105
|
+
// BR-Z-04: Zero rate VAT category code must be "Z"
|
|
106
|
+
if (breakdown.categoryCode && breakdown.categoryCode !== 'Z') {
|
|
107
|
+
this.addError('BR-Z-04', 'Zero rate VAT category code must be "Z"', 'taxBreakdown.categoryCode', breakdown.categoryCode, 'Z');
|
|
108
|
+
}
|
|
109
|
+
// BR-Z-05: Zero rate VAT rate must be zero
|
|
110
|
+
if (breakdown.taxPercent !== 0) {
|
|
111
|
+
this.addError('BR-Z-05', 'Zero rate VAT rate must be zero', 'taxBreakdown.taxPercent', breakdown.taxPercent, 0);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Validate Exempt from Tax (BR-E-*)
|
|
116
|
+
*/
|
|
117
|
+
validateExempt(items, breakdown, invoice) {
|
|
118
|
+
if (!items || items.length === 0)
|
|
119
|
+
return;
|
|
120
|
+
// BR-E-01: Invoice with exempt items must have exempt breakdown
|
|
121
|
+
if (!breakdown) {
|
|
122
|
+
this.addError('BR-E-01', 'Invoice with tax exempt items must have an exempt VAT breakdown', 'taxBreakdown');
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// BR-E-02: Exempt VAT category taxable amount
|
|
126
|
+
const expectedTaxable = this.calculateTaxableAmount(items);
|
|
127
|
+
if (!this.areAmountsEqual(breakdown.netAmount, expectedTaxable)) {
|
|
128
|
+
this.addError('BR-E-02', 'Exempt VAT taxable amount mismatch', 'taxBreakdown.netAmount', breakdown.netAmount, expectedTaxable);
|
|
129
|
+
}
|
|
130
|
+
// BR-E-03: Exempt VAT tax amount must be zero
|
|
131
|
+
if (breakdown.taxAmount !== 0) {
|
|
132
|
+
this.addError('BR-E-03', 'Exempt VAT tax amount must be zero', 'taxBreakdown.taxAmount', breakdown.taxAmount, 0);
|
|
133
|
+
}
|
|
134
|
+
// BR-E-04: Exempt VAT category code must be "E"
|
|
135
|
+
if (breakdown.categoryCode && breakdown.categoryCode !== 'E') {
|
|
136
|
+
this.addError('BR-E-04', 'Exempt VAT category code must be "E"', 'taxBreakdown.categoryCode', breakdown.categoryCode, 'E');
|
|
137
|
+
}
|
|
138
|
+
// BR-E-05: Exempt VAT rate must be zero
|
|
139
|
+
if (breakdown.taxPercent !== 0) {
|
|
140
|
+
this.addError('BR-E-05', 'Exempt VAT rate must be zero', 'taxBreakdown.taxPercent', breakdown.taxPercent, 0);
|
|
141
|
+
}
|
|
142
|
+
// BR-E-06: Exempt VAT must have exemption reason
|
|
143
|
+
if (!breakdown.exemptionReason && !breakdown.exemptionReasonCode) {
|
|
144
|
+
this.addError('BR-E-06', 'Exempt VAT must have an exemption reason or exemption reason code', 'taxBreakdown.exemptionReason');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Validate VAT Reverse Charge (BR-AE-*)
|
|
149
|
+
*/
|
|
150
|
+
validateReverseCharge(items, breakdown, invoice) {
|
|
151
|
+
if (!items || items.length === 0)
|
|
152
|
+
return;
|
|
153
|
+
// BR-AE-01: Invoice with reverse charge items must have reverse charge breakdown
|
|
154
|
+
if (!breakdown) {
|
|
155
|
+
this.addError('BR-AE-01', 'Invoice with reverse charge items must have a reverse charge VAT breakdown', 'taxBreakdown');
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
// BR-AE-02: Reverse charge VAT category taxable amount
|
|
159
|
+
const expectedTaxable = this.calculateTaxableAmount(items);
|
|
160
|
+
if (!this.areAmountsEqual(breakdown.netAmount, expectedTaxable)) {
|
|
161
|
+
this.addError('BR-AE-02', 'Reverse charge VAT taxable amount mismatch', 'taxBreakdown.netAmount', breakdown.netAmount, expectedTaxable);
|
|
162
|
+
}
|
|
163
|
+
// BR-AE-03: Reverse charge VAT tax amount must be zero
|
|
164
|
+
if (breakdown.taxAmount !== 0) {
|
|
165
|
+
this.addError('BR-AE-03', 'Reverse charge VAT tax amount must be zero', 'taxBreakdown.taxAmount', breakdown.taxAmount, 0);
|
|
166
|
+
}
|
|
167
|
+
// BR-AE-04: Reverse charge VAT category code must be "AE"
|
|
168
|
+
if (breakdown.categoryCode && breakdown.categoryCode !== 'AE') {
|
|
169
|
+
this.addError('BR-AE-04', 'Reverse charge VAT category code must be "AE"', 'taxBreakdown.categoryCode', breakdown.categoryCode, 'AE');
|
|
170
|
+
}
|
|
171
|
+
// BR-AE-05: Reverse charge VAT rate must be zero
|
|
172
|
+
if (breakdown.taxPercent !== 0) {
|
|
173
|
+
this.addError('BR-AE-05', 'Reverse charge VAT rate must be zero', 'taxBreakdown.taxPercent', breakdown.taxPercent, 0);
|
|
174
|
+
}
|
|
175
|
+
// BR-AE-06: Reverse charge must have exemption reason
|
|
176
|
+
if (!breakdown.exemptionReason && !breakdown.exemptionReasonCode) {
|
|
177
|
+
this.addError('BR-AE-06', 'Reverse charge VAT must have an exemption reason', 'taxBreakdown.exemptionReason');
|
|
178
|
+
}
|
|
179
|
+
// BR-AE-08: Buyer must have VAT identifier for reverse charge
|
|
180
|
+
if (!invoice?.metadata?.buyerTaxId) {
|
|
181
|
+
this.addError('BR-AE-08', 'Buyer must have a VAT identifier for reverse charge invoices', 'metadata.buyerTaxId');
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Validate Intra-Community Supply (BR-K-*)
|
|
186
|
+
*/
|
|
187
|
+
validateIntraCommunity(items, breakdown, invoice) {
|
|
188
|
+
if (!items || items.length === 0)
|
|
189
|
+
return;
|
|
190
|
+
// BR-K-01: Invoice with intra-community items must have intra-community breakdown
|
|
191
|
+
if (!breakdown) {
|
|
192
|
+
this.addError('BR-K-01', 'Invoice with intra-community supply must have corresponding VAT breakdown', 'taxBreakdown');
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
// BR-K-02: Intra-community VAT category taxable amount
|
|
196
|
+
const expectedTaxable = this.calculateTaxableAmount(items);
|
|
197
|
+
if (!this.areAmountsEqual(breakdown.netAmount, expectedTaxable)) {
|
|
198
|
+
this.addError('BR-K-02', 'Intra-community VAT taxable amount mismatch', 'taxBreakdown.netAmount', breakdown.netAmount, expectedTaxable);
|
|
199
|
+
}
|
|
200
|
+
// BR-K-03: Intra-community VAT tax amount must be zero
|
|
201
|
+
if (breakdown.taxAmount !== 0) {
|
|
202
|
+
this.addError('BR-K-03', 'Intra-community VAT tax amount must be zero', 'taxBreakdown.taxAmount', breakdown.taxAmount, 0);
|
|
203
|
+
}
|
|
204
|
+
// BR-K-04: Intra-community VAT category code must be "K"
|
|
205
|
+
if (breakdown.categoryCode && breakdown.categoryCode !== 'K') {
|
|
206
|
+
this.addError('BR-K-04', 'Intra-community VAT category code must be "K"', 'taxBreakdown.categoryCode', breakdown.categoryCode, 'K');
|
|
207
|
+
}
|
|
208
|
+
// BR-K-05: Intra-community VAT rate must be zero
|
|
209
|
+
if (breakdown.taxPercent !== 0) {
|
|
210
|
+
this.addError('BR-K-05', 'Intra-community VAT rate must be zero', 'taxBreakdown.taxPercent', breakdown.taxPercent, 0);
|
|
211
|
+
}
|
|
212
|
+
// BR-K-06: Must have exemption reason
|
|
213
|
+
if (!breakdown.exemptionReason && !breakdown.exemptionReasonCode) {
|
|
214
|
+
this.addError('BR-K-06', 'Intra-community supply must have an exemption reason', 'taxBreakdown.exemptionReason');
|
|
215
|
+
}
|
|
216
|
+
// BR-K-08: Both seller and buyer must have VAT identifiers
|
|
217
|
+
if (!invoice?.metadata?.sellerTaxId) {
|
|
218
|
+
this.addError('BR-K-08', 'Seller must have a VAT identifier for intra-community supply', 'metadata.sellerTaxId');
|
|
219
|
+
}
|
|
220
|
+
if (!invoice?.metadata?.buyerTaxId) {
|
|
221
|
+
this.addError('BR-K-09', 'Buyer must have a VAT identifier for intra-community supply', 'metadata.buyerTaxId');
|
|
222
|
+
}
|
|
223
|
+
// BR-K-10: Must be in different EU member states
|
|
224
|
+
if (invoice?.from?.address?.countryCode === invoice?.to?.address?.countryCode) {
|
|
225
|
+
this.addWarning('BR-K-10', 'Intra-community supply should be between different EU member states', 'address.countryCode');
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Validate Export Outside EU (BR-G-*)
|
|
230
|
+
*/
|
|
231
|
+
validateExport(items, breakdown, invoice) {
|
|
232
|
+
if (!items || items.length === 0)
|
|
233
|
+
return;
|
|
234
|
+
// BR-G-01: Invoice with export items must have export breakdown
|
|
235
|
+
if (!breakdown) {
|
|
236
|
+
this.addError('BR-G-01', 'Invoice with export items must have an export VAT breakdown', 'taxBreakdown');
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
// BR-G-02: Export VAT category taxable amount
|
|
240
|
+
const expectedTaxable = this.calculateTaxableAmount(items);
|
|
241
|
+
if (!this.areAmountsEqual(breakdown.netAmount, expectedTaxable)) {
|
|
242
|
+
this.addError('BR-G-02', 'Export VAT taxable amount mismatch', 'taxBreakdown.netAmount', breakdown.netAmount, expectedTaxable);
|
|
243
|
+
}
|
|
244
|
+
// BR-G-03: Export VAT tax amount must be zero
|
|
245
|
+
if (breakdown.taxAmount !== 0) {
|
|
246
|
+
this.addError('BR-G-03', 'Export VAT tax amount must be zero', 'taxBreakdown.taxAmount', breakdown.taxAmount, 0);
|
|
247
|
+
}
|
|
248
|
+
// BR-G-04: Export VAT category code must be "G"
|
|
249
|
+
if (breakdown.categoryCode && breakdown.categoryCode !== 'G') {
|
|
250
|
+
this.addError('BR-G-04', 'Export VAT category code must be "G"', 'taxBreakdown.categoryCode', breakdown.categoryCode, 'G');
|
|
251
|
+
}
|
|
252
|
+
// BR-G-05: Export VAT rate must be zero
|
|
253
|
+
if (breakdown.taxPercent !== 0) {
|
|
254
|
+
this.addError('BR-G-05', 'Export VAT rate must be zero', 'taxBreakdown.taxPercent', breakdown.taxPercent, 0);
|
|
255
|
+
}
|
|
256
|
+
// BR-G-06: Must have exemption reason
|
|
257
|
+
if (!breakdown.exemptionReason && !breakdown.exemptionReasonCode) {
|
|
258
|
+
this.addError('BR-G-06', 'Export must have an exemption reason', 'taxBreakdown.exemptionReason');
|
|
259
|
+
}
|
|
260
|
+
// BR-G-08: Buyer should be outside EU
|
|
261
|
+
const buyerCountry = invoice?.to?.address?.countryCode;
|
|
262
|
+
if (buyerCountry && this.isEUCountry(buyerCountry)) {
|
|
263
|
+
this.addWarning('BR-G-08', 'Export category should be used for buyers outside EU', 'to.address.countryCode', buyerCountry, 'non-EU');
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Validate Out of Scope Services (BR-O-*)
|
|
268
|
+
*/
|
|
269
|
+
validateOutOfScope(items, breakdown, invoice) {
|
|
270
|
+
if (!items || items.length === 0)
|
|
271
|
+
return;
|
|
272
|
+
// BR-O-01: Invoice with out of scope items must have out of scope breakdown
|
|
273
|
+
if (!breakdown) {
|
|
274
|
+
this.addError('BR-O-01', 'Invoice with out of scope items must have corresponding VAT breakdown', 'taxBreakdown');
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
// BR-O-02: Out of scope VAT category taxable amount
|
|
278
|
+
const expectedTaxable = this.calculateTaxableAmount(items);
|
|
279
|
+
if (!this.areAmountsEqual(breakdown.netAmount, expectedTaxable)) {
|
|
280
|
+
this.addError('BR-O-02', 'Out of scope VAT taxable amount mismatch', 'taxBreakdown.netAmount', breakdown.netAmount, expectedTaxable);
|
|
281
|
+
}
|
|
282
|
+
// BR-O-03: Out of scope VAT tax amount must be zero
|
|
283
|
+
if (breakdown.taxAmount !== 0) {
|
|
284
|
+
this.addError('BR-O-03', 'Out of scope VAT tax amount must be zero', 'taxBreakdown.taxAmount', breakdown.taxAmount, 0);
|
|
285
|
+
}
|
|
286
|
+
// BR-O-04: Out of scope VAT category code must be "O"
|
|
287
|
+
if (breakdown.categoryCode && breakdown.categoryCode !== 'O') {
|
|
288
|
+
this.addError('BR-O-04', 'Out of scope VAT category code must be "O"', 'taxBreakdown.categoryCode', breakdown.categoryCode, 'O');
|
|
289
|
+
}
|
|
290
|
+
// BR-O-05: Out of scope VAT rate must be zero
|
|
291
|
+
if (breakdown.taxPercent !== 0) {
|
|
292
|
+
this.addError('BR-O-05', 'Out of scope VAT rate must be zero', 'taxBreakdown.taxPercent', breakdown.taxPercent, 0);
|
|
293
|
+
}
|
|
294
|
+
// BR-O-06: Must have exemption reason
|
|
295
|
+
if (!breakdown.exemptionReason && !breakdown.exemptionReasonCode) {
|
|
296
|
+
this.addError('BR-O-06', 'Out of scope services must have an exemption reason', 'taxBreakdown.exemptionReason');
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Cross-category validation rules
|
|
301
|
+
*/
|
|
302
|
+
validateCrossCategoryRules(invoice, itemsByCategory, breakdownsByCategory) {
|
|
303
|
+
// BR-CO-17: VAT category tax amount = Σ(VAT category taxable amount × VAT rate)
|
|
304
|
+
breakdownsByCategory.forEach((breakdown, category) => {
|
|
305
|
+
if (category === 'S' && breakdown.taxPercent > 0) {
|
|
306
|
+
const expectedTax = this.calculateVATAmount(breakdown.netAmount, breakdown.taxPercent);
|
|
307
|
+
if (!this.areAmountsEqual(breakdown.taxAmount, expectedTax)) {
|
|
308
|
+
this.addError('BR-CO-17', `VAT tax amount calculation error for category ${category}`, 'taxBreakdown.taxAmount', breakdown.taxAmount, expectedTax);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
// BR-CO-18: Invoice with mixed VAT categories
|
|
313
|
+
const categoriesUsed = new Set();
|
|
314
|
+
itemsByCategory.forEach((items, category) => {
|
|
315
|
+
if (items.length > 0)
|
|
316
|
+
categoriesUsed.add(category);
|
|
317
|
+
});
|
|
318
|
+
// BR-IC-01: Supply to EU countries without VAT ID should use standard rate
|
|
319
|
+
if (categoriesUsed.has('K') && !invoice.metadata?.buyerTaxId) {
|
|
320
|
+
this.addError('BR-IC-01', 'Intra-community supply requires buyer VAT identifier', 'metadata.buyerTaxId');
|
|
321
|
+
}
|
|
322
|
+
// BR-IC-02: Reverse charge requires specific conditions
|
|
323
|
+
if (categoriesUsed.has('AE')) {
|
|
324
|
+
// Check for service codes that qualify for reverse charge
|
|
325
|
+
const hasQualifyingServices = invoice.items?.some(item => this.isReverseChargeService(item));
|
|
326
|
+
if (!hasQualifyingServices) {
|
|
327
|
+
this.addWarning('BR-IC-02', 'Reverse charge should only be used for qualifying services', 'items');
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
// BR-CO-19: Sum of VAT breakdown taxable amounts must equal invoice tax exclusive total
|
|
331
|
+
let totalTaxable = 0;
|
|
332
|
+
breakdownsByCategory.forEach(breakdown => {
|
|
333
|
+
totalTaxable += breakdown.netAmount || 0;
|
|
334
|
+
});
|
|
335
|
+
const declaredTotal = invoice.totalNet || 0;
|
|
336
|
+
if (!this.areAmountsEqual(totalTaxable, declaredTotal)) {
|
|
337
|
+
this.addError('BR-CO-19', 'Sum of VAT breakdown taxable amounts must equal invoice total without VAT', 'totalNet', declaredTotal, totalTaxable);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
// Helper methods
|
|
341
|
+
groupItemsByVATCategory(items) {
|
|
342
|
+
const groups = new Map();
|
|
343
|
+
items.forEach(item => {
|
|
344
|
+
const category = this.determineVATCategory(item);
|
|
345
|
+
if (!groups.has(category)) {
|
|
346
|
+
groups.set(category, []);
|
|
347
|
+
}
|
|
348
|
+
groups.get(category).push(item);
|
|
349
|
+
});
|
|
350
|
+
return groups;
|
|
351
|
+
}
|
|
352
|
+
groupBreakdownsByCategory(breakdowns) {
|
|
353
|
+
const groups = new Map();
|
|
354
|
+
breakdowns.forEach(breakdown => {
|
|
355
|
+
const category = breakdown.categoryCode || this.inferCategoryFromRate(breakdown.taxPercent);
|
|
356
|
+
groups.set(category, breakdown);
|
|
357
|
+
});
|
|
358
|
+
return groups;
|
|
359
|
+
}
|
|
360
|
+
determineVATCategory(item) {
|
|
361
|
+
// Determine VAT category from item metadata or rate
|
|
362
|
+
const metadata = item.metadata;
|
|
363
|
+
if (metadata?.vatCategory) {
|
|
364
|
+
return metadata.vatCategory;
|
|
365
|
+
}
|
|
366
|
+
// Infer from rate
|
|
367
|
+
if (item.vatPercentage === undefined || item.vatPercentage === null) {
|
|
368
|
+
return 'S'; // Default to standard
|
|
369
|
+
}
|
|
370
|
+
else if (item.vatPercentage > 0) {
|
|
371
|
+
return 'S'; // Standard rate
|
|
372
|
+
}
|
|
373
|
+
else if (item.vatPercentage === 0) {
|
|
374
|
+
// Could be Z, E, AE, K, G, or O - need more context
|
|
375
|
+
if (metadata?.exemptionReason) {
|
|
376
|
+
if (metadata.exemptionReason.includes('reverse'))
|
|
377
|
+
return 'AE';
|
|
378
|
+
if (metadata.exemptionReason.includes('intra'))
|
|
379
|
+
return 'K';
|
|
380
|
+
if (metadata.exemptionReason.includes('export'))
|
|
381
|
+
return 'G';
|
|
382
|
+
if (metadata.exemptionReason.includes('scope'))
|
|
383
|
+
return 'O';
|
|
384
|
+
return 'E'; // Default exempt
|
|
385
|
+
}
|
|
386
|
+
return 'Z'; // Default zero-rated
|
|
387
|
+
}
|
|
388
|
+
return 'S'; // Default
|
|
389
|
+
}
|
|
390
|
+
inferCategoryFromRate(rate) {
|
|
391
|
+
if (!rate || rate === 0)
|
|
392
|
+
return 'Z';
|
|
393
|
+
if (rate > 0)
|
|
394
|
+
return 'S';
|
|
395
|
+
return 'S';
|
|
396
|
+
}
|
|
397
|
+
calculateTaxableAmount(items) {
|
|
398
|
+
const total = items.reduce((sum, item) => {
|
|
399
|
+
const lineNet = (item.unitNetPrice || 0) * (item.unitQuantity || 0);
|
|
400
|
+
return sum + (this.currencyCalculator ? this.currencyCalculator.round(lineNet) : lineNet);
|
|
401
|
+
}, 0);
|
|
402
|
+
return this.currencyCalculator ? this.currencyCalculator.round(total) : total;
|
|
403
|
+
}
|
|
404
|
+
calculateVATAmount(taxableAmount, rate) {
|
|
405
|
+
const vat = taxableAmount * (rate / 100);
|
|
406
|
+
return this.currencyCalculator ? this.currencyCalculator.round(vat) : vat;
|
|
407
|
+
}
|
|
408
|
+
areAmountsEqual(value1, value2) {
|
|
409
|
+
if (this.currencyCalculator) {
|
|
410
|
+
return this.currencyCalculator.areEqual(value1, value2);
|
|
411
|
+
}
|
|
412
|
+
return Math.abs(value1 - value2) < 0.01;
|
|
413
|
+
}
|
|
414
|
+
isEUCountry(countryCode) {
|
|
415
|
+
const euCountries = [
|
|
416
|
+
'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR',
|
|
417
|
+
'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL',
|
|
418
|
+
'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE'
|
|
419
|
+
];
|
|
420
|
+
return euCountries.includes(countryCode);
|
|
421
|
+
}
|
|
422
|
+
isReverseChargeService(item) {
|
|
423
|
+
// Check if item qualifies for reverse charge
|
|
424
|
+
// This would typically check service codes
|
|
425
|
+
const metadata = item.metadata;
|
|
426
|
+
if (metadata?.serviceCode) {
|
|
427
|
+
// Construction services, telecommunication, etc.
|
|
428
|
+
const reverseChargeServices = ['44', '45', '61', '62'];
|
|
429
|
+
return reverseChargeServices.some(code => metadata.serviceCode.startsWith(code));
|
|
430
|
+
}
|
|
431
|
+
return false;
|
|
432
|
+
}
|
|
433
|
+
addError(ruleId, message, field, value, expected) {
|
|
434
|
+
this.results.push({
|
|
435
|
+
ruleId,
|
|
436
|
+
source: 'EN16931',
|
|
437
|
+
severity: 'error',
|
|
438
|
+
message,
|
|
439
|
+
field,
|
|
440
|
+
value,
|
|
441
|
+
expected,
|
|
442
|
+
btReference: this.getBTReference(ruleId),
|
|
443
|
+
bgReference: 'BG-23' // VAT breakdown
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
addWarning(ruleId, message, field, value, expected) {
|
|
447
|
+
this.results.push({
|
|
448
|
+
ruleId,
|
|
449
|
+
source: 'EN16931',
|
|
450
|
+
severity: 'warning',
|
|
451
|
+
message,
|
|
452
|
+
field,
|
|
453
|
+
value,
|
|
454
|
+
expected,
|
|
455
|
+
btReference: this.getBTReference(ruleId),
|
|
456
|
+
bgReference: 'BG-23'
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
getBTReference(ruleId) {
|
|
460
|
+
const btMap = {
|
|
461
|
+
'BR-S-': 'BT-118', // VAT category rate
|
|
462
|
+
'BR-Z-': 'BT-118',
|
|
463
|
+
'BR-E-': 'BT-120', // VAT exemption reason
|
|
464
|
+
'BR-AE-': 'BT-120',
|
|
465
|
+
'BR-K-': 'BT-120',
|
|
466
|
+
'BR-G-': 'BT-120',
|
|
467
|
+
'BR-O-': 'BT-120',
|
|
468
|
+
'BR-CO-17': 'BT-117', // VAT category tax amount
|
|
469
|
+
'BR-CO-18': 'BT-118',
|
|
470
|
+
'BR-CO-19': 'BT-116' // VAT category taxable amount
|
|
471
|
+
};
|
|
472
|
+
for (const [prefix, bt] of Object.entries(btMap)) {
|
|
473
|
+
if (ruleId.startsWith(prefix)) {
|
|
474
|
+
return bt;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return undefined;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Get VAT category name
|
|
482
|
+
*/
|
|
483
|
+
export function getVATCategoryName(category) {
|
|
484
|
+
const names = {
|
|
485
|
+
[VATCategory.S]: 'Standard rate',
|
|
486
|
+
[VATCategory.Z]: 'Zero rated',
|
|
487
|
+
[VATCategory.E]: 'Exempt from tax',
|
|
488
|
+
[VATCategory.AE]: 'VAT Reverse Charge',
|
|
489
|
+
[VATCategory.K]: 'VAT exempt for EEA intra-community supply',
|
|
490
|
+
[VATCategory.G]: 'Free export outside EU',
|
|
491
|
+
[VATCategory.O]: 'Services outside scope of tax',
|
|
492
|
+
[VATCategory.L]: 'Canary Islands general indirect tax',
|
|
493
|
+
[VATCategory.M]: 'Tax for production, services and importation in Ceuta and Melilla'
|
|
494
|
+
};
|
|
495
|
+
return names[category] || 'Unknown';
|
|
496
|
+
}
|
|
497
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmF0LWNhdGVnb3JpZXMudmFsaWRhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvZm9ybWF0cy92YWxpZGF0aW9uL3ZhdC1jYXRlZ29yaWVzLnZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBRzVDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBR2hFOztHQUVHO0FBQ0gsTUFBTSxDQUFOLElBQVksV0FVWDtBQVZELFdBQVksV0FBVztJQUNyQixzQkFBTyxDQUFBO0lBQ1Asc0JBQU8sQ0FBQTtJQUNQLHNCQUFPLENBQUE7SUFDUCx3QkFBUyxDQUFBO0lBQ1Qsc0JBQU8sQ0FBQTtJQUNQLHNCQUFPLENBQUE7SUFDUCxzQkFBTyxDQUFBO0lBQ1Asc0JBQU8sQ0FBQTtJQUNQLHNCQUFPLENBQUEsQ0FBSSxvRUFBb0U7QUFDakYsQ0FBQyxFQVZXLFdBQVcsS0FBWCxXQUFXLFFBVXRCO0FBY0Q7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLHNCQUFzQjtJQUFuQztRQUNVLFlBQU8sR0FBdUIsRUFBRSxDQUFDO0lBbXhCM0MsQ0FBQztJQWh4QkM7O09BRUc7SUFDSSxRQUFRLENBQUMsT0FBaUI7UUFDL0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFFbEIsMERBQTBEO1FBQzFELElBQUksT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNyRSxDQUFDO1FBRUQsOEJBQThCO1FBQzlCLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxPQUFPLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzFFLE1BQU0sb0JBQW9CLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixD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
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XRechnung CIUS Validator
|
|
3
|
+
* Implements German-specific validation rules for XRechnung 3.0
|
|
4
|
+
*
|
|
5
|
+
* XRechnung is the German Core Invoice Usage Specification (CIUS) of EN16931
|
|
6
|
+
* Required for B2G invoicing in Germany since November 2020
|
|
7
|
+
*/
|
|
8
|
+
import type { EInvoice } from '../../einvoice.js';
|
|
9
|
+
import type { ValidationResult } from './validation.types.js';
|
|
10
|
+
/**
|
|
11
|
+
* XRechnung-specific validator implementing German CIUS rules
|
|
12
|
+
*/
|
|
13
|
+
export declare class XRechnungValidator {
|
|
14
|
+
private static readonly LEITWEG_ID_PATTERN;
|
|
15
|
+
private static readonly IBAN_PATTERNS;
|
|
16
|
+
private static readonly BIC_PATTERN;
|
|
17
|
+
private static readonly SEPA_COUNTRIES;
|
|
18
|
+
/**
|
|
19
|
+
* Validate XRechnung-specific requirements
|
|
20
|
+
*/
|
|
21
|
+
validateXRechnung(invoice: EInvoice): ValidationResult[];
|
|
22
|
+
/**
|
|
23
|
+
* Check if invoice is XRechnung based on profile/customization ID
|
|
24
|
+
*/
|
|
25
|
+
private isXRechnungInvoice;
|
|
26
|
+
/**
|
|
27
|
+
* Validate Leitweg-ID (routing ID for German public administration)
|
|
28
|
+
* Pattern: [0-9]{2,3}-[0-9]{1,12}-[0-9]{2,30}
|
|
29
|
+
* Rule: XR-DE-01
|
|
30
|
+
*/
|
|
31
|
+
private validateLeitwegId;
|
|
32
|
+
/**
|
|
33
|
+
* Check if string looks like a Leitweg-ID
|
|
34
|
+
*/
|
|
35
|
+
private looksLikeLeitwegId;
|
|
36
|
+
/**
|
|
37
|
+
* Check if this is a B2G invoice
|
|
38
|
+
*/
|
|
39
|
+
private isB2GInvoice;
|
|
40
|
+
/**
|
|
41
|
+
* Validate mandatory buyer reference (BT-10)
|
|
42
|
+
* Rule: XR-DE-15
|
|
43
|
+
*/
|
|
44
|
+
private validateBuyerReference;
|
|
45
|
+
/**
|
|
46
|
+
* Validate payment details (IBAN/BIC for SEPA)
|
|
47
|
+
* Rules: XR-DE-19, XR-DE-20
|
|
48
|
+
*/
|
|
49
|
+
private validatePaymentDetails;
|
|
50
|
+
/**
|
|
51
|
+
* Validate IBAN format and checksum
|
|
52
|
+
*/
|
|
53
|
+
private validateIBAN;
|
|
54
|
+
/**
|
|
55
|
+
* Validate BIC format
|
|
56
|
+
*/
|
|
57
|
+
private validateBIC;
|
|
58
|
+
/**
|
|
59
|
+
* Validate seller contact details
|
|
60
|
+
* Rule: XR-DE-02
|
|
61
|
+
*/
|
|
62
|
+
private validateSellerContact;
|
|
63
|
+
/**
|
|
64
|
+
* Validate email format
|
|
65
|
+
*/
|
|
66
|
+
private isValidEmail;
|
|
67
|
+
/**
|
|
68
|
+
* Validate phone format (basic)
|
|
69
|
+
*/
|
|
70
|
+
private isValidPhone;
|
|
71
|
+
/**
|
|
72
|
+
* Validate tax registration details
|
|
73
|
+
* Rules: XR-DE-03, XR-DE-04
|
|
74
|
+
*/
|
|
75
|
+
private validateTaxRegistration;
|
|
76
|
+
/**
|
|
77
|
+
* Validate German VAT ID format
|
|
78
|
+
*/
|
|
79
|
+
private isValidGermanVatId;
|
|
80
|
+
/**
|
|
81
|
+
* Check if value looks like a German Tax ID
|
|
82
|
+
*/
|
|
83
|
+
private looksLikeGermanTaxId;
|
|
84
|
+
/**
|
|
85
|
+
* Validate German Tax ID format
|
|
86
|
+
*/
|
|
87
|
+
private isValidGermanTaxId;
|
|
88
|
+
/**
|
|
89
|
+
* Create XRechnung profile validator instance
|
|
90
|
+
*/
|
|
91
|
+
static create(): XRechnungValidator;
|
|
92
|
+
}
|