@fin.cx/einvoice 10.0.1 → 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/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/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 +3 -3
- package/readme.md +55 -19
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/einvoice.ts +8 -14
- 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/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,28 +1,111 @@
|
|
|
1
1
|
import { EInvoiceFormatError } from '../../errors.js';
|
|
2
|
+
/** Every VAT category code EN 16931 allows, in the order of `TVatCategoryCode` */
|
|
3
|
+
export const VAT_CATEGORY_CODES = ['S', 'Z', 'E', 'AE', 'K', 'G', 'O', 'L', 'M'];
|
|
2
4
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
+
* Whether a value is a VAT category code EN 16931 allows
|
|
6
|
+
* @param value The value
|
|
7
|
+
*/
|
|
8
|
+
export const isVatCategoryCode = (value) => typeof value === 'string' && VAT_CATEGORY_CODES.includes(value);
|
|
9
|
+
/**
|
|
10
|
+
* The categories whose VAT breakdown states an exemption reason, as a code
|
|
11
|
+
* (BT-121) or a text (BT-120): exempt (BR-E-10), reverse charge (BR-AE-10),
|
|
12
|
+
* intra-community supply (BR-IC-10), export (BR-G-10) and not subject to VAT
|
|
13
|
+
* (BR-O-10). The others state none (BR-S-10, BR-Z-10, BR-AF-10, BR-AG-10).
|
|
14
|
+
*/
|
|
15
|
+
export const VAT_CATEGORIES_WITH_EXEMPTION = ['E', 'AE', 'K', 'G', 'O'];
|
|
16
|
+
/**
|
|
17
|
+
* The CEF VATEX code list, as the CEN/TC 434 EN 16931 validation artefacts
|
|
18
|
+
* 1.3.16 check a VAT exemption reason code (BT-121) against it (BR-CL-22,
|
|
19
|
+
* compared in upper case)
|
|
20
|
+
*/
|
|
21
|
+
export const VATEX_CODES = new Set(('VATEX-EU-79-C VATEX-EU-132 VATEX-EU-132-1A VATEX-EU-132-1B VATEX-EU-132-1C VATEX-EU-132-1D VATEX-EU-132-1E ' +
|
|
22
|
+
'VATEX-EU-132-1F VATEX-EU-132-1G VATEX-EU-132-1H VATEX-EU-132-1I VATEX-EU-132-1J VATEX-EU-132-1K VATEX-EU-132-1L ' +
|
|
23
|
+
'VATEX-EU-132-1M VATEX-EU-132-1N VATEX-EU-132-1O VATEX-EU-132-1P VATEX-EU-132-1Q VATEX-EU-135-1 VATEX-EU-143 ' +
|
|
24
|
+
'VATEX-EU-143-1A VATEX-EU-143-1B VATEX-EU-143-1C VATEX-EU-143-1D VATEX-EU-143-1E VATEX-EU-143-1F VATEX-EU-143-1FA ' +
|
|
25
|
+
'VATEX-EU-143-1G VATEX-EU-143-1H VATEX-EU-143-1I VATEX-EU-143-1J VATEX-EU-143-1K VATEX-EU-143-1L VATEX-EU-144 ' +
|
|
26
|
+
'VATEX-EU-146-1E VATEX-EU-159 VATEX-EU-309 VATEX-EU-148 VATEX-EU-148-A VATEX-EU-148-B VATEX-EU-148-C VATEX-EU-148-D ' +
|
|
27
|
+
'VATEX-EU-148-E VATEX-EU-148-F VATEX-EU-148-G VATEX-EU-151 VATEX-EU-151-1A VATEX-EU-151-1AA VATEX-EU-151-1B ' +
|
|
28
|
+
'VATEX-EU-151-1C VATEX-EU-151-1D VATEX-EU-151-1E VATEX-EU-G VATEX-EU-O VATEX-EU-IC VATEX-EU-AE VATEX-EU-D VATEX-EU-F ' +
|
|
29
|
+
'VATEX-EU-I VATEX-EU-J VATEX-FR-FRANCHISE VATEX-FR-CNWVAT VATEX-EU-153 VATEX-FR-CGI261-1 VATEX-FR-CGI261-2 ' +
|
|
30
|
+
'VATEX-FR-CGI261-3 VATEX-FR-CGI261-4 VATEX-FR-CGI261-5 VATEX-FR-CGI261-7 VATEX-FR-CGI261-8 VATEX-FR-CGI261A ' +
|
|
31
|
+
'VATEX-FR-CGI261B VATEX-FR-CGI261C-1 VATEX-FR-CGI261C-2 VATEX-FR-CGI261C-3 VATEX-FR-CGI261D-1 VATEX-FR-CGI261D-1BIS ' +
|
|
32
|
+
'VATEX-FR-CGI261D-2 VATEX-FR-CGI261D-3 VATEX-FR-CGI261D-4 VATEX-FR-CGI261E-1 VATEX-FR-CGI261E-2 VATEX-FR-CGI277A ' +
|
|
33
|
+
'VATEX-FR-CGI275 VATEX-FR-298SEXDECIESA VATEX-FR-CGI295 VATEX-FR-AE').split(' '));
|
|
34
|
+
/**
|
|
35
|
+
* Whether a VAT exemption reason code is on the CEF VATEX code list (BR-CL-22)
|
|
36
|
+
* @param code The code
|
|
37
|
+
*/
|
|
38
|
+
export const isVatexCode = (code) => VATEX_CODES.has(code.trim().toUpperCase());
|
|
39
|
+
/**
|
|
40
|
+
* The VAT category of an item: the one it states (`vatCategory`, BT-151), else
|
|
41
|
+
* reverse charge (AE) when the document states `reverseCharge`, standard rated
|
|
42
|
+
* (S) otherwise.
|
|
5
43
|
* @param accountingDoc The document
|
|
44
|
+
* @param item The item
|
|
45
|
+
*/
|
|
46
|
+
export const getItemVatCategory = (accountingDoc, item) => item.vatCategory ?? (accountingDoc.reverseCharge ? 'AE' : 'S');
|
|
47
|
+
/**
|
|
48
|
+
* The exemption reason an item states: its VATEX code (BT-121) and its text
|
|
49
|
+
* (BT-120), each trimmed; undefined when it states neither
|
|
50
|
+
* @param item The item
|
|
6
51
|
*/
|
|
7
|
-
export const
|
|
52
|
+
export const getItemVatExemption = (item) => {
|
|
53
|
+
const code = item.vatExemptionReasonCode?.trim();
|
|
54
|
+
const reason = item.vatExemptionReason?.trim();
|
|
55
|
+
if (!code && !reason) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
return { ...(code ? { code } : {}), ...(reason ? { reason } : {}) };
|
|
59
|
+
};
|
|
8
60
|
/**
|
|
9
|
-
* The exemption reason a
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
61
|
+
* The exemption reason a VAT breakdown of a category states when none of its
|
|
62
|
+
* items states one.
|
|
63
|
+
* - Reverse charge (AE): the code `VATEX-EU-AE` and the wording the law
|
|
64
|
+
* prescribes, "Steuerschuldnerschaft des Leistungsempfängers" (§ 14a Abs. 1
|
|
65
|
+
* and 5 UStG). A document in another language may use the wording of
|
|
66
|
+
* Article 226 Nr. 11a of the VAT Directive in that language, "Reverse charge"
|
|
67
|
+
* in English (Abschnitt 14a.1 Abs. 6 Satz 2 UStAE).
|
|
68
|
+
* - Intra-community supply (K), export outside the EU (G) and not subject to
|
|
69
|
+
* VAT (O): the VATEX code that means the category, `VATEX-EU-IC`,
|
|
70
|
+
* `VATEX-EU-G` and `VATEX-EU-O`, which BR-IC-10, BR-G-10 and BR-O-10 accept.
|
|
71
|
+
* - Exempt (E): none. The reason depends on the exemption applied, which only
|
|
72
|
+
* the issuer knows; a document with an exempt item that states none is
|
|
73
|
+
* refused (BR-E-10).
|
|
15
74
|
* @param category The VAT category
|
|
16
75
|
* @param language The document language
|
|
17
76
|
*/
|
|
18
|
-
export const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
77
|
+
export const getDefaultVatExemption = (category, language) => {
|
|
78
|
+
switch (category) {
|
|
79
|
+
case 'AE':
|
|
80
|
+
return {
|
|
81
|
+
code: 'VATEX-EU-AE',
|
|
82
|
+
reason: (language ?? '').toLowerCase().startsWith('de') ? 'Steuerschuldnerschaft des Leistungsempfängers' : 'Reverse charge',
|
|
83
|
+
};
|
|
84
|
+
case 'K':
|
|
85
|
+
return { code: 'VATEX-EU-IC' };
|
|
86
|
+
case 'G':
|
|
87
|
+
return { code: 'VATEX-EU-G' };
|
|
88
|
+
case 'O':
|
|
89
|
+
return { code: 'VATEX-EU-O' };
|
|
90
|
+
default:
|
|
91
|
+
return undefined;
|
|
24
92
|
}
|
|
25
|
-
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* The exemption reason a VAT breakdown states: the code and the text its items
|
|
96
|
+
* state, each completed by the category's default where they state none
|
|
97
|
+
* (`getDefaultVatExemption`); undefined when there is neither
|
|
98
|
+
* @param stated The exemption the items state
|
|
99
|
+
* @param categoryDefault The category's default
|
|
100
|
+
*/
|
|
101
|
+
export const mergeVatExemption = (stated, categoryDefault) => {
|
|
102
|
+
const code = stated?.code ?? categoryDefault?.code;
|
|
103
|
+
const reason = stated?.reason ?? categoryDefault?.reason;
|
|
104
|
+
if (!code && !reason) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
return { ...(code ? { code } : {}), ...(reason ? { reason } : {}) };
|
|
108
|
+
};
|
|
26
109
|
/**
|
|
27
110
|
* Whether a VAT rate is a number not greater than zero; a rate that is no
|
|
28
111
|
* number is refused as such (`findInvalidItemAmounts`), not as BR-S-05
|
|
@@ -30,70 +113,275 @@ export const getVatExemption = (category, language) => category === 'AE'
|
|
|
30
113
|
*/
|
|
31
114
|
export const isRateNotAboveZero = (rate) => typeof rate === 'number' && Number.isFinite(rate) && !(rate > 0);
|
|
32
115
|
/**
|
|
33
|
-
* The
|
|
34
|
-
* greater than zero
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
116
|
+
* The refusal or finding for a standard rated line whose VAT rate is not
|
|
117
|
+
* greater than zero (BR-S-05)
|
|
118
|
+
* @param line The line index and its rate
|
|
119
|
+
* @param statedCategory Whether the item states the category S itself
|
|
120
|
+
*/
|
|
121
|
+
export const standardRatedLineWithoutRateMessage = (line, statedCategory = false) => `In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "Standard rated" the Invoiced item VAT rate (BT-152) shall be greater than zero; items[${line.index}].vatPercentage is ${String(line.vatPercentage)}. ` +
|
|
122
|
+
(statedCategory
|
|
123
|
+
? `items[${line.index}].vatCategory states S`
|
|
124
|
+
: `An item outside reverse charge that states no category (items[${line.index}].vatCategory) is standard rated (S); an item that is zero rated, exempt, an intra-community supply, an export or not subject to VAT states its category, Z, E, K, G or O`);
|
|
125
|
+
/** The package's own check: the items of one VAT breakdown state different exemption reasons */
|
|
126
|
+
export const VAT_EXEMPTION_DIFFERS = 'EINVOICE-VAT-EXEMPTION-DIFFERS';
|
|
127
|
+
/**
|
|
128
|
+
* The item VAT rate each category allows: greater than zero for S (BR-S-05);
|
|
129
|
+
* 0 for Z, E, AE, K and G (BR-Z-05, BR-E-05, BR-AE-05, BR-IC-05, BR-G-05);
|
|
130
|
+
* 0 or greater for L and M (BR-AF-05, BR-AG-05). An item not subject to VAT
|
|
131
|
+
* (O) is written without a rate (BR-O-05), so it states 0.
|
|
40
132
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
133
|
+
const RATE_RULES = {
|
|
134
|
+
S: { ruleId: 'BR-S-05', allows: (rate) => rate > 0, expected: 'greater than zero' },
|
|
135
|
+
Z: { ruleId: 'BR-Z-05', allows: (rate) => rate === 0, expected: '0' },
|
|
136
|
+
E: { ruleId: 'BR-E-05', allows: (rate) => rate === 0, expected: '0' },
|
|
137
|
+
AE: { ruleId: 'BR-AE-05', allows: (rate) => rate === 0, expected: '0' },
|
|
138
|
+
K: { ruleId: 'BR-IC-05', allows: (rate) => rate === 0, expected: '0' },
|
|
139
|
+
G: { ruleId: 'BR-G-05', allows: (rate) => rate === 0, expected: '0' },
|
|
140
|
+
O: { ruleId: 'BR-O-05', allows: (rate) => rate === 0, expected: '0, as an item not subject to VAT is written without a VAT rate' },
|
|
141
|
+
L: { ruleId: 'BR-AF-05', allows: (rate) => rate >= 0, expected: '0 or greater' },
|
|
142
|
+
M: { ruleId: 'BR-AG-05', allows: (rate) => rate >= 0, expected: '0 or greater' },
|
|
44
143
|
};
|
|
45
144
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
145
|
+
* BR-AF-05 as the CII binding of the CEN/TC 434 artefacts 1.3.16 checks it:
|
|
146
|
+
* `ram:RateApplicablePercent > 0`, where the rule text and the UBL binding
|
|
147
|
+
* allow 0. A CII document with IGIC at 0 fails the official check, so it is
|
|
148
|
+
* not written.
|
|
48
149
|
*/
|
|
49
|
-
|
|
150
|
+
const CII_IGIC_RATE_RULE = {
|
|
151
|
+
ruleId: 'BR-AF-05',
|
|
152
|
+
allows: (rate) => rate > 0,
|
|
153
|
+
expected: 'greater than zero in CII, whose binding of the CEN artefacts checks BR-AF-05 so; UBL allows 0',
|
|
154
|
+
};
|
|
155
|
+
/** The rule a VAT breakdown of each category breaks by stating, or by lacking, an exemption reason */
|
|
156
|
+
const EXEMPTION_RULES = {
|
|
157
|
+
S: 'BR-S-10',
|
|
158
|
+
Z: 'BR-Z-10',
|
|
159
|
+
E: 'BR-E-10',
|
|
160
|
+
AE: 'BR-AE-10',
|
|
161
|
+
K: 'BR-IC-10',
|
|
162
|
+
G: 'BR-G-10',
|
|
163
|
+
O: 'BR-O-10',
|
|
164
|
+
L: 'BR-AF-10',
|
|
165
|
+
M: 'BR-AG-10',
|
|
166
|
+
};
|
|
50
167
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* -
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
168
|
+
* Every rule of EN 16931 on the VAT categories of a document's items that the
|
|
169
|
+
* envelope can break, in item order and then per document; an empty list when
|
|
170
|
+
* the document can be written. Amounts that are no number are not checked
|
|
171
|
+
* here (`findInvalidItemAmounts`).
|
|
172
|
+
* - The rate each category allows (BR-S-05, BR-Z-05, BR-E-05, BR-AE-05,
|
|
173
|
+
* BR-IC-05, BR-G-05, BR-O-05, BR-AF-05, BR-AG-05).
|
|
174
|
+
* - The exemption reason: stated for E, AE, K, G and O (a default for AE, K,
|
|
175
|
+
* G and O, `getDefaultVatExemption`), not stated for S, Z, L and M (the
|
|
176
|
+
* BR-x-10 rules); a code on the VATEX list (BR-CL-22); one reason per VAT
|
|
177
|
+
* breakdown, as a breakdown states one (`EINVOICE-VAT-EXEMPTION-DIFFERS`).
|
|
178
|
+
* - The parties' identifiers: for Z, E, L and M the seller VAT identifier
|
|
179
|
+
* (BT-31) or tax registration identifier (BT-32) (BR-Z-02, BR-E-02,
|
|
180
|
+
* BR-AF-02, BR-AG-02); for AE that and the buyer VAT identifier (BT-48) or
|
|
181
|
+
* legal registration identifier (BT-47) (BR-AE-02); for K the seller and the
|
|
182
|
+
* buyer VAT identifier (BR-IC-02); for G the seller VAT identifier
|
|
183
|
+
* (BR-G-02); for O neither VAT identifier (BR-O-02). The rules also accept
|
|
184
|
+
* a seller tax representative (BT-63), which the envelope cannot state.
|
|
185
|
+
* - An intra-community supply states the delivery date (BT-72) or the
|
|
186
|
+
* invoicing period (BG-14) (BR-IC-11) and the deliver to country (BT-80,
|
|
187
|
+
* `metadata.deliveryAddress.countryCode`) (BR-IC-12).
|
|
188
|
+
* - A document not subject to VAT has no item of another category (BR-O-11,
|
|
189
|
+
* BR-O-12).
|
|
190
|
+
* The rule for a standard rated item holds whether it states S or is S
|
|
191
|
+
* because it states no category, so an item at the rate 0 outside reverse
|
|
192
|
+
* charge that states no category breaks BR-S-05. Whether a document in
|
|
193
|
+
* reverse charge meets § 14a Abs. 1 UStG (both VAT identification numbers for
|
|
194
|
+
* a supply in another member state) cannot be told from the envelope, which
|
|
195
|
+
* has no place of supply; the issuing application enforces it.
|
|
71
196
|
* @param accountingDoc The document
|
|
72
|
-
* @param targetFormat The format being written
|
|
73
197
|
*/
|
|
74
|
-
export const
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
198
|
+
export const findVatCategoryViolations = (accountingDoc, syntax) => {
|
|
199
|
+
const violations = [];
|
|
200
|
+
const items = accountingDoc.items ?? [];
|
|
201
|
+
const categories = items.map((item) => getItemVatCategory(accountingDoc, item));
|
|
202
|
+
items.forEach((item, index) => {
|
|
203
|
+
const category = categories[index];
|
|
204
|
+
const rule = syntax === 'cii' && category === 'L' ? CII_IGIC_RATE_RULE : RATE_RULES[category];
|
|
205
|
+
if (typeof item.vatPercentage === 'number' && Number.isFinite(item.vatPercentage) && !rule.allows(item.vatPercentage)) {
|
|
206
|
+
violations.push({
|
|
207
|
+
ruleId: rule.ruleId,
|
|
208
|
+
field: `items[${index}].vatPercentage`,
|
|
209
|
+
message: category === 'S'
|
|
210
|
+
? standardRatedLineWithoutRateMessage({ index, vatPercentage: item.vatPercentage }, item.vatCategory === 'S')
|
|
211
|
+
: `an item of the VAT category ${category} has the VAT rate ${rule.expected}; items[${index}].vatPercentage is ${String(item.vatPercentage)}`,
|
|
212
|
+
});
|
|
82
213
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
214
|
+
const code = item.vatExemptionReasonCode?.trim();
|
|
215
|
+
if (code && !isVatexCode(code)) {
|
|
216
|
+
violations.push({
|
|
217
|
+
ruleId: 'BR-CL-22',
|
|
218
|
+
field: `items[${index}].vatExemptionReasonCode`,
|
|
219
|
+
message: `the VAT exemption reason code (BT-121) belongs to the CEF VATEX code list; items[${index}].vatExemptionReasonCode is ${code}`,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
// one VAT breakdown per category and rate, as the encoders write them (computeDocumentTotals)
|
|
224
|
+
const groups = new Map();
|
|
225
|
+
items.forEach((item, index) => {
|
|
226
|
+
const key = `${categories[index]}|${item.vatPercentage}`;
|
|
227
|
+
const group = groups.get(key) ?? { category: categories[index], indexes: [] };
|
|
228
|
+
group.indexes.push(index);
|
|
229
|
+
groups.set(key, group);
|
|
230
|
+
});
|
|
231
|
+
for (const { category, indexes } of groups.values()) {
|
|
232
|
+
const stated = indexes
|
|
233
|
+
.map((index) => ({ index, exemption: getItemVatExemption(items[index]) }))
|
|
234
|
+
.filter((entry) => entry.exemption !== undefined);
|
|
235
|
+
const distinct = new Set(stated.map((entry) => `${entry.exemption.code ?? ''}|${entry.exemption.reason ?? ''}`));
|
|
236
|
+
const fields = indexes.map((index) => `items[${index}]`).join(', ');
|
|
237
|
+
if (distinct.size > 1) {
|
|
238
|
+
violations.push({
|
|
239
|
+
ruleId: VAT_EXEMPTION_DIFFERS,
|
|
240
|
+
field: stated.map((entry) => `items[${entry.index}]`).join(', '),
|
|
241
|
+
message: `the items of one VAT breakdown (category ${category}) state one exemption reason, as the breakdown states one (BT-120, BT-121); ${stated
|
|
242
|
+
.map((entry) => `items[${entry.index}] states ${[entry.exemption.code, entry.exemption.reason].filter(Boolean).join(' ')}`)
|
|
243
|
+
.join(', ')}`,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
const withExemption = VAT_CATEGORIES_WITH_EXEMPTION.includes(category);
|
|
247
|
+
if (withExemption && stated.length === 0 && !getDefaultVatExemption(category, accountingDoc.language)) {
|
|
248
|
+
violations.push({
|
|
249
|
+
ruleId: EXEMPTION_RULES[category],
|
|
250
|
+
field: fields,
|
|
251
|
+
message: `a VAT breakdown of the category ${category} states a VAT exemption reason code (BT-121) or text (BT-120); ${fields} state neither vatExemptionReasonCode nor vatExemptionReason`,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
if (!withExemption && stated.length > 0) {
|
|
255
|
+
violations.push({
|
|
256
|
+
ruleId: EXEMPTION_RULES[category],
|
|
257
|
+
field: stated.map((entry) => `items[${entry.index}]`).join(', '),
|
|
258
|
+
message: `a VAT breakdown of the category ${category} states no VAT exemption reason (BT-120, BT-121); ${stated
|
|
259
|
+
.map((entry) => `items[${entry.index}]`)
|
|
260
|
+
.join(', ')} state one`,
|
|
261
|
+
});
|
|
88
262
|
}
|
|
89
263
|
}
|
|
264
|
+
const has = (category) => categories.includes(category);
|
|
90
265
|
const seller = accountingDoc.from?.registrationDetails;
|
|
91
|
-
if (!seller?.vatId && !seller?.taxNumber) {
|
|
92
|
-
refuse('BR-AE-02', 'a reverse charge document states the seller VAT identifier (BT-31) or tax registration identifier (BT-32), from.registrationDetails.vatId and .taxNumber are missing; the rule would also accept a tax representative (BT-63), which the envelope cannot state');
|
|
93
|
-
}
|
|
94
266
|
const buyer = accountingDoc.to?.registrationDetails;
|
|
95
|
-
|
|
96
|
-
|
|
267
|
+
const sellerVatId = !!seller?.vatId?.trim();
|
|
268
|
+
const sellerTaxNumber = !!seller?.taxNumber?.trim();
|
|
269
|
+
const buyerVatId = !!buyer?.vatId?.trim();
|
|
270
|
+
const sellerNeither = (rule, category) => violations.push({
|
|
271
|
+
ruleId: rule,
|
|
272
|
+
field: 'from.registrationDetails',
|
|
273
|
+
message: `a document with an item of the VAT category ${category} states the seller VAT identifier (BT-31) or tax registration identifier (BT-32); from.registrationDetails.vatId and .taxNumber are missing. The rule would also accept a tax representative (BT-63), which the envelope cannot state`,
|
|
274
|
+
});
|
|
275
|
+
for (const [category, rule] of [['Z', 'BR-Z-02'], ['E', 'BR-E-02'], ['L', 'BR-AF-02'], ['M', 'BR-AG-02'], ['AE', 'BR-AE-02']]) {
|
|
276
|
+
if (has(category) && !sellerVatId && !sellerTaxNumber) {
|
|
277
|
+
sellerNeither(rule, category);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
if (has('AE') && !buyerVatId && !buyer?.registrationId?.trim()) {
|
|
281
|
+
violations.push({
|
|
282
|
+
ruleId: 'BR-AE-02',
|
|
283
|
+
field: 'to.registrationDetails',
|
|
284
|
+
message: 'a reverse charge document states the buyer VAT identifier (BT-48) or legal registration identifier (BT-47), to.registrationDetails.vatId and .registrationId are missing',
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
if (has('K') && (!sellerVatId || !buyerVatId)) {
|
|
288
|
+
violations.push({
|
|
289
|
+
ruleId: 'BR-IC-02',
|
|
290
|
+
field: !sellerVatId ? 'from.registrationDetails.vatId' : 'to.registrationDetails.vatId',
|
|
291
|
+
message: 'a document with an intra-community supply (K) states the seller VAT identifier (BT-31) and the buyer VAT identifier (BT-48) (§ 14a Abs. 3 Satz 2 UStG); ' +
|
|
292
|
+
[!sellerVatId ? 'from.registrationDetails.vatId' : '', !buyerVatId ? 'to.registrationDetails.vatId' : ''].filter(Boolean).join(' and ') +
|
|
293
|
+
' missing. The rule would also accept a seller tax representative (BT-63), which the envelope cannot state',
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
if (has('K') && accountingDoc.deliveryDate === undefined && accountingDoc.periodOfPerformance === undefined) {
|
|
297
|
+
violations.push({
|
|
298
|
+
ruleId: 'BR-IC-11',
|
|
299
|
+
field: 'deliveryDate',
|
|
300
|
+
message: 'a document with an intra-community supply (K) states the actual delivery date (BT-72) or the invoicing period (BG-14); deliveryDate and periodOfPerformance are missing',
|
|
301
|
+
});
|
|
97
302
|
}
|
|
303
|
+
if (has('K') && !accountingDoc.metadata?.deliveryAddress?.countryCode?.trim()) {
|
|
304
|
+
violations.push({
|
|
305
|
+
ruleId: 'BR-IC-12',
|
|
306
|
+
field: 'metadata.deliveryAddress.countryCode',
|
|
307
|
+
message: 'a document with an intra-community supply (K) states the deliver to country code (BT-80); metadata.deliveryAddress.countryCode is missing',
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
if (has('G') && !sellerVatId) {
|
|
311
|
+
violations.push({
|
|
312
|
+
ruleId: 'BR-G-02',
|
|
313
|
+
field: 'from.registrationDetails.vatId',
|
|
314
|
+
message: 'a document with an export outside the EU (G) states the seller VAT identifier (BT-31); from.registrationDetails.vatId is missing. The rule would also accept a seller tax representative (BT-63), which the envelope cannot state',
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
if (has('O') && (sellerVatId || buyerVatId)) {
|
|
318
|
+
violations.push({
|
|
319
|
+
ruleId: 'BR-O-02',
|
|
320
|
+
field: sellerVatId ? 'from.registrationDetails.vatId' : 'to.registrationDetails.vatId',
|
|
321
|
+
message: `a document with an item not subject to VAT (O) states neither the seller VAT identifier (BT-31) nor the buyer VAT identifier (BT-48); ${[
|
|
322
|
+
sellerVatId ? 'from.registrationDetails.vatId' : '',
|
|
323
|
+
buyerVatId ? 'to.registrationDetails.vatId' : '',
|
|
324
|
+
]
|
|
325
|
+
.filter(Boolean)
|
|
326
|
+
.join(' and ')} stated`,
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
if (has('O') && categories.some((category) => category !== 'O')) {
|
|
330
|
+
violations.push({
|
|
331
|
+
ruleId: 'BR-O-11',
|
|
332
|
+
field: categories.map((category, index) => (category === 'O' ? '' : `items[${index}].vatCategory`)).filter(Boolean).join(', '),
|
|
333
|
+
message: `a document with an item not subject to VAT (O) has no item of another VAT category, as its VAT breakdown is the one of O; ${categories
|
|
334
|
+
.map((category, index) => (category === 'O' ? '' : `items[${index}] is ${category}`))
|
|
335
|
+
.filter(Boolean)
|
|
336
|
+
.join(', ')}`,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
return violations;
|
|
340
|
+
};
|
|
341
|
+
/**
|
|
342
|
+
* Refuses a document whose items cannot be written with a valid VAT category
|
|
343
|
+
* (`findVatCategoryViolations`), naming the first rule it breaks; no value is
|
|
344
|
+
* put in place of a missing one.
|
|
345
|
+
* @param accountingDoc The document
|
|
346
|
+
* @param targetFormat The syntax being written
|
|
347
|
+
*/
|
|
348
|
+
export const assertVatCategoryWritable = (accountingDoc, targetFormat) => {
|
|
349
|
+
const [violation] = findVatCategoryViolations(accountingDoc, targetFormat);
|
|
350
|
+
if (violation) {
|
|
351
|
+
throw new EInvoiceFormatError(`${violation.ruleId}: ${violation.message}`, {
|
|
352
|
+
targetFormat,
|
|
353
|
+
unsupportedFeatures: [violation.ruleId],
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
/**
|
|
358
|
+
* Gives the items of a decoded document the VAT category their lines state
|
|
359
|
+
* (BT-151) and the exemption reason (BT-120) and code (BT-121) of the VAT
|
|
360
|
+
* breakdown they belong to: the one of their category and rate, or of their
|
|
361
|
+
* category for an item not subject to VAT, which states no rate. A line that
|
|
362
|
+
* states no category, or a code EN 16931 does not allow, keeps none; the item
|
|
363
|
+
* is then read as AE or S (`getItemVatCategory`) and the code list rules
|
|
364
|
+
* report the code.
|
|
365
|
+
* @param items The decoded items, in line order
|
|
366
|
+
* @param statedValues What the document states; undefined for a ZUGFeRD 1.0 document
|
|
367
|
+
*/
|
|
368
|
+
export const applyStatedVatCategories = (items, statedValues) => {
|
|
369
|
+
if (!statedValues) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
items.forEach((item, index) => {
|
|
373
|
+
const category = statedValues.lines[index]?.vatCategoryCode;
|
|
374
|
+
if (!isVatCategoryCode(category)) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
item.vatCategory = category;
|
|
378
|
+
const breakdown = statedValues.vatBreakdown.find((group) => group.categoryCode === category && (category === 'O' || group.rate === item.vatPercentage));
|
|
379
|
+
if (breakdown?.exemptionReason) {
|
|
380
|
+
item.vatExemptionReason = breakdown.exemptionReason;
|
|
381
|
+
}
|
|
382
|
+
if (breakdown?.exemptionReasonCode) {
|
|
383
|
+
item.vatExemptionReasonCode = breakdown.exemptionReasonCode;
|
|
384
|
+
}
|
|
385
|
+
});
|
|
98
386
|
};
|
|
99
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmF0LmNhdGVnb3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvZm9ybWF0cy91dGlscy92YXQuY2F0ZWdvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFnQnREOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxhQUEwQyxFQUFvQixFQUFFLENBQzdGLGFBQWEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0FBRTNDOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxDQUFDLFFBQTBCLEVBQUUsUUFBNEIsRUFBNkIsRUFBRSxDQUNySCxRQUFRLEtBQUssSUFBSTtJQUNmLENBQUMsQ0FBQztRQUNFLElBQUksRUFBRSxhQUFhO1FBQ25CLE1BQU0sRUFBRSxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO1lBQ3JELENBQUMsQ0FBQywrQ0FBK0M7WUFDakQsQ0FBQyxDQUFDLGdCQUFnQjtLQUNyQjtJQUNILENBQUMsQ0FBQyxTQUFTLENBQUM7QUFFaEI7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQUMsSUFBYSxFQUFXLEVBQUUsQ0FBQyxPQUFPLElBQUksS0FBSyxRQUFRLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBUS9IOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sZ0NBQWdDLEdBQUcsQ0FDOUMsS0FBMEMsRUFDQyxFQUFFO0lBQzdDLE1BQU0sS0FBSyxHQUFHLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7SUFDeEYsT0FBTyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsYUFBYSxFQUFFLENBQUM7QUFDdkYsQ0FBQyxDQUFDO0FBRUY7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sbUNBQW1DLEdBQUcsQ0FBQyxJQUFtQyxFQUFVLEVBQUUsQ0FDakcsMktBQTJLLElBQUksQ0FBQyxLQUFLLHNCQUFzQixNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQywwTkFBME4sQ0FBQztBQUVsYzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFDSCxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRyxDQUFDLGFBQTZCLEVBQUUsWUFBb0IsRUFBUSxFQUFFO0lBQ3JHLE1BQU0sTUFBTSxHQUFHLENBQUMsSUFBWSxFQUFFLE9BQWUsRUFBUyxFQUFFO1FBQ3RELE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxHQUFHLElBQUksS0FBSyxPQUFPLEVBQUUsRUFBRSxFQUFFLFlBQVksRUFBRSxtQkFBbUIsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN0RyxDQUFDLENBQUM7SUFDRixJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ2pDLE1BQU0sSUFBSSxHQUFHLGdDQUFnQyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuRSxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsTUFBTSxDQUFDLFNBQVMsRUFBRSxtQ0FBbUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQy9ELENBQUM7UUFDRCxPQUFPO0lBQ1QsQ0FBQztJQUNELEtBQUssTUFBTSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztRQUNsRSxJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDN0IsTUFBTSxDQUFDLFVBQVUsRUFBRSxtREFBbUQsS0FBSyxzQkFBc0IsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDakksQ0FBQztJQUNILENBQUM7SUFDRCxNQUFNLE1BQU0sR0FBRyxhQUFhLENBQUMsSUFBSSxFQUFFLG1CQUFtQixDQUFDO0lBQ3ZELElBQUksQ0FBQyxNQUFNLEVBQUUsS0FBSyxJQUFJLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxDQUFDO1FBQ3pDLE1BQU0sQ0FDSixVQUFVLEVBQ1YsZ1FBQWdRLENBQ2pRLENBQUM7SUFDSixDQUFDO0lBQ0QsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLEVBQUUsRUFBRSxtQkFBbUIsQ0FBQztJQUNwRCxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssSUFBSSxDQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsQ0FBQztRQUM1QyxNQUFNLENBQ0osVUFBVSxFQUNWLDBLQUEwSyxDQUMzSyxDQUFDO0lBQ0osQ0FBQztBQUNILENBQUMsQ0FBQyJ9
|
|
387
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmF0LmNhdGVnb3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvZm9ybWF0cy91dGlscy92YXQuY2F0ZWdvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFXdEQsa0ZBQWtGO0FBQ2xGLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFnQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFFOUc7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxLQUFjLEVBQTZCLEVBQUUsQ0FDN0UsT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFLLGtCQUF3QyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUV6Rjs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLDZCQUE2QixHQUFnQyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztBQVdyRzs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUF3QixJQUFJLEdBQUcsQ0FDckQsQ0FDRSw2R0FBNkc7SUFDN0csa0hBQWtIO0lBQ2xILDhHQUE4RztJQUM5RyxtSEFBbUg7SUFDbkgsK0dBQStHO0lBQy9HLHFIQUFxSDtJQUNySCw2R0FBNkc7SUFDN0csc0hBQXNIO0lBQ3RILDRHQUE0RztJQUM1Ryw2R0FBNkc7SUFDN0cscUhBQXFIO0lBQ3JILGtIQUFrSDtJQUNsSCxvRUFBb0UsQ0FDckUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQ2IsQ0FBQztBQUVGOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBRyxDQUFDLElBQVksRUFBVyxFQUFFLENB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
|
|
@@ -29,16 +29,15 @@ export interface VATBreakdown {
|
|
|
29
29
|
* The EN 16931 VAT category rules of a document, checked on the VAT categories
|
|
30
30
|
* and the VAT breakdown the encoders write.
|
|
31
31
|
*
|
|
32
|
-
* The category of every line is the one the encoders write
|
|
33
|
-
*
|
|
34
|
-
* (
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* and rate. The envelope has no document level allowances or charges, so the
|
|
32
|
+
* The category of every line is the one the encoders write
|
|
33
|
+
* (`getItemVatCategory`): the one the item states (`vatCategory`, BT-151),
|
|
34
|
+
* else reverse charge (AE) when the document states `reverseCharge` and
|
|
35
|
+
* standard rated (S) otherwise. A decoded line carries the category its
|
|
36
|
+
* document states. The rules on the items, their exemption reasons and the
|
|
37
|
+
* parties' identifiers are those export refuses a document for
|
|
38
|
+
* (`findVatCategoryViolations`). The VAT breakdown is the one the encoders
|
|
39
|
+
* write (`computeDocumentTotals().vatGroups`): one group per category and
|
|
40
|
+
* rate. The envelope has no document level allowances or charges, so the
|
|
42
41
|
* rules on them (BR-S-02 to -04 and -06 to -07 and their counterparts) do not
|
|
43
42
|
* apply, and a taxable amount is the sum of the line net amounts.
|
|
44
43
|
*/
|
|
@@ -49,13 +48,13 @@ export declare class VATCategoriesValidator {
|
|
|
49
48
|
*/
|
|
50
49
|
validate(invoice: EInvoice): ValidationResult[];
|
|
51
50
|
/**
|
|
52
|
-
* The
|
|
53
|
-
*
|
|
51
|
+
* The breakdown a category of the lines needs: at least one for S (BR-S-01), exactly one for
|
|
52
|
+
* reverse charge (BR-AE-01)
|
|
54
53
|
*/
|
|
55
|
-
private
|
|
54
|
+
private validateBreakdownPresence;
|
|
56
55
|
/**
|
|
57
|
-
* The rules on each VAT breakdown group: its taxable amount (BR-S-08
|
|
58
|
-
*
|
|
56
|
+
* The rules on each VAT breakdown group: its taxable amount (BR-S-08 and its counterparts of
|
|
57
|
+
* every category) and its tax amount (BR-S-09 and its counterparts, BR-CO-17)
|
|
59
58
|
*/
|
|
60
59
|
private validateBreakdown;
|
|
61
60
|
private addError;
|