[IMP] l10n_at_hr_payroll_private: GP7 mBGM/JASV + Versichertenmeldung + fallweise Anmeldung auf dem ELDA-Framework

mBGM/JASV (models/mbgm.py — DM-ORG 42.7.0 E.32, BEST MB, Version 02): Paket PS (BKNR/DGNA/BZRM/GSUM/ANZM) → mBGM G1 (REFW/VSNR/FANA/VONA/VSUM/VERG=1) → Tarifblock T1 (BSGR/VVON) → Verrechnungsbasis BS (VBTY/VBBT) → Verrechnungsposition V1 (VPTY/VPVZ/VPTA/RSVZ/RSUM). KEIN DN/DG-Zweig-Split: T01 = GESAMT-Prozentsatz des Tarifsystems je Beschäftigtengruppe (Parameter at_mbgm_tarif, normativ: laufend 39,05 % = KV 7,65 + PV 22,80 + AV 5,90 + UV 1,10 + WF 1,00 + IESG 0,10; SZ 37,55 % = DN KV 3,87 + PV 10,25 + AV 2,95 + DG 20,48). Abschläge als EIGENE Verrechnungspositionen je Basis: A03/A02/A01 = Minderung AV auf 0/1/2 % (§ 2a AMPFG, nur DN-AV, je Verrechnungsbasis AB UND SZ), A09 = UV-Entfall 60, A10 = AV+IE-Entfall Pensionsanspruch (Konkurrenz a4: sperrt Staffelabschlag), A15 = PV-Halbierung Bonusphase — konsistent mit der GP4-§-2a-DN-seitig-Konvention. BV (BMSVG): eigene Verrechnungsbasis BV (ungedeckelt, GP5) + Position V01 1,53 %. RSUM = Basis x Satz (mBGM-Tarifierung), Konsistenz-Check gegen GP4-Payslip-Beitragssummen ±0,10 € als Prüfwarnung. Storno: R1-Sätze mit REFU/VSUM wie Original. Fehlanzeige: Paket ohne mBGM-Sätze (ANZM 0). Geringfügige/fallweise ohne Parametrisierung: listenweiser Abbruch (keine Tarif-Erfindung; BSGR B044/B045/B010/B030 aus dem SV-Tarifsystem pflegen).

Versichertenmeldung (models/versichertenmeldung.py — DM-ORG E.29, BEST VR, Version 03, Satzlänge 772): M3 vor Arbeitsantritt / M4 (7 Kalendertage ab PV-Ende) mit deklarativer Event-Erkennung über die Meldungs-Registry (l10n.at.payroll.vr.event) — idempotente Läufe, Dimona-auto-Idee ohne write-diff-Hacks. Felder: BKNR/VSNR/GEBD/FANA/VONA (Namenssplit am letzten Leerzeichen), ADAT/EBSV, BBER 01-04 aus l10n_at_personalgruppe/lehrling, GERF (Kataloggehalt vs. GFG), FRDV, BVAB/BVJN aus dem GP5-BMSVG-Flag, VWAZ (Stunden x100, neu ab 01.01.2026), AGRD aus dem hr.departure.reason-Mapping (Standard 00). Fallweise Anmeldung (BEST MA, SART 32, Version 07, Länge 450): MVP je Anmeldetag am Vertragsbeginn; tagesgenaue Einsatztage via Work-Entry-Auswertung = dokumentierter Rest.

NSchAB-Branche als Company-Flag (l10n_at_nschab): B001-T01 + 3,80 % (Schlechtwetterentschädigung, ÖGK-Tarifsystem Normalbetriebe mit Schlechtwetterentschädigung).

Tests: test_meldewesen_private (2 — mBGM-Satzhierarchie mit A03 je Basis aus November-Fixture + GSUM-Konsistenz; VR M3/M4 mit Registry-Idempotenz und AGRD). Rechenfälle docs/rechenfaelle/meldewesen.md. 19.0.7.0.0.
This commit is contained in:
2026-09-12 17:31:12 +02:00
parent c474a39466
commit 14940ac31a
11 changed files with 1434 additions and 13 deletions
@@ -0,0 +1,112 @@
# Rechenfälle Meldewesen/Belege (GP7) — ELDA/eSV, L16, Belege
**Quellen:** DM-ORG 42.7.0 „Datenaustausch mit Dienstgebern", 42.
Ergänzung 07/2026 (`.firecrawl/ris/elda/` — Volltext-PDF + pdftotext;
Satzstrukturen PDF-verifiziert extrahiert 2026-09-12, Positions-
Ketten lückenlos); Pruefkatalog L16 ab 2026 (Stand 12/2025, xlsx);
KB lb-lvr-04/05 (L16), lb-mel-08 (Fristen), lb-bes-02/03 (fallweise),
lb-sva-14 (SZ-Sätze), lb-swa-05 (Schwerarbeit, out); Nutzer-
Entscheidungen 5.15.4 (Arbeitsstättenmeldung in GP7; Mitteilungsfile-
Import Rest; **FB+ = keine Personalverrechnung** — bei Steuer < 0
Arbeitnehmerveranlagung, **Kind-Modell für die FABO+-Wartung**; alles
in einem GP7). Umsetzung: Kern `l10n_at_hr_payroll` 19.0.4.0.0
(`models/elda.py`, `lohnzettel_l16.py`, `kind.py`, `meldewesen.py`,
`monatsreports.py`, `report/belege_reports.xml`), privat
19.0.7.0.0 (`models/mbgm.py`, `versichertenmeldung.py`,
`data/rule_parameters_mbgm_private.xml`). Tests: `test_elda_l16`,
`test_meldewesen_private`.
## Systematik (GP7, verifiziert)
- **ELDA-Fixlängen-Dateien** (C.1/C.2, E.1E.3): Datei = optionaler
Dateiheader (DHKZ 2×blank, DHVN 01, ENCD **ISO-8859-15**) + Daten-
bestand (Vorlaufsatz SART 00 mit BEST/VSTR/VERS → Datensätze →
Schlusssatz SART 99 mit SANZ inkl. Vorlauf/Schluss); a/n linksbündig
blank-gefüllt, n rechtsbündig null-gefüllt, **Cent ohne
Interpunktion**, Prozentsätze ×1000 (3 Nachkommastellen), SANR
lückenlos ab 1. **CRLF als Satztrenner = Praxis-Annahme** (die
DM-ORG normiert kein Trennzeichen — Parallellauf verifizieren).
- **mBGM/JASV** (BEST `MB`, Version 02; E.32): Hierarchie Paket PS
(BKNR/DGNA/BZRM/GSUM/ANZM) → mBGM G1 (REFW/VSNR/FANA/VONA/VSUM/
VERG=1) → Tarifblock T1 (BSGR/VVON) → Verrechnungsbasis BS (VBTY/
VBBT) → Verrechnungsposition V1 (VPTY/VPVZ/VPTA/RSVZ/RSUM).
**KEIN DN/DG-Zweig-Split**: T01 = GESAMT-Prozentsatz des Tarifsystems
(Parameter `at_mbgm_tarif`, normativ: laufend **39,05 %** =
KV 7,65 + PV 22,80 + AV 5,90 + UV 1,10 + WF 1,00 + IESG 0,10; SZ
**37,55 %** = DN KV 3,87 + PV 10,25 + AV 2,95 + DG 20,48). Abschläge
als EIGENE Positionen je Basis: **A01/A02/A03** = Minderung AV auf
2/1/0 % (§ 2a AMPFG — nur DN-AV, **je Verrechnungsbasis AB UND SZ**;
A03 = 2,95 % der Basis, RSVZ ), A09 = UV-Entfall 60 (1,10 %), A10
= AV+IE-Entfall (6,00 %), A15 = PV-Halbierung (11,40 %);
Konkurrenz a4: Entfall vor Minderung (A10 sperrt A0x). **BV**:
Basis `BV` (GP5, ungedeckelt) + `V01` 1,53 %. RSUM = Basis × Satz
(mBGM-Tarifierung); Konsistenz gegen GP4-Payslip-Summen als
Prüfwarnung (Toleranz 0,10 €). Storno: R-Satz je stornierter mBGM
(REFU, VSUM wie Original, ohne T/BS/V). Fehlanzeige: Paket ohne
mBGM-Sätze (ANZM 0). Fallweise/Geringfügige ohne Parametrisierung:
Lauf bricht listenweise ab (BSGR B044/B045/B010/B030 —
Tarifsystem-Werte pflegen, keine Erfindung).
- **L16 Lohnzettel Finanz** (BEST `LF`, VSTR `94` BRZ; E.13/E.14):
I1 (Länge 1100, Strukturversion 03) + L1 (Länge **3500**,
Lohnzettelversion 28, zwingend ab 01.03.2026). **KZ 210 =
Bruttobezüge gem. § 25 GESAMT** (laufende + sonstige §-67-Bezüge,
DM-ORG-Feldbeschreibung!) — deshalb ist **KZ 245 = 210 215 220
230 243** die laufende Steuerbemessung und per Konstruktion mit
der GP3-§-66-Kette konsistent. KZ-Ableitung aus den Kern-Flags
(kein paralleles Klassifikationsfeld): 210 = laufend+sonstig § 67
(ohne Abs-3/6), 215 = `_l10n_at_freibetraege_68` (§-68-Caps je LZP),
220 = sonstig ohne Abs-3/6 (inkl. 620-€-Freibetrag vor SV), 225 =
SVDN_SZ, 230 = laufende SVDN+AK+WF, 243 = 0 (nicht im Inventar),
260/BIEL = LST_LFD + LST_SZ. FB+-Felder (BFABO/KFABO/VFABO/FABO +
Kinderblock 15×123 ab Pos. 1501) aus der **Kind-Stammdaten-Wartung**
(Nutzer-Entscheidung: FB+ rechnet nicht im Lohnsteuerkern — ANV).
REFN je AG+Jahr+DV eindeutig; berichtigter Lohnzettel: ARTL 18 +
KORR K + FIND J.
- **Arbeitsstättenmeldung** § 34 Abs 6 ASVG (BEST `AD`, VSTR `ST`
Statistik Austria; E.20, SART 45, Länge 300): je AN Adresse am
31. 12. aus dem Dienstort-Partner; **GKZ** (Gemeindekennziffer) als
manuelles Partner-Feld — Warnung, wenn fehlt.
- **Versichertenmeldung** (BEST `VR`, Version 03, Länge 772; E.29):
M3 vor Arbeitsantritt (BKNR/VSNR/GEBD/FANA/VONA/ADAT/BBER 0104/
GERF/FRDV/BVAB/BVJN aus GP5/VWAZ Stunden×100), M4 7 Tage (ADAT +
EBSV, AGRD aus dem hr.departure.reason-Mapping, Standard 00),
M6 nur Ausnahmefälle; **deklarative Event-Erkennung** über die
Meldungs-Registry (keine write-diff-Hacks; idempotente Läufe).
**Fallweise** (BEST `MA`, SART 32, Länge 450, Version 07): je
Beschäftigungstag vor Arbeitsantritt; MVP: je AN/Vertragsbeginn
ein Anmeldetag (tagesgenaue Einsatztage via Work-Entries = Rest).
- **Belege (AP6)**: Lohnzettel AT (ir.actions.report auf hr.payslip,
AT-Layout mit Bezügen/Abzügen/**DG-Anteilen**/Netto; per Structure
über `report_id`), Monatsdienstliste (mBGM-Kontrollschicht je AN:
BG laufend/SZ, SV-DN/SZ, SV-DG, LSt, Netto) + Monatsjournal (je
Lohnart Summen je Lauf) auf `hr.payslip.run` (QWeb, AbstractModel).
Kein HR-Modul nutzt `account.report` — QWeb ist der framework-
gerechte Weg (Contribution-Register-Muster).
## Rechenfälle (Fixtures)
| RF | Konstellation | Erwartung |
|---|---|---|
| RF-ELDA-1 | Feld-Formatter | a/n linksbündig blank; n rechtsbündig 0-gefüllt; Cent kaufmännisch (0,005 → 1); Prozentsatz skala 3 (39,30 → 039300) |
| RF-ELDA-2 | Bestand/Datei | Vorlauf SART 00 (VSTR/BEST/EDAT TTMMJJJJ/VERS), SANR lückenlos, SANZ inkl. Rahmen, CRLF, Dateiheader ` 01ISO-8859-15…`, Umlaute ISO-8859-15-codiert |
| RF-L16-1 | November mit B13 (Jahr 2026) | KZ 210 = 4.118,82 (§ 25 gesamt!), KZ 220 = 2.059,41, KZ 245 = laufende Bemessung > 0; I1 (1.100) mit STNRA/JAHR/GESA; L1 (3.500) exakte Positionen: REFN/ARTL 01/BELZ 0111/SOZS 3/AVLN 1234/AGBD 150590/B210 0000411882; Vorlauf VSTR 94, BEST LF, VERS 28; SANZ 4 |
| RF-L16-2 | Arbeitsstätte | Satz 45 (300): BKNR/VSNR/STNR; VSTR ST, BEST AD; Warnung GKZ fehlt |
| RF-MBGM-1 | November mit B13, Angestellte (B002) | PS (BKNR/BZRM 112026/ANZM 1/GSUM = Σ VSUM), G1 (VSNR), T1 BSGR B002, Positionen T01 039050, **A03 je Basis** (AB + SZ, RSVZ ), T02 037550, V01; GSUM ≈ GP4-Beitragssummen ± 0,10 € |
| RF-VR-1 | Vertrag ab 2020, Ende 15.02.2026 | M3 (ADAT 01012020, BBER 02, GERF N, FRDV N, VWAZ 4000, BVJN J); Registry verhindert Doppelanmeldung; M4 (ADAT 15022026, EBSV, AGRD 00) |
## Offene Punkte / bewusst nicht in GP7
- **Schwerarbeitsmeldung** (DM-ORG E.22 Satzstruktur existiert!):
blockiert — keine ASchV-Work-Entry-Typen/Zähler im Modul, ASchV in
RQ-Privat ❓ nicht erschlossen. Erst nach Datenmodell-Bau.
- **§ 109a** (W1-Satz): separater Baustein (Honorare außerhalb der
Lohnverrechnung); Mitteilungs-XSDs/Prüfkatalog beschafft.
- **L17** (A1-Satz): keine AG-Pflicht. **Mitteilungsfile-Import**
(Rückantwort-Fehler ins Deklarationsmodell): GP8-Rest (5.2).
- Geringfügigen-mBGM (B010/B030-Sätze, Z04-Jahreszahlung + 2,5 %):
parametrisieren, sobai vorkommend; mBGM je Lauf bei Mehrfachläufen
im Monat; M6/Änderung; FB+-Lohnsteuermechanik (ANV-Sache);
VSNR-Prüfziffer-Algorithmus (SVS-Quelle beschaffen);
tagesgenaue fallweise-Einsatztage (Work-Entry-Auswertung).
- Referenzbuchhaltung/Parallellauf: CRLF-Satztrenner, ELDA-Kanäle
(Sendemodul https/ftps 40/220 MB), Fristenkalender (GP8).