@fin.cx/einvoice 10.0.0 → 10.1.0
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 +2 -0
- package/dist_ts/einvoice.js +7 -13
- package/dist_ts/formats/base/base.decoder.d.ts +9 -1
- package/dist_ts/formats/base/base.decoder.js +24 -12
- package/dist_ts/formats/cii/cii.decoder.d.ts +11 -3
- package/dist_ts/formats/cii/cii.decoder.js +27 -8
- package/dist_ts/formats/cii/cii.encoder.d.ts +12 -0
- package/dist_ts/formats/cii/cii.encoder.js +36 -1
- package/dist_ts/formats/cii/cii.types.js +2 -1
- package/dist_ts/formats/cii/facturx/facturx.encoder.js +12 -8
- package/dist_ts/formats/cii/zugferd/zugferd.encoder.js +12 -8
- package/dist_ts/formats/semantic/semantic.adapter.d.ts +0 -4
- package/dist_ts/formats/semantic/semantic.adapter.js +7 -18
- package/dist_ts/formats/ubl/generic/ubl.encoder.d.ts +6 -1
- package/dist_ts/formats/ubl/generic/ubl.encoder.js +40 -8
- package/dist_ts/formats/ubl/ubl.decoder.d.ts +11 -0
- package/dist_ts/formats/ubl/ubl.decoder.js +30 -1
- package/dist_ts/formats/ubl/xrechnung/xrechnung.decoder.js +3 -3
- package/dist_ts/formats/utils/date.value.d.ts +24 -0
- package/dist_ts/formats/utils/date.value.js +77 -12
- package/dist_ts/formats/utils/delivery.address.d.ts +18 -0
- package/dist_ts/formats/utils/delivery.address.js +30 -0
- package/dist_ts/formats/utils/document.totals.d.ts +5 -4
- package/dist_ts/formats/utils/document.totals.js +24 -8
- package/dist_ts/formats/utils/stated.values.js +4 -2
- package/dist_ts/formats/utils/vat.category.d.ts +146 -55
- package/dist_ts/formats/utils/vat.category.js +357 -69
- package/dist_ts/formats/validation/vat-categories.validator.d.ts +14 -15
- package/dist_ts/formats/validation/vat-categories.validator.js +123 -85
- package/package.json +5 -5
- package/readme.md +61 -20
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/einvoice.ts +8 -14
- package/ts/formats/base/base.decoder.ts +24 -17
- package/ts/formats/cii/cii.decoder.ts +28 -7
- package/ts/formats/cii/cii.encoder.ts +36 -0
- package/ts/formats/cii/cii.types.ts +1 -0
- package/ts/formats/cii/facturx/facturx.encoder.ts +12 -7
- package/ts/formats/cii/zugferd/zugferd.encoder.ts +12 -7
- package/ts/formats/semantic/semantic.adapter.ts +6 -15
- package/ts/formats/ubl/generic/ubl.encoder.ts +40 -7
- package/ts/formats/ubl/ubl.decoder.ts +31 -0
- package/ts/formats/ubl/xrechnung/xrechnung.decoder.ts +2 -2
- package/ts/formats/utils/date.value.ts +84 -11
- package/ts/formats/utils/delivery.address.ts +36 -0
- package/ts/formats/utils/document.totals.ts +38 -11
- package/ts/formats/utils/stated.values.ts +4 -1
- package/ts/formats/utils/vat.category.ts +426 -95
- package/ts/formats/validation/vat-categories.validator.ts +169 -88
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { computeDocumentTotals, findInvalidItemAmounts, getDocumentCalculator, getTotalsSkippedResult, } from '../utils/document.totals.js';
|
|
2
2
|
import { Decimal } from '../utils/decimal.js';
|
|
3
|
+
import { findVatCategoryViolations, VAT_EXEMPTION_DIFFERS, } from '../utils/vat.category.js';
|
|
3
4
|
/**
|
|
4
5
|
* VAT Category codes according to UNCL5305
|
|
5
6
|
*/
|
|
@@ -16,9 +17,11 @@ export var VATCategory;
|
|
|
16
17
|
VATCategory["M"] = "M"; // Tax for production, services and importation in Ceuta and Melilla
|
|
17
18
|
})(VATCategory || (VATCategory = {}));
|
|
18
19
|
/**
|
|
19
|
-
* The EN 16931 rules this validator checks, with their official text (CEN/TC 434
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* The EN 16931 rules this validator checks, with their official text (CEN/TC 434 EN 16931
|
|
21
|
+
* validation artefacts 1.3.16, the UBL model; the CII model differs only in the case of
|
|
22
|
+
* "Breakdown" in BR-AE-10 and BR-S-10 and "VAT breakdown" in BR-AE-01), BR-CL-22 with the
|
|
23
|
+
* text of the code list rules, and the package's own check that the items of one breakdown
|
|
24
|
+
* state one exemption reason
|
|
22
25
|
*/
|
|
23
26
|
const VAT_CATEGORY_RULES = {
|
|
24
27
|
'BR-S-01': 'An Invoice that contains an Invoice line (BG-25), a Document level allowance (BG-20) or a Document level charge (BG-21) where the VAT category code (BT-151, BT-95 or BT-102) is "Standard rated" shall contain in the VAT breakdown (BG-23) at least one VAT category code (BT-118) equal with "Standard rated".',
|
|
@@ -26,28 +29,111 @@ const VAT_CATEGORY_RULES = {
|
|
|
26
29
|
'BR-S-08': 'For each different value of VAT category rate (BT-119) where the VAT category code (BT-118) is "Standard rated", the VAT category taxable amount (BT-116) in a VAT breakdown (BG-23) shall equal the sum of Invoice line net amounts (BT-131) plus the sum of document level charge amounts (BT-99) minus the sum of document level allowance amounts (BT-92) where the VAT category code (BT-151, BT-102, BT-95) is "Standard rated" and the VAT rate (BT-152, BT-103, BT-96) equals the VAT category rate (BT-119).',
|
|
27
30
|
'BR-S-09': 'The VAT category tax amount (BT-117) in a VAT breakdown (BG-23) where VAT category code (BT-118) is "Standard rated" shall equal the VAT category taxable amount (BT-116) multiplied by the VAT category rate (BT-119).',
|
|
28
31
|
'BR-S-10': 'A VAT breakdown (BG-23) with VAT Category code (BT-118) "Standard rate" shall not have a VAT exemption reason code (BT-121) or VAT exemption reason text (BT-120).',
|
|
32
|
+
'BR-Z-02': 'An Invoice that contains an Invoice line where the Invoiced item VAT category code (BT-151) is "Zero rated" shall contain the Seller VAT Identifier (BT-31), the Seller tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).',
|
|
33
|
+
'BR-Z-05': 'In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "Zero rated" the Invoiced item VAT rate (BT-152) shall be 0 (zero).',
|
|
34
|
+
'BR-Z-08': 'In a VAT breakdown (BG-23) where VAT category code (BT-118) is "Zero rated" the VAT category taxable amount (BT-116) shall equal the sum of Invoice line net amount (BT-131) minus the sum of Document level allowance amounts (BT-92) plus the sum of Document level charge amounts (BT-99) where the VAT category codes (BT-151, BT-95, BT-102) are "Zero rated".',
|
|
35
|
+
'BR-Z-09': 'The VAT category tax amount (BT-117) in a VAT breakdown (BG-23) where VAT category code (BT-118) is "Zero rated" shall equal 0 (zero).',
|
|
36
|
+
'BR-Z-10': 'A VAT breakdown (BG-23) with VAT Category code (BT-118) "Zero rated" shall not have a VAT exemption reason code (BT-121) or VAT exemption reason text (BT-120).',
|
|
37
|
+
'BR-E-02': 'An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "Exempt from VAT" shall contain the Seller VAT Identifier (BT-31), the Seller tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).',
|
|
38
|
+
'BR-E-05': 'In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "Exempt from VAT", the Invoiced item VAT rate (BT-152) shall be 0 (zero).',
|
|
39
|
+
'BR-E-08': 'In a VAT breakdown (BG-23) where the VAT category code (BT-118) is "Exempt from VAT" the VAT category taxable amount (BT-116) shall equal the sum of Invoice line net amounts (BT-131) minus the sum of Document level allowance amounts (BT-92) plus the sum of Document level charge amounts (BT-99) where the VAT category codes (BT-151, BT-95, BT-102) are "Exempt from VAT".',
|
|
40
|
+
'BR-E-09': 'The VAT category tax amount (BT-117) In a VAT breakdown (BG-23) where the VAT category code (BT-118) equals "Exempt from VAT" shall equal 0 (zero).',
|
|
41
|
+
'BR-E-10': 'A VAT breakdown (BG-23) with VAT Category code (BT-118) "Exempt from VAT" shall have a VAT exemption reason code (BT-121) or a VAT exemption reason text (BT-120).',
|
|
29
42
|
'BR-AE-01': 'An Invoice that contains an Invoice line (BG-25), a Document level allowance (BG-20) or a Document level charge (BG-21) where the VAT category code (BT-151, BT-95 or BT-102) is "Reverse charge" shall contain in the VAT Breakdown (BG-23) exactly one VAT category code (BT-118) equal with "VAT reverse charge".',
|
|
30
43
|
'BR-AE-02': 'An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "Reverse charge" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63) and the Buyer VAT identifier (BT-48) and/or the Buyer legal registration identifier (BT-47).',
|
|
31
44
|
'BR-AE-05': 'In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "Reverse charge" the Invoiced item VAT rate (BT-152) shall be 0 (zero).',
|
|
32
45
|
'BR-AE-08': 'In a VAT breakdown (BG-23) where the VAT category code (BT-118) is "Reverse charge" the VAT category taxable amount (BT-116) shall equal the sum of Invoice line net amounts (BT-131) minus the sum of Document level allowance amounts (BT-92) plus the sum of Document level charge amounts (BT-99) where the VAT category codes (BT-151, BT-95, BT-102) are "Reverse charge".',
|
|
33
46
|
'BR-AE-09': 'The VAT category tax amount (BT-117) in a VAT breakdown (BG-23) where the VAT category code (BT-118) is "Reverse charge" shall be 0 (zero).',
|
|
34
47
|
'BR-AE-10': 'A VAT breakdown (BG-23) with VAT Category code (BT-118) "Reverse charge" shall have a VAT exemption reason code (BT-121), meaning "Reverse charge" or the VAT exemption reason text (BT-120) "Reverse charge" (or the equivalent standard text in another language).',
|
|
48
|
+
'BR-IC-02': 'An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "Intra-community supply" shall contain the Seller VAT Identifier (BT-31) or the Seller tax representative VAT identifier (BT-63) and the Buyer VAT identifier (BT-48).',
|
|
49
|
+
'BR-IC-05': 'In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "Intracommunity supply" the Invoiced item VAT rate (BT-152) shall be 0 (zero).',
|
|
50
|
+
'BR-IC-08': 'In a VAT breakdown (BG-23) where the VAT category code (BT-118) is "Intra-community supply" the VAT category taxable amount (BT-116) shall equal the sum of Invoice line net amounts (BT-131) minus the sum of Document level allowance amounts (BT-92) plus the sum of Document level charge amounts (BT-99) where the VAT category codes (BT-151, BT-95, BT-102) are "Intra-community supply".',
|
|
51
|
+
'BR-IC-09': 'The VAT category tax amount (BT-117) in a VAT breakdown (BG-23) where the VAT category code (BT-118) is "Intra-community supply" shall be 0 (zero).',
|
|
52
|
+
'BR-IC-10': 'A VAT breakdown (BG-23) with the VAT Category code (BT-118) "Intra-community supply" shall have a VAT exemption reason code (BT-121), meaning "Intra-community supply" or the VAT exemption reason text (BT-120) "Intra-community supply" (or the equivalent standard text in another language).',
|
|
53
|
+
'BR-IC-11': 'In an Invoice with a VAT breakdown (BG-23) where the VAT category code (BT-118) is "Intra-community supply" the Actual delivery date (BT-72) or the Invoicing period (BG-14) shall not be blank.',
|
|
54
|
+
'BR-IC-12': 'In an Invoice with a VAT breakdown (BG-23) where the VAT category code (BT-118) is "Intra-community supply" the Deliver to country code (BT-80) shall not be blank.',
|
|
55
|
+
'BR-G-02': 'An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "Export outside the EU" shall contain the Seller VAT Identifier (BT-31) or the Seller tax representative VAT identifier (BT-63).',
|
|
56
|
+
'BR-G-05': 'In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "Export outside the EU" the Invoiced item VAT rate (BT-152) shall be 0 (zero).',
|
|
57
|
+
'BR-G-08': 'In a VAT breakdown (BG-23) where the VAT category code (BT-118) is "Export outside the EU" the VAT category taxable amount (BT-116) shall equal the sum of Invoice line net amounts (BT-131) minus the sum of Document level allowance amounts (BT-92) plus the sum of Document level charge amounts (BT-99) where the VAT category codes (BT-151, BT-95, BT-102) are "Export outside the EU".',
|
|
58
|
+
'BR-G-09': 'The VAT category tax amount (BT-117) in a VAT breakdown (BG-23) where the VAT category code (BT-118) is "Export outside the EU" shall be 0 (zero).',
|
|
59
|
+
'BR-G-10': 'A VAT breakdown (BG-23) with the VAT Category code (BT-118) "Export outside the EU" shall have a VAT exemption reason code (BT-121), meaning "Export outside the EU" or the VAT exemption reason text (BT-120) "Export outside the EU" (or the equivalent standard text in another language).',
|
|
60
|
+
'BR-O-02': 'An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "Not subject to VAT" shall not contain the Seller VAT identifier (BT-31), the Seller tax representative VAT identifier (BT-63) or the Buyer VAT identifier (BT-48).',
|
|
61
|
+
'BR-O-05': 'An Invoice line (BG-25) where the VAT category code (BT-151) is "Not subject to VAT" shall not contain an Invoiced item VAT rate (BT-152).',
|
|
62
|
+
'BR-O-08': 'In a VAT breakdown (BG-23) where the VAT category code (BT-118) is " Not subject to VAT" the VAT category taxable amount (BT-116) shall equal the sum of Invoice line net amounts (BT-131) minus the sum of Document level allowance amounts (BT-92) plus the sum of Document level charge amounts (BT-99) where the VAT category codes (BT-151, BT-95, BT-102) are "Not subject to VAT".',
|
|
63
|
+
'BR-O-09': 'The VAT category tax amount (BT-117) in a VAT breakdown (BG-23) where the VAT category code (BT-118) is "Not subject to VAT" shall be 0 (zero).',
|
|
64
|
+
'BR-O-10': 'A VAT breakdown (BG-23) with VAT Category code (BT-118) " Not subject to VAT" shall have a VAT exemption reason code (BT-121), meaning " Not subject to VAT" or a VAT exemption reason text (BT-120) " Not subject to VAT" (or the equivalent standard text in another language).',
|
|
65
|
+
'BR-O-11': 'An Invoice that contains a VAT breakdown group (BG-23) with a VAT category code (BT-118) "Not subject to VAT" shall not contain other VAT breakdown groups (BG-23).',
|
|
66
|
+
'BR-AF-02': 'An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IGIC" shall contain the Seller VAT Identifier (BT-31), the Seller tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).',
|
|
67
|
+
'BR-AF-05': 'In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IGIC" the invoiced item VAT rate (BT-152) shall be 0 (zero) or greater than zero.',
|
|
68
|
+
'BR-AF-08': 'For each different value of VAT category rate (BT-119) where the VAT category code (BT-118) is "IGIC", the VAT category taxable amount (BT-116) in a VAT breakdown (BG-23) shall equal the sum of Invoice line net amounts (BT-131) plus the sum of document level charge amounts (BT-99) minus the sum of document level allowance amounts (BT-92) where the VAT category code (BT-151, BT-102, BT-95) is "IGIC" and the VAT rate (BT-152, BT-103, BT-96) equals the VAT category rate (BT-119).',
|
|
69
|
+
'BR-AF-09': 'The VAT category tax amount (BT-117) in a VAT breakdown (BG-23) where VAT category code (BT-118) is "IGIC" shall equal the VAT category taxable amount (BT-116) multiplied by the VAT category rate (BT-119).',
|
|
70
|
+
'BR-AF-10': 'A VAT breakdown (BG-23) with VAT Category code (BT-118) "IGIC" shall not have a VAT exemption reason code (BT-121) or VAT exemption reason text (BT-120).',
|
|
71
|
+
'BR-AG-02': 'An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).',
|
|
72
|
+
'BR-AG-05': 'In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IPSI" the Invoiced item VAT rate (BT-152) shall be 0 (zero) or greater than zero.',
|
|
73
|
+
'BR-AG-08': 'For each different value of VAT category rate (BT-119) where the VAT category code (BT-118) is "IPSI", the VAT category taxable amount (BT-116) in a VAT breakdown (BG-23) shall equal the sum of Invoice line net amounts (BT-131) plus the sum of document level charge amounts (BT-99) minus the sum of document level allowance amounts (BT-92) where the VAT category code (BT-151, BT-102, BT-95) is "IPSI" and the VAT rate (BT-152, BT-103, BT-96) equals the VAT category rate (BT-119).',
|
|
74
|
+
'BR-AG-09': 'The VAT category tax amount (BT-117) in a VAT breakdown (BG-23) where VAT category code (BT-118) is "IPSI" shall equal the VAT category taxable amount (BT-116) multiplied by the VAT category rate (BT-119).',
|
|
75
|
+
'BR-AG-10': 'A VAT breakdown (BG-23) with VAT Category code (BT-118) "IPSI" shall not have a VAT exemption reason code (BT-121) or VAT exemption reason text (BT-120).',
|
|
35
76
|
'BR-CO-17': 'VAT category tax amount (BT-117) = VAT category taxable amount (BT-116) x (VAT category rate (BT-119) / 100), rounded to two decimals.',
|
|
77
|
+
'BR-CL-22': 'Tax exemption reason code identifier scheme identifier MUST belong to the CEF VATEX code list',
|
|
78
|
+
[VAT_EXEMPTION_DIFFERS]: 'The Invoice lines (BG-25) of one VAT breakdown (BG-23) state one VAT exemption reason text (BT-120) and code (BT-121), as the breakdown states one.',
|
|
79
|
+
};
|
|
80
|
+
/** The rule IDs of the taxable amount (-08) and the tax amount (-09) of a VAT breakdown, per category */
|
|
81
|
+
const BREAKDOWN_RULES = {
|
|
82
|
+
S: { taxable: 'BR-S-08', tax: 'BR-S-09' },
|
|
83
|
+
Z: { taxable: 'BR-Z-08', tax: 'BR-Z-09' },
|
|
84
|
+
E: { taxable: 'BR-E-08', tax: 'BR-E-09' },
|
|
85
|
+
AE: { taxable: 'BR-AE-08', tax: 'BR-AE-09' },
|
|
86
|
+
K: { taxable: 'BR-IC-08', tax: 'BR-IC-09' },
|
|
87
|
+
G: { taxable: 'BR-G-08', tax: 'BR-G-09' },
|
|
88
|
+
O: { taxable: 'BR-O-08', tax: 'BR-O-09' },
|
|
89
|
+
L: { taxable: 'BR-AF-08', tax: 'BR-AF-09' },
|
|
90
|
+
M: { taxable: 'BR-AG-08', tax: 'BR-AG-09' },
|
|
91
|
+
};
|
|
92
|
+
/** The categories whose tax amount is the taxable amount × rate (BR-S-09, BR-AF-09, BR-AG-09); the others state 0 */
|
|
93
|
+
const TAXED_CATEGORIES = ['S', 'L', 'M'];
|
|
94
|
+
/**
|
|
95
|
+
* The business terms and groups a finding of a rule on the items' VAT categories points at
|
|
96
|
+
* @param violation The violation
|
|
97
|
+
*/
|
|
98
|
+
const referencesOf = (violation) => {
|
|
99
|
+
const suffix = violation.ruleId.split('-').pop();
|
|
100
|
+
if (violation.ruleId === 'BR-CL-22') {
|
|
101
|
+
return { btReference: 'BT-121', bgReference: 'BG-23' };
|
|
102
|
+
}
|
|
103
|
+
if (violation.ruleId === VAT_EXEMPTION_DIFFERS) {
|
|
104
|
+
return { btReference: 'BT-120', bgReference: 'BG-23' };
|
|
105
|
+
}
|
|
106
|
+
if (violation.ruleId === 'BR-IC-11') {
|
|
107
|
+
return { btReference: 'BT-72', bgReference: 'BG-13' };
|
|
108
|
+
}
|
|
109
|
+
if (violation.ruleId === 'BR-IC-12') {
|
|
110
|
+
return { btReference: 'BT-80', bgReference: 'BG-15' };
|
|
111
|
+
}
|
|
112
|
+
if (violation.ruleId === 'BR-O-11') {
|
|
113
|
+
return { btReference: 'BT-151', bgReference: 'BG-25' };
|
|
114
|
+
}
|
|
115
|
+
switch (suffix) {
|
|
116
|
+
case '02':
|
|
117
|
+
return violation.field.startsWith('to.') ? { btReference: 'BT-48', bgReference: 'BG-7' } : { btReference: 'BT-31', bgReference: 'BG-4' };
|
|
118
|
+
case '05':
|
|
119
|
+
return { btReference: 'BT-152', bgReference: 'BG-25' };
|
|
120
|
+
default:
|
|
121
|
+
return { btReference: 'BT-121', bgReference: 'BG-23' };
|
|
122
|
+
}
|
|
36
123
|
};
|
|
37
124
|
/**
|
|
38
125
|
* The EN 16931 VAT category rules of a document, checked on the VAT categories
|
|
39
126
|
* and the VAT breakdown the encoders write.
|
|
40
127
|
*
|
|
41
|
-
* The category of every line is the one the encoders write
|
|
42
|
-
*
|
|
43
|
-
* (
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* and rate. The envelope has no document level allowances or charges, so the
|
|
128
|
+
* The category of every line is the one the encoders write
|
|
129
|
+
* (`getItemVatCategory`): the one the item states (`vatCategory`, BT-151),
|
|
130
|
+
* else reverse charge (AE) when the document states `reverseCharge` and
|
|
131
|
+
* standard rated (S) otherwise. A decoded line carries the category its
|
|
132
|
+
* document states. The rules on the items, their exemption reasons and the
|
|
133
|
+
* parties' identifiers are those export refuses a document for
|
|
134
|
+
* (`findVatCategoryViolations`). The VAT breakdown is the one the encoders
|
|
135
|
+
* write (`computeDocumentTotals().vatGroups`): one group per category and
|
|
136
|
+
* rate. The envelope has no document level allowances or charges, so the
|
|
51
137
|
* rules on them (BR-S-02 to -04 and -06 to -07 and their counterparts) do not
|
|
52
138
|
* apply, and a taxable amount is the sum of the line net amounts.
|
|
53
139
|
*/
|
|
@@ -68,40 +154,22 @@ export class VATCategoriesValidator {
|
|
|
68
154
|
const totals = computeDocumentTotals(invoice);
|
|
69
155
|
const calculator = getDocumentCalculator(invoice.currency);
|
|
70
156
|
const items = invoice.items ?? [];
|
|
71
|
-
|
|
157
|
+
for (const violation of findVatCategoryViolations(invoice)) {
|
|
158
|
+
this.addError(violation.ruleId, {
|
|
159
|
+
field: violation.field,
|
|
160
|
+
...referencesOf(violation),
|
|
161
|
+
remediation: violation.message,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
this.validateBreakdownPresence(totals);
|
|
72
165
|
this.validateBreakdown(items, totals, calculator);
|
|
73
166
|
return this.results;
|
|
74
167
|
}
|
|
75
168
|
/**
|
|
76
|
-
* The
|
|
77
|
-
*
|
|
169
|
+
* The breakdown a category of the lines needs: at least one for S (BR-S-01), exactly one for
|
|
170
|
+
* reverse charge (BR-AE-01)
|
|
78
171
|
*/
|
|
79
|
-
|
|
80
|
-
items.forEach((item, index) => {
|
|
81
|
-
const category = totals.lineVatCategories[index];
|
|
82
|
-
// A decoded line keeps the category its document states (BT-151). One that is not S is a
|
|
83
|
-
// category the envelope cannot express (Z, E, K, G, O, or AE in a document that mixes S and
|
|
84
|
-
// AE lines, which the decoders do not read as reverse charge); its rate says nothing of BR-S-05.
|
|
85
|
-
const statedCategory = invoice.statedValues?.lines[index]?.vatCategoryCode;
|
|
86
|
-
if (category === 'S' && !(item.vatPercentage > 0) && (statedCategory === undefined || statedCategory === 'S')) {
|
|
87
|
-
this.addError('BR-S-05', {
|
|
88
|
-
field: `items[${index}].vatPercentage`,
|
|
89
|
-
btReference: 'BT-152',
|
|
90
|
-
bgReference: 'BG-25',
|
|
91
|
-
value: item.vatPercentage,
|
|
92
|
-
expected: '> 0',
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
if (category === 'AE' && item.vatPercentage !== 0) {
|
|
96
|
-
this.addError('BR-AE-05', {
|
|
97
|
-
field: `items[${index}].vatPercentage`,
|
|
98
|
-
btReference: 'BT-152',
|
|
99
|
-
bgReference: 'BG-25',
|
|
100
|
-
value: item.vatPercentage,
|
|
101
|
-
expected: 0,
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
});
|
|
172
|
+
validateBreakdownPresence(totals) {
|
|
105
173
|
const hasCategory = (category) => totals.lineVatCategories.includes(category);
|
|
106
174
|
const groupsOf = (category) => totals.vatGroups.filter((group) => group.category === category);
|
|
107
175
|
if (hasCategory('S') && groupsOf('S').length === 0) {
|
|
@@ -116,30 +184,10 @@ export class VATCategoriesValidator {
|
|
|
116
184
|
remediation: 'a reverse charge breakdown per rate: give every reverse charge line the VAT rate 0 (BR-AE-05)',
|
|
117
185
|
});
|
|
118
186
|
}
|
|
119
|
-
if (hasCategory('AE')) {
|
|
120
|
-
const seller = invoice.from?.registrationDetails;
|
|
121
|
-
if (!seller?.vatId?.trim() && !seller?.taxNumber?.trim()) {
|
|
122
|
-
this.addError('BR-AE-02', {
|
|
123
|
-
field: 'from.registrationDetails',
|
|
124
|
-
btReference: 'BT-31',
|
|
125
|
-
bgReference: 'BG-4',
|
|
126
|
-
remediation: 'state from.registrationDetails.vatId (BT-31) or .taxNumber (BT-32); the envelope cannot state a tax representative (BT-63)',
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
const buyer = invoice.to?.registrationDetails;
|
|
130
|
-
if (!buyer?.vatId?.trim() && !buyer?.registrationId?.trim()) {
|
|
131
|
-
this.addError('BR-AE-02', {
|
|
132
|
-
field: 'to.registrationDetails',
|
|
133
|
-
bgReference: 'BG-7',
|
|
134
|
-
btReference: 'BT-48',
|
|
135
|
-
remediation: 'state to.registrationDetails.vatId (BT-48) or .registrationId (BT-47)',
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
187
|
}
|
|
140
188
|
/**
|
|
141
|
-
* The rules on each VAT breakdown group: its taxable amount (BR-S-08
|
|
142
|
-
*
|
|
189
|
+
* The rules on each VAT breakdown group: its taxable amount (BR-S-08 and its counterparts of
|
|
190
|
+
* every category) and its tax amount (BR-S-09 and its counterparts, BR-CO-17)
|
|
143
191
|
*/
|
|
144
192
|
validateBreakdown(items, totals, calculator) {
|
|
145
193
|
for (const group of totals.vatGroups) {
|
|
@@ -147,28 +195,18 @@ export class VATCategoriesValidator {
|
|
|
147
195
|
const expectedTaxable = calculator.round(Decimal.sum(lineNetAmounts));
|
|
148
196
|
const expectedTax = calculator.calculateVAT(group.taxableAmount, group.rate);
|
|
149
197
|
const amounts = (value, expected) => ({ value: value.toNumber(), expected: expected.toNumber() });
|
|
150
|
-
const at =
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
198
|
+
const at = `${group.category} rate ${group.rate}`;
|
|
199
|
+
const rules = BREAKDOWN_RULES[group.category];
|
|
200
|
+
if (!group.taxableAmount.equals(expectedTaxable)) {
|
|
201
|
+
this.addError(rules.taxable, { field: `taxBreakdown[${at}].netAmount`, btReference: 'BT-116', ...amounts(group.taxableAmount, expectedTaxable) });
|
|
202
|
+
}
|
|
203
|
+
if (TAXED_CATEGORIES.includes(group.category)) {
|
|
155
204
|
if (!group.taxAmount.equals(expectedTax)) {
|
|
156
|
-
this.addError(
|
|
157
|
-
}
|
|
158
|
-
if (group.exemption) {
|
|
159
|
-
this.addError('BR-S-10', { field: `taxBreakdown[${at}]`, btReference: 'BT-121', value: group.exemption.code });
|
|
205
|
+
this.addError(rules.tax, { field: `taxBreakdown[${at}].taxAmount`, btReference: 'BT-117', ...amounts(group.taxAmount, expectedTax) });
|
|
160
206
|
}
|
|
161
207
|
}
|
|
162
|
-
if (group.
|
|
163
|
-
|
|
164
|
-
this.addError('BR-AE-08', { field: `taxBreakdown[${at}].netAmount`, btReference: 'BT-116', ...amounts(group.taxableAmount, expectedTaxable) });
|
|
165
|
-
}
|
|
166
|
-
if (!group.taxAmount.isZero()) {
|
|
167
|
-
this.addError('BR-AE-09', { field: `taxBreakdown[${at}].taxAmount`, btReference: 'BT-117', value: group.taxAmount.toNumber(), expected: 0 });
|
|
168
|
-
}
|
|
169
|
-
if (group.exemption?.code !== 'VATEX-EU-AE' && !group.exemption?.reason.trim()) {
|
|
170
|
-
this.addError('BR-AE-10', { field: `taxBreakdown[${at}]`, btReference: 'BT-121' });
|
|
171
|
-
}
|
|
208
|
+
else if (!group.taxAmount.isZero()) {
|
|
209
|
+
this.addError(rules.tax, { field: `taxBreakdown[${at}].taxAmount`, btReference: 'BT-117', value: group.taxAmount.toNumber(), expected: 0 });
|
|
172
210
|
}
|
|
173
211
|
if (!group.taxAmount.equals(expectedTax)) {
|
|
174
212
|
this.addError('BR-CO-17', { field: `taxBreakdown[${at}].taxAmount`, btReference: 'BT-117', ...amounts(group.taxAmount, expectedTax) });
|
|
@@ -178,7 +216,7 @@ export class VATCategoriesValidator {
|
|
|
178
216
|
addError(ruleId, finding) {
|
|
179
217
|
this.results.push({
|
|
180
218
|
ruleId,
|
|
181
|
-
source: 'EN16931',
|
|
219
|
+
source: ruleId === VAT_EXEMPTION_DIFFERS ? 'EINVOICE' : 'EN16931',
|
|
182
220
|
severity: 'error',
|
|
183
221
|
message: VAT_CATEGORY_RULES[ruleId],
|
|
184
222
|
bgReference: 'BG-23',
|
|
@@ -203,4 +241,4 @@ export function getVATCategoryName(category) {
|
|
|
203
241
|
};
|
|
204
242
|
return names[category] || 'Unknown';
|
|
205
243
|
}
|
|
206
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmF0LWNhdGVnb3JpZXMudmFsaWRhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvZm9ybWF0cy92YWxpZGF0aW9uL3ZhdC1jYXRlZ29yaWVzLnZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wscUJBQXFCLEVBQ3JCLHNCQUFzQixFQUN0QixxQkFBcUIsRUFDckIsc0JBQXNCLEdBRXZCLE1BQU0sNkJBQTZCLENBQUM7QUFJckMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBSTlDOztHQUVHO0FBQ0gsTUFBTSxDQUFOLElBQVksV0FVWDtBQVZELFdBQVksV0FBVztJQUNyQixzQkFBTyxDQUFBO0lBQ1Asc0JBQU8sQ0FBQTtJQUNQLHNCQUFPLENBQUE7SUFDUCx3QkFBUyxDQUFBO0lBQ1Qsc0JBQU8sQ0FBQTtJQUNQLHNCQUFPLENBQUE7SUFDUCxzQkFBTyxDQUFBO0lBQ1Asc0JBQU8sQ0FBQTtJQUNQLHNCQUFPLENBQUEsQ0FBSSxvRUFBb0U7QUFDakYsQ0FBQyxFQVZXLFdBQVcsS0FBWCxXQUFXLFFBVXRCO0FBY0Q7Ozs7R0FJRztBQUNILE1BQU0sa0JBQWtCLEdBQUc7SUFDekIsU0FBUyxFQUNQLG1UQUFtVDtJQUNyVCxTQUFTLEVBQ1AsbUtBQW1LO0lBQ3JLLFNBQVMsRUFDUCx1ZkFBdWY7SUFDemYsU0FBUyxFQUNQLHlOQUF5TjtJQUMzTixTQUFTLEVBQ1Asb0tBQW9LO0lBQ3RLLFVBQVUsRUFDUixzVEFBc1Q7SUFDeFQsVUFBVSxFQUNSLGtYQUFrWDtJQUNwWCxVQUFVLEVBQ1IsMEpBQTBKO0lBQzVKLFVBQVUsRUFDUixrWEFBa1g7SUFDcFgsVUFBVSxFQUNSLDZJQUE2STtJQUMvSSxVQUFVLEVBQ1Isc1FBQXNRO0lBQ3hRLFVBQVUsRUFDUix3SUFBd0k7Q0FDbEksQ0FBQztBQWNYOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBQ0gsTUFBTSxPQUFPLHNC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
|
|
244
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmF0LWNhdGVnb3JpZXMudmFsaWRhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvZm9ybWF0cy92YWxpZGF0aW9uL3ZhdC1jYXRlZ29yaWVzLnZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wscUJBQXFCLEVBQ3JCLHNCQUFzQixFQUN0QixxQkFBcUIsRUFDckIsc0JBQXNCLEdBRXZCLE1BQU0sNkJBQTZCLENBQUM7QUFJckMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzlDLE9BQU8sRUFDTCx5QkFBeUIsRUFDekIscUJBQXFCLEdBR3RCLE1BQU0sMEJBQTBCLENBQUM7QUFHbEM7O0dBRUc7QUFDSCxNQUFNLENBQU4sSUFBWSxXQVVYO0FBVkQsV0FBWSxXQUFXO0lBQ3JCLHNCQUFPLENBQUE7SUFDUCxzQkFBTyxDQUFBO0lBQ1Asc0JBQU8sQ0FBQTtJQUNQLHdCQUFTLENBQUE7SUFDVCxzQkFBTyxDQUFBO0lBQ1Asc0JBQU8sQ0FBQTtJQUNQLHNCQUFPLENBQUE7SUFDUCxzQkFBTyxDQUFBO0lBQ1Asc0JBQU8sQ0FBQSxDQUFJLG9FQUFvRTtBQUNqRixDQUFDLEVBVlcsV0FBVyxLQUFYLFdBQVcsUUFVdEI7QUFjRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLGtCQUFrQixHQUFHO0lBQ3pCLFNBQVMsRUFDUCxtVEFBbVQ7SUFDclQsU0FBUyxFQUNQLG1LQUFtSztJQUNySyxTQUFTLEVBQ1AsdWZBQXVmO0lBQ3pmLFNBQVMsRUFDUCx5TkFBeU47SUFDM04sU0FBUyxFQUNQLG9LQUFvSztJQUN0SyxTQUFTLEVBQ1AsMFFBQTBRO0lBQzVRLFNBQVMsRUFDUCxzSkFBc0o7SUFDeEosU0FBUyxFQUNQLHFXQUFxVztJQUN2VyxTQUFTLEVBQ1Asd0lBQXdJO0lBQzFJLFNBQVMsRUFDUCxpS0FBaUs7SUFDbkssU0FBUyxFQUNQLHVSQUF1UjtJQUN6UixTQUFTLEVBQ1As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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fin.cx/einvoice",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A TypeScript module for creating, manipulating, and embedding XML data within PDF files specifically tailored for electronic invoice (einvoice) packages.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
"@git.zone/tsbuild": "^5.0.0",
|
|
17
17
|
"@git.zone/tsbundle": "^2.15.0",
|
|
18
18
|
"@git.zone/tsrun": "^3.0.0",
|
|
19
|
-
"@git.zone/tstest": "^6.
|
|
19
|
+
"@git.zone/tstest": "^6.3.1",
|
|
20
20
|
"@push.rocks/smartfile": "^13.1.3",
|
|
21
|
-
"@types/node": "^26.6.
|
|
21
|
+
"@types/node": "^26.6.2"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@push.rocks/smartxml": "^2.1.0",
|
|
25
|
-
"@tsclass/tsclass": "^9.
|
|
25
|
+
"@tsclass/tsclass": "^9.11.0",
|
|
26
26
|
"@xmldom/xmldom": "^0.9.10",
|
|
27
27
|
"pako": "^2.1.0",
|
|
28
28
|
"pdf-lib": "^1.17.1",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
],
|
|
68
68
|
"scripts": {
|
|
69
69
|
"test": "pnpm run test:unit",
|
|
70
|
-
"test:unit": "tstest test/test.cii-xrechnung.node.ts --verbose --logfile --timeout 60 && tstest test/test.einvoice.ts --verbose --logfile --timeout 60 && tstest test/test.decimal.ts --verbose --logfile --timeout 60 && tstest test/test.decimal-currency-calculator.ts --verbose --logfile --timeout 60 && tstest test/test.currency-utils.ts --verbose --logfile --timeout 60 && tstest test/test.en16931-validators.ts --verbose --logfile --timeout 60 && tstest test/test.schematron-validator.ts --verbose --logfile --timeout 60 && tstest test/test.xrechnung-creditnote.node.ts --verbose --logfile --timeout 60 && tstest test/test.accountingdoc-types.node.ts --verbose --logfile --timeout 60 && tstest test/test.corrected-invoice.node.ts --verbose --logfile --timeout 60 && tstest test/test.xrechnung-3-due-date.node.ts --verbose --logfile --timeout 60 && tstest test/test.calendar-dates.node.ts --verbose --logfile --timeout 60 && tstest test/test.document-totals.node.ts --verbose --logfile --timeout 60 && tstest test/test.reverse-charge.node.ts --verbose --logfile --timeout 60 && tstest test/test.cii-schema-order.node.ts --verbose --logfile --timeout 60 && tstest test/test.tax-number.node.ts --verbose --logfile --timeout 60 && tstest test/test.country-codes.node.ts --verbose --logfile --timeout 60 && tstest test/test.paid-amount.node.ts --verbose --logfile --timeout 60 && tstest test/test.en16931-unitcodes.node.ts --verbose --logfile --timeout 60 && tstest test/test.en16931-lineunit.node.ts --verbose --logfile --timeout 60 && tstest test/test.cii-profile.node.ts --verbose --logfile --timeout 60 && tstest test/test.validator-rule-ids.node.ts --verbose --logfile --timeout 60 && tstest test/test.cii-period-address.node.ts --verbose --logfile --timeout 60 && tstest test/test.amount-due.node.ts --verbose --logfile --timeout 60 && tstest test/test.ubl-zoned-dates.node.ts --verbose --logfile --timeout 60 && tstest test/test.vat-categories.node.ts --verbose --logfile --timeout 60 && tstest test/test.xrechnung-buyer-reference.node.ts --verbose --logfile --timeout 60 && tstest test/test.specification-identifier.node.ts --verbose --logfile --timeout 60 && tstest test/test.seller-identifier.node.ts --verbose --logfile --timeout 60 && tstest test/test.stated-values.node.ts --verbose --logfile --timeout 60 && tstest test/test.vat-category-limits.node.ts --verbose --logfile --timeout 60 && tstest test/test.received-conformance.node.ts --verbose --logfile --timeout 60",
|
|
70
|
+
"test:unit": "tstest test/test.cii-xrechnung.node.ts --verbose --logfile --timeout 60 && tstest test/test.einvoice.ts --verbose --logfile --timeout 60 && tstest test/test.decimal.ts --verbose --logfile --timeout 60 && tstest test/test.decimal-currency-calculator.ts --verbose --logfile --timeout 60 && tstest test/test.currency-utils.ts --verbose --logfile --timeout 60 && tstest test/test.en16931-validators.ts --verbose --logfile --timeout 60 && tstest test/test.schematron-validator.ts --verbose --logfile --timeout 60 && tstest test/test.xrechnung-creditnote.node.ts --verbose --logfile --timeout 60 && tstest test/test.accountingdoc-types.node.ts --verbose --logfile --timeout 60 && tstest test/test.corrected-invoice.node.ts --verbose --logfile --timeout 60 && tstest test/test.xrechnung-3-due-date.node.ts --verbose --logfile --timeout 60 && tstest test/test.calendar-dates.node.ts --verbose --logfile --timeout 60 && tstest test/test.document-totals.node.ts --verbose --logfile --timeout 60 && tstest test/test.reverse-charge.node.ts --verbose --logfile --timeout 60 && tstest test/test.cii-schema-order.node.ts --verbose --logfile --timeout 60 && tstest test/test.tax-number.node.ts --verbose --logfile --timeout 60 && tstest test/test.country-codes.node.ts --verbose --logfile --timeout 60 && tstest test/test.paid-amount.node.ts --verbose --logfile --timeout 60 && tstest test/test.en16931-unitcodes.node.ts --verbose --logfile --timeout 60 && tstest test/test.en16931-lineunit.node.ts --verbose --logfile --timeout 60 && tstest test/test.cii-profile.node.ts --verbose --logfile --timeout 60 && tstest test/test.validator-rule-ids.node.ts --verbose --logfile --timeout 60 && tstest test/test.cii-period-address.node.ts --verbose --logfile --timeout 60 && tstest test/test.amount-due.node.ts --verbose --logfile --timeout 60 && tstest test/test.ubl-zoned-dates.node.ts --verbose --logfile --timeout 60 && tstest test/test.vat-categories.node.ts --verbose --logfile --timeout 60 && tstest test/test.xrechnung-buyer-reference.node.ts --verbose --logfile --timeout 60 && tstest test/test.specification-identifier.node.ts --verbose --logfile --timeout 60 && tstest test/test.seller-identifier.node.ts --verbose --logfile --timeout 60 && tstest test/test.stated-values.node.ts --verbose --logfile --timeout 60 && tstest test/test.vat-category-limits.node.ts --verbose --logfile --timeout 60 && tstest test/test.received-conformance.node.ts --verbose --logfile --timeout 60 && tstest test/test.cii-stated-dates.node.ts --verbose --logfile --timeout 60 && tstest test/test.vat-category-items.node.ts --verbose --logfile --timeout 60",
|
|
71
71
|
"test:format": "tstest test/test.format-detection.ts --verbose --logfile --timeout 60",
|
|
72
72
|
"test:corpus": "tstest test/suite/einvoice_corpus-validation/ --verbose --logfile --timeout 60",
|
|
73
73
|
"test:performance": "NODE_OPTIONS=--expose-gc tstest test/suite/einvoice_performance/ --verbose --logfile --timeout 60",
|
package/readme.md
CHANGED
|
@@ -400,25 +400,61 @@ Satz 3 UStG) is for the issuing application to enforce: the parties' countries
|
|
|
400
400
|
do not tell it, since a domestic § 13b supply to a buyer based in another
|
|
401
401
|
member state is taxed in Germany and may state a tax number.
|
|
402
402
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
BR-
|
|
403
|
+
An item can also state reverse charge on its own (`vatCategory: 'AE'`), so one
|
|
404
|
+
document can carry reverse charge items beside taxed ones; the same rules apply
|
|
405
|
+
to it. A decoded document states `reverseCharge: true` when every line is `AE`,
|
|
406
|
+
and each item carries the category its line states.
|
|
407
|
+
|
|
408
|
+
## VAT categories
|
|
409
|
+
|
|
410
|
+
Every item has a VAT category (EN 16931 BT-151, `TAccountingDocItem.vatCategory`
|
|
411
|
+
of `@tsclass/tsclass`): the one it states, else reverse charge (`AE`) when the
|
|
412
|
+
document states `reverseCharge`, standard rated (`S`) otherwise. The encoders
|
|
413
|
+
write one VAT breakdown (BG-23) per category and rate, and the decoders give
|
|
414
|
+
every item the category its line states and the exemption reason of its
|
|
415
|
+
breakdown.
|
|
416
|
+
|
|
417
|
+
| Category | Meaning | Rate | Exemption reason (BT-120, BT-121) |
|
|
418
|
+
| --- | --- | --- | --- |
|
|
419
|
+
| `S` | standard rated | greater than 0 (BR-S-05) | none (BR-S-10) |
|
|
420
|
+
| `Z` | zero rated, e.g. photovoltaic systems (§ 12 Abs. 3 UStG) | 0 (BR-Z-05) | none (BR-Z-10) |
|
|
421
|
+
| `E` | exempt, e.g. § 4 UStG or a small business (§ 19 Abs. 1 UStG) | 0 (BR-E-05) | the item's reason or VATEX code, required (BR-E-10) |
|
|
422
|
+
| `AE` | reverse charge (§ 13b UStG) | 0 (BR-AE-05) | the item's, else `VATEX-EU-AE` and the § 14a Abs. 5 UStG wording |
|
|
423
|
+
| `K` | intra-community supply (§ 4 Nr. 1 Buchst. b, § 6a UStG) | 0 (BR-IC-05) | the item's, else `VATEX-EU-IC` |
|
|
424
|
+
| `G` | export outside the EU (§ 4 Nr. 1 Buchst. a, § 6 UStG) | 0 (BR-G-05) | the item's, else `VATEX-EU-G` |
|
|
425
|
+
| `O` | not subject to VAT | none written; the item states 0 (BR-O-05) | the item's, else `VATEX-EU-O` |
|
|
426
|
+
| `L` | IGIC (Canary Islands) | 0 or more (BR-AF-05); more than 0 in CII | none (BR-AF-10) |
|
|
427
|
+
| `M` | IPSI (Ceuta and Melilla) | 0 or more (BR-AG-05) | none (BR-AG-10) |
|
|
428
|
+
|
|
429
|
+
The tax of a breakdown is its taxable amount × rate for `S`, `L` and `M`, and 0
|
|
430
|
+
for every other category. An item states its exemption in
|
|
431
|
+
`vatExemptionReason` (BT-120) and `vatExemptionReasonCode` (BT-121, a code of
|
|
432
|
+
the CEF VATEX list, BR-CL-22); the items of one breakdown state the same one,
|
|
433
|
+
as a breakdown states one.
|
|
434
|
+
|
|
435
|
+
Export refuses a document that breaks a rule of its categories with an
|
|
436
|
+
`EInvoiceFormatError` naming the rule, and `validate()` reports it at the
|
|
437
|
+
business level for a document built in code: the rate and the exemption reason
|
|
438
|
+
above; for `Z`, `E`, `L` and `M` the seller VAT identifier or tax number
|
|
439
|
+
(BR-Z-02, BR-E-02, BR-AF-02, BR-AG-02); for `K` the seller and the buyer VAT
|
|
440
|
+
identifier (BR-IC-02), the delivery date or invoicing period (BR-IC-11) and the
|
|
441
|
+
deliver to country (BR-IC-12); for `G` the seller VAT identifier (BR-G-02); for
|
|
442
|
+
`O` neither VAT identifier (BR-O-02) and no item of another category (BR-O-11);
|
|
443
|
+
items of one breakdown with different exemption reasons
|
|
444
|
+
(`EINVOICE-VAT-EXEMPTION-DIFFERS`). The rules would also accept a seller tax
|
|
445
|
+
representative (BT-63), which the envelope cannot state.
|
|
446
|
+
|
|
447
|
+
The deliver to address (BG-15) is `metadata.deliveryAddress`; every format
|
|
448
|
+
writes it when it states a country (`countryCode`, BT-80) and reads it back.
|
|
449
|
+
An item at the rate 0 outside reverse charge that states no category is
|
|
450
|
+
standard rated and refused as BR-S-05: state its category.
|
|
451
|
+
|
|
452
|
+
The tests check documents of every category with the official CEN EN 16931
|
|
453
|
+
rules on all four exports and with the KoSIT XRechnung rules on the XRechnung
|
|
454
|
+
export only.
|
|
455
|
+
|
|
456
|
+
A ZUGFeRD 1.0 document states no values einvoice reads as stated
|
|
457
|
+
(`statedValues`), so its items carry no category; it is read as before.
|
|
422
458
|
|
|
423
459
|
## Paid amount and advance payments
|
|
424
460
|
|
|
@@ -509,7 +545,12 @@ the UTC midnight of that day, `Date.UTC(2026, 8, 20)`.
|
|
|
509
545
|
- The decoders return that timestamp. A UBL date may carry a time zone
|
|
510
546
|
(`2026-09-20+02:00`, `2026-09-20Z`); the zone does not move the day, so the
|
|
511
547
|
decoders return the UTC midnight of the stated day, and every format writes
|
|
512
|
-
that day.
|
|
548
|
+
that day. A CII date stated with a time of day, in format 203
|
|
549
|
+
(`202609202330`) or 204 (`20260920233000`), or without a format code as an
|
|
550
|
+
ISO 8601 date or date and time (`2026-09-20T00:30:00+02:00`), is read the
|
|
551
|
+
same way: the day it states, whatever the time of day and the zone. A CII
|
|
552
|
+
date in another form, or in a format that names no day, is refused with an
|
|
553
|
+
`EInvoiceParsingError`; no day is guessed.
|
|
513
554
|
- The encoders write the day of that timestamp in UTC and count the payment
|
|
514
555
|
term in UTC days, so what they write does not depend on the time zone of the
|
|
515
556
|
machine that writes it.
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@fin.cx/einvoice',
|
|
6
|
-
version: '10.
|
|
6
|
+
version: '10.1.0',
|
|
7
7
|
description: 'A TypeScript module for creating, manipulating, and embedding XML data within PDF files specifically tailored for electronic invoice (einvoice) packages.'
|
|
8
8
|
}
|
package/ts/einvoice.ts
CHANGED
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
// Import enhanced validators
|
|
47
47
|
import { EN16931Validator } from './formats/validation/en16931.validator.js';
|
|
48
48
|
import { EN16931BusinessRulesValidator } from './formats/validation/en16931.business-rules.validator.js';
|
|
49
|
-
import {
|
|
49
|
+
import { findVatCategoryViolations, type TVatCategoryCode } from './formats/utils/vat.category.js';
|
|
50
50
|
import { BR_CO_26_TEXT, envelopeSellerMeetsBrCo26 } from './formats/utils/seller.identifier.js';
|
|
51
51
|
import { findEnvelopeDifferences } from './formats/utils/stated.values.js';
|
|
52
52
|
import type { IEInvoiceStatedValues } from './interfaces/stated.values.js';
|
|
@@ -247,7 +247,7 @@ export class EInvoice implements TAccountingDocEnvelope<TAccountingDocType, {}>
|
|
|
247
247
|
return computeDocumentTotals(this).grandTotal.toNumber();
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
-
public get taxBreakdown(): Array<{ taxPercent: number; netAmount: number; taxAmount: number }> {
|
|
250
|
+
public get taxBreakdown(): Array<{ category: TVatCategoryCode; taxPercent: number; netAmount: number; taxAmount: number }> {
|
|
251
251
|
return this.calculateTaxBreakdown();
|
|
252
252
|
}
|
|
253
253
|
|
|
@@ -658,17 +658,10 @@ export class EInvoice implements TAccountingDocEnvelope<TAccountingDocType, {}>
|
|
|
658
658
|
);
|
|
659
659
|
|
|
660
660
|
if (level === ValidationLevel.BUSINESS) {
|
|
661
|
-
//
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
errors.push({
|
|
666
|
-
code: 'BR-S-05',
|
|
667
|
-
message: standardRatedLineWithoutRateMessage({ index, vatPercentage: item.vatPercentage }),
|
|
668
|
-
location: `items[${index}].vatPercentage`,
|
|
669
|
-
});
|
|
670
|
-
}
|
|
671
|
-
});
|
|
661
|
+
// the rules of the items' VAT categories, as export refuses a document that breaks one: the
|
|
662
|
+
// rate of each category (BR-S-05, BR-Z-05, ...), the exemption reasons and the identifiers
|
|
663
|
+
for (const violation of findVatCategoryViolations({ ...invoice, metadata: this.metadata })) {
|
|
664
|
+
errors.push({ code: violation.ruleId, message: violation.message, location: violation.field });
|
|
672
665
|
}
|
|
673
666
|
// BR-CO-26: the seller states a seller, legal registration or VAT identifier; a tax number alone does not identify it
|
|
674
667
|
if (!envelopeSellerMeetsBrCo26(invoice)) {
|
|
@@ -879,9 +872,10 @@ export class EInvoice implements TAccountingDocEnvelope<TAccountingDocType, {}>
|
|
|
879
872
|
/**
|
|
880
873
|
* Calculates tax breakdown by rate
|
|
881
874
|
*/
|
|
882
|
-
private calculateTaxBreakdown(): Array<{ taxPercent: number; netAmount: number; taxAmount: number }> {
|
|
875
|
+
private calculateTaxBreakdown(): Array<{ category: TVatCategoryCode; taxPercent: number; netAmount: number; taxAmount: number }> {
|
|
883
876
|
// the VAT breakdown (BG-23) the encoders write
|
|
884
877
|
return computeDocumentTotals(this).vatGroups.map((group) => ({
|
|
878
|
+
category: group.category,
|
|
885
879
|
taxPercent: group.rate,
|
|
886
880
|
netAmount: group.taxableAmount.toNumber(),
|
|
887
881
|
taxAmount: group.taxAmount.toNumber(),
|
|
@@ -2,7 +2,7 @@ import type { TAccountingDoc } from '../../interfaces/common.js';
|
|
|
2
2
|
import { ValidationLevel } from '../../interfaces/common.js';
|
|
3
3
|
import type { ValidationResult } from '../../interfaces/common.js';
|
|
4
4
|
import { EInvoiceParsingError } from '../../errors.js';
|
|
5
|
-
import { parseXsdDateDay } from '../utils/date.value.js';
|
|
5
|
+
import { parseCiiDateDay, parseIsoDateTimeDay, parseXsdDateDay } from '../utils/date.value.js';
|
|
6
6
|
import type { IEInvoiceStatedValues } from '../../interfaces/stated.values.js';
|
|
7
7
|
import { statedValueProblemMessage, type IStatedValuesRead } from '../utils/stated.values.js';
|
|
8
8
|
|
|
@@ -102,7 +102,15 @@ export abstract class BaseDecoder {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
|
-
* Parses a required CII date without inventing a fallback value
|
|
105
|
+
* Parses a required CII date without inventing a fallback value: the
|
|
106
|
+
* calendar day it states, as the UTC midnight of that day. Format 102
|
|
107
|
+
* (`YYYYMMDD`) is the one EN 16931 asks for; a date stated with a time of
|
|
108
|
+
* day in format 203 (`YYYYMMDDhhmm`) or 204 (`YYYYMMDDhhmmss`), or without a
|
|
109
|
+
* format code as an ISO 8601 date or date and time (`parseIsoDateTimeDay`),
|
|
110
|
+
* is read as the day it states, whatever the time of day and the zone.
|
|
111
|
+
* Format 610 (`YYYYMM`) is read as the 1st of the month. Any other value is
|
|
112
|
+
* refused with an `EInvoiceParsingError`: no day is guessed, and none is read
|
|
113
|
+
* in the zone of the machine.
|
|
106
114
|
*/
|
|
107
115
|
protected parseRequiredCIIDate(dateStr: string, format?: string): number {
|
|
108
116
|
const value = dateStr.trim();
|
|
@@ -111,22 +119,17 @@ export abstract class BaseDecoder {
|
|
|
111
119
|
format: 'cii',
|
|
112
120
|
});
|
|
113
121
|
}
|
|
122
|
+
const formatCode = (format ?? '').trim();
|
|
114
123
|
|
|
115
|
-
if (
|
|
116
|
-
const
|
|
117
|
-
if (
|
|
118
|
-
throw this.createInvalidDateError(value,
|
|
124
|
+
if (formatCode === '102' || formatCode === '203' || formatCode === '204') {
|
|
125
|
+
const day = parseCiiDateDay(value, formatCode);
|
|
126
|
+
if (day === undefined) {
|
|
127
|
+
throw this.createInvalidDateError(value, `CII format ${formatCode}`);
|
|
119
128
|
}
|
|
120
|
-
return
|
|
121
|
-
Number(match[1]),
|
|
122
|
-
Number(match[2]),
|
|
123
|
-
Number(match[3]),
|
|
124
|
-
value,
|
|
125
|
-
'CII format 102',
|
|
126
|
-
);
|
|
129
|
+
return day;
|
|
127
130
|
}
|
|
128
131
|
|
|
129
|
-
if (
|
|
132
|
+
if (formatCode === '610') {
|
|
130
133
|
const match = /^(\d{4})(\d{2})$/.exec(value);
|
|
131
134
|
if (!match) {
|
|
132
135
|
throw this.createInvalidDateError(value, 'CII format 610');
|
|
@@ -140,11 +143,15 @@ export abstract class BaseDecoder {
|
|
|
140
143
|
);
|
|
141
144
|
}
|
|
142
145
|
|
|
143
|
-
|
|
144
|
-
|
|
146
|
+
if (formatCode) {
|
|
147
|
+
throw this.createInvalidDateError(value, `CII format ${formatCode}`);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const day = parseIsoDateTimeDay(value);
|
|
151
|
+
if (day === undefined) {
|
|
145
152
|
throw this.createInvalidDateError(value, 'CII');
|
|
146
153
|
}
|
|
147
|
-
return
|
|
154
|
+
return day;
|
|
148
155
|
}
|
|
149
156
|
|
|
150
157
|
/**
|