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: GP4 SV/DB-Anbindung (SVDN_SZ-Nachtrag, DG-Regelblock, FLAF/KommSt/DZ)
Anbindung der privatwirtschaftlichen Structure an den GP4-Kern nach dem bewährten GP3-Muster (dünne 1-Zeilen-Regeln; Logik und Werte verbleiben im Kern — hr.salary.rule.struct_id ist required, geteilte Kern-Regeln sind mechanisch unmöglich). SVDN_SZ-Nachtrag (§ 67 Abs 12): Die SV-DN auf sonstigen Bezügen war in GP3 nur als Bemessungsbestandteil der §-67-Lohnsteuer wirksam, fehlte aber als eigene Abzugszeile — das Netto in §-67-Monaten war um den SV-DN(SZ) zu hoch (RF-L1: 290,79 € nach §-2a-Korrektur). Die Erwartungen in test_01/test_20 wurden entsprechend korrigiert. DG-Block (Kategorie ATP_DG, ohne Nettoeffekt): SVDG_KV/PV/AV/UV/WF/IESG laufend, SVDG_SZ_* auf Sonderzahlungen, SVDG_UV_GFG (§-53a-Pauschale geringfügig Beschäftigter) sowie die Lohnnebenkosten FLAFDB (§ 41 FLAG), KOMMST (§ 9 KommStG) und DZ (§§ 122/126 WKG, nur bei Company- Flag l10n_at_wk_mitglied; Satz je Betriebsstätten-Bundesland). Gemeinsame LNK-Basis in payslip_private.py (_at_lnk_basis): monatlich gezahlte Arbeitslöhne nach Zufluss, ohne §-67-Abs-3/6-Bezüge (Kern-Flag l10n_at_s67_abs), lit-f-Befreiung nur für FLAF und DZ (KommSt ohne), Freibetragsstaffel 1.095/1.460 €. Rechenfälle docs/rechenfaelle/sozialversicherung.md (RF-SV-1 bis -7) und §-2a-Korrekturvermerk in lohnsteuer.md. Tests: test_sv_private (8 Fälle); gesamt 74/74 grün auf odoo_dev.
This commit is contained in:
@@ -305,6 +305,78 @@ class HrPayslip(models.Model):
|
||||
monate = {l.slip_id.id for l in linien}
|
||||
return len(monate) >= 7, sum(l.total for l in linien) / 12.0
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Lohnnebenkosten FLAF-DG-Beitrag / KommSt / DZ (GP4; § 41 FLAG,
|
||||
# § 5+§ 9 KommStG, §§ 122/126 WKG — Werte/Staffeln im Kern)
|
||||
# ------------------------------------------------------------------
|
||||
def _at_lnk_basis(self, steuer, result_rules=None):
|
||||
"""LNK-Bemessungsgrundlage nach Freibetragsstaffel: monatlich
|
||||
gezahlte Arbeitslöhne (laufend + im Monat gezahlte §-67-Bezüge,
|
||||
Zuflussprinzip; kein SV-Abzug), ohne §-67-Abs-3/6-Bezüge
|
||||
(Abfertigung/Abfindung). 'flaf'/'dz' zusätzlich ohne lit-f-AN
|
||||
(Arbeitslöhne ab Folgemonat nach Vollendung des 60. Lebensjahres,
|
||||
§ 41 Abs 4 lit f FLAG — die Kommunalsteuer hat KEINE lit-f-
|
||||
Befreiung). Freibetrag: ≤ 1.095 € keine Abgabe, bis 1.460 € →
|
||||
Freibetrag 1.095 €, darüber volle BG (at_lnk_freibetrag)."""
|
||||
self.ensure_one()
|
||||
basis = (self._l10n_at_brutto('laufend', result_rules)
|
||||
+ self._l10n_at_brutto('sonstig', result_rules))
|
||||
for rule in self.struct_id.rule_ids:
|
||||
if rule.l10n_at_s67_abs in ('abs3', 'abs6'):
|
||||
if result_rules is not None and rule.code in result_rules:
|
||||
basis -= result_rules[rule.code]['total']
|
||||
elif result_rules is None:
|
||||
linie = self.line_ids.filtered(
|
||||
lambda l: l.code == rule.code)
|
||||
basis -= sum(linie.mapped('total'))
|
||||
basis = max(basis, 0.0)
|
||||
if steuer in ('flaf', 'dz'):
|
||||
version = self.version_id
|
||||
if (version.l10n_at_lnkp_frei_ab
|
||||
and self.date_from >= version.l10n_at_lnkp_frei_ab):
|
||||
return 0.0
|
||||
freibetrag = self.env['hr.rule.parameter']._get_parameter_from_code(
|
||||
'at_lnk_freibetrag', self.date_to, raise_if_not_found=False) or {}
|
||||
grenze = float(freibetrag.get('grenze', 0.0))
|
||||
if basis <= 0.0:
|
||||
return 0.0
|
||||
if basis <= grenze:
|
||||
basis -= float(freibetrag.get('freibetrag', 0.0))
|
||||
return max(basis, 0.0)
|
||||
|
||||
def _at_flaf_db(self, result_rules=None):
|
||||
"""FLAF-Dienstgeberbeitrag § 41 FLAG (3,7 % ab 2025, 2,7 % ab
|
||||
2028 — at_flaf_db; BG s. _at_lnk_basis)."""
|
||||
self.ensure_one()
|
||||
basis = self._at_lnk_basis('flaf', result_rules)
|
||||
satz = float(self.env['hr.rule.parameter']._get_parameter_from_code(
|
||||
'at_flaf_db', self.date_to, raise_if_not_found=False) or 0.0)
|
||||
return basis * satz / 100.0
|
||||
|
||||
def _at_kommst(self, result_rules=None):
|
||||
"""Kommunalsteuer § 9 KommStG 1993 (3 % — at_kommst_satz; BG
|
||||
§ 5 Abs 2: ohne §-67-Abs-3/6-Bezüge, ohne lit-f-Befreiung)."""
|
||||
self.ensure_one()
|
||||
basis = self._at_lnk_basis('kommst', result_rules)
|
||||
satz = float(self.env['hr.rule.parameter']._get_parameter_from_code(
|
||||
'at_kommst_satz', self.date_to, raise_if_not_found=False) or 0.0)
|
||||
return basis * satz / 100.0
|
||||
|
||||
def _at_dz(self, result_rules=None):
|
||||
"""Zuschlag zum Dienstgeberbeitrag (§§ 122/126 WKG) für WKO-
|
||||
Mitgliedsbetriebe: Landeskammersatz je Betriebsstätten-Bundesland
|
||||
inkl. Bundeskammeranteil (at_dz_vektor; ⚠ WKO-Verifikation 8.11);
|
||||
BG identisch FLAF-DB inkl. lit f (lb-lnk-07)."""
|
||||
self.ensure_one()
|
||||
if not self.company_id.l10n_at_wk_mitglied:
|
||||
return 0.0
|
||||
basis = self._at_lnk_basis('dz', result_rules)
|
||||
vektor = self.env['hr.rule.parameter']._get_parameter_from_code(
|
||||
'at_dz_vektor', self.date_to, raise_if_not_found=False) or {}
|
||||
satz = float((vektor.get('laender') or {}).get(
|
||||
self.company_id.l10n_at_bundesland or '', 0.0))
|
||||
return basis * satz / 100.0
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# All-in-Deckungsrechnung (§ 2g AVRAG) — minimale GP2-Umsetzung:
|
||||
# Jahresvergleich geschuldete ÜStd-Vergütung vs. erhaltene Pauschale
|
||||
|
||||
Reference in New Issue
Block a user