[IMP] l10n_at_gemeinde_payroll: implement AP2 pay computation engine (GemBG Bgld.)

Entgelt-Engine nach Implementierungsplan AP2 (freigegeben 2026-09-09):

- Structure Type "Bgld. GemBG 2014" + Structure "Gemeindebedienstete"
  mit 4 Kategorien (GEMBG_BRUTTO, GEMBG_ABZUG, GEMBG_NETTO, GEMBG_DG).
- Work-Entry-Types: Überstunden Tag/Nacht (§ 76), Mehrdienstleistung,
  Journaldienst (§ 79), Bereitschaft (§ 80), Sonn-/Feiertag (§ 78).
- Input-Types: Erschwerniszulage (§ 83), Fahrtkostenzuschuss (§ 88),
  Jubiläumszuwendung (§ 89).
- Entgelt-Regeln (13 Rules):
  * ME — Monatsentgelt: Katalog-Lookup (Gruppe+Stufe+Stichtag),
    Ausbildungsphase 5 % Abzug (§ 133h), Teilzeit via work_time_rate.
  * KIZU — Kinderzulage: kinder_anzahl × 15,60 EUR (§ 61 GemBG),
    bei Teilzeit UNGEKÜRZT (§ 59 Abs 2).
  * FUZU — Funktionszulage: hr.version-Feld × work_time_rate (§ 62).
  * UEZ_TAG/UEZ_NACHT — Überstundenvergütung (§ 76):
    Grund = ME / (4,33 × Wochenstunden); Zuschlag 50 % Tag / 100 % Nacht.
  * JZU — Journaldienstzulage (§ 79): Work-Entry × Parametersatz.
  * SFZU — Sonn-/Feiertagszulage (§ 78): Stunden × Grundvergütung × %.
  * BERB — Bereitschaftsentschädigung (§ 80): Stunden × Parametersatz.
  * ERZU/FKZ/JUB — Input-basierte Bezüge (§§ 83/88/89).
  * SZQ — Sonderzahlung QUARTALSWEISE (§ 133n): in Quartalsendmonaten
    (März, Juni, September, Dezember) 50 % × (ME + KIZU).
  * NETTO — Kategoriensumme (wird mit AP3/AP4 erweitert).
- hr.version-Felder: kinder_anzahl, funktionszulage, ausbildungsphase
  (§ 61/§ 62/§ 133h) mit Employee-Spiegel nach Engine-Muster.
- Rule-Parameter: Kinderzulage 15,60 EUR, Journaldienstzulage,
  Sonn-/Feiertags-%, Bereitschaftsstunde (letzte 3 als AP0-Platzhalter
  mit 0.0 — Werte aus der Bezügeanpassung nach Beschaffung).
- Tests (8 Rechenfälle): Vollzeit av1 Stufe 1, Kinderzulage 2 Kinder
  = 31,20 EUR, Funktionszulage, Ausbildungsphase 5 % Abzug,
  SZ Quartalsende + Nicht-Quartalsende, Netto=Brutto (AP3/AP4 offen),
  Stufe 12 Max.
- Employee-Form um Zulagen-Gruppe erweitert.

Modul-Version 19.0.1.3.0. Statische Validierung grün; Runtime-Testlauf
auf dem Dev-Host ausständig.
This commit is contained in:
2026-09-09 13:01:00 +02:00
parent 42bb759fd1
commit a7959c1259
9 changed files with 627 additions and 2 deletions
@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- ============================================================ -->
<!-- Structure Type: Bgld. GemBG -->
<!-- ============================================================ -->
<record id="structure_type_gembg_bgld" model="hr.payroll.structure.type">
<field name="name">Bgld. GemBG 2014</field>
<field name="country_id" ref="base.at"/>
<field name="default_schedule_pay">monthly</field>
</record>
<!-- ============================================================ -->
<!-- Structure: Gemeindebedienstete Bgld. -->
<!-- ============================================================ -->
<record id="structure_gembg_bgld" model="hr.payroll.structure">
<field name="name">Gemeindebedienstete (Bgld. GemBG 2014)</field>
<field name="code">GEMBG.BGLD</field>
<field name="type_id" ref="structure_type_gembg_bgld"/>
<field name="regular_pay" eval="True"/>
</record>
<!-- ============================================================ -->
<!-- Kategorien -->
<!-- ============================================================ -->
<record id="category_gembg_brutto" model="hr.salary.rule.category">
<field name="name">GemBG Brutto (Entgelt)</field>
<field name="code">GEMBG_BRUTTO</field>
</record>
<record id="category_gembg_abzug" model="hr.salary.rule.category">
<field name="name">GemBG Abzüge (LSt, SV)</field>
<field name="code">GEMBG_ABZUG</field>
</record>
<record id="category_gembg_netto" model="hr.salary.rule.category">
<field name="name">GemBG Netto</field>
<field name="code">GEMBG_NETTO</field>
</record>
<record id="category_gembg_dg" model="hr.salary.rule.category">
<field name="name">GemBG Arbeitgeberanteile</field>
<field name="code">GEMBG_DG</field>
</record>
<!-- ============================================================ -->
<!-- Work-Entry-Types für GemBG-Komponenten -->
<!-- ============================================================ -->
<record id="work_entry_type_ueberstunden_tag" model="hr.work.entry.type">
<field name="name">Überstunden (tagsüber, § 76 GemBG)</field>
<field name="code">GEMBG_UEB_TAG</field>
<field name="round_days">NO</field>
<field name="round_days_type">DOWN</field>
<field name="is_paid" eval="True"/>
</record>
<record id="work_entry_type_ueberstunden_nacht" model="hr.work.entry.type">
<field name="name">Überstunden (Nachtzeit 22-6 Uhr, § 76 GemBG)</field>
<field name="code">GEMBG_UEB_NACHT</field>
<field name="round_days">NO</field>
<field name="round_days_type">DOWN</field>
<field name="is_paid" eval="True"/>
</record>
<record id="work_entry_type_mehrdienst" model="hr.work.entry.type">
<field name="name">Mehrdienstleistung (§ 76 GemBG)</field>
<field name="code">GEMBG_MEHR</field>
<field name="round_days">NO</field>
<field name="round_days_type">DOWN</field>
<field name="is_paid" eval="True"/>
</record>
<record id="work_entry_type_journaldienst" model="hr.work.entry.type">
<field name="name">Journaldienst (§ 79 GemBG)</field>
<field name="code">GEMBG_JOURNAL</field>
<field name="round_days">NO</field>
<field name="round_days_type">DOWN</field>
<field name="is_paid" eval="True"/>
</record>
<record id="work_entry_type_bereitschaft" model="hr.work.entry.type">
<field name="name">Bereitschaftsdienst (§ 80 GemBG)</field>
<field name="code">GEMBG_BEREIT</field>
<field name="round_days">NO</field>
<field name="round_days_type">DOWN</field>
<field name="is_paid" eval="True"/>
</record>
<record id="work_entry_type_sonn_feiertag" model="hr.work.entry.type">
<field name="name">Sonn-/Feiertagsdienst (§ 78 GemBG)</field>
<field name="code">GEMBG_SONNFEI</field>
<field name="round_days">NO</field>
<field name="round_days_type">DOWN</field>
<field name="is_paid" eval="True"/>
</record>
<!-- ============================================================ -->
<!-- Input-Types für manuelle Zulagen -->
<!-- ============================================================ -->
<record id="input_type_funktionszulage" model="hr.payslip.input.type">
<field name="name">Funktionszulage Überschreibung (§ 62)</field>
<field name="code">FUZU_INPUT</field>
</record>
<record id="input_type_erschwerniszulage" model="hr.payslip.input.type">
<field name="name">Erschwerniszulage (§ 83 GemBG)</field>
<field name="code">ERZU_INPUT</field>
</record>
<record id="input_type_fahrtkosten" model="hr.payslip.input.type">
<field name="name">Fahrtkostenzuschuss (§ 88 GemBG)</field>
<field name="code">FKZ_INPUT</field>
</record>
<record id="input_type_jubilaeum" model="hr.payslip.input.type">
<field name="name">Jubiläumszuwendung (§ 89 GemBG)</field>
<field name="code">JUB_INPUT</field>
</record>
</odoo>
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Entgelt-Parameter aus GemBG 2014 (konsolidiert 09.09.2026) -->
<!-- Kinderzulage § 61 GemBG: 15,60 EUR je Kind monatlich -->
<record id="hr_rule_parameter_gembg_kinderzulage_rate" model="hr.rule.parameter">
<field name="name">GemBG Kinderzulage je Kind (monatlich, § 61)</field>
<field name="code">gembg_kinderzulage_rate</field>
<field name="country_id" ref="base.at"/>
</record>
<record id="hr_rule_parameter_value_gembg_kinderzulage_rate" model="hr.rule.parameter.value">
<field name="rule_parameter_id" ref="hr_rule_parameter_gembg_kinderzulage_rate"/>
<field name="date_from">2019-01-01</field>
<field name="parameter_value">15.60</field>
</record>
<!-- Journaldienstzulage § 79 GemBG — pro Journaldienst-Tag -->
<record id="hr_rule_parameter_gembg_journaldienstzulage" model="hr.rule.parameter">
<field name="name">GemBG Journaldienstzulage je Werktag (§ 79)</field>
<field name="code">gembg_journaldienstzulage</field>
<field name="country_id" ref="base.at"/>
</record>
<record id="hr_rule_parameter_value_gembg_journaldienstzulage" model="hr.rule.parameter.value">
<field name="rule_parameter_id" ref="hr_rule_parameter_gembg_journaldienstzulage"/>
<field name="date_from">2019-01-01</field>
<field name="parameter_value">0.0</field>
</record>
<!-- Sonn-/Feiertagszulage § 78 GemBG — Prozentsatz auf Grundvergütung -->
<record id="hr_rule_parameter_gembg_sonnfeiertags_prozent" model="hr.rule.parameter">
<field name="name">GemBG Sonn-/Feiertagszulage Prozentsatz (§ 78)</field>
<field name="code">gembg_sonnfeiertags_prozent</field>
<field name="country_id" ref="base.at"/>
</record>
<record id="hr_rule_parameter_value_gembg_sonnfeiertags_prozent" model="hr.rule.parameter.value">
<field name="rule_parameter_id" ref="hr_rule_parameter_gembg_sonnfeiertags_prozent"/>
<field name="date_from">2019-01-01</field>
<field name="parameter_value">0.0</field>
</record>
<!-- Bereitschaftsentschädigung § 80 GemBG — je Bereitschaftsstunde -->
<record id="hr_rule_parameter_gembg_bereitschaftsstunde" model="hr.rule.parameter">
<field name="name">GemBG Bereitschaftsentschädigung je Stunde (§ 80)</field>
<field name="code">gembg_bereitschaftsstunde</field>
<field name="country_id" ref="base.at"/>
</record>
<record id="hr_rule_parameter_value_gembg_bereitschaftsstunde" model="hr.rule.parameter.value">
<field name="rule_parameter_id" ref="hr_rule_parameter_gembg_bereitschaftsstunde"/>
<field name="date_from">2019-01-01</field>
<field name="parameter_value">0.0</field>
</record>
</odoo>
@@ -0,0 +1,290 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- ============================================================ -->
<!-- Monatsentgelt (§ 55 GemBG / IVa §§ 133 ff) -->
<!-- ============================================================ -->
<record id="rule_me" model="hr.salary.rule">
<field name="name">Monatsentgelt</field>
<field name="code">ME</field>
<field name="sequence" eval="1"/>
<field name="category_id" ref="payroll_structure_bgld.category_gembg_brutto"/>
<field name="struct_id" ref="payroll_structure_bgld.structure_gembg_bgld"/>
<field name="condition_select">python</field>
<field name="condition_python">result = bool(employee.entlohnungsgruppe_id and employee.entlohnungsstufe)</field>
<field name="amount_select">python</field>
<field name="amount_python_compute"><![CDATA[
# Monatsentgelt nach Bgld. GemBG 2014 (IVa. Hauptstück §§ 133 ff).
# Katalog-Lookup: Entlohnungsgruppe + Stufe + Stichtag.
katalog_pos = employee.entlohnungsgruppe_id._get_entgelt(
employee.entlohnungsstufe, payslip.date_to)
if not katalog_pos:
result = 0
else:
base = katalog_pos.monatsentgelt
# Ausbildungsphase: 5 % Abzug (§ 133h GemBG)
if employee.ausbildungsphase:
base *= 0.95
# Teilzeit: anteilig über work_time_rate (§ 59 GemBG)
work_rate = employee.work_time_rate or 100.0
result = base * work_rate / 100.0
]]></field>
</record>
<!-- ============================================================ -->
<!-- Kinderzulage (§ 61 GemBG: 15,60 EUR je Kind, ungekürzt) -->
<!-- ============================================================ -->
<record id="rule_kizu" model="hr.salary.rule">
<field name="name">Kinderzulage (§ 61 GemBG)</field>
<field name="code">KIZU</field>
<field name="sequence" eval="2"/>
<field name="category_id" ref="payroll_structure_bgld.category_gembg_brutto"/>
<field name="struct_id" ref="payroll_structure_bgld.structure_gembg_bgld"/>
<field name="condition_select">python</field>
<field name="condition_python">result = employee.kinder_anzahl > 0</field>
<field name="amount_select">code</field>
<field name="amount_python_compute"><![CDATA[
# Kinderzulage § 61 GemBG: 15,60 EUR je Kind monatlich.
# Bei Teilzeit UNGEKÜRZT (§ 59 Abs 2: "die Kinderzulage gebührt
# jedoch in ungekürzter Höhe").
kiz_satz = payslip._rule_parameter('gembg_kinderzulage_rate')
result = employee.kinder_anzahl * kiz_satz
]]></field>
</record>
<!-- ============================================================ -->
<!-- Funktionszulage (§ 62 GemBG) -->
<!-- ============================================================ -->
<record id="rule_fuzu" model="hr.salary.rule">
<field name="name">Funktionszulage (§ 62 GemBG)</field>
<field name="code">FUZU</field>
<field name="sequence" eval="3"/>
<field name="category_id" ref="payroll_structure_bgld.category_gembg_brutto"/>
<field name="struct_id" ref="payroll_structure_bgld.structure_gembg_bgld"/>
<field name="condition_select">python</field>
<field name="condition_python">result = employee.funktionszulage > 0</field>
<field name="amount_select">code</field>
<field name="amount_python_compute"><![CDATA[
# Funktionszulage § 62 GemBG — Satz am Dienstvertrag (hr.version).
# Bei Teilzeit anteilig (wie Monatsentgelt).
work_rate = employee.work_time_rate or 100.0
result = employee.funktionszulage * work_rate / 100.0
]]></field>
</record>
<!-- ============================================================ -->
<!-- Überstundenvergütung (§ 76 GemBG) -->
<!-- ============================================================ -->
<record id="rule_uez_tag" model="hr.salary.rule">
<field name="name">Überstundenvergütung tagsüber (§ 76 GemBG)</field>
<field name="code">UEZ_TAG</field>
<field name="sequence" eval="10"/>
<field name="category_id" ref="payroll_structure_bgld.category_gembg_brutto"/>
<field name="struct_id" ref="payroll_structure_bgld.structure_gembg_bgld"/>
<field name="condition_select">python</field>
<field name="condition_python">result = 'GEMBG_UEB_TAG' in worked_days and worked_days['GEMBG_UEB_TAG'].number_of_hours > 0</field>
<field name="amount_select">code</field>
<field name="amount_python_compute"><![CDATA[
# § 76 GemBG: Grundvergütung + 50 % Zuschlag (tagsüber).
# Grundvergütung/ÜStd = Monatsentgelt / (4,33 × Wochenstundenzahl)
base_entgelt = rules['ME'].total
if base_entgelt and employee.entlohnungsgruppe_id:
wochenstunden = employee.hours_per_week or 40.0
grund_pro_uestd = base_entgelt / (4.33 * wochenstunden)
ueb_stunden = worked_days['GEMBG_UEB_TAG'].number_of_hours
result = ueb_stunden * grund_pro_uestd * 1.5 # 100 % + 50 % Zuschlag
else:
result = 0
]]></field>
</record>
<record id="rule_uez_nacht" model="hr.salary.rule">
<field name="name">Überstundenvergütung Nachtzeit (§ 76 GemBG)</field>
<field name="code">UEZ_NACHT</field>
<field name="sequence" eval="11"/>
<field name="category_id" ref="payroll_structure_bgld.category_gembg_brutto"/>
<field name="struct_id" ref="payroll_structure_bgld.structure_gembg_bgld"/>
<field name="condition_select">python</field>
<field name="condition_python">result = 'GEMBG_UEB_NACHT' in worked_days and worked_days['GEMBG_UEB_NACHT'].number_of_hours > 0</field>
<field name="amount_select">code</field>
<field name="amount_python_compute"><![CDATA[
# § 76 GemBG: Grundvergütung + 100 % Zuschlag (Nachtzeit 22-6 Uhr).
base_entgelt = rules['ME'].total
if base_entgelt and employee.entlohnungsgruppe_id:
wochenstunden = employee.hours_per_week or 40.0
grund_pro_uestd = base_entgelt / (4.33 * wochenstunden)
ueb_stunden = worked_days['GEMBG_UEB_NACHT'].number_of_hours
result = ueb_stunden * grund_pro_uestd * 2.0 # 100 % + 100 % Zuschlag
else:
result = 0
]]></field>
</record>
<!-- ============================================================ -->
<!-- Journaldienstzulage (§ 79 GemBG) — Input -->
<!-- ============================================================ -->
<record id="rule_jzu" model="hr.salary.rule">
<field name="name">Journaldienstzulage (§ 79 GemBG)</field>
<field name="code">JZU</field>
<field name="sequence" eval="12"/>
<field name="category_id" ref="payroll_structure_bgld.category_gembg_brutto"/>
<field name="struct_id" ref="payroll_structure_bgld.structure_gembg_bgld"/>
<field name="condition_select">python</field>
<field name="condition_python">result = 'GEMBG_JOURNAL' in worked_days and worked_days['GEMBG_JOURNAL'].number_of_hours > 0</field>
<field name="amount_select">code</field>
<field name="amount_python_compute"><![CDATA[
# Journaldienstzulage § 79 GemBG: pro Journaldienst (Werktag).
# Pauschaler Betrag je Journaldienst — Parameter aus Bezügeanpassung.
satz = payslip._rule_parameter('gembg_journaldienstzulage')
tage = worked_days['GEMBG_JOURNAL'].number_of_days or 0
result = tage * satz
]]></field>
</record>
<!-- ============================================================ -->
<!-- Sonn-/Feiertagszulage (§ 78 GemBG) — Input -->
<!-- ============================================================ -->
<record id="rule_sfzu" model="hr.salary.rule">
<field name="name">Sonn-/Feiertagszulage (§ 78 GemBG)</field>
<field name="code">SFZU</field>
<field name="sequence" eval="13"/>
<field name="category_id" ref="payroll_structure_bgld.category_gembg_brutto"/>
<field name="struct_id" ref="payroll_structure_bgld.structure_gembg_bgld"/>
<field name="condition_select">python</field>
<field name="condition_python">result = 'GEMBG_SONNFEI' in worked_days and worked_days['GEMBG_SONNFEI'].number_of_hours > 0</field>
<field name="amount_select">code</field>
<field name="amount_python_compute"><![CDATA[
# Sonn-/Feiertagszulage § 78 GemBG: Zuschlag auf Grundvergütung.
# Der Prozentsatz steht in der Bezügeanpassung (Parameter).
# R1: Pauschal je Stunde — Detailabbildung nach Bestandsaufnahme.
base_entgelt = rules['ME'].total
if base_entgelt:
wochenstunden = employee.hours_per_week or 40.0
grund_pro_stunde = base_entgelt / (4.33 * wochenstunden)
stunden = worked_days['GEMBG_SONNFEI'].number_of_hours
satz = payslip._rule_parameter('gembg_sonnfeiertags_prozent') / 100.0
result = stunden * grund_pro_stunde * satz
else:
result = 0
]]></field>
</record>
<!-- ============================================================ -->
<!-- Bereitschaftsentschädigung (§ 80 GemBG) — Input -->
<!-- ============================================================ -->
<record id="rule_berb" model="hr.salary.rule">
<field name="name">Bereitschaftsentschädigung (§ 80 GemBG)</field>
<field name="code">BERB</field>
<field name="sequence" eval="14"/>
<field name="category_id" ref="payroll_structure_bgld.category_gembg_brutto"/>
<field name="struct_id" ref="payroll_structure_bgld.structure_gembg_bgld"/>
<field name="condition_select">python</field>
<field name="condition_python">result = 'GEMBG_BEREIT' in worked_days and worked_days['GEMBG_BEREIT'].number_of_hours > 0</field>
<field name="amount_select">code</field>
<field name="amount_python_compute"><![CDATA[
# Bereitschaftsentschädigung § 80 GemBG.
# Pauschaler Betrag je Bereitschaftsstunde — Parameter.
satz = payslip._rule_parameter('gembg_bereitschaftsstunde')
stunden = worked_days['GEMBG_BEREIT'].number_of_hours
result = stunden * satz
]]></field>
</record>
<!-- ============================================================ -->
<!-- Erschwerniszulage (§ 83 GemBG) — Input -->
<!-- ============================================================ -->
<record id="rule_erzu" model="hr.salary.rule">
<field name="name">Erschwerniszulage (§ 83 GemBG)</field>
<field name="code">ERZU</field>
<field name="sequence" eval="15"/>
<field name="category_id" ref="payroll_structure_bgld.category_gembg_brutto"/>
<field name="struct_id" ref="payroll_structure_bgld.structure_gembg_bgld"/>
<field name="condition_select">python</field>
<field name="condition_python">result = 'ERZU_INPUT' in inputs and inputs['ERZU_INPUT'].amount > 0</field>
<field name="amount_select">code</field>
<field name="amount_python_compute"><![CDATA[
result = inputs['ERZU_INPUT'].amount
]]></field>
</record>
<!-- ============================================================ -->
<!-- Jubiläumszuwendung (§ 89 GemBG) — Input -->
<!-- ============================================================ -->
<record id="rule_jub" model="hr.salary.rule">
<field name="name">Jubiläumszuwendung (§ 89 GemBG)</field>
<field name="code">JUB</field>
<field name="sequence" eval="16"/>
<field name="category_id" ref="payroll_structure_bgld.category_gembg_brutto"/>
<field name="struct_id" ref="payroll_structure_bgld.structure_gembg_bgld"/>
<field name="condition_select">python</field>
<field name="condition_python">result = 'JUB_INPUT' in inputs and inputs['JUB_INPUT'].amount > 0</field>
<field name="amount_select">code</field>
<field name="amount_python_compute"><![CDATA[
result = inputs['JUB_INPUT'].amount
]]></field>
</record>
<!-- ============================================================ -->
<!-- Fahrtkostenzuschuss (§ 88 GemBG) — Input -->
<!-- ============================================================ -->
<record id="rule_fkz" model="hr.salary.rule">
<field name="name">Fahrtkostenzuschuss (§ 88 GemBG)</field>
<field name="code">FKZ</field>
<field name="sequence" eval="17"/>
<field name="category_id" ref="payroll_structure_bgld.category_gembg_brutto"/>
<field name="struct_id" ref="payroll_structure_bgld.structure_gembg_bgld"/>
<field name="condition_select">python</field>
<field name="condition_python">result = 'FKZ_INPUT' in inputs and inputs['FKZ_INPUT'].amount > 0</field>
<field name="amount_select">code</field>
<field name="amount_python_compute"><![CDATA[
result = inputs['FKZ_INPUT'].amount
]]></field>
</record>
<!-- ============================================================ -->
<!-- Sonderzahlung (§ 133n GemBG: 50 % je Kalendervierteljahr) -->
<!-- ============================================================ -->
<record id="rule_szq" model="hr.salary.rule">
<field name="name">Sonderzahlung (quartalsweise, § 133n GemBG)</field>
<field name="code">SZQ</field>
<field name="sequence" eval="30"/>
<field name="category_id" ref="payroll_structure_bgld.category_gembg_brutto"/>
<field name="struct_id" ref="payroll_structure_bgld.structure_gembg_bgld"/>
<field name="condition_select">python</field>
<field name="condition_python"><![CDATA[
# § 133n GemBG: 50 % des Monatsentgelts (und der Kinderzulage)
# für jedes Kalendervierteljahr. Auszahlung in den Monaten am
# Quartalsende (März, Juni, September, Dezember).
# Der Monat der Auszahlung ist der Monat, für den das Entgelt
# gebührt (§ 56 Abs 2 GemBG: 15.3., 15.6., 15.9., 15.12.).
import datetime
month = payslip.date_to.month
result = month in (3, 6, 9, 12)
]]></field>
<field name="amount_select">code</field>
<field name="amount_python_compute"><![CDATA[
# 50 % des Monatsentgelts + Kinderzulage des AUSZAHLUNGSMONATS
# (§ 133n: "in der Höhe von 50% des Monatsentgelts (und der
# Kinderzulage), die ihnen für den Monat der Auszahlung zustehen").
# Bei unterbrochenem Vierteljahr: nur der entsprechende Teil
# (R1: Vollzeit-Rechnung; Anteil folgt mit der Zeit-Erfassung).
me_total = rules['ME'].total or 0
kizu_total = rules['KIZU'].total or 0
result = (me_total + kizu_total) * 0.5
]]></field>
</record>
<!-- ============================================================ -->
<!-- NETTO (Kategoriensumme; wird mit AP3/AP4 erweitert) -->
<!-- ============================================================ -->
<record id="rule_netto" model="hr.salary.rule">
<field name="name">Netto</field>
<field name="code">NETTO</field>
<field name="sequence" eval="100"/>
<field name="category_id" ref="payroll_structure_bgld.category_gembg_netto"/>
<field name="struct_id" ref="payroll_structure_bgld.structure_gembg_bgld"/>
<field name="condition_select">none</field>
<field name="amount_select">code</field>
<field name="amount_python_compute"><![CDATA[
result = categories.GEMBG_BRUTTO - categories.GEMBG_ABZUG
]]></field>
</record>
</odoo>