Files
odoo-at-payroll/addons/l10n_at_gemeinde_payroll/models/hr_version_bgld.py
T
fegger 0abc1383d1 [FIX] l10n_at_gemeinde_payroll: Modul erstmals installierbar — 9 Odoo-19-Latenzfehler; BDA-Vordienstzeiten-Vorschlag (AP10+AP9)
AP10 — Latenzfehler des nie installierten Vorlaufs:
- regular_pay auf hr.payroll.structure entfernt (Feld existiert nicht)
- is_paid/round_days/round_days_type von WET-Records entfernt
- Falscher XML-ID-Praefix payroll_structure_bgld. -> Modul-Referenzen
- amount_select 'python' -> 'code' (Selection)
- import in Regelcode entfernt (safe_eval verbietet IMPORT_NAME)
- rules['ME'].total -> result_rules['ME']['total'] (Odoo 19 befuellt
  rules nie; SZQ-Sonderzahlung rechnete gegen Null)
- categories.X -> categories['X'] (NETTO-Regel)
- work_time_rate /100 entfernt (Odoo 19 speichert Bruchteil 0..1)
- nie gelaufene Tests: Payslip-name-Pflichtfeld, Stichtag vor
  Katalog-Gueltigkeit (Wizard-Skip korrekt), date_start ist Compute
  aus contract_date_start

AP9 — BDA-Vordienstzeiten (GemBG S 67 Abs 1-3, RIS LrB GesNr
20001002 verifiziert): Feld vordienstzeiten_monate (Help dokumentiert
Anrechnungskatalog inkl. Obergrenzen), Compute bda_vorschlag
(Vertragsbeginn - Monate), Uebernahme-Button als Verwaltungsakt,
View-Erweiterung
2026-09-12 23:18:07 +02:00

125 lines
6.0 KiB
Python

# Part of the gem360 onboarding. See LICENSE / project docs for details.
from dateutil.relativedelta import relativedelta
from odoo import api, fields, models
class HrVersion(models.Model):
"""GemBG-Besoldungsfelder auf der Payroll-Version des Mitarbeiters.
§ 66 Abs 2 Bgld. GemBG 2014: Die Vorrückung erfolgt mit dem ersten Tag
jenes Monats, der auf die Vollendung weiterer vier Jahre des
Besoldungsdienstalters folgt (Vorrückungstermin); für bestimmte Gruppen
zwei Jahre (§ 150c Abs 2, § 150d ff). Überleitungsfälle (§§ 157a ff)
können einen einmalig vorgezogenen Termin haben — daher ist der
berechnete Termin manuell überschreibbar.
"""
_inherit = 'hr.version'
entlohnungsgruppe_id = fields.Many2one(
'gemeinde.payroll.entlohnungsgruppe', index=True,
groups="hr_payroll.group_hr_payroll_user", tracking=True)
entlohnungsstufe = fields.Integer(
groups="hr_payroll.group_hr_payroll_user", tracking=True)
besoldungsdienstalter = fields.Date(
string='Besoldungsdienstalter (ab)',
groups="hr_payroll.group_hr_payroll_user", tracking=True)
vordienstzeiten_monate = fields.Integer(
string='Anerkannte Vordienstzeiten (Monate)',
groups="hr_payroll.group_hr_payroll_user", tracking=True,
help='AP9 — Bgld. GemBG § 67: Das Besoldungsdienstalter umfasst '
'die im Dienstverhältnis verbrachten wirksamen Zeiten '
'ZUSAMMEN mit den anrechenbaren Vordienstzeiten '
'(Abs 1). Anzurechnen sind u. a. Zeiten in einem '
'Dienstverhältnis zu einer Gebietskörperschaft/einem '
'Gemeindeverband (EWR/Türkei/Schweiz) sowie EU- und '
'zwischenstaatliche Dienstverhältnisse (Abs 2 Z 1 f); '
'Grundwehr-/Ausbildungsdienst zusammen max. 6 Monate, '
'Zivil-/Ersatzdienst max. 9 Monate (Abs 2 Z 4); über '
'die Pflichtzeiten hinaus einschlägige Berufstätigkeit '
'oder ein Verwaltungspraktikum max. 10 Jahre (Abs 3). '
'Doppelanrechnung desselben Zeitraums unzulässig. '
'Hier: die vom Bescheid anerkannten Monate gesamt.')
bda_vorschlag = fields.Date(
string='BDA-Vorschlag (Vordienstzeiten)',
compute='_compute_bda_vorschlag',
groups="hr_payroll.group_hr_payroll_user",
help='Vorschlag: Vertragsbeginn zurückverlegt um die '
'anerkannten Vordienstzeiten (§ 67 Abs 1). Übernahme '
'bewusst manuell — Besoldungsdienstalter ist ein '
'dokumentationspflichtiger Verwaltungsakt (s. Vorrückungs-'
'Wizard).')
vorrueckungstermin = fields.Date(
compute='_compute_vorrueckungstermin', store=True, readonly=False,
groups="hr_payroll.group_hr_payroll_user", tracking=True,
help="Vorschlag nach § 66 Abs 2 GemBG (BDA + Vorrückungszeitraum); "
"bei Überleitungsfällen manuell korrigierbar.")
@api.depends('contract_date_start', 'vordienstzeiten_monate')
def _compute_bda_vorschlag(self):
for version in self:
if not (version.contract_date_start
and version.vordienstzeiten_monate):
version.bda_vorschlag = False
continue
version.bda_vorschlag = version.contract_date_start \
- relativedelta(months=version.vordienstzeiten_monate)
def action_bda_uebernehmen(self):
"""BDA-Vorschlag als Besoldungsdienstalter übernehmen — ein
expliziter Verwaltungsakt, kein stilles Schreiben im Lohnlauf
(Muster: Vorrückungs-Wizard § 66 Abs 2)."""
for version in self:
if version.bda_vorschlag:
version.besoldungsdienstalter = version.bda_vorschlag
@api.depends('entlohnungsgruppe_id', 'besoldungsdienstalter')
def _compute_vorrueckungstermin(self):
for version in self:
bda = version.besoldungsdienstalter
gruppe = version.entlohnungsgruppe_id
if not bda or not gruppe:
version.vorrueckungstermin = False
continue
period = gruppe.vorrueckungszeitraum_jahre or 4
today = fields.Date.context_today(version)
elapsed_years = relativedelta(today, bda).years
next_maturity = bda + relativedelta(
years=(elapsed_years // period + 1) * period)
version.vorrueckungstermin = (
fields.Date.end_of(next_maturity, 'month')
+ relativedelta(days=1)
)
def _get_katalog_entgelt(self, datum=None):
"""Katalog-Position (Monatsentgelt) der Version zum Stichtag."""
self.ensure_one()
return self.entlohnungsgruppe_id._get_entgelt(
self.entlohnungsstufe, datum)
class HrEmployee(models.Model):
_inherit = 'hr.employee'
entlohnungsgruppe_id = fields.Many2one(
related="version_id.entlohnungsgruppe_id", inherited=True,
readonly=False, groups="hr_payroll.group_hr_payroll_user")
entlohnungsstufe = fields.Integer(
related="version_id.entlohnungsstufe", inherited=True,
readonly=False, groups="hr_payroll.group_hr_payroll_user")
besoldungsdienstalter = fields.Date(
related="version_id.besoldungsdienstalter", inherited=True,
readonly=False, groups="hr_payroll.group_hr_payroll_user")
vordienstzeiten_monate = fields.Integer(
related="version_id.vordienstzeiten_monate", inherited=True,
readonly=False, groups="hr_payroll.group_hr_payroll_user")
bda_vorschlag = fields.Date(
related="version_id.bda_vorschlag", inherited=True,
groups="hr_payroll.group_hr_payroll_user")
vorrueckungstermin = fields.Date(
related="version_id.vorrueckungstermin", inherited=True,
readonly=False, groups="hr_payroll.group_hr_payroll_user")
def action_bda_uebernehmen(self):
"""Delegation an die Version (Button am Mitarbeiterformular)."""
self.mapped('version_id').action_bda_uebernehmen()