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: add voluntary severance under § 67 Abs 6 (AP15-B)
Split the voluntary severance into its privileged part and a tariff remainder on the exit run: the privileged part combines the quarter rule (1/4 of the last twelve months' running pay, capped at nine times the monthly HBG) with the twelfth rule (2/12 to 12/12 by proven service, capped at n × 3 × HBG), reduced per Z 3 by severance already received and the statutory claim due at this termination, all taxed at the flat 6 % rate. The excess runs as its own rule flagged l10n_at_s67_abs6_ueberhang: taxed with the running tariff of the payment month but excluded from the annual sixth, since Z 5 exempts only the Z 1/Z 2 amounts and the excess is a special payment, not running pay. The twelve-month basis aggregates validated prior runs plus own lines, excluding the flagged excess and § 26 Z 4 travel overhang via a dedicated rule flag. Free of SV (§ 49 Abs 3 Z 7 ASVG), payroll levies regardless of the 6 %/tarif split (§ 41 Abs 4 lit b FLAG, § 122 Abs 8 WKG, § 5 Abs 2 lit b KommStG) and BV contributions; the former BV-Anwartschaft exclusion Z 7 is repealed (BGBl I 118/2015). The wizard proposes the rolling basis and the statutory claim, previews Z 1/Z 2/reduction/privileged/excess/tax and requires explicit confirmation against claim-conversion risk. The § 291d EO termination pot nets both severance wage-tax rules; key 260 now includes LST_ABF_FREI. Verified against the original statute text in .ris/ (EStG § 67 Abs 6) and the knowledge-base sources lb-end-12/13/15; KZ positioning of Abs-6 amounts and the excess's § 291d pot allocation remain documented verification points against LStR Rz 1087 ff. Version 19.0.14.0.0 (private), 19.0.10.0.0 (core)
This commit is contained in:
@@ -69,10 +69,15 @@ L10N_AT_BUCHUNGSMATRIX = {
|
||||
'rule_lst_lfd': {'credit': ('3540',)},
|
||||
'rule_lst_sz': {'credit': ('3540',)},
|
||||
'rule_lst_abf': {'credit': ('3540',)},
|
||||
'rule_lst_abf_frei': {'credit': ('3540',)},
|
||||
# Gesetzliche Abfertigung Alt: bis zur Referenzbuchhaltungs-
|
||||
# Fixierung allgemeiner Gehalts-/Lohnaufwand, company-dependent
|
||||
# Regelkonto bleibt übersteuerbar.
|
||||
'rule_abf_alt': {'debit': ('6200',), 'debit_arbeiter': ('6000',)},
|
||||
# Freiwillige Abfertigung (§ 67 Abs 6): begünstigter Teil und
|
||||
# tarifischer Überhang — gleiche vorläufige Aufwandskonten.
|
||||
'rule_abf_frei': {'debit': ('6200',), 'debit_arbeiter': ('6000',)},
|
||||
'rule_abf_frei_tarif': {'debit': ('6200',), 'debit_arbeiter': ('6000',)},
|
||||
# Nettoauszahlung (reconcilable, s. o.)
|
||||
'rule_netto': {'credit': ('3850',)},
|
||||
# DG-Beiträge (650–655 SV Arbeiter · 656–659 SV Angestellte)
|
||||
|
||||
@@ -28,6 +28,8 @@ Am Originalwortlaut verifiziert (.ris/, Stand 2026-09-14):
|
||||
"""
|
||||
from datetime import timedelta
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
@@ -51,6 +53,11 @@ class HrSalaryRule(models.Model):
|
||||
'(Deckel: ein Fünftel des Neunfachen der monatlichen HBG), '
|
||||
'der Rest läuft tarifisch im Zuflussmonat — ohne '
|
||||
'Jahressechstel-Erhöhung (Abs 2 nicht anzuwenden).')
|
||||
l10n_at_s26_z4_reise = fields.Boolean(
|
||||
string='AT § 26 Z 4 Reisevergütung',
|
||||
help='§-26-Z-4-Reisevergütungen zählen nicht in die '
|
||||
'12-Monats-Basis der §-67-Abs-6-Begünstigung (lb-end-13); '
|
||||
'Sonderzahlungen sind ohnehin nicht bemessung „laufend“.')
|
||||
|
||||
|
||||
class HrPayslip(models.Model):
|
||||
@@ -83,6 +90,31 @@ class HrPayslip(models.Model):
|
||||
string='AT Abfertigung Alt — Anspruchsfaktor', copy=False)
|
||||
l10n_at_abf_alt_nachweis = fields.Text(
|
||||
string='AT Abfertigung Alt — Nachweis/Begründung', copy=False)
|
||||
l10n_at_abf_frei_basis_12 = fields.Float(
|
||||
string='AT Freiwillige Abfertigung — 12-Monats-Basis', copy=False,
|
||||
help='Laufende Bezüge der letzten zwölf Monate (§ 67 Abs 6 Z 1/2 '
|
||||
'EStG): vom Wizard bestätigt — alle steuerbaren Bezugsteile '
|
||||
'inklusive steuerfreier Zuschläge und Sachbezüge, ohne '
|
||||
'Sonderzahlungen und ohne §-26-Z-4-Reisevergütungen; keine '
|
||||
'Bezüge anderer Arbeitgeber, keine Hochrechnung kurzer DV.')
|
||||
l10n_at_abf_frei_dienstzeit_monate = fields.Integer(
|
||||
string='AT Freiwillige Abfertigung — nachgewiesene Dienstzeit '
|
||||
'(Monate)', copy=False)
|
||||
l10n_at_abf_frei_erhaltene_abfertigungen = fields.Float(
|
||||
string='AT Freiwillige Abfertigung — erhaltene Abfertigungen',
|
||||
copy=False,
|
||||
help='Während der nachgewiesenen Dienstzeit bereits erhaltene '
|
||||
'Abfertigungen nach § 67 Abs 3 oder Abs 6 EStG — kürzen das '
|
||||
'Z-2-Ausmaß (§ 67 Abs 6 Z 3).')
|
||||
l10n_at_abf_frei_gesetzlicher_anspruch = fields.Float(
|
||||
string='AT Freiwillige Abfertigung — bestehender gesetzlicher '
|
||||
'Anspruch', copy=False,
|
||||
help='Bestehender Anspruch auf eine gesetzliche Abfertigung am '
|
||||
'aktuellen Dienstverhältnis-Ende (§ 67 Abs 6 Z 3 EStG) — '
|
||||
'kürzt das Z-2-Ausmaß.')
|
||||
l10n_at_abf_frei_nachweis = fields.Text(
|
||||
string='AT Freiwillige Abfertigung — Nachweis/Begründung',
|
||||
copy=False)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# SV-Tage-Umrechnung und Verlängerungsmonate (§ 11 Abs 2 ASVG)
|
||||
@@ -232,6 +264,87 @@ class HrPayslip(models.Model):
|
||||
return min(self._at_abf_alt_steuer_vervielfachung(result_rules),
|
||||
self._at_abf_alt_steuer_6(result_rules))
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Freiwillige Abfertigung — § 67 Abs 6 EStG (Viertel-/Zwölftelregelung)
|
||||
# ------------------------------------------------------------------
|
||||
def _at_bezuege_12_monate(self):
|
||||
"""Laufende Bezüge der letzten zwölf Monate (§ 67 Abs 6 Z 1/2):
|
||||
validierte Vormonats-Läufe plus eigene Zeilen — ohne den als
|
||||
Abs-6-Überhang gekennzeichneten Betrag (das ist ein sonstiger
|
||||
Bezug, kein laufender) und ohne §-26-Z-4-Reisevergütungen;
|
||||
Sonderzahlungen sind ohnehin nicht bemessung „laufend“
|
||||
(lb-end-13)."""
|
||||
self.ensure_one()
|
||||
start = (self.date_from - relativedelta(months=11)).replace(day=1)
|
||||
vor_slips = self.env['hr.payslip'].search([
|
||||
('employee_id', '=', self.employee_id.id),
|
||||
('id', '!=', self.id),
|
||||
('date_from', '>=', start),
|
||||
('date_from', '<', self.date_from.replace(day=1)),
|
||||
]).filtered(lambda p: p.state not in ('draft', 'cancel'))
|
||||
total = 0.0
|
||||
for slip in list(vor_slips) + [self]:
|
||||
for line in slip.line_ids:
|
||||
rule = line.salary_rule_id
|
||||
if rule.l10n_at_bemessung != 'laufend':
|
||||
continue
|
||||
if (rule.l10n_at_s67_abs6_ueberhang
|
||||
or rule.l10n_at_s26_z4_reise):
|
||||
continue
|
||||
total += line.total
|
||||
return total
|
||||
|
||||
def _at_abf_frei_zwoelftel(self):
|
||||
"""Zwölftel-Anzahl nach § 67 Abs 6 Z 2: die Dienstzeitstaffel
|
||||
entspricht den §-23-Grenzen (36→2/12 … 300→12/12)."""
|
||||
self.ensure_one()
|
||||
return self._at_abf_alt_staffel(
|
||||
self.l10n_at_abf_frei_dienstzeit_monate)
|
||||
|
||||
def _at_abf_frei_split(self, result_rules=None):
|
||||
"""§ 67 Abs 6: begünstigter Teil (Viertel- und Zwölftelregelung,
|
||||
gedeckelt 9 × bzw. n × 3 × monatliche HBG, Z-3-Kürzung um
|
||||
erhaltene Abfertigungen und den bestehenden gesetzlichen
|
||||
Anspruch) und der tarifische Überhang (Z 6)."""
|
||||
self.ensure_one()
|
||||
brutto = max(self._at_input_amount('ATP_ABF_FREI'), 0.0)
|
||||
basis = self.l10n_at_abf_frei_basis_12
|
||||
if basis <= 0:
|
||||
basis = self._at_bezuege_12_monate()
|
||||
basis = max(basis, 0.0)
|
||||
hbg = float(self._l10n_at_param('at_sv_hbg_monatlich'))
|
||||
z1 = min(basis / 4.0, 9.0 * hbg)
|
||||
zwoelftel = self._at_abf_frei_zwoelftel()
|
||||
z2 = min(basis * zwoelftel / 12.0, zwoelftel * 3.0 * hbg)
|
||||
kuerzung = max(
|
||||
self.l10n_at_abf_frei_erhaltene_abfertigungen
|
||||
+ self.l10n_at_abf_frei_gesetzlicher_anspruch, 0.0)
|
||||
z2 = max(z2 - kuerzung, 0.0)
|
||||
beguenstigt = min(brutto, z1 + z2)
|
||||
return {
|
||||
'basis': basis,
|
||||
'z1': z1,
|
||||
'z2': z2,
|
||||
'kuerzung': kuerzung,
|
||||
'beguenstigt': beguenstigt,
|
||||
'ueberhang': brutto - beguenstigt,
|
||||
}
|
||||
|
||||
def _at_abf_frei_beguenstigt(self, result_rules=None):
|
||||
self.ensure_one()
|
||||
return self._at_abf_frei_split(result_rules)['beguenstigt']
|
||||
|
||||
def _at_abf_frei_ueberhang(self, result_rules=None):
|
||||
self.ensure_one()
|
||||
return self._at_abf_frei_split(result_rules)['ueberhang']
|
||||
|
||||
def _at_abf_frei_lst_6(self, result_rules=None):
|
||||
"""6 % auf den begünstigten Teil (§ 67 Abs 6, fester Steuersatz)."""
|
||||
self.ensure_one()
|
||||
satz = float(self._l10n_at_param(
|
||||
'at_endabrechnung')['abfertigung_steuersatz'])
|
||||
return self._at_abf_frei_beguenstigt(result_rules) * satz / 100.0
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Urlaubsersatzleistung — § 67 Abs 8 lit d, lb-url-15/16
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@@ -386,7 +386,8 @@ class HrPayslip(models.Model):
|
||||
linie = self.line_ids.filtered(
|
||||
lambda l, c=rule.code: l.code == c)
|
||||
total += sum(linie.mapped('total'))
|
||||
steuer = self._at_pfa_rule_amount(result_rules, 'LST_ABF')
|
||||
steuer = sum(self._at_pfa_rule_amount(result_rules, c)
|
||||
for c in ('LST_ABF', 'LST_ABF_FREI'))
|
||||
return round(max(0.0, total - steuer), 2)
|
||||
raise UserError('Unbekannter Pfändungstopf: %s' % topf)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user