mirror of
http://100.103.83.12:3003/fegger/odoo-at-payroll.git
synced 2026-09-17 08:52:45 +00:00
[IMP] l10n_at_hr_payroll(_private): Meldewesen-Reste (AP17) und Status-Sonderfälle (AP18/AP19)
AP17 — Lohnnachweis L17, Finanz-Mitteilungen § 109a/§ 109b, GfB-Jahreszahlung:
- L17 (DM-ORG E.24, BEST LF, SART A1/1100, Version 28): je
Lohnzahlungszeitraum je DN aus den GP3-Kennzahlen-Flags; Prüfkatalog-
Semantik (KZ 350 = Brutto gesamt, 351/352/354 Teilbeträge) und formale
Prüfungen (350-Formel, 357/347-Caps, aliquotierte 354/HOPA-Caps);
ODL-PDF-Extraktion der Kapitel E.24/E.16/E.26 (txt feldversetzt)
- Finanz-Mitteilungen § 109a (W1, E.16) und § 109b (B1, E.26): Modelle
je Leistungserbringer/Auftragnehmer, Schwellen als hr.rule.parameter
(450/900 — § 109a-VO; 100.000 — § 109b Abs 4 lit a, RIS NOR40263383),
AL31/32/33, LKZ1-7, UID, bis 3 maßgebliche natürliche Personen,
KORR K/S; Unter-Schwellen-Zeilen entfallen mit Protokollhinweis
- mBGM: geringfügig Beschäftigte (BSGR B010/B030) — T01 § 53a-UV-
Pauschale + V01 BMSVG 1,53 %, kein T02 (GfB-SZ beitragsfrei,
§ 49 Abs 3); JAGB-Pakettrennung für die jährliche Abrechnung
(§ 58 Abs 8 ASVG iVm § 6 Abs 2a BMSVG, DM-ORG D.52) mit
2,5 vH-Zuschlag (Z04) in der GfB-Jahresabrechnung (Fälligkeit
15. 1. Folgejahr)
- Fristenkalender: L17- und § 109b-Fristarten (Ende Februar;
§ 109a/§ 109b EStG und § 58 Abs 8 ASVG RIS-verifiziert)
AP18 — Schwerarbeit/NSchG (Beschaffungsgate erledigt, RIS):
- NSchG (RIS 10008502, BGBl 1981/354) Art XI Abs 3 (2 vH Stammnorm,
3,80 % via Sistierung) und Abs 6 (Nachtschwerarbeitsmonat: 6-Tage-
Kriterium, Rückblick-Fenster 12/18, Randmonat); ASchV (20004642)
§ 1/§ 4/§ 5; DM-ORG E.22.2-Erstellvorschriften (Z 1 analog NSchG,
Z 2/4/5 ≥ 15 Tage, Z 3/GfB nicht melden)
- Kern: Schwerarbeitsmeldung (BEST SM, SART 65/66, Länge 800,
Tätigkeitsblöcke 26 × 10) mit Altersfilter- und Erstellvorschrift-
Prüfungen
- Privat: Nachtschwerarbeitsmonat-Zähler (WET ATP_NACHTSCHWER,
Art-XI-Abs-6-Fenster inkl. Randmonat-Proxy) als stored Flag am Lauf
AP19 — Status- und Verhinderungs-Sonderfälle:
- hr.version-Status (Organ ≤/≥ 25 %, lb-vst-03): Organ ≥ 25 % — kein
SV-Verhältnis (SVDN/SVDG 0 via SV-Satz-Override, mBGM-Ausschluss,
LSt läuft weiter); Ferialpraktikanten-Flag (dokumentativ — BMSVG § 6
nennt keinen Ausschluss, Entgelt-/SV-Logik bleibt normal)
- Präsenz-/Ausbildungs-/Zivildienst-Fiktion (§ 7 Abs 1/2 BMSVG):
fiktive BV-Bemessungsgrundlage 435,90 € (KBGG § 3 Abs 1 idF vor
BGBl I 53/2016, lb-vor-04) aliquotiert auf ATP_PRD_TAGE
- Dienstverhinderungs-Sonderfälle bleiben dokumentiert offen
(lb-dvh-01/04, KB-❓); Feiertags-EFZ ist durch das AP4-WET-Modell
abgedeckt
Tests: 21 neue (L17-Positionen/Prüfkatalog, W1/B1-Schwellen, GfB-mBGM/
JAGB/Jahresabrechnung, NSchM-Fenster/Randmonat, SM-Fixsatz, Organ-Sperre,
PRD-Fiktion); Suite 252/252 grün auf frischer -i-DB (85 Kern, 18 GemBG,
213 Privat, 10 Dokumente). Dokumentierte Reste: DZR-36-Fenster,
Randmonat-Proxy und UV-Pauschale-vs-mBGM im Parallellauf (GP8),
fallweise mBGM (G3/G4), 2027er-Schwellen (C7).
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# Part of the odoo-at-payroll project. License: LGPL-3.
|
||||
"""AP18: Nachtschwerarbeitsmonat-Zähler (NSchG Art XI Abs 6) —
|
||||
RIS-verifiziert 2026-09-16 (NOR40144608, RIS GesNr 10008502, BGBl
|
||||
1981/354):
|
||||
|
||||
- **≥ 6 Arbeitstage** Nachtschwerarbeit im Kalendermonat → Nachtschwer-
|
||||
arbeitsmonat;
|
||||
- **< 6 Tage**: Rückblick-Fenster — Monat + 1 Vormonat ≥ **12** Tage bzw.
|
||||
Monat + 2 Vormonate ≥ **18** Tage;
|
||||
- (DZR > 3 Monate: Monat + 5 Vormonate ≥ 36 Tage — dokumentierter Rest,
|
||||
kein Durchrechnungszeitraum-Datenmodell);
|
||||
- **Randmonat**: die 6 erwarteten Nachtschwerarbeitstage werden nur
|
||||
deswegen nicht erreicht, weil die Arbeit nicht am Monats-Ersten begonnen
|
||||
bzw. am Letzten geendet hat — v1 mit Pro-rata-Proxy (Tage ≥ 6 × belegte
|
||||
Monatskalendertage / Monatskalendertage, aufgerundet) implementiert ⚠
|
||||
(Arbeitszeiteinteilung der Muster im Parallellauf verifizieren);
|
||||
- Arbeitsunterbrechungen bleiben außer Betracht, solange die PV-Pflicht-
|
||||
versicherung weiterbesteht.
|
||||
|
||||
Datenbasis: Work Entries des Typs ``ATP_NACHTSCHWER`` (mandantenseitige
|
||||
Klassifikation der Nachtschwerarbeit nach NSchG Art VII Abs 2/4 bzw. ASchV
|
||||
§ 1 — die Katalog-Kriterien kann die Engine nicht ableiten). Abgleich mit
|
||||
der E01-Belegung (mBGM-Ergb, AP0/TASY) als Protokoll-Hinweis in der
|
||||
mBGM-Generierung."""
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
_NACHTSCHWER_WET = 'ATP_NACHTSCHWER'
|
||||
|
||||
|
||||
class HrVersion(models.Model):
|
||||
_inherit = 'hr.version'
|
||||
|
||||
def _l10n_at_nachtschwer_tage(self, monat_erster, monat_letzter):
|
||||
"""Tage mit Nachtschwerarbeit-WETs im (Teil-)Monat."""
|
||||
self.ensure_one()
|
||||
eintraege = self.env['hr.work.entry'].search([
|
||||
('employee_id', '=', self.employee_id.id),
|
||||
('date', '>=', monat_erster),
|
||||
('date', '<=', monat_letzter),
|
||||
('state', '!=', 'cancelled'),
|
||||
('work_entry_type_id.code', '=', _NACHTSCHWER_WET),
|
||||
])
|
||||
return len({eintrag.date for eintrag in eintraege})
|
||||
|
||||
|
||||
class HrPayslip(models.Model):
|
||||
_inherit = 'hr.payslip'
|
||||
|
||||
l10n_at_nachtschwerarbeitsmonat = fields.Boolean(
|
||||
string='AT Nachtschwerarbeitsmonat',
|
||||
compute='_compute_l10n_at_nachtschwerarbeitsmonat',
|
||||
store=True,
|
||||
help='NSchG Art XI Abs 6 (RIS NOR40144608): ≥ 6 Nachtschwerarbeits-'
|
||||
'tage im Monat bzw. Rückblick-Fenster (12/18; 36 bei DZR > '
|
||||
'3 Monate — dokumentierter Rest) bzw. Randmonat (Pro-rata-'
|
||||
'Proxy ⚠). Grundlage NSchAB 3,80 % (Art XI Abs 3 iVm '
|
||||
'Sistierung; TASY-ERGB E01).')
|
||||
|
||||
@api.depends('date_from', 'date_to', 'version_id')
|
||||
def _compute_l10n_at_nachtschwerarbeitsmonat(self):
|
||||
for slip in self:
|
||||
slip.l10n_at_nachtschwerarbeitsmonat = \
|
||||
slip._l10n_at_nachtschwerarbeitsmonat(slip.date_from)
|
||||
|
||||
def _l10n_at_nachtschwerarbeitsmonat(self, stichtag):
|
||||
"""Art XI Abs 6: 6/12/18-Fenster + Randmonat-Proxy."""
|
||||
self.ensure_one()
|
||||
version = self.version_id
|
||||
if not version:
|
||||
return False
|
||||
erster = stichtag.replace(day=1)
|
||||
letzter = (erster + relativedelta(months=1)) \
|
||||
- relativedelta(days=1)
|
||||
monatstage = (letzter - erster).days + 1
|
||||
tage = version._l10n_at_nachtschwer_tage(erster, letzter)
|
||||
if tage >= 6:
|
||||
return True
|
||||
# Randmonat (Art XI Abs 6 letzter Satz): die sechs erwarteten
|
||||
# Nachtschwerarbeitstage werden nur deswegen nicht erreicht,
|
||||
# weil die Arbeit nicht am Monats-Ersten begonnen bzw. am
|
||||
# Letzten geendet hat — v1 Pro-rata-Proxy.
|
||||
beginn = max(erster, self.date_from)
|
||||
ende = min(letzter, self.date_to)
|
||||
if (beginn, ende) != (erster, letzter):
|
||||
belegte = (ende - beginn).days + 1
|
||||
erforderlich = int(-(-6 * belegte // monatstage)) # ceil
|
||||
if tage >= erforderlich:
|
||||
return True
|
||||
# Rückblick-Fenster (12/18): Monat + 1 bzw. + 2 Vormonate.
|
||||
tage_1 = version._l10n_at_nachtschwer_tage(
|
||||
erster - relativedelta(months=1),
|
||||
erster - relativedelta(days=1))
|
||||
if tage + tage_1 >= 12:
|
||||
return True
|
||||
tage_2 = version._l10n_at_nachtschwer_tage(
|
||||
erster - relativedelta(months=2),
|
||||
erster - relativedelta(days=1))
|
||||
if tage + tage_1 + tage_2 >= 18:
|
||||
return True
|
||||
return False
|
||||
Reference in New Issue
Block a user