@fin.cx/einvoice 5.0.2 → 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 +13 -8
- 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,529 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PEPPOL BIS 3.0 validator for compliance with PEPPOL e-invoice specifications
|
|
3
|
+
* Implements PEPPOL-specific validation rules on top of EN16931
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* PEPPOL BIS 3.0 Validator
|
|
7
|
+
* Implements PEPPOL-specific validation rules and constraints
|
|
8
|
+
*/
|
|
9
|
+
export class PeppolValidator {
|
|
10
|
+
/**
|
|
11
|
+
* Singleton pattern for validator instance
|
|
12
|
+
*/
|
|
13
|
+
static create() {
|
|
14
|
+
if (!PeppolValidator.instance) {
|
|
15
|
+
PeppolValidator.instance = new PeppolValidator();
|
|
16
|
+
}
|
|
17
|
+
return PeppolValidator.instance;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Main validation entry point for PEPPOL
|
|
21
|
+
*/
|
|
22
|
+
validatePeppol(invoice) {
|
|
23
|
+
const results = [];
|
|
24
|
+
// Check if this is a PEPPOL invoice
|
|
25
|
+
if (!this.isPeppolInvoice(invoice)) {
|
|
26
|
+
return results; // Not a PEPPOL invoice, skip validation
|
|
27
|
+
}
|
|
28
|
+
// Run all PEPPOL validations
|
|
29
|
+
results.push(...this.validateEndpointId(invoice));
|
|
30
|
+
results.push(...this.validateDocumentTypeId(invoice));
|
|
31
|
+
results.push(...this.validateProcessId(invoice));
|
|
32
|
+
results.push(...this.validatePartyIdentification(invoice));
|
|
33
|
+
results.push(...this.validatePeppolBusinessRules(invoice));
|
|
34
|
+
results.push(...this.validateSchemeIds(invoice));
|
|
35
|
+
results.push(...this.validateTransportProtocol(invoice));
|
|
36
|
+
return results;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if invoice is PEPPOL
|
|
40
|
+
*/
|
|
41
|
+
isPeppolInvoice(invoice) {
|
|
42
|
+
const profileId = invoice.metadata?.profileId || '';
|
|
43
|
+
const customizationId = invoice.metadata?.customizationId || '';
|
|
44
|
+
const peppolProfiles = [
|
|
45
|
+
'urn:fdc:peppol.eu:2017:poacc:billing:3.0',
|
|
46
|
+
'urn:fdc:peppol.eu:2017:poacc:billing:01:1.0',
|
|
47
|
+
'peppol-bis-3',
|
|
48
|
+
'peppol'
|
|
49
|
+
];
|
|
50
|
+
return peppolProfiles.some(profile => profileId.toLowerCase().includes(profile.toLowerCase()) ||
|
|
51
|
+
customizationId.toLowerCase().includes(profile.toLowerCase()));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Validate Endpoint ID format (0088:xxxxxxxxx or other schemes)
|
|
55
|
+
* PEPPOL-T001, PEPPOL-T002
|
|
56
|
+
*/
|
|
57
|
+
validateEndpointId(invoice) {
|
|
58
|
+
const results = [];
|
|
59
|
+
// Check seller endpoint ID
|
|
60
|
+
const sellerEndpointId = invoice.metadata?.extensions?.sellerEndpointId ||
|
|
61
|
+
invoice.metadata?.extensions?.peppolSellerEndpoint;
|
|
62
|
+
if (sellerEndpointId) {
|
|
63
|
+
if (!this.isValidEndpointId(sellerEndpointId)) {
|
|
64
|
+
results.push({
|
|
65
|
+
ruleId: 'PEPPOL-T001',
|
|
66
|
+
severity: 'error',
|
|
67
|
+
message: 'Invalid seller endpoint ID format. Expected format: scheme:identifier (e.g., 0088:1234567890128)',
|
|
68
|
+
field: 'metadata.extensions.sellerEndpointId',
|
|
69
|
+
value: sellerEndpointId,
|
|
70
|
+
source: 'PEPPOL'
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (this.isPeppolB2G(invoice)) {
|
|
75
|
+
// Endpoint ID is mandatory for B2G
|
|
76
|
+
results.push({
|
|
77
|
+
ruleId: 'PEPPOL-T001',
|
|
78
|
+
severity: 'error',
|
|
79
|
+
message: 'Seller endpoint ID is mandatory for PEPPOL B2G invoices',
|
|
80
|
+
field: 'metadata.extensions.sellerEndpointId',
|
|
81
|
+
source: 'PEPPOL'
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// Check buyer endpoint ID
|
|
85
|
+
const buyerEndpointId = invoice.metadata?.extensions?.buyerEndpointId ||
|
|
86
|
+
invoice.metadata?.extensions?.peppolBuyerEndpoint;
|
|
87
|
+
if (buyerEndpointId) {
|
|
88
|
+
if (!this.isValidEndpointId(buyerEndpointId)) {
|
|
89
|
+
results.push({
|
|
90
|
+
ruleId: 'PEPPOL-T002',
|
|
91
|
+
severity: 'error',
|
|
92
|
+
message: 'Invalid buyer endpoint ID format. Expected format: scheme:identifier (e.g., 0088:1234567890128)',
|
|
93
|
+
field: 'metadata.extensions.buyerEndpointId',
|
|
94
|
+
value: buyerEndpointId,
|
|
95
|
+
source: 'PEPPOL'
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (this.isPeppolB2G(invoice)) {
|
|
100
|
+
// Endpoint ID is mandatory for B2G
|
|
101
|
+
results.push({
|
|
102
|
+
ruleId: 'PEPPOL-T002',
|
|
103
|
+
severity: 'error',
|
|
104
|
+
message: 'Buyer endpoint ID is mandatory for PEPPOL B2G invoices',
|
|
105
|
+
field: 'metadata.extensions.buyerEndpointId',
|
|
106
|
+
source: 'PEPPOL'
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return results;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Validate endpoint ID format
|
|
113
|
+
*/
|
|
114
|
+
isValidEndpointId(endpointId) {
|
|
115
|
+
// PEPPOL endpoint ID format: scheme:identifier
|
|
116
|
+
// Common schemes: 0088 (GLN), 0192 (Norwegian org), 9906 (IT VAT), etc.
|
|
117
|
+
const endpointPattern = /^[0-9]{4}:[A-Za-z0-9\-._]+$/;
|
|
118
|
+
// Special validation for GLN (0088)
|
|
119
|
+
if (endpointId.startsWith('0088:')) {
|
|
120
|
+
const gln = endpointId.substring(5);
|
|
121
|
+
// GLN should be 13 digits
|
|
122
|
+
if (!/^\d{13}$/.test(gln)) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
// Validate GLN check digit
|
|
126
|
+
return this.validateGLNCheckDigit(gln);
|
|
127
|
+
}
|
|
128
|
+
return endpointPattern.test(endpointId);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Validate GLN check digit using modulo 10
|
|
132
|
+
*/
|
|
133
|
+
validateGLNCheckDigit(gln) {
|
|
134
|
+
if (gln.length !== 13)
|
|
135
|
+
return false;
|
|
136
|
+
let sum = 0;
|
|
137
|
+
for (let i = 0; i < 12; i++) {
|
|
138
|
+
const digit = parseInt(gln[i], 10);
|
|
139
|
+
sum += digit * (i % 2 === 0 ? 1 : 3);
|
|
140
|
+
}
|
|
141
|
+
const checkDigit = (10 - (sum % 10)) % 10;
|
|
142
|
+
return checkDigit === parseInt(gln[12], 10);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Validate Document Type ID
|
|
146
|
+
* PEPPOL-T003
|
|
147
|
+
*/
|
|
148
|
+
validateDocumentTypeId(invoice) {
|
|
149
|
+
const results = [];
|
|
150
|
+
const documentTypeId = invoice.metadata?.extensions?.documentTypeId ||
|
|
151
|
+
invoice.metadata?.extensions?.peppolDocumentType;
|
|
152
|
+
if (!documentTypeId && this.isPeppolB2G(invoice)) {
|
|
153
|
+
results.push({
|
|
154
|
+
ruleId: 'PEPPOL-T003',
|
|
155
|
+
severity: 'error',
|
|
156
|
+
message: 'Document type ID is mandatory for PEPPOL invoices',
|
|
157
|
+
field: 'metadata.extensions.documentTypeId',
|
|
158
|
+
source: 'PEPPOL'
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
else if (documentTypeId) {
|
|
162
|
+
// Validate against known PEPPOL document types
|
|
163
|
+
const validDocumentTypes = [
|
|
164
|
+
'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1',
|
|
165
|
+
'urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2::CreditNote##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1',
|
|
166
|
+
// Add more valid document types as needed
|
|
167
|
+
];
|
|
168
|
+
if (!validDocumentTypes.some(type => documentTypeId.includes(type))) {
|
|
169
|
+
results.push({
|
|
170
|
+
ruleId: 'PEPPOL-T003',
|
|
171
|
+
severity: 'warning',
|
|
172
|
+
message: 'Document type ID may not be a valid PEPPOL document type',
|
|
173
|
+
field: 'metadata.extensions.documentTypeId',
|
|
174
|
+
value: documentTypeId,
|
|
175
|
+
source: 'PEPPOL'
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return results;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Validate Process ID
|
|
183
|
+
* PEPPOL-T004
|
|
184
|
+
*/
|
|
185
|
+
validateProcessId(invoice) {
|
|
186
|
+
const results = [];
|
|
187
|
+
const processId = invoice.metadata?.extensions?.processId ||
|
|
188
|
+
invoice.metadata?.extensions?.peppolProcessId;
|
|
189
|
+
if (!processId && this.isPeppolB2G(invoice)) {
|
|
190
|
+
results.push({
|
|
191
|
+
ruleId: 'PEPPOL-T004',
|
|
192
|
+
severity: 'error',
|
|
193
|
+
message: 'Process ID is mandatory for PEPPOL invoices',
|
|
194
|
+
field: 'metadata.extensions.processId',
|
|
195
|
+
source: 'PEPPOL'
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
else if (processId) {
|
|
199
|
+
// Validate against known PEPPOL processes
|
|
200
|
+
const validProcessIds = [
|
|
201
|
+
'urn:fdc:peppol.eu:2017:poacc:billing:01:1.0',
|
|
202
|
+
'urn:fdc:peppol.eu:2017:poacc:billing:3.0',
|
|
203
|
+
// Legacy process IDs
|
|
204
|
+
'urn:www.cenbii.eu:profile:bii05:ver2.0',
|
|
205
|
+
'urn:www.cenbii.eu:profile:bii04:ver2.0'
|
|
206
|
+
];
|
|
207
|
+
if (!validProcessIds.includes(processId)) {
|
|
208
|
+
results.push({
|
|
209
|
+
ruleId: 'PEPPOL-T004',
|
|
210
|
+
severity: 'warning',
|
|
211
|
+
message: 'Process ID may not be a valid PEPPOL process',
|
|
212
|
+
field: 'metadata.extensions.processId',
|
|
213
|
+
value: processId,
|
|
214
|
+
source: 'PEPPOL'
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return results;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Validate Party Identification Schemes
|
|
222
|
+
* PEPPOL-T005, PEPPOL-T006
|
|
223
|
+
*/
|
|
224
|
+
validatePartyIdentification(invoice) {
|
|
225
|
+
const results = [];
|
|
226
|
+
// Validate seller party identification
|
|
227
|
+
if (invoice.from?.type === 'company') {
|
|
228
|
+
const company = invoice.from;
|
|
229
|
+
const partyId = company.registrationDetails?.peppolPartyId ||
|
|
230
|
+
company.registrationDetails?.partyIdentification;
|
|
231
|
+
if (partyId && partyId.schemeId) {
|
|
232
|
+
if (!this.isValidSchemeId(partyId.schemeId)) {
|
|
233
|
+
results.push({
|
|
234
|
+
ruleId: 'PEPPOL-T005',
|
|
235
|
+
severity: 'warning',
|
|
236
|
+
message: 'Seller party identification scheme may not be valid',
|
|
237
|
+
field: 'from.registrationDetails.partyIdentification.schemeId',
|
|
238
|
+
value: partyId.schemeId,
|
|
239
|
+
source: 'PEPPOL'
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// Validate buyer party identification
|
|
245
|
+
const buyerPartyId = invoice.metadata?.extensions?.buyerPartyId;
|
|
246
|
+
if (buyerPartyId && buyerPartyId.schemeId) {
|
|
247
|
+
if (!this.isValidSchemeId(buyerPartyId.schemeId)) {
|
|
248
|
+
results.push({
|
|
249
|
+
ruleId: 'PEPPOL-T006',
|
|
250
|
+
severity: 'warning',
|
|
251
|
+
message: 'Buyer party identification scheme may not be valid',
|
|
252
|
+
field: 'metadata.extensions.buyerPartyId.schemeId',
|
|
253
|
+
value: buyerPartyId.schemeId,
|
|
254
|
+
source: 'PEPPOL'
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return results;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Validate scheme IDs against PEPPOL code list
|
|
262
|
+
*/
|
|
263
|
+
isValidSchemeId(schemeId) {
|
|
264
|
+
// PEPPOL Party Identifier Scheme (subset of ISO 6523 ICD list)
|
|
265
|
+
const validSchemes = [
|
|
266
|
+
'0002', // System Information et Repertoire des Entreprise et des Etablissements (SIRENE)
|
|
267
|
+
'0007', // Organisationsnummer (Swedish legal entities)
|
|
268
|
+
'0009', // SIRET
|
|
269
|
+
'0037', // LY-tunnus (Finnish business ID)
|
|
270
|
+
'0060', // DUNS number
|
|
271
|
+
'0088', // EAN Location Code (GLN)
|
|
272
|
+
'0096', // VIOC (Danish CVR)
|
|
273
|
+
'0097', // Danish Ministry of the Interior and Health
|
|
274
|
+
'0106', // Netherlands Chamber of Commerce
|
|
275
|
+
'0130', // Direktoratet for forvaltning og IKT (DIFI)
|
|
276
|
+
'0135', // IT:SIA
|
|
277
|
+
'0142', // IT:SECETI
|
|
278
|
+
'0184', // Danish CVR
|
|
279
|
+
'0190', // Dutch Originator's Identification Number
|
|
280
|
+
'0191', // Centre of Registers and Information Systems of the Ministry of Justice (Estonia)
|
|
281
|
+
'0192', // Norwegian Legal Entity
|
|
282
|
+
'0193', // UBL.BE party identifier
|
|
283
|
+
'0195', // Singapore UEN
|
|
284
|
+
'0196', // Kennitala (Iceland)
|
|
285
|
+
'0198', // ERSTORG
|
|
286
|
+
'0199', // Legal Entity Identifier (LEI)
|
|
287
|
+
'0200', // Legal entity code (Lithuania)
|
|
288
|
+
'0201', // CODICE UNIVOCO UNITÀ ORGANIZZATIVA
|
|
289
|
+
'0204', // German Leitweg-ID
|
|
290
|
+
'0208', // Belgian enterprise number
|
|
291
|
+
'0209', // GS1 identification keys
|
|
292
|
+
'0210', // CODICE FISCALE
|
|
293
|
+
'0211', // PARTITA IVA
|
|
294
|
+
'0212', // Finnish Organization Number
|
|
295
|
+
'0213', // Finnish VAT number
|
|
296
|
+
'9901', // Danish CVR
|
|
297
|
+
'9902', // Danish SE
|
|
298
|
+
'9904', // German VAT number
|
|
299
|
+
'9905', // German Leitweg ID
|
|
300
|
+
'9906', // IT:VAT
|
|
301
|
+
'9907', // IT:CF
|
|
302
|
+
'9910', // HU:VAT
|
|
303
|
+
'9914', // AT:VAT
|
|
304
|
+
'9915', // AT:GOV
|
|
305
|
+
'9917', // Netherlands OIN
|
|
306
|
+
'9918', // IS:KT
|
|
307
|
+
'9919', // IS company code
|
|
308
|
+
'9920', // ES:VAT
|
|
309
|
+
'9922', // AD:VAT
|
|
310
|
+
'9923', // AL:VAT
|
|
311
|
+
'9924', // BA:VAT
|
|
312
|
+
'9925', // BE:VAT
|
|
313
|
+
'9926', // BG:VAT
|
|
314
|
+
'9927', // CH:VAT
|
|
315
|
+
'9928', // CY:VAT
|
|
316
|
+
'9929', // CZ:VAT
|
|
317
|
+
'9930', // DE:VAT
|
|
318
|
+
'9931', // EE:VAT
|
|
319
|
+
'9932', // GB:VAT
|
|
320
|
+
'9933', // GR:VAT
|
|
321
|
+
'9934', // HR:VAT
|
|
322
|
+
'9935', // IE:VAT
|
|
323
|
+
'9936', // LI:VAT
|
|
324
|
+
'9937', // LT:VAT
|
|
325
|
+
'9938', // LU:VAT
|
|
326
|
+
'9939', // LV:VAT
|
|
327
|
+
'9940', // MC:VAT
|
|
328
|
+
'9941', // ME:VAT
|
|
329
|
+
'9942', // MK:VAT
|
|
330
|
+
'9943', // MT:VAT
|
|
331
|
+
'9944', // NL:VAT
|
|
332
|
+
'9945', // PL:VAT
|
|
333
|
+
'9946', // PT:VAT
|
|
334
|
+
'9947', // RO:VAT
|
|
335
|
+
'9948', // RS:VAT
|
|
336
|
+
'9949', // SI:VAT
|
|
337
|
+
'9950', // SK:VAT
|
|
338
|
+
'9951', // SM:VAT
|
|
339
|
+
'9952', // TR:VAT
|
|
340
|
+
'9953', // VA:VAT
|
|
341
|
+
'9955', // SE:VAT
|
|
342
|
+
'9956', // BE:CBE
|
|
343
|
+
'9957', // FR:VAT
|
|
344
|
+
'9958', // German Leitweg ID
|
|
345
|
+
];
|
|
346
|
+
return validSchemes.includes(schemeId);
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Validate PEPPOL-specific business rules
|
|
350
|
+
*/
|
|
351
|
+
validatePeppolBusinessRules(invoice) {
|
|
352
|
+
const results = [];
|
|
353
|
+
// PEPPOL-B-01: Invoice must have a buyer reference or purchase order reference
|
|
354
|
+
const purchaseOrderRef = invoice.metadata?.extensions?.purchaseOrderReference;
|
|
355
|
+
if (!invoice.metadata?.buyerReference && !purchaseOrderRef) {
|
|
356
|
+
results.push({
|
|
357
|
+
ruleId: 'PEPPOL-B-01',
|
|
358
|
+
severity: 'error',
|
|
359
|
+
message: 'Invoice must have either a buyer reference (BT-10) or purchase order reference (BT-13)',
|
|
360
|
+
field: 'metadata.buyerReference',
|
|
361
|
+
source: 'PEPPOL'
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
// PEPPOL-B-02: Seller electronic address is mandatory
|
|
365
|
+
const sellerEmail = invoice.from?.type === 'company' ?
|
|
366
|
+
invoice.from.contact?.email :
|
|
367
|
+
invoice.from?.email;
|
|
368
|
+
if (!sellerEmail) {
|
|
369
|
+
results.push({
|
|
370
|
+
ruleId: 'PEPPOL-B-02',
|
|
371
|
+
severity: 'warning',
|
|
372
|
+
message: 'Seller electronic address (email) is recommended for PEPPOL invoices',
|
|
373
|
+
field: 'from.contact.email',
|
|
374
|
+
source: 'PEPPOL'
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
// PEPPOL-B-03: Item standard identifier
|
|
378
|
+
if (invoice.items && invoice.items.length > 0) {
|
|
379
|
+
invoice.items.forEach((item, index) => {
|
|
380
|
+
const itemId = item.standardItemIdentification;
|
|
381
|
+
if (!itemId) {
|
|
382
|
+
results.push({
|
|
383
|
+
ruleId: 'PEPPOL-B-03',
|
|
384
|
+
severity: 'info',
|
|
385
|
+
message: `Item ${index + 1} should have a standard item identification (GTIN, EAN, etc.)`,
|
|
386
|
+
field: `items[${index}].standardItemIdentification`,
|
|
387
|
+
source: 'PEPPOL'
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
else if (itemId.schemeId === '0160' && !this.isValidGTIN(itemId.id)) {
|
|
391
|
+
// Validate GTIN if scheme is 0160
|
|
392
|
+
results.push({
|
|
393
|
+
ruleId: 'PEPPOL-B-03',
|
|
394
|
+
severity: 'error',
|
|
395
|
+
message: `Item ${index + 1} has invalid GTIN`,
|
|
396
|
+
field: `items[${index}].standardItemIdentification.id`,
|
|
397
|
+
value: itemId.id,
|
|
398
|
+
source: 'PEPPOL'
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
// PEPPOL-B-04: Payment means code must be from UNCL4461
|
|
404
|
+
const paymentMeansCode = invoice.metadata?.extensions?.paymentMeans?.paymentMeansCode;
|
|
405
|
+
if (paymentMeansCode) {
|
|
406
|
+
const validPaymentMeans = [
|
|
407
|
+
'1', '2', '3', '4', '5', '6', '7', '8', '9', '10',
|
|
408
|
+
'11', '12', '13', '14', '15', '16', '17', '18', '19', '20',
|
|
409
|
+
'21', '22', '23', '24', '25', '26', '27', '28', '29', '30',
|
|
410
|
+
'31', '32', '33', '34', '35', '36', '37', '38', '39', '40',
|
|
411
|
+
'41', '42', '43', '44', '45', '46', '47', '48', '49', '50',
|
|
412
|
+
'51', '52', '53', '54', '55', '56', '57', '58', '59', '60',
|
|
413
|
+
'61', '62', '63', '64', '65', '66', '67', '68', '70', '74',
|
|
414
|
+
'75', '76', '77', '78', '91', '92', '93', '94', '95', '96', '97', 'ZZZ'
|
|
415
|
+
];
|
|
416
|
+
if (!validPaymentMeans.includes(paymentMeansCode)) {
|
|
417
|
+
results.push({
|
|
418
|
+
ruleId: 'PEPPOL-B-04',
|
|
419
|
+
severity: 'error',
|
|
420
|
+
message: 'Payment means code must be from UNCL4461 code list',
|
|
421
|
+
field: 'metadata.extensions.paymentMeans.paymentMeansCode',
|
|
422
|
+
value: paymentMeansCode,
|
|
423
|
+
source: 'PEPPOL'
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return results;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Validate GTIN (Global Trade Item Number)
|
|
431
|
+
*/
|
|
432
|
+
isValidGTIN(gtin) {
|
|
433
|
+
// GTIN can be 8, 12, 13, or 14 digits
|
|
434
|
+
if (!/^(\d{8}|\d{12}|\d{13}|\d{14})$/.test(gtin)) {
|
|
435
|
+
return false;
|
|
436
|
+
}
|
|
437
|
+
// Validate check digit
|
|
438
|
+
const digits = gtin.split('').map(d => parseInt(d, 10));
|
|
439
|
+
const checkDigit = digits[digits.length - 1];
|
|
440
|
+
let sum = 0;
|
|
441
|
+
for (let i = digits.length - 2; i >= 0; i--) {
|
|
442
|
+
const multiplier = ((digits.length - 2 - i) % 2 === 0) ? 3 : 1;
|
|
443
|
+
sum += digits[i] * multiplier;
|
|
444
|
+
}
|
|
445
|
+
const calculatedCheck = (10 - (sum % 10)) % 10;
|
|
446
|
+
return calculatedCheck === checkDigit;
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Validate scheme IDs used in the invoice
|
|
450
|
+
*/
|
|
451
|
+
validateSchemeIds(invoice) {
|
|
452
|
+
const results = [];
|
|
453
|
+
// Check tax scheme ID
|
|
454
|
+
const taxSchemeId = invoice.metadata?.extensions?.taxDetails?.[0]?.taxScheme?.id;
|
|
455
|
+
if (taxSchemeId && taxSchemeId !== 'VAT') {
|
|
456
|
+
results.push({
|
|
457
|
+
ruleId: 'PEPPOL-S-01',
|
|
458
|
+
severity: 'warning',
|
|
459
|
+
message: 'Tax scheme ID should be "VAT" for PEPPOL invoices',
|
|
460
|
+
field: 'metadata.extensions.taxDetails[0].taxScheme.id',
|
|
461
|
+
value: taxSchemeId,
|
|
462
|
+
source: 'PEPPOL'
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
// Check currency code is from ISO 4217
|
|
466
|
+
if (invoice.currency) {
|
|
467
|
+
// This is already validated by CodeListValidator, but we can add PEPPOL-specific check
|
|
468
|
+
if (!['EUR', 'USD', 'GBP', 'SEK', 'NOK', 'DKK', 'CHF', 'PLN', 'CZK', 'HUF'].includes(invoice.currency)) {
|
|
469
|
+
results.push({
|
|
470
|
+
ruleId: 'PEPPOL-S-02',
|
|
471
|
+
severity: 'info',
|
|
472
|
+
message: `Currency ${invoice.currency} is uncommon in PEPPOL network`,
|
|
473
|
+
field: 'currency',
|
|
474
|
+
value: invoice.currency,
|
|
475
|
+
source: 'PEPPOL'
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
return results;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Validate transport protocol requirements
|
|
483
|
+
*/
|
|
484
|
+
validateTransportProtocol(invoice) {
|
|
485
|
+
const results = [];
|
|
486
|
+
// Check if transport protocol is specified
|
|
487
|
+
const transportProtocol = invoice.metadata?.extensions?.transportProtocol;
|
|
488
|
+
if (transportProtocol) {
|
|
489
|
+
const validProtocols = ['AS2', 'AS4'];
|
|
490
|
+
if (!validProtocols.includes(transportProtocol)) {
|
|
491
|
+
results.push({
|
|
492
|
+
ruleId: 'PEPPOL-P-01',
|
|
493
|
+
severity: 'warning',
|
|
494
|
+
message: 'Transport protocol should be AS2 or AS4 for PEPPOL',
|
|
495
|
+
field: 'metadata.extensions.transportProtocol',
|
|
496
|
+
value: transportProtocol,
|
|
497
|
+
source: 'PEPPOL'
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
// Check if SMP lookup is possible
|
|
502
|
+
const sellerEndpointId = invoice.metadata?.extensions?.sellerEndpointId;
|
|
503
|
+
if (sellerEndpointId && !invoice.metadata?.extensions?.smpRegistered) {
|
|
504
|
+
results.push({
|
|
505
|
+
ruleId: 'PEPPOL-P-02',
|
|
506
|
+
severity: 'info',
|
|
507
|
+
message: 'Seller endpoint should be registered in PEPPOL SMP for discovery',
|
|
508
|
+
field: 'metadata.extensions.smpRegistered',
|
|
509
|
+
source: 'PEPPOL'
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
return results;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Check if invoice is B2G (Business to Government)
|
|
516
|
+
*/
|
|
517
|
+
isPeppolB2G(invoice) {
|
|
518
|
+
// Check if buyer has government indicators
|
|
519
|
+
const buyerSchemeId = invoice.metadata?.extensions?.buyerPartyId?.schemeId;
|
|
520
|
+
const buyerCategory = invoice.metadata?.extensions?.buyerCategory;
|
|
521
|
+
// Government scheme IDs often include specific codes
|
|
522
|
+
const governmentSchemes = ['0204', '9905', '0197', '0215'];
|
|
523
|
+
// Check various indicators for government entity
|
|
524
|
+
return buyerCategory === 'government' ||
|
|
525
|
+
(buyerSchemeId && governmentSchemes.includes(buyerSchemeId)) ||
|
|
526
|
+
invoice.metadata?.extensions?.isB2G === true;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVwcG9sLnZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2Zvcm1hdHMvdmFsaWRhdGlvbi9wZXBwb2wudmFsaWRhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUtIOzs7R0FHRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBRzFCOztPQUVHO0lBQ0ksTUFBTSxDQUFDLE1BQU07UUFDbEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUM5QixlQUFlLENBQUMsUUFBUSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7UUFDbkQsQ0FBQztRQUNELE9BQU8sZUFBZSxDQUFDLFFBQVEsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxjQUFjLENBQUMsT0FBaUI7UUFDckMsTUFBTSxPQUFPLEdBQXVCLEVBQUUsQ0FBQztRQUV2QyxvQ0FBb0M7UUFDcEMsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNuQyxPQUFPLE9BQU8sQ0FBQyxDQUFDLHdDQUF3QztRQUMxRCxDQUFDO1FBRUQsNkJBQTZCO1FBQzdCLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNsRCxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDdEQsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ2pELE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsMkJBQTJCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUMzRCxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixDQUFDLE9BQU8s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
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schematron rule sources
|
|
3
|
+
*/
|
|
4
|
+
export interface SchematronSource {
|
|
5
|
+
name: string;
|
|
6
|
+
version: string;
|
|
7
|
+
url: string;
|
|
8
|
+
description: string;
|
|
9
|
+
format: 'UBL' | 'CII' | 'BOTH';
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Official Schematron sources for e-invoicing standards
|
|
13
|
+
*/
|
|
14
|
+
export declare const SCHEMATRON_SOURCES: Record<string, SchematronSource[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Schematron downloader and cache manager
|
|
17
|
+
*/
|
|
18
|
+
export declare class SchematronDownloader {
|
|
19
|
+
private cacheDir;
|
|
20
|
+
private smartfile;
|
|
21
|
+
constructor(cacheDir?: string);
|
|
22
|
+
/**
|
|
23
|
+
* Initialize the downloader
|
|
24
|
+
*/
|
|
25
|
+
initialize(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Download a Schematron file
|
|
28
|
+
*/
|
|
29
|
+
download(source: SchematronSource): Promise<string>;
|
|
30
|
+
/**
|
|
31
|
+
* Download all Schematron files for a standard
|
|
32
|
+
*/
|
|
33
|
+
downloadStandard(standard: 'EN16931' | 'XRECHNUNG' | 'PEPPOL'): Promise<string[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Check if a file is cached
|
|
36
|
+
*/
|
|
37
|
+
private isCached;
|
|
38
|
+
/**
|
|
39
|
+
* Get cached Schematron files
|
|
40
|
+
*/
|
|
41
|
+
getCachedFiles(): Promise<Array<{
|
|
42
|
+
path: string;
|
|
43
|
+
metadata: any;
|
|
44
|
+
}>>;
|
|
45
|
+
/**
|
|
46
|
+
* Clear cache
|
|
47
|
+
*/
|
|
48
|
+
clearCache(): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Get the appropriate Schematron for a format
|
|
51
|
+
*/
|
|
52
|
+
getSchematronForFormat(standard: 'EN16931' | 'XRECHNUNG' | 'PEPPOL', format: 'UBL' | 'CII'): Promise<string | null>;
|
|
53
|
+
/**
|
|
54
|
+
* Update all cached Schematron files
|
|
55
|
+
*/
|
|
56
|
+
updateAll(): Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* ISO Schematron skeleton URLs
|
|
60
|
+
* These are needed to compile Schematron to XSLT
|
|
61
|
+
*/
|
|
62
|
+
export declare const ISO_SCHEMATRON_SKELETONS: {
|
|
63
|
+
'iso_dsdl_include.xsl': string;
|
|
64
|
+
'iso_abstract_expand.xsl': string;
|
|
65
|
+
'iso_svrl_for_xslt2.xsl': string;
|
|
66
|
+
'iso_schematron_skeleton_for_saxon.xsl': string;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Download ISO Schematron skeleton files
|
|
70
|
+
*/
|
|
71
|
+
export declare function downloadISOSkeletons(targetDir?: string): Promise<void>;
|