@fin.cx/chartdata 2.13.0 → 2.15.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 +3 -3
- package/dist_ts/chartdata.euer.d.ts +67 -0
- package/dist_ts/chartdata.euer.js +162 -0
- package/dist_ts/chartdata.lookup.d.ts +23 -1
- package/dist_ts/chartdata.lookup.js +32 -1
- package/dist_ts/chartdata.types.d.ts +158 -1
- package/dist_ts/data/skr03.2026.js +770 -1
- package/dist_ts/data/skr04.2026.js +735 -1
- package/dist_ts/index.d.ts +1 -0
- package/dist_ts/index.js +2 -1
- package/package.json +2 -2
- package/readme.md +129 -1
- package/ts/00_commitinfo_data.ts +2 -2
- package/ts/chartdata.euer.ts +219 -0
- package/ts/chartdata.lookup.ts +52 -0
- package/ts/chartdata.types.ts +188 -1
- package/ts/data/skr03.2026.ts +769 -0
- package/ts/data/skr04.2026.ts +734 -0
- package/ts/index.ts +1 -0
package/dist_ts/index.d.ts
CHANGED
package/dist_ts/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './chartdata.types.js';
|
|
2
2
|
export * from './chartdata.lookup.js';
|
|
3
3
|
export * from './chartdata.hgb.js';
|
|
4
|
+
export * from './chartdata.euer.js';
|
|
4
5
|
export { SKR03_2026 } from './data/skr03.2026.js';
|
|
5
6
|
export { SKR04_2026 } from './data/skr04.2026.js';
|
|
6
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
7
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHNCQUFzQixDQUFDO0FBQ3JDLGNBQWMsdUJBQXVCLENBQUM7QUFDdEMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUMifQ==
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fin.cx/chartdata",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.0",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "Year-versioned German SKR03/SKR04 chart-of-accounts datasets with Automatikkonto functions, BU-key rules,
|
|
5
|
+
"description": "Year-versioned German SKR03/SKR04 chart-of-accounts datasets with Automatikkonto functions, BU-key rules, UStVA-Kennzahl and Anlage EÜR mappings",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
7
7
|
"typings": "dist_ts/index.d.ts",
|
|
8
8
|
"type": "module",
|
package/readme.md
CHANGED
|
@@ -27,6 +27,20 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|
|
27
27
|
not tell it apart from the others of its position: a fixed asset's sale
|
|
28
28
|
proceeds (`asset_sale_proceeds`) and the book value of a disposed fixed
|
|
29
29
|
asset (`disposal_book_value`), listed per chart by `getAccountsByRole`
|
|
30
|
+
- Securities accounts (Wertpapiere) with their securities role
|
|
31
|
+
(`securitiesRole`): the holdings of fixed and current assets, their income,
|
|
32
|
+
their sale (net for current assets, gross on a Finanzanlage's disposal
|
|
33
|
+
accounts), the costs of a sale, write-downs and write-ups, the taxes withheld
|
|
34
|
+
from their income and the margin interest, listed per chart by
|
|
35
|
+
`getAccountsBySecuritiesRole` and found one by one with `getSecuritiesAccount`
|
|
36
|
+
- The tax rule an income or expense account is kept for (`taxRule`):
|
|
37
|
+
`estg_3_40_kstg_8b` on every account DATEV names "§ 3 Nr. 40 EStG bzw. § 8b …
|
|
38
|
+
KStG", whose income DATEV's corporate-tax interface treats as tax-free and
|
|
39
|
+
whose expenses as non-deductible
|
|
40
|
+
- Account→Anlage EÜR mappings (`euer`) for the Einnahmenüberschussrechnung
|
|
41
|
+
(§ 4 Abs. 3 EStG, § 60 Abs. 4 EStDV), with the lines of the 2025 and 2026
|
|
42
|
+
forms (`ANLAGE_EUER_FORMS`); every account maps or is excluded with its
|
|
43
|
+
reason (`euerExclusion`)
|
|
30
44
|
- Coverage introspection that fails loudly on mapping gaps
|
|
31
45
|
- Provenance on every record
|
|
32
46
|
|
|
@@ -71,6 +85,115 @@ getAccountsByRole('SKR04', 2026, 'disposal_book_value').map((account) => account
|
|
|
71
85
|
// ['4855', '4856', '4857', '4858', '6895', '6896', '6897', '6898']
|
|
72
86
|
```
|
|
73
87
|
|
|
88
|
+
### Securities
|
|
89
|
+
|
|
90
|
+
A booking of securities finds its account by the securities role and the tax
|
|
91
|
+
rule; within a chart no two accounts share both. DATEV keeps an account under
|
|
92
|
+
§ 3 Nr. 40 EStG / § 8b KStG beside most ordinary ones (`taxRule:
|
|
93
|
+
'estg_3_40_kstg_8b'`); whether a dividend or a gain belongs there is the
|
|
94
|
+
booking's decision, not the account's: a holding of less than 10 % at the start
|
|
95
|
+
of the calendar year receives taxable dividends (§ 8b Abs. 4 KStG), while a
|
|
96
|
+
share's sale gain falls under § 8b Abs. 2 KStG whatever the holding.
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import { getSecuritiesAccount, getAccountsBySecuritiesRole } from '@fin.cx/chartdata';
|
|
100
|
+
|
|
101
|
+
getSecuritiesAccount('SKR04', 2026, 'holding_current')?.accountNumber; // '1510' Sonstige Wertpapiere
|
|
102
|
+
getSecuritiesAccount('SKR04', 2026, 'sale_gain_current', 'estg_3_40_kstg_8b')?.accountNumber; // '4906'
|
|
103
|
+
getSecuritiesAccount('SKR03', 2026, 'income_current')?.accountNumber; // '2654'
|
|
104
|
+
getSecuritiesAccount('SKR03', 2026, 'income_current', 'estg_3_40_kstg_8b')?.accountNumber; // '2655'
|
|
105
|
+
getSecuritiesAccount('SKR03', 2026, 'sale_costs_gain'); // null: DATEV keeps the costs of a sale only under § 8b
|
|
106
|
+
getAccountsBySecuritiesRole('SKR03', 2026, 'sale_proceeds_fixed_gain').map((account) => account.accountNumber);
|
|
107
|
+
// ['8838', '8839']: a Finanzanlage's sale stated gross, on the accounts of a fixed asset's disposal
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
| Role | What it books | SKR03 | SKR04 |
|
|
111
|
+
| --- | --- | --- | --- |
|
|
112
|
+
| `holding_fixed`, `holding_fixed_shares`, `holding_fixed_bonds` | Wertpapiere des Anlagevermögens (A.III.5) | 0525, 0530, 0535 | 0900, 0910, 0920 |
|
|
113
|
+
| `holding_current` | Sonstige Wertpapiere (B.III.2) | 1348 | 1510 |
|
|
114
|
+
| `income_fixed` / `income_current` | dividends, distributions, coupons (GuV 10 / 11) | 2620 (§ 8b 2625) / 2654 (§ 8b 2655) | 7010 (§ 8b 7014) / 7115 (§ 8b 7103) |
|
|
115
|
+
| `sale_gain_current` / `sale_loss_current` | a current asset's sale, net (GuV 4 / 8) | 2725 (§ 8b 2726) / 2325 (§ 8b 2326) | 4905 (§ 8b 4906) / 6905 (§ 8b 6906) |
|
|
116
|
+
| `sale_proceeds_fixed_*`, `book_value_fixed_*` | a Finanzanlage's sale, gross | 8838/8818, 2317/2312 (§ 8b 8839/8819, 2318/2313) | 4851/6891, 4857/6897 (§ 8b 4852/6892, 4858/6898) |
|
|
117
|
+
| `sale_costs_gain` / `sale_costs_loss` | the costs of a sale under § 8b KStG | 4976 / 4977 | 6857 / 6858 |
|
|
118
|
+
| `writedown_fixed_lasting`, `writedown_fixed_temporary`, `writedown_current` | write-downs (GuV 12) | 4870 (§ 8b 4871), 4866, 4875 (§ 8b 4876) | 7200 (§ 8b 7204), 7201, 7210 (§ 8b 7214) |
|
|
119
|
+
| `writeup_fixed`, `writeup_current`, `writeup` | write-ups (GuV 4) | 2712, 2715, § 8b 2714 | 4912, 4915, § 8b 4914 |
|
|
120
|
+
| `capital_gains_tax`, `capital_gains_tax_soli` | Kapitalertragsteuer and its Solidaritätszuschlag (GuV 14) | 2213, 2216 | 7630, 7633 |
|
|
121
|
+
| `foreign_withholding_tax`, `foreign_tax_exempt_income` | foreign tax to credit or deduct; on income exempt at home (GuV 14) | 2219, 2218 | 7639, 7638 |
|
|
122
|
+
| `foreign_tax_refund` | a foreign tax to be refunded (B.II.4) | 1542 | 1440 |
|
|
123
|
+
| `margin_interest` | interest on a short-term debt (GuV 13) | 2110 | 7310 |
|
|
124
|
+
|
|
125
|
+
None of them carries a tax function or a UStVA figure. In the Anlage EÜR the
|
|
126
|
+
holdings are no part of the form (fixed assets reach it by their residual book
|
|
127
|
+
value, current ones of § 4 Abs. 3 Satz 4 EStG by their cost when sold:
|
|
128
|
+
`deferred_current_asset`); income and gains on sale are receipts free of VAT or
|
|
129
|
+
not taxable for VAT (Kz 103), a loss on sale is cost at the sale (Kz 100), the costs of a
|
|
130
|
+
sale other expenses (Kz 183), write-downs and write-ups values at a closing date
|
|
131
|
+
(`valuation`), the margin interest other debt interest (Kz 234), and the taxes
|
|
132
|
+
on income a withdrawal (Kz 122, § 12 Nr. 3 EStG).
|
|
133
|
+
|
|
134
|
+
### Anlage EÜR
|
|
135
|
+
|
|
136
|
+
Every account of a chart either maps to the Anlage EÜR or is excluded from it
|
|
137
|
+
with its reason. A mapping names the line by its Kennzahl, which stays the same
|
|
138
|
+
from one form year to the next while the line number may change. The 2026 form
|
|
139
|
+
inserts Zeile 27, so the goods move from Zeile 27 (2025) to Zeile 29 (2026).
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
import { getEuerLines, euerAmountsOf, getEuerForm, getMappingCoverage } from '@fin.cx/chartdata';
|
|
143
|
+
|
|
144
|
+
// a fiscal year 2025 booked on the 2026 chart, stated on the 2025 form
|
|
145
|
+
getEuerLines('SKR03', 2026, '8400', 2025);
|
|
146
|
+
// { kind: 'netted', line: { kennzahl: 112, line: 15, label: 'Umsatzsteuerpflichtige Betriebseinnahmen …',
|
|
147
|
+
// section: 'income', sign: 1, side: 'credit' } }
|
|
148
|
+
getEuerLines('SKR03', 2026, '1780', 2026);
|
|
149
|
+
// { kind: 'split', debitLine: { kennzahl: 186, line: 59, … }, creditLine: { kennzahl: 141, line: 18, … } }
|
|
150
|
+
getEuerLines('SKR03', 2026, '1787', 2026); // { kind: 'excluded', exclusion: 'reverse_charge' }
|
|
151
|
+
getEuerLines('SKR03', 2026, '8400', 2026, { smallBusiness: true }); // Kz 111, Zeile 12 (Zeile 13 stays with the caller)
|
|
152
|
+
|
|
153
|
+
// what a period's movements on an account amount to on its lines, in cents
|
|
154
|
+
euerAmountsOf(getEuerLines('SKR03', 2026, '8400', 2026)!, 20000, 500000); // [{ line: Kz 112, cents: 480000 }]
|
|
155
|
+
|
|
156
|
+
// before stating an EÜR: every used account must have a decision
|
|
157
|
+
getMappingCoverage('SKR04', 2026, usedAccountNumbers, 'euer').missing; // []
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
- `netted` accounts count both sides on one line, toward its side. A line of
|
|
161
|
+
receipts counts credits less debits, so a sales deduction lowers the
|
|
162
|
+
receipts; a line of expenses counts debits less credits, so a received
|
|
163
|
+
discount lowers the goods. `split` accounts put each side on a line of its
|
|
164
|
+
own. The VAT prepayment and past-year accounts split what was paid to the
|
|
165
|
+
tax office (Kz 186) from what it refunded (Kz 141).
|
|
166
|
+
- Exclusions (`TEuerExclusion`): `balance_sheet`, `fixed_asset` (reaches the
|
|
167
|
+
form through depreciation and the residual value), `inventory`, `valuation`,
|
|
168
|
+
`pass_through` (§ 4 Abs. 3 Satz 2 EStG), `reverse_charge` (the tax of an
|
|
169
|
+
intra-Community acquisition or under § 13b UStG: such invoices contain no
|
|
170
|
+
input tax, Anleitung zur Anlage EÜR, Zeile 58, and the tax is no receipt;
|
|
171
|
+
what a return leaves to pay counts as paid VAT, Kz 186), `closing` and
|
|
172
|
+
`deferred_current_asset` (shares, securities, land and buildings held as
|
|
173
|
+
current assets, whose cost counts at their sale, § 4 Abs. 3 Satz 4 EStG).
|
|
174
|
+
- A line's `sign` says how it enters its section's sum: 1 adds, -1 subtracts
|
|
175
|
+
(Zeilen 73 and 75), 0 not at all (a "davon" line, the column "nicht
|
|
176
|
+
abziehbar", the Entnahmen and Einlagen).
|
|
177
|
+
- The form counts the year's movements, not the opening balances (EB-Werte):
|
|
178
|
+
a caller sums a period's bookings over the entries it holds and leaves out
|
|
179
|
+
the opening entries, which on a `split` account would otherwise count as a
|
|
180
|
+
refund (Kz 141) or a payment (Kz 186). When a payment counts is the
|
|
181
|
+
caller's period logic too: a VAT refund or prepayment of the prior year
|
|
182
|
+
that falls due and is paid within ten days of the year's start belongs to
|
|
183
|
+
the prior year (§ 11 Abs. 1 Satz 2 and Abs. 2 Satz 2 EStG, Anleitung,
|
|
184
|
+
Zeilen 18 and 59).
|
|
185
|
+
- With `smallBusiness`, a Kleinunternehmer's taxable and tax-free receipts go
|
|
186
|
+
to Zeile 12 (Kz 111). Zeile 13 (Kz 119) states within it, "nachrichtlich",
|
|
187
|
+
the non-taxable receipts and those under § 19 Abs. 2 Satz 1 Nr. 1 und 2
|
|
188
|
+
UStG. An account does not tell which of its receipts those are, so no
|
|
189
|
+
account resolves to Kz 119 and that amount stays with the caller.
|
|
190
|
+
- The decisions the line texts do not make on their own are written at the
|
|
191
|
+
table in `tools/generate-charts.ts`. Revenue without a tax function counts
|
|
192
|
+
with the taxable receipts, and interest, exchange gains and damages with the
|
|
193
|
+
tax-free ones. Employees' travel goes with the staff (Anleitung, Zeile 45),
|
|
194
|
+
and another member state's VAT (OSS) is received in Kz 103 and paid in
|
|
195
|
+
Kz 183.
|
|
196
|
+
|
|
74
197
|
## Data Provenance and Verification
|
|
75
198
|
|
|
76
199
|
Records carry a `provenance` string. The datasets are a curated table authored
|
|
@@ -85,7 +208,12 @@ PDFs (Art.-Nr. 11174/11175) are public, and accounts verified against them say
|
|
|
85
208
|
so in their provenance. The standing verification gates are ERiC validation
|
|
86
209
|
of generated filings and periodic manual DATEV imports.
|
|
87
210
|
HGB §266/§275 positions are populated and validated against the exported statutory
|
|
88
|
-
position trees.
|
|
211
|
+
position trees. The Anlage EÜR lines (`ANLAGE_EUER_FORMS`) were read from the
|
|
212
|
+
BMF's published forms and Anleitungen: Anlage EÜR 2025 (BMF-Schreiben of
|
|
213
|
+
2025-08-29) and Anlage EÜR 2026 (BMF-Schreiben of 2026-09-01). Each line's pair
|
|
214
|
+
of line number and Kennzahl was checked against the forms. The generator fails
|
|
215
|
+
on an account without an EÜR decision, and on a Kennzahl or side a form year
|
|
216
|
+
does not hold. E-Bilanz (de-gaap-ci) positions are not populated yet —
|
|
89
217
|
`getMappingCoverage(..., 'ebilanz')` reports them as missing by design.
|
|
90
218
|
|
|
91
219
|
The generation pipeline lives in the unpublished `tools/` directory
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@fin.cx/chartdata',
|
|
6
|
-
version: '2.
|
|
7
|
-
description: 'Year-versioned German SKR03/SKR04 chart-of-accounts datasets with Automatikkonto functions, BU-key rules,
|
|
6
|
+
version: '2.15.0',
|
|
7
|
+
description: 'Year-versioned German SKR03/SKR04 chart-of-accounts datasets with Automatikkonto functions, BU-key rules, UStVA-Kennzahl and Anlage EÜR mappings'
|
|
8
8
|
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Anlage EÜR (standardised Einnahmenüberschussrechnung, § 60 Abs. 4
|
|
3
|
+
* EStDV) of the form years the datasets serve: the lines an account's
|
|
4
|
+
* movements can go to, with their Kennzahlen, their line numbers per year and
|
|
5
|
+
* the form's wording (amtliches Werk, § 5 UrhG — public domain).
|
|
6
|
+
*
|
|
7
|
+
* Read from the BMF's published forms: "Standardisierte Einnahmenüberschuss-
|
|
8
|
+
* rechnung nach § 60 Absatz 4 EStDV; Anlage EÜR 2025" (BMF-Schreiben of
|
|
9
|
+
* 2025-08-29, IV C 6 - S 2142/00023/010/001) and "… Anlage EÜR 2026"
|
|
10
|
+
* (2026-09-01, IV C 6 - S 2142/00024/010/001), with their Anleitungen. The
|
|
11
|
+
* two years list the same lines under the same Kennzahlen; 2026 inserts
|
|
12
|
+
* Zeile 27 (Bildung Rücklage Tierbewertung, from the Anlage LuF), so the
|
|
13
|
+
* goods are Zeile 27 in 2025 and 29 in 2026, and every later line is one
|
|
14
|
+
* number higher in 2026.
|
|
15
|
+
*
|
|
16
|
+
* The table holds the lines of the Betriebseinnahmen, the Betriebsausgaben
|
|
17
|
+
* and the Entnahmen and Einlagen that carry a Kennzahl of their own. Sums,
|
|
18
|
+
* transfers ("Übertrag") and the transfers from the Anlage LuF (2026
|
|
19
|
+
* Zeilen 25 to 27) are not lines an account's movements go to.
|
|
20
|
+
*/
|
|
21
|
+
import type { IChartAccount, IEuerForm, IEuerFormLine, TEuerAccountLines, TEuerSection } from './chartdata.types.js';
|
|
22
|
+
|
|
23
|
+
type TRow = [
|
|
24
|
+
kennzahl: number,
|
|
25
|
+
line2025: number,
|
|
26
|
+
line2026: number,
|
|
27
|
+
section: TEuerSection,
|
|
28
|
+
sign: IEuerFormLine['sign'],
|
|
29
|
+
label: string,
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
const INCOME = 'income';
|
|
33
|
+
const EXPENSE = 'expense';
|
|
34
|
+
|
|
35
|
+
/** Every line once, with its line numbers on the 2025 and the 2026 form. */
|
|
36
|
+
const ROWS: TRow[] = [
|
|
37
|
+
// 1. Betriebseinnahmen
|
|
38
|
+
[111, 12, 12, INCOME, 1, 'Betriebseinnahmen als umsatzsteuerlicher Kleinunternehmer (nach § 19 Abs. 1 UStG)'],
|
|
39
|
+
[119, 13, 13, INCOME, 0, 'davon nicht steuerbare Umsätze sowie Umsätze nach § 19 Abs. 2 Satz 1 Nr. 1 und 2 sowie Satz 2 UStG'],
|
|
40
|
+
[104, 14, 14, INCOME, 1, 'Betriebseinnahmen als Land- und Forstwirt, soweit die Durchschnittssatzbesteuerung nach § 24 UStG angewandt wird'],
|
|
41
|
+
[112, 15, 15, INCOME, 1, 'Umsatzsteuerpflichtige Betriebseinnahmen (ohne solche zum ermäßigten Steuersatz von 0 %)'],
|
|
42
|
+
[103, 16, 16, INCOME, 1, 'Betriebseinnahmen, die umsatzsteuerfrei (§ 4 UStG) oder nicht umsatzsteuerbar sind oder nach § 12 Abs. 3 UStG dem ermäßigten Steuersatz von 0 % unterliegen oder für die der Leistungsempfänger die Umsatzsteuer nach § 13b UStG schuldet'],
|
|
43
|
+
[140, 17, 17, INCOME, 1, 'Vereinnahmte Umsatzsteuer sowie Umsatzsteuer auf unentgeltliche Wertabgaben'],
|
|
44
|
+
[141, 18, 18, INCOME, 1, 'Vom Finanzamt erstattete und ggf. verrechnete Umsatzsteuer'],
|
|
45
|
+
[102, 19, 19, INCOME, 1, 'Veräußerung oder Entnahme von Anlagevermögen'],
|
|
46
|
+
[106, 20, 20, INCOME, 1, 'Private Kfz-Nutzung'],
|
|
47
|
+
[108, 21, 21, INCOME, 1, 'Sonstige Sach-, Nutzungs- und Leistungsentnahmen'],
|
|
48
|
+
// 2. Betriebsausgaben
|
|
49
|
+
[195, 24, 24, EXPENSE, 1, 'Betriebsausgabenpauschale für bestimmte Berufsgruppen'],
|
|
50
|
+
[100, 27, 29, EXPENSE, 1, 'Waren, Rohstoffe und Hilfsstoffe einschließlich der Nebenkosten'],
|
|
51
|
+
[110, 29, 30, EXPENSE, 1, 'Bezogene Fremdleistungen'],
|
|
52
|
+
[120, 30, 31, EXPENSE, 1, 'Ausgaben für eigenes Personal (z. B. Gehälter, Löhne und Versicherungsbeiträge)'],
|
|
53
|
+
[136, 31, 32, EXPENSE, 1, 'AfA auf Grundstücke/grundstücksgleiche Rechte'],
|
|
54
|
+
[131, 32, 33, EXPENSE, 1, 'AfA auf immaterielle Wirtschaftsgüter'],
|
|
55
|
+
[130, 33, 34, EXPENSE, 1, 'AfA auf bewegliche Wirtschaftsgüter'],
|
|
56
|
+
[134, 34, 35, EXPENSE, 1, 'Sonderabschreibungen nach § 7b EStG und § 7g Abs. 5 und 6 EStG'],
|
|
57
|
+
[138, 35, 36, EXPENSE, 1, 'Herabsetzungsbeträge nach § 7g Abs. 2 Satz 3 EStG'],
|
|
58
|
+
[132, 36, 37, EXPENSE, 1, 'Aufwendungen für geringwertige Wirtschaftsgüter nach § 6 Abs. 2 EStG'],
|
|
59
|
+
[137, 37, 38, EXPENSE, 1, 'Auflösung Sammelposten nach § 6 Abs. 2a EStG'],
|
|
60
|
+
[135, 38, 39, EXPENSE, 1, 'Restbuchwerte der ausgeschiedenen Anlagegüter'],
|
|
61
|
+
[150, 39, 40, EXPENSE, 1, 'Miete/Pacht für Geschäftsräume und betrieblich genutzte Grundstücke'],
|
|
62
|
+
[152, 40, 41, EXPENSE, 1, 'Aufwendungen für doppelte Haushaltsführung (z. B. Miete)'],
|
|
63
|
+
[151, 41, 42, EXPENSE, 1, 'Sonstige Aufwendungen für betrieblich genutzte Grundstücke (ohne Schuldzinsen und AfA)'],
|
|
64
|
+
[153, 42, 43, EXPENSE, 0, 'davon Erhaltungsaufwendungen'],
|
|
65
|
+
[280, 43, 44, EXPENSE, 1, 'Aufwendungen für Telekommunikation (z. B. Telefon, Internet)'],
|
|
66
|
+
[221, 44, 45, EXPENSE, 1, 'Übernachtungs- und Reisenebenkosten bei Geschäftsreisen des Steuerpflichtigen'],
|
|
67
|
+
[281, 45, 46, EXPENSE, 1, 'Fortbildungskosten (ohne Reisekosten)'],
|
|
68
|
+
[194, 46, 47, EXPENSE, 1, 'Kosten für Rechts- und Steuerberatung, Buchführung'],
|
|
69
|
+
[222, 47, 48, EXPENSE, 1, 'Miete/Leasing für bewegliche Wirtschaftsgüter (ohne Kfz)'],
|
|
70
|
+
[225, 48, 49, EXPENSE, 1, 'Erhaltungsaufwendungen (z. B. Instandhaltung, Wartung, Reparatur; ohne solche für Gebäude und Kfz)'],
|
|
71
|
+
[223, 49, 50, EXPENSE, 1, 'Beiträge, Gebühren, Abgaben und Versicherungen (ohne solche für Gebäude und Kfz)'],
|
|
72
|
+
[228, 50, 51, EXPENSE, 1, 'Laufende EDV-Kosten (z. B. Beratung, Wartung, Reparatur)'],
|
|
73
|
+
[229, 51, 52, EXPENSE, 1, 'Arbeitsmittel (z. B. Bürobedarf, Porto, Fachliteratur)'],
|
|
74
|
+
[226, 52, 53, EXPENSE, 1, 'Kosten für Abfallbeseitigung und Entsorgung'],
|
|
75
|
+
[227, 53, 54, EXPENSE, 1, 'Kosten für Verpackung und Transport'],
|
|
76
|
+
[224, 54, 55, EXPENSE, 1, 'Werbekosten (z. B. Inserate, Werbespots, Plakate)'],
|
|
77
|
+
[232, 55, 56, EXPENSE, 1, 'Schuldzinsen zur Finanzierung von Anschaffungs- und Herstellungskosten von Wirtschaftsgütern des Anlagevermögens (ohne häusliches Arbeitszimmer)'],
|
|
78
|
+
[234, 56, 57, EXPENSE, 1, 'Übrige Schuldzinsen'],
|
|
79
|
+
[185, 57, 58, EXPENSE, 1, 'Gezahlte und nach § 15 UStG abziehbare Vorsteuerbeträge'],
|
|
80
|
+
[186, 58, 59, EXPENSE, 1, 'An das Finanzamt gezahlte und ggf. verrechnete Umsatzsteuer'],
|
|
81
|
+
[183, 60, 61, EXPENSE, 1, 'Übrige unbeschränkt abziehbare Betriebsausgaben'],
|
|
82
|
+
[164, 62, 63, EXPENSE, 0, 'Geschenke (nicht abziehbar)'],
|
|
83
|
+
[174, 62, 63, EXPENSE, 1, 'Geschenke (abziehbar)'],
|
|
84
|
+
[165, 63, 64, EXPENSE, 0, 'Bewirtungsaufwendungen (nicht abziehbar)'],
|
|
85
|
+
[175, 63, 64, EXPENSE, 1, 'Bewirtungsaufwendungen (abziehbar)'],
|
|
86
|
+
[171, 64, 65, EXPENSE, 1, 'Verpflegungsmehraufwendungen'],
|
|
87
|
+
[162, 65, 66, EXPENSE, 0, 'Aufwendungen für ein häusliches Arbeitszimmer (nicht abziehbar)'],
|
|
88
|
+
[172, 65, 66, EXPENSE, 1, 'Aufwendungen für ein häusliches Arbeitszimmer (abziehbar)'],
|
|
89
|
+
[163, 66, 67, EXPENSE, 1, 'Tagespauschale für die Tätigkeit in der häuslichen Wohnung'],
|
|
90
|
+
[168, 67, 68, EXPENSE, 0, 'Sonstige beschränkt abziehbare Betriebsausgaben (nicht abziehbar)'],
|
|
91
|
+
[177, 67, 68, EXPENSE, 1, 'Sonstige beschränkt abziehbare Betriebsausgaben (abziehbar)'],
|
|
92
|
+
[144, 68, 69, EXPENSE, 1, 'Kfz-Kosten und andere Fahrtkosten: Leasingkosten'],
|
|
93
|
+
[145, 69, 70, EXPENSE, 1, 'Kfz-Kosten und andere Fahrtkosten: Steuern, Versicherungen und Maut'],
|
|
94
|
+
[146, 70, 71, EXPENSE, 1, 'Sonstige tatsächliche Fahrtkosten ohne AfA und Zinsen (z. B. Reparaturen, Wartungen, Treibstoff, Kosten für Flugstrecken, Kosten für öffentliche Verkehrsmittel)'],
|
|
95
|
+
[147, 71, 72, EXPENSE, 1, 'Fahrtkosten für nicht zum Betriebsvermögen gehörende Fahrzeuge (Nutzungseinlage)'],
|
|
96
|
+
[142, 72, 73, EXPENSE, -1, 'Fahrtkosten für Wege zwischen Wohnung und erster Betriebsstätte; Familienheimfahrten (pauschaliert oder tatsächlich)'],
|
|
97
|
+
[176, 73, 74, EXPENSE, 1, 'Mindestens abziehbare Fahrtkosten für Wege zwischen Wohnung und erster Betriebsstätte (Entfernungspauschale); Familienheimfahrten'],
|
|
98
|
+
[139, 74, 75, EXPENSE, -1, 'Nicht abziehbare Beträge'],
|
|
99
|
+
// 5. Zusätzliche Angaben bei Einzelunternehmen: Entnahmen und Einlagen i. S. d. § 4 Abs. 4a EStG
|
|
100
|
+
[122, 106, 107, 'private', 0, 'Entnahmen einschließlich Sach-, Leistungs- und Nutzungsentnahmen'],
|
|
101
|
+
[123, 107, 108, 'private', 0, 'Einlagen einschließlich Sach-, Leistungs- und Nutzungseinlagen'],
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
/** The side a line counts: receipts and Einlagen credit, expenses and Entnahmen debit. */
|
|
105
|
+
const sideOf = (kennzahlArg: number, sectionArg: TEuerSection): IEuerFormLine['side'] =>
|
|
106
|
+
sectionArg === 'income' || kennzahlArg === 123 ? 'credit' : 'debit';
|
|
107
|
+
|
|
108
|
+
const formOf = (yearArg: 2025 | 2026, provenanceArg: string): IEuerForm => ({
|
|
109
|
+
year: yearArg,
|
|
110
|
+
lines: ROWS.map(([kennzahl, line2025, line2026, section, sign, label]) => ({
|
|
111
|
+
kennzahl,
|
|
112
|
+
line: yearArg === 2025 ? line2025 : line2026,
|
|
113
|
+
label,
|
|
114
|
+
section,
|
|
115
|
+
sign,
|
|
116
|
+
side: sideOf(kennzahl, section),
|
|
117
|
+
})),
|
|
118
|
+
provenance: provenanceArg,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
/** The Anlage EÜR of each form year, by year. */
|
|
122
|
+
export const ANLAGE_EUER_FORMS: IEuerForm[] = [
|
|
123
|
+
formOf(2025, 'BMF-Schreiben 2025-08-29 (IV C 6 - S 2142/00023/010/001), Anlage EÜR 2025 and its Anleitung; lines read 2026-10-07'),
|
|
124
|
+
formOf(2026, 'BMF-Schreiben 2026-09-01 (IV C 6 - S 2142/00024/010/001), Anlage EÜR 2026 and its Anleitung; lines read 2026-10-07'),
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The Kennzahl a Kleinunternehmer (§ 19 Abs. 1 UStG) states every receipt
|
|
129
|
+
* under but those of Zeilen 18 to 22: "Die Zeilen 15 bis 17 sind von
|
|
130
|
+
* Kleinunternehmern in der Regel nicht zu verwenden" (Anleitung, Zeile 12).
|
|
131
|
+
* `euerLinesOf` and `getEuerLines` with `smallBusiness` take the taxable (Kz 112) and the
|
|
132
|
+
* tax-free or non-taxable receipts (Kz 103) there. Zeile 13 (Kz 119), the
|
|
133
|
+
* "davon" of the non-taxable receipts and those under § 19 Abs. 2 Satz 1
|
|
134
|
+
* Nr. 1 und 2 UStG within Zeile 12, is stated "nachrichtlich" (Anleitung,
|
|
135
|
+
* Zeile 13): no account resolves to it, since an account does not tell which
|
|
136
|
+
* of its receipts fall under it, so that amount stays with the caller.
|
|
137
|
+
*/
|
|
138
|
+
export const EUER_SMALL_BUSINESS_KENNZAHL = 111;
|
|
139
|
+
|
|
140
|
+
/** The form years the table holds, ascending. */
|
|
141
|
+
export function listEuerFormYears(): number[] {
|
|
142
|
+
return ANLAGE_EUER_FORMS.map((formArg) => formArg.year);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The Anlage EÜR of a form year. Throws for a year the table does not hold —
|
|
147
|
+
* a form's lines must never fall back to another year's silently.
|
|
148
|
+
*/
|
|
149
|
+
export function getEuerForm(year: number): IEuerForm {
|
|
150
|
+
const form = ANLAGE_EUER_FORMS.find((candidateArg) => candidateArg.year === year);
|
|
151
|
+
if (!form) {
|
|
152
|
+
throw new Error(`No Anlage EÜR for ${year}. Available: ${listEuerFormYears().join(', ')}`);
|
|
153
|
+
}
|
|
154
|
+
return form;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** A line of a form year by its Kennzahl; throws where the year's table has none. */
|
|
158
|
+
export function getEuerFormLine(year: number, kennzahl: number): IEuerFormLine {
|
|
159
|
+
const line = getEuerForm(year).lines.find((candidateArg) => candidateArg.kennzahl === kennzahl);
|
|
160
|
+
if (!line) {
|
|
161
|
+
throw new Error(`The Anlage EÜR ${year} has no line of Kz ${kennzahl}`);
|
|
162
|
+
}
|
|
163
|
+
return line;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Options of `getEuerLines`. */
|
|
167
|
+
export interface IEuerLinesOptions {
|
|
168
|
+
/** the business is a Kleinunternehmer (§ 19 Abs. 1 UStG): its taxable and tax-free receipts go to Kz 111 */
|
|
169
|
+
smallBusiness?: boolean;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* The lines of an account in a form year, resolved from the account's
|
|
174
|
+
* mapping (`IChartAccount.euer`, `euerExclusion`). Throws for an account that
|
|
175
|
+
* has neither, which a dataset of this package never holds.
|
|
176
|
+
*/
|
|
177
|
+
export function euerLinesOf(account: IChartAccount, formYear: number, options: IEuerLinesOptions = {}): TEuerAccountLines {
|
|
178
|
+
const lineOf = (kennzahlArg: number): IEuerFormLine =>
|
|
179
|
+
getEuerFormLine(
|
|
180
|
+
formYear,
|
|
181
|
+
options.smallBusiness && (kennzahlArg === 112 || kennzahlArg === 103) ? EUER_SMALL_BUSINESS_KENNZAHL : kennzahlArg,
|
|
182
|
+
);
|
|
183
|
+
if (account.euer && 'kennzahl' in account.euer) {
|
|
184
|
+
return { kind: 'netted', line: lineOf(account.euer.kennzahl) };
|
|
185
|
+
}
|
|
186
|
+
if (account.euer) {
|
|
187
|
+
return { kind: 'split', debitLine: lineOf(account.euer.debitKennzahl), creditLine: lineOf(account.euer.creditKennzahl) };
|
|
188
|
+
}
|
|
189
|
+
if (account.euerExclusion) {
|
|
190
|
+
return { kind: 'excluded', exclusion: account.euerExclusion };
|
|
191
|
+
}
|
|
192
|
+
throw new Error(`Account ${account.accountNumber} has neither an Anlage EÜR mapping nor an exclusion`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** An amount on a line of the Anlage EÜR, in integer cents. */
|
|
196
|
+
export interface IEuerAmount {
|
|
197
|
+
line: IEuerFormLine;
|
|
198
|
+
cents: number;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* What an account's movements of a period, its debits and its credits in
|
|
203
|
+
* integer cents, amount to on its lines: a netted line counts its own side
|
|
204
|
+
* less the other (it may come out negative: a credit note's reversal), a split
|
|
205
|
+
* account each side on its line, an excluded one nothing.
|
|
206
|
+
*/
|
|
207
|
+
export function euerAmountsOf(lines: TEuerAccountLines, debitCents: number, creditCents: number): IEuerAmount[] {
|
|
208
|
+
switch (lines.kind) {
|
|
209
|
+
case 'netted':
|
|
210
|
+
return [{ line: lines.line, cents: lines.line.side === 'credit' ? creditCents - debitCents : debitCents - creditCents }];
|
|
211
|
+
case 'split':
|
|
212
|
+
return [
|
|
213
|
+
{ line: lines.debitLine, cents: debitCents },
|
|
214
|
+
{ line: lines.creditLine, cents: creditCents },
|
|
215
|
+
];
|
|
216
|
+
case 'excluded':
|
|
217
|
+
return [];
|
|
218
|
+
}
|
|
219
|
+
}
|
package/ts/chartdata.lookup.ts
CHANGED
|
@@ -5,8 +5,12 @@ import type {
|
|
|
5
5
|
IScenarioKennzahlen,
|
|
6
6
|
TAccountRole,
|
|
7
7
|
TChartName,
|
|
8
|
+
TEuerAccountLines,
|
|
8
9
|
TMappingDimension,
|
|
10
|
+
TSecuritiesRole,
|
|
11
|
+
TTaxRule,
|
|
9
12
|
} from './chartdata.types.js';
|
|
13
|
+
import { euerLinesOf, type IEuerLinesOptions } from './chartdata.euer.js';
|
|
10
14
|
import { SKR03_2026 } from './data/skr03.2026.js';
|
|
11
15
|
import { SKR04_2026 } from './data/skr04.2026.js';
|
|
12
16
|
|
|
@@ -81,6 +85,34 @@ export function getAccountsByRole(
|
|
|
81
85
|
return getChart(chart, year).accounts.filter((account) => account.accountRole === role);
|
|
82
86
|
}
|
|
83
87
|
|
|
88
|
+
/**
|
|
89
|
+
* The accounts of a chart with the securities role (`IChartAccount.securitiesRole`),
|
|
90
|
+
* in the chart's order: one without a tax rule and, where DATEV keeps one apart,
|
|
91
|
+
* one under § 3 Nr. 40 EStG / § 8b KStG. Throws for unknown chart/year
|
|
92
|
+
* combinations, as `getChart`.
|
|
93
|
+
*/
|
|
94
|
+
export function getAccountsBySecuritiesRole(
|
|
95
|
+
chart: TChartName,
|
|
96
|
+
year: number,
|
|
97
|
+
role: TSecuritiesRole,
|
|
98
|
+
): IChartAccount[] {
|
|
99
|
+
return getChart(chart, year).accounts.filter((account) => account.securitiesRole === role);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The one account of a chart that books the securities role under the tax rule
|
|
104
|
+
* (`taxRule`; none: the account without one), or `null` where the chart keeps
|
|
105
|
+
* none for it. Throws for unknown chart/year combinations, as `getChart`.
|
|
106
|
+
*/
|
|
107
|
+
export function getSecuritiesAccount(
|
|
108
|
+
chart: TChartName,
|
|
109
|
+
year: number,
|
|
110
|
+
role: TSecuritiesRole,
|
|
111
|
+
taxRule?: TTaxRule,
|
|
112
|
+
): IChartAccount | null {
|
|
113
|
+
return getAccountsBySecuritiesRole(chart, year, role).find((account) => account.taxRule === taxRule) ?? null;
|
|
114
|
+
}
|
|
115
|
+
|
|
84
116
|
function hasMapping(account: IChartAccount, dimension: TMappingDimension): boolean {
|
|
85
117
|
switch (dimension) {
|
|
86
118
|
case 'ustva':
|
|
@@ -91,6 +123,8 @@ function hasMapping(account: IChartAccount, dimension: TMappingDimension): boole
|
|
|
91
123
|
return account.hgb275Position !== undefined;
|
|
92
124
|
case 'ebilanz':
|
|
93
125
|
return account.ebilanzPosition !== undefined;
|
|
126
|
+
case 'euer':
|
|
127
|
+
return account.euer !== undefined || account.euerExclusion !== undefined;
|
|
94
128
|
}
|
|
95
129
|
}
|
|
96
130
|
|
|
@@ -120,3 +154,21 @@ export function getMappingCoverage(
|
|
|
120
154
|
}
|
|
121
155
|
return { dimension, requested: usedAccounts.length, covered, missing, unknown };
|
|
122
156
|
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* The Anlage EÜR lines of a chart's account in a form year (`euerLinesOf`):
|
|
160
|
+
* where its movements go, or why they are no part of the form. `null` for an
|
|
161
|
+
* account the chart does not hold. Throws for an unknown chart, chart year or
|
|
162
|
+
* form year. The chart year and the form year are apart on purpose: a host
|
|
163
|
+
* that books a year on the nearest chart dataset states it on that year's form.
|
|
164
|
+
*/
|
|
165
|
+
export function getEuerLines(
|
|
166
|
+
chart: TChartName,
|
|
167
|
+
chartYear: number,
|
|
168
|
+
accountNumber: string,
|
|
169
|
+
formYear: number,
|
|
170
|
+
options: IEuerLinesOptions = {},
|
|
171
|
+
): TEuerAccountLines | null {
|
|
172
|
+
const account = getAccount(chart, chartYear, accountNumber);
|
|
173
|
+
return account ? euerLinesOf(account, formYear, options) : null;
|
|
174
|
+
}
|