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_gemeinde_payroll: implement AP1 pay scale model (GemBG Bgld.)
Katalogmodell nach Implementierungsplan AP1 (freigegeben 2026-09-09): - ``gemeinde.payroll.entlohnungsgruppe`` (Code, Schema, §, Bundesland, Vorrückungszeitraum je Gruppe; § 66 Abs 2 GemBG: 4 Jahre, abweichend 2 Jahre für Betreuungspersonen-/Sondergruppen) und ``gemeinde.payroll.entlohnungsstufe`` (Stufe, Monatsentgelt, Stichtag, unique je Gruppe/Stufe/Stichtag) mit Stichtags-Lookup-Helfern. - Seed 2026: 35 Entlohnungsgruppen, 433 Werte (Schemata I/gv, II/gh, Ia/bv, IIa/bh, kb, av sowie §-Gruppen 150c/151/151c), Werte aus der konsolidierten GemBG-Fassung 09.09.2026 (Wert 1.7.2026 gemäß Artikel 4 RV 0715/XXIII. GP; 2025er-Stichtagsannahme für nicht 2026 angepasste Tabellen als AP0-Verifikationspunkt dokumentiert). Generator mit Herkunftsnachweis: personalverrechnung/tools/extract_gembg_katalog.py. - GemBG-Felder auf der Payroll-Version (hr.version) plus Employee-Spiegel nach dem Engine-Muster (related/inherited): Entlohnungsgruppe, Stufe, Besoldungsdienstalter, Vorrückungstermin — berechnet nach § 66 Abs 2 (erster Tag des Monats nach Vollendung weiterer n Jahre BDA), manuell überschreibbar für Überleitungsfälle (§§ 157a ff). - Vorrückungs-Wizard (§ 66 Abs 2): fällige Versionen zum Stichtag, Stufenerhöhung mit Höchststufen-Schutz und Ergebnis-Notification — bewusst kein stilles Mutieren im Lohnlauf (Dokumentationspflicht). - Views/Menüs (Personalverrechnung Bgld. unter Payroll), Security auf hr_payroll-Gruppen, Employee-Form-Anbindung in payroll_group. - Tests (Rechenfälle AP1): Seed-Werte inkl. Quellenanomalie kb1a/6, Stichtags-Lookup, Jahresversionierung, Vorrückungstermin (BDA 15.03.2020 -> 1.4.2028), Wizard-Anwendung mit Höchststufen-Skip. Statische Validierung grün (py_compile, XML, Manifest, CSV-Integrität); Runtime-Testlauf auf dem Dev-Host (gem360_dev) ausständig, wie im Implementierungsplan M2 vorgesehen.
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
# Part of the gem360 onboarding. See LICENSE / project docs for details.
|
||||
from . import test_katalog
|
||||
@@ -0,0 +1,95 @@
|
||||
# Part of the gem360 onboarding. See LICENSE / project docs for details.
|
||||
from datetime import date
|
||||
|
||||
from odoo.tests import TransactionCase, tagged
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class KatalogTest(TransactionCase):
|
||||
"""Rechenfälle AP1: Katalog-Seed 2026, Stichtags-Lookup, Versionierung,
|
||||
Vorrückungstermin nach § 66 Abs 2 GemBG und Vorrückungs-Wizard."""
|
||||
|
||||
def test_01_seed_2026_values(self):
|
||||
"""Seed-Werte der konsolidierten GemBG-Fassung (Wert 1.7.2026)."""
|
||||
av1 = self.env.ref('l10n_at_gemeinde_payroll.bgld_grp_av_av1')
|
||||
bv1 = self.env.ref('l10n_at_gemeinde_payroll.bgld_grp_ia_bv1')
|
||||
kb1a = self.env.ref('l10n_at_gemeinde_payroll.bgld_grp_kb_kb1a')
|
||||
gb1a = self.env.ref('l10n_at_gemeinde_payroll.bgld_grp__151c_gb1a')
|
||||
gv1 = self.env.ref('l10n_at_gemeinde_payroll.bgld_grp_i_gv1')
|
||||
stichtag = date(2026, 7, 1)
|
||||
self.assertEqual(av1._get_entgelt(1, stichtag).monatsentgelt, 7135.20)
|
||||
self.assertEqual(av1._get_entgelt(12, stichtag).monatsentgelt, 8712.50)
|
||||
self.assertEqual(bv1._get_entgelt(1, stichtag).monatsentgelt, 5329.00)
|
||||
# Quellenanomalie "3843,80" (fehlender Tausenderpunkt) korrekt geparst
|
||||
self.assertEqual(kb1a._get_entgelt(6, stichtag).monatsentgelt, 3843.80)
|
||||
self.assertEqual(gb1a._get_entgelt(1, stichtag).monatsentgelt, 3328.20)
|
||||
# gv1 endet laut Tabelle bei Stufe 11
|
||||
self.assertEqual(gv1._max_stufe(stichtag), 11)
|
||||
self.assertEqual(av1._max_stufe(stichtag), 12)
|
||||
|
||||
def test_02_lookup_before_gueltig_ab(self):
|
||||
"""Vor dem Stichtag gibt es keinen Wert (Vorrückungsbasis alt)."""
|
||||
av1 = self.env.ref('l10n_at_gemeinde_payroll.bgld_grp_av_av1')
|
||||
self.assertFalse(av1._get_entgelt(1, date(2026, 6, 30)))
|
||||
|
||||
def test_03_versioning(self):
|
||||
"""Jahresversionen: neuer Wert greift erst ab seinem Stichtag."""
|
||||
av1 = self.env.ref('l10n_at_gemeinde_payroll.bgld_grp_av_av1')
|
||||
self.env['gemeinde.payroll.entlohnungsstufe'].create({
|
||||
'entlohnungsgruppe_id': av1.id,
|
||||
'stufe': 1,
|
||||
'monatsentgelt': 7300.00,
|
||||
'gueltig_ab': date(2027, 7, 1),
|
||||
})
|
||||
self.assertEqual(
|
||||
av1._get_entgelt(1, date(2026, 12, 31)).monatsentgelt, 7135.20)
|
||||
self.assertEqual(
|
||||
av1._get_entgelt(1, date(2027, 7, 1)).monatsentgelt, 7300.00)
|
||||
|
||||
def _version_mit_katalog(self, bda, stufe=1):
|
||||
employee = self.env['hr.employee'].create({'name': 'Test GemBG'})
|
||||
version = self.env['hr.version'].search(
|
||||
[('employee_id', '=', employee.id)], limit=1)
|
||||
if not version:
|
||||
version = self.env['hr.version'].create({
|
||||
'employee_id': employee.id,
|
||||
'date_start': date(2020, 1, 1),
|
||||
})
|
||||
version.write({
|
||||
'entlohnungsgruppe_id':
|
||||
self.env.ref('l10n_at_gemeinde_payroll.bgld_grp_av_av1').id,
|
||||
'entlohnungsstufe': stufe,
|
||||
'besoldungsdienstalter': bda,
|
||||
})
|
||||
return version
|
||||
|
||||
def test_04_vorrueckungstermin(self):
|
||||
"""§ 66 Abs 2: 4-Jahres-Rhythmus, erster Tag des Folgemonats.
|
||||
|
||||
BDA 15.03.2020, heute >= 2026: die nächste Vollendung weiterer
|
||||
4 Jahre ist 15.03.2028 → Vorrückungstermin 1.4.2028.
|
||||
"""
|
||||
version = self._version_mit_katalog(date(2020, 3, 15))
|
||||
self.assertEqual(version.vorrueckungstermin, date(2028, 4, 1))
|
||||
|
||||
def test_05_wizard_apply(self):
|
||||
"""Wizard erhöht die Stufe fälliger Versionen und überspringt
|
||||
die Höchststufe."""
|
||||
version = self._version_mit_katalog(date(2014, 3, 15), stufe=3)
|
||||
version.vorrueckungstermin = date(2024, 4, 1)
|
||||
max_stufe = version.entlohnungsgruppe_id._max_stufe(date(2024, 4, 1))
|
||||
wizard = self.env['gemeinde.payroll.vorrueckung.wizard'].create({
|
||||
'stichtag': date(2024, 4, 1),
|
||||
})
|
||||
self.assertIn(version, wizard.version_ids)
|
||||
wizard.action_apply()
|
||||
self.assertEqual(version.entlohnungsstufe, 4)
|
||||
|
||||
version_top = self._version_mit_katalog(date(2014, 3, 15),
|
||||
stufe=max_stufe)
|
||||
version_top.vorrueckungstermin = date(2024, 4, 1)
|
||||
wizard2 = self.env['gemeinde.payroll.vorrueckung.wizard'].create({
|
||||
'stichtag': date(2024, 4, 1),
|
||||
})
|
||||
wizard2.action_apply()
|
||||
self.assertEqual(version_top.entlohnungsstufe, max_stufe)
|
||||
Reference in New Issue
Block a user