@fin.cx/chartdata 3.2.0 → 3.3.1

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.
@@ -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.bwa.js';
4
5
  export * from './chartdata.euer.js';
5
6
  export { SKR03_2026 } from './data/skr03.2026.js';
6
7
  export { SKR04_2026 } from './data/skr04.2026.js';
package/dist_ts/index.js CHANGED
@@ -1,9 +1,10 @@
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.bwa.js';
4
5
  export * from './chartdata.euer.js';
5
6
  export { SKR03_2026 } from './data/skr03.2026.js';
6
7
  export { SKR04_2026 } from './data/skr04.2026.js';
7
8
  export * from './chartdata.individual.js';
8
9
  export { DATEV_NUMBERS_SKR03_2026, DATEV_NUMBERS_SKR04_2026 } from './data/datevnumbers.2026.js';
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHNCQUFzQixDQUFDO0FBQ3JDLGNBQWMsdUJBQXVCLENBQUM7QUFDdEMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsY0FBYywyQkFBMkIsQ0FBQztBQUMxQyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQyJ9
10
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHNCQUFzQixDQUFDO0FBQ3JDLGNBQWMsdUJBQXVCLENBQUM7QUFDdEMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLG9CQUFvQixDQUFDO0FBQ25DLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxjQUFjLDJCQUEyQixDQUFDO0FBQzFDLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDIn0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fin.cx/chartdata",
3
- "version": "3.2.0",
3
+ "version": "3.3.1",
4
4
  "private": false,
5
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",
@@ -28,10 +28,10 @@
28
28
  },
29
29
  "homepage": "https://code.foss.global/fin.cx/chartdata#readme",
30
30
  "devDependencies": {
31
- "@git.zone/tsbuild": "^5.1.2",
32
- "@git.zone/tsrun": "^3.0.2",
31
+ "@git.zone/tsbuild": "^6.0.2",
32
+ "@git.zone/tsrun": "^3.0.3",
33
33
  "@git.zone/tstest": "^7.2.0",
34
- "@types/node": "^26.6.3"
34
+ "@types/node": "^26.6.4"
35
35
  },
36
36
  "files": [
37
37
  "ts/**/*",
package/readme.md CHANGED
@@ -58,6 +58,8 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
58
58
  checked against the numbers the DATEV Kontenrahmen assigns and reserves
59
59
  (`getDatevNumbers`)
60
60
  - Coverage introspection that fails loudly on mapping gaps
61
+ - Report metadata: an independently defined standard KER (`bwaLine`, `BWA_LINES`),
62
+ balance-side rules (`balanceRule`), and explicit technical exclusions (`hgb266Exclusion`)
61
63
  - Provenance on every record
62
64
 
63
65
  ## Installation
@@ -266,6 +268,53 @@ part (§ 8 Nr. 1 f GewStG); the books book a licence of a right there
266
268
  themselves. An individual account takes no expense role: a role names the
267
269
  DATEV account.
268
270
 
271
+ ### Funding and reimbursement settlements
272
+
273
+ The charts classify the following DATEV 2026 accounts. Their availability is
274
+ not a rule selecting an account for a business or deciding its funding agreement.
275
+
276
+ | Purpose | SKR03 | SKR04 |
277
+ | --- | --- | --- |
278
+ | Cash of the books' till (Kasse) | 1000 | 1600 |
279
+ | Ordinary payroll clearing (Lohn- und Gehaltsverrechnungskonto) | 1755 | 3790 |
280
+ | Special recurring-payroll timing under § 11 Abs. 2 Satz 2 EStG for § 4 Abs. 3 EStG | 1756 | 3791 |
281
+ | Privateinlagen where legally applicable | 1890 | 2180 |
282
+ | Verbindlichkeiten gegenüber Gesellschaftern | 0730 | 3510 |
283
+ | Verbindlichkeiten gegenüber GmbH-Gesellschaftern | 1665 | 3640 |
284
+ | Verbindlichkeiten gegenüber persönlich haftenden Gesellschaftern | 1670 | 3645 |
285
+ | Verbindlichkeiten gegenüber Kommanditisten | 1675 | 3650 |
286
+
287
+ The debt accounts are liabilities under `Passiva C.8`; DATEV also states
288
+ receivables there by their debit balance (`balanceRule.debitPosition:
289
+ 'Aktiva B.II.4'`). Payroll clearing is curated under `Aktiva B.II.4`, with a
290
+ credit balance under `Passiva C.8`. These settlement accounts have no tax
291
+ automatism, VAT figure or P&L line and are excluded from Anlage EÜR as
292
+ `balance_sheet`. A liability settlement is not a second expense or supplier
293
+ receipt; it does not itself change the original receipt's input tax.
294
+
295
+ 1756/3791 do not replace 1755/3790 merely because the books use EÜR. They carry
296
+ no payroll role; `getPayrollAccount(..., 'clearing')` still returns 1755/3790.
297
+ The books select the actual cash/payroll counter-account. For private funding,
298
+ the payer, legal form in force, partner status and evidenced equity contribution
299
+ or reimbursement/repayment right determine the treatment. A liability owed to
300
+ a shareholder is not a claim against that shareholder. Do not infer contribution,
301
+ loan maturity or an individual partner account from the payment label or chart.
302
+ Refuse when the books have not supplied the deciding facts or account. Existing
303
+ private-contribution restrictions (`sole_trader`, `partnership`) remain; they
304
+ do not establish that a particular partner's payment is equity. Separately
305
+ agreed corporate equity contributions require their lawful equity account,
306
+ not a private-account or debt default.
307
+
308
+ Sources: DATEV's [SKR03 2026](https://www.datev.de/content/dam/markenassets/themen-und-produktgruppen/zielgruppen/mandant/unternehmer/branche/bau/11174%20SKR03%20BilrUg.pdf),
309
+ pp. 3, 6, 9-12, and [SKR04 2026](https://www.datev.de/content/dam/markenassets/themen-und-produktgruppen/zielgruppen/mandant/unternehmer/branche/bau/11175%20SKR04%20BilrUg.pdf),
310
+ pp. 6-7, 12-13; DATEV's [business-specific Kontenplan explanation](https://www.datev.de/web/de/berufsgruppenuebergreifend/ratgeber/rechnungswesen/datev-standard-kontenrahmen);
311
+ GoB traceability and accurate recording ([§ 238 HGB](https://www.gesetze-im-internet.de/hgb/__238.html),
312
+ [§ 239 HGB](https://www.gesetze-im-internet.de/hgb/__239.html)); contribution versus
313
+ repayment ([§ 4 EStG](https://www.gesetze-im-internet.de/estg/__4.html),
314
+ [§ 670 BGB](https://www.gesetze-im-internet.de/bgb/__670.html),
315
+ [§ 272 Abs. 2 Nr. 4 HGB](https://www.gesetze-im-internet.de/hgb/__272.html));
316
+ the original invoice's input tax ([§ 15 UStG](https://www.gesetze-im-internet.de/ustg_1980/__15.html)).
317
+
269
318
  ### Individual accounts
270
319
 
271
320
  The books may set up accounts of their own (Individualkonten) on the numbers
@@ -400,6 +449,139 @@ getMappingCoverage('SKR04', 2026, usedAccountNumbers, 'euer').missing; // []
400
449
  and another member state's VAT (OSS) is received in Kz 103 and paid in
401
450
  Kz 183.
402
451
 
452
+ ### BWA: independently defined standard KER
453
+
454
+ `BWA_LINES` is this package's own short-term income statement (Kurzfristige
455
+ Erfolgsrechnung), **not DATEV BWA schema 0906300** and not an implementation of
456
+ its proprietary account-assignment rules. It combines the existing HGB §275
457
+ Gesamtkostenverfahren positions with the public account purposes/ranges of SKR03
458
+ and SKR04 2026. Every curated revenue or expense account has exactly one
459
+ `bwaLine: TBwaPostingLineKey`; balance-sheet accounts have none. Unknown HGB
460
+ positions fail generation instead of silently reaching an unassigned bucket.
461
+
462
+ The ordered, exported `BWA_LINES: readonly TBwaLine[]` contains:
463
+
464
+ - Posting lines: `{ key, label, kind: 'posting', normalSide: 'debit' | 'credit' }`.
465
+ Use selected-period movements, credit minus debit for a credit-normal line,
466
+ debit minus credit for a debit-normal line. Account type does not override this
467
+ sign: disposal proceeds can reduce a neutral expense, and a disposed asset's
468
+ book value can reduce a neutral income.
469
+ - Computed lines: `{ key, label, kind: 'subtotal', terms: [{ line, factor }] }`.
470
+ `factor` is `1` or `-1`; every referenced line precedes the subtotal. Sum the
471
+ already computed amounts times those factors, without posting to subtotals.
472
+
473
+ Credit-normal posting keys are `revenue`, `inventory_changes`,
474
+ `own_work_capitalized`, `other_operating_income`, `interest_income`,
475
+ `other_neutral_income`, and `unassigned_account_classes`. All other posting
476
+ keys are debit-normal. `unassigned_account_classes` is the explicit
477
+ "Kontenklassen-unbesetzt" row, zero for the curated charts; it is no fallback
478
+ for unknown accounts or missing mappings.
479
+
480
+ Exact subtotal definitions (the exported `terms` encode these formulas):
481
+
482
+ | Subtotal key | Definition |
483
+ | --- | --- |
484
+ | `total_output` | `revenue + inventory_changes + own_work_capitalized` |
485
+ | `gross_profit` | `total_output - material_costs` |
486
+ | `operating_gross_profit` | `gross_profit + other_operating_income` |
487
+ | `total_costs` | `personnel_costs + premises_costs + business_taxes + insurance_contributions + special_costs + vehicle_costs + advertising_travel_costs + goods_distribution_costs + depreciation + repairs_maintenance + other_operating_costs` |
488
+ | `operating_result` | `operating_gross_profit - total_costs` |
489
+ | `neutral_expense` | `interest_expense + other_neutral_expense` |
490
+ | `neutral_income` | `interest_income + other_neutral_income` |
491
+ | `result_before_taxes` | `operating_result - neutral_expense + neutral_income + unassigned_account_classes` |
492
+ | `provisional_result` | `result_before_taxes - income_taxes` |
493
+
494
+ Derivation order is significant. GuV 1→`revenue`, 2→`inventory_changes`,
495
+ 3→`own_work_capitalized`, 5→`material_costs`, 6a/6b→`personnel_costs`,
496
+ 7→`depreciation`, 9/10→`other_neutral_income`, 11→`interest_income`,
497
+ 12→`other_neutral_expense`, 13→`interest_expense`, 14→`income_taxes`,
498
+ 16→`business_taxes`. GuV 15 and 17 are results, not posting positions.
499
+ In particular, trade tax (4320/7610, GuV 14) is an income tax, not an
500
+ operating tax merely because of its number.
501
+
502
+ GuV 4 disposal-role accounts and neutral-income ranges (SKR03 2500–2699,
503
+ 2710–2729; SKR04 4840–4929) go to `other_neutral_income`; remaining GuV 4
504
+ accounts go to `other_operating_income`. GuV 8 disposal-role accounts and
505
+ neutral-expense ranges (SKR03 2000–2399, 4976–4977; SKR04 6857–6858,
506
+ 6880–6909) go to `other_neutral_expense`. Remaining GuV 8 accounts use these
507
+ inclusive, non-overlapping operating-cost ranges, then `other_operating_costs`:
508
+
509
+ | Posting key | SKR03 | SKR04 |
510
+ | --- | --- | --- |
511
+ | `premises_costs` | 4200–4299 | 6310–6349 |
512
+ | `business_taxes` | 4340–4359 | 7680–7699 |
513
+ | `insurance_contributions` | 4360–4399 | 6400–6449 |
514
+ | `special_costs` | 4400–4499 (free-purpose range) | 6390–6399 (donations) |
515
+ | `vehicle_costs` | 4500–4599 | 6500–6599 |
516
+ | `advertising_travel_costs` | 4600–4699 | 6600–6699 |
517
+ | `goods_distribution_costs` | 4700–4799 | 6700–6799 |
518
+ | `repairs_maintenance` | 4800–4809 | 6450–6499 |
519
+ | `depreciation` | 4810–4899 | 6910–6919 |
520
+
521
+ The ranges categorise existing GuV accounts; they neither add accounts to the
522
+ curated selection nor license booking on DATEV-reserved numbers. Financial
523
+ write-downs stay in the neutral result because GuV 12 is resolved first.
524
+ The ordinary write-down of other current assets (4886/6910, GuV 8) is included
525
+ in the KER's depreciation line. This is our published derivation, not a promise
526
+ of identical intermediate totals to any third-party BWA.
527
+
528
+ ### Bilanz: balance rules and exclusions
529
+
530
+ Use cumulative balances through the cutoff, not only the report-period
531
+ movements. `hgb266Position` remains the normal-side position;
532
+ `balanceRule: IBalanceRule` supplies an exceptional `debitPosition` or
533
+ `creditPosition` only. An individual account's normal-side HGB override
534
+ therefore remains authoritative. The standard metadata specifies:
535
+
536
+ - Bank credit balances: `Passiva C.2` (SKR03 1200–1299, SKR04 1800–1899,
537
+ restricted to accounts whose normal position is `Aktiva B.IV`). Cash and
538
+ Geldtransit are not bank-overdraft rules.
539
+ - Debtor credit balances: `Passiva C.4`; creditor debit balances:
540
+ `Aktiva B.II.1`. The Debitoren/Kreditoren carry-forward accounts 9008/9009
541
+ keep their normal positions and these same exceptional-side rules.
542
+ - Current domestic VAT: `vatNetGroup: 'vat_current_year'`, the cumulative
543
+ debit-minus-credit sum of the group at `Aktiva B.II.4` when positive and
544
+ `Passiva C.8` when negative. SKR03 members are 1570, 1571, 1574, 1576, 1577,
545
+ 1588, 1770, 1771, 1774, 1776, 1780, 1781, 1784, 1787; SKR04 members are
546
+ 1400, 1401, 1404, 1406, 1407, 1433, 3800, 3801, 3804, 3806, 3820, 3830,
547
+ 3837. Do not state individual members again after netting the group.
548
+ - Prior-year VAT (1790/1791, 3841/3845) and foreign VAT (1728/1767/1768,
549
+ 3798/3817/3818) have sign-sensitive asset/liability rules but **no net group**:
550
+ they remain separate from the current domestic VAT. Payroll taxes do not
551
+ enter the VAT group.
552
+ - Private drawings **and contributions** (1800/1890, 2100/2180):
553
+ `legalForms: ['sole_trader', 'partnership']`. `TLegalForm` also contains
554
+ `'corporation'`, which these accounts do not permit. A report must explicitly
555
+ refuse a nonzero private balance for a corporation instead of treating it as
556
+ corporate equity. This is a conservative report eligibility rule, not a
557
+ substitute for the distinct partnership equity presentation of §264c HGB.
558
+ - Exactly 9000/9400/9998: `hgb266Exclusion: 'technical'`, no balance-sheet
559
+ position. Exclusion explains classification, **not permission to discard
560
+ a nonzero balance**. A report must refuse nonzero technical balances; 9000
561
+ must net to zero across a complete set of opening entries.
562
+
563
+ `HGB_ANNUAL_RESULT_POSITION` is `Passiva A.V`. Add cumulative, credit-minus-debit
564
+ P&L through the cutoff there once, including a negative annual result. Do not
565
+ use `Passiva A.IV` (prior-year retained result) or technical 9400 for it.
566
+ `getMappingCoverage(..., 'hgb266')` treats an explicit technical exclusion as
567
+ classified; the report still enforces the nonzero-balance refusal.
568
+ `getMappingCoverage(..., 'bwa')` checks posting-line metadata. In either
569
+ dimension, unknown and missing accounts remain distinct errors.
570
+
571
+ `BooksChart` individual accounts inherit `bwaLine`, `hgb266Exclusion`, and a
572
+ copy of `balanceRule` from their parent. Report consumers use the books' chart,
573
+ not a separate hardcoded account map. Mapping and report-generation rules
574
+ live in `tools/report-mappings.ts` and `tools/generate-charts.ts`.
575
+
576
+ Primary sources read on 2026-10-09: [HGB §266](https://www.gesetze-im-internet.de/hgb/__266.html),
577
+ [HGB §275](https://www.gesetze-im-internet.de/hgb/__275.html),
578
+ [HGB §264c](https://www.gesetze-im-internet.de/hgb/__264c.html),
579
+ [UStG §16](https://www.gesetze-im-internet.de/ustg_1980/__16.html), and the
580
+ public DATEV Kontenrahmen 2026 [SKR03, Art.-Nr. 11174](https://help-center.apps.datev.de/api/amr/knowledge-common/v1/entities/st9007262836099723_de.pdf)
581
+ (pp. 13–17, 22–25) and [SKR04, Art.-Nr. 11175](https://help-center.apps.datev.de/api/amr/knowledge-common/v1/entities/st9007262836101387_de.pdf)
582
+ (pp. 17–24). Account categories come from those public charts; the KER
583
+ selection, labels, boundaries and calculations above are independently defined.
584
+
403
585
  ## Data Provenance and Verification
404
586
 
405
587
  Records carry a `provenance` string. The datasets are a curated table authored
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@fin.cx/chartdata',
6
- version: '3.2.0',
6
+ version: '3.3.1',
7
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,74 @@
1
+ import type { TBwaLine } from './chartdata.types.js';
2
+
3
+ export const BWA_LINES: readonly TBwaLine[] = [
4
+ { key: 'revenue', label: 'Umsatzerlöse', kind: 'posting', normalSide: 'credit' },
5
+ { key: 'inventory_changes', label: 'Bestandsveränderungen', kind: 'posting', normalSide: 'credit' },
6
+ { key: 'own_work_capitalized', label: 'Aktivierte Eigenleistungen', kind: 'posting', normalSide: 'credit' },
7
+ { key: 'total_output', label: 'Gesamtleistung', kind: 'subtotal', terms: [
8
+ { line: 'revenue', factor: 1 },
9
+ { line: 'inventory_changes', factor: 1 },
10
+ { line: 'own_work_capitalized', factor: 1 },
11
+ ] },
12
+ { key: 'material_costs', label: 'Material- und Wareneinsatz', kind: 'posting', normalSide: 'debit' },
13
+ { key: 'gross_profit', label: 'Rohertrag', kind: 'subtotal', terms: [
14
+ { line: 'total_output', factor: 1 },
15
+ { line: 'material_costs', factor: -1 },
16
+ ] },
17
+ { key: 'other_operating_income', label: 'Sonstige betriebliche Erlöse', kind: 'posting', normalSide: 'credit' },
18
+ { key: 'operating_gross_profit', label: 'Betrieblicher Rohertrag', kind: 'subtotal', terms: [
19
+ { line: 'gross_profit', factor: 1 },
20
+ { line: 'other_operating_income', factor: 1 },
21
+ ] },
22
+ { key: 'personnel_costs', label: 'Personalkosten', kind: 'posting', normalSide: 'debit' },
23
+ { key: 'premises_costs', label: 'Raumkosten', kind: 'posting', normalSide: 'debit' },
24
+ { key: 'business_taxes', label: 'Betriebliche Steuern', kind: 'posting', normalSide: 'debit' },
25
+ { key: 'insurance_contributions', label: 'Versicherungen und Beiträge', kind: 'posting', normalSide: 'debit' },
26
+ { key: 'special_costs', label: 'Besondere Kosten', kind: 'posting', normalSide: 'debit' },
27
+ { key: 'vehicle_costs', label: 'Fahrzeugkosten', kind: 'posting', normalSide: 'debit' },
28
+ { key: 'advertising_travel_costs', label: 'Werbe- und Reisekosten', kind: 'posting', normalSide: 'debit' },
29
+ { key: 'goods_distribution_costs', label: 'Kosten der Warenabgabe', kind: 'posting', normalSide: 'debit' },
30
+ { key: 'depreciation', label: 'Abschreibungen', kind: 'posting', normalSide: 'debit' },
31
+ { key: 'repairs_maintenance', label: 'Reparaturen und Instandhaltung', kind: 'posting', normalSide: 'debit' },
32
+ { key: 'other_operating_costs', label: 'Sonstige Kosten', kind: 'posting', normalSide: 'debit' },
33
+ { key: 'total_costs', label: 'Gesamtkosten', kind: 'subtotal', terms: [
34
+ { line: 'personnel_costs', factor: 1 },
35
+ { line: 'premises_costs', factor: 1 },
36
+ { line: 'business_taxes', factor: 1 },
37
+ { line: 'insurance_contributions', factor: 1 },
38
+ { line: 'special_costs', factor: 1 },
39
+ { line: 'vehicle_costs', factor: 1 },
40
+ { line: 'advertising_travel_costs', factor: 1 },
41
+ { line: 'goods_distribution_costs', factor: 1 },
42
+ { line: 'depreciation', factor: 1 },
43
+ { line: 'repairs_maintenance', factor: 1 },
44
+ { line: 'other_operating_costs', factor: 1 },
45
+ ] },
46
+ { key: 'operating_result', label: 'Betriebsergebnis', kind: 'subtotal', terms: [
47
+ { line: 'operating_gross_profit', factor: 1 },
48
+ { line: 'total_costs', factor: -1 },
49
+ ] },
50
+ { key: 'interest_expense', label: 'Zinsaufwand', kind: 'posting', normalSide: 'debit' },
51
+ { key: 'other_neutral_expense', label: 'Sonstiger neutraler Aufwand', kind: 'posting', normalSide: 'debit' },
52
+ { key: 'neutral_expense', label: 'Neutraler Aufwand', kind: 'subtotal', terms: [
53
+ { line: 'interest_expense', factor: 1 },
54
+ { line: 'other_neutral_expense', factor: 1 },
55
+ ] },
56
+ { key: 'interest_income', label: 'Zinserträge', kind: 'posting', normalSide: 'credit' },
57
+ { key: 'other_neutral_income', label: 'Sonstiger neutraler Ertrag', kind: 'posting', normalSide: 'credit' },
58
+ { key: 'neutral_income', label: 'Neutraler Ertrag', kind: 'subtotal', terms: [
59
+ { line: 'interest_income', factor: 1 },
60
+ { line: 'other_neutral_income', factor: 1 },
61
+ ] },
62
+ { key: 'unassigned_account_classes', label: 'Kontenklassen-unbesetzt', kind: 'posting', normalSide: 'credit' },
63
+ { key: 'result_before_taxes', label: 'Ergebnis vor Steuern', kind: 'subtotal', terms: [
64
+ { line: 'operating_result', factor: 1 },
65
+ { line: 'neutral_expense', factor: -1 },
66
+ { line: 'neutral_income', factor: 1 },
67
+ { line: 'unassigned_account_classes', factor: 1 },
68
+ ] },
69
+ { key: 'income_taxes', label: 'Steuern vom Einkommen und Ertrag', kind: 'posting', normalSide: 'debit' },
70
+ { key: 'provisional_result', label: 'Vorläufiges Ergebnis', kind: 'subtotal', terms: [
71
+ { line: 'result_before_taxes', factor: 1 },
72
+ { line: 'income_taxes', factor: -1 },
73
+ ] },
74
+ ];
@@ -10,6 +10,8 @@ export interface IHgbPosition {
10
10
  label: string;
11
11
  }
12
12
 
13
+ export const HGB_ANNUAL_RESULT_POSITION = 'Passiva A.V';
14
+
13
15
  export const HGB_266_POSITIONS: IHgbPosition[] = [
14
16
  { key: 'Aktiva A.I.1', label: 'Selbst geschaffene gewerbliche Schutzrechte und ähnliche Rechte und Werte' },
15
17
  { key: 'Aktiva A.I.2', label: 'Entgeltlich erworbene Konzessionen, gewerbliche Schutzrechte und ähnliche Rechte und Werte sowie Lizenzen an solchen Rechten und Werten' },
@@ -247,6 +247,12 @@ function individualAccountOf(parentArg: IChartAccount, declarationArg: IIndividu
247
247
  ...(ustva ? { ustva } : {}),
248
248
  ...(hgb266Position ? { hgb266Position } : {}),
249
249
  ...(hgb275Position ? { hgb275Position } : {}),
250
+ ...(parentArg.bwaLine ? { bwaLine: parentArg.bwaLine } : {}),
251
+ ...(parentArg.hgb266Exclusion ? { hgb266Exclusion: parentArg.hgb266Exclusion } : {}),
252
+ ...(parentArg.balanceRule ? { balanceRule: {
253
+ ...parentArg.balanceRule,
254
+ ...(parentArg.balanceRule.legalForms ? { legalForms: [...parentArg.balanceRule.legalForms] } : {}),
255
+ } } : {}),
250
256
  ...(parentArg.ebilanzPosition ? { ebilanzPosition: parentArg.ebilanzPosition } : {}),
251
257
  ...(euer ? { euer } : {}),
252
258
  ...(euerExclusion ? { euerExclusion } : {}),
@@ -136,7 +136,9 @@ function hasMapping(account: IChartAccount, dimension: TMappingDimension): boole
136
136
  case 'ustva':
137
137
  return account.ustva !== undefined;
138
138
  case 'hgb266':
139
- return account.hgb266Position !== undefined;
139
+ return account.hgb266Position !== undefined || account.hgb266Exclusion !== undefined;
140
+ case 'bwa':
141
+ return account.bwaLine !== undefined;
140
142
  case 'hgb275':
141
143
  return account.hgb275Position !== undefined;
142
144
  case 'ebilanz':
@@ -386,6 +386,70 @@ export type TEuerAccountLines =
386
386
  | { kind: 'split'; debitLine: IEuerFormLine; creditLine: IEuerFormLine }
387
387
  | { kind: 'excluded'; exclusion: TEuerExclusion };
388
388
 
389
+ export type TLegalForm = 'sole_trader' | 'partnership' | 'corporation';
390
+
391
+ export type THgb266Exclusion = 'technical';
392
+
393
+ export interface IBalanceRule {
394
+ debitPosition?: string;
395
+ creditPosition?: string;
396
+ vatNetGroup?: string;
397
+ legalForms?: readonly TLegalForm[];
398
+ }
399
+
400
+ export type TBwaPostingLineKey =
401
+ | 'revenue'
402
+ | 'inventory_changes'
403
+ | 'own_work_capitalized'
404
+ | 'material_costs'
405
+ | 'other_operating_income'
406
+ | 'personnel_costs'
407
+ | 'premises_costs'
408
+ | 'business_taxes'
409
+ | 'insurance_contributions'
410
+ | 'special_costs'
411
+ | 'vehicle_costs'
412
+ | 'advertising_travel_costs'
413
+ | 'goods_distribution_costs'
414
+ | 'depreciation'
415
+ | 'repairs_maintenance'
416
+ | 'other_operating_costs'
417
+ | 'interest_expense'
418
+ | 'other_neutral_expense'
419
+ | 'interest_income'
420
+ | 'other_neutral_income'
421
+ | 'unassigned_account_classes'
422
+ | 'income_taxes';
423
+
424
+ export type TBwaSubtotalLineKey =
425
+ | 'total_output'
426
+ | 'gross_profit'
427
+ | 'operating_gross_profit'
428
+ | 'total_costs'
429
+ | 'operating_result'
430
+ | 'neutral_expense'
431
+ | 'neutral_income'
432
+ | 'result_before_taxes'
433
+ | 'provisional_result';
434
+
435
+ export type TBwaLineKey = TBwaPostingLineKey | TBwaSubtotalLineKey;
436
+
437
+ export interface IBwaPostingLine {
438
+ key: TBwaPostingLineKey;
439
+ label: string;
440
+ kind: 'posting';
441
+ normalSide: 'debit' | 'credit';
442
+ }
443
+
444
+ export interface IBwaSubtotalLine {
445
+ key: TBwaSubtotalLineKey;
446
+ label: string;
447
+ kind: 'subtotal';
448
+ terms: readonly { line: TBwaLineKey; factor: 1 | -1 }[];
449
+ }
450
+
451
+ export type TBwaLine = IBwaPostingLine | IBwaSubtotalLine;
452
+
389
453
  export interface IChartAccount {
390
454
  accountNumber: string;
391
455
  accountName: string;
@@ -417,6 +481,9 @@ export interface IChartAccount {
417
481
  hgb266Position?: string;
418
482
  /** HGB §275 GuV position path (A2) */
419
483
  hgb275Position?: string;
484
+ bwaLine?: TBwaPostingLineKey;
485
+ hgb266Exclusion?: THgb266Exclusion;
486
+ balanceRule?: IBalanceRule;
420
487
  /** E-Bilanz de-gaap-ci taxonomy position (A3 — not yet populated) */
421
488
  ebilanzPosition?: string;
422
489
  /** the Anlage EÜR line(s) the account's movements go to; every account has this or `euerExclusion` */
@@ -437,7 +504,7 @@ export interface IChart {
437
504
  }
438
505
 
439
506
  /** 'euer' counts an account covered when it maps to the Anlage EÜR or is excluded from it with a reason. */
440
- export type TMappingDimension = 'ustva' | 'hgb266' | 'hgb275' | 'ebilanz' | 'euer';
507
+ export type TMappingDimension = 'ustva' | 'hgb266' | 'hgb275' | 'bwa' | 'ebilanz' | 'euer';
441
508
 
442
509
  export interface IMappingCoverage {
443
510
  dimension: TMappingDimension;