[IMP] l10n_at_hr_payroll_private: add unpaid care/parental leave family (AP16)

Close the parental/care-leave block after the pilot-client scope release (8.13): six unpaid full-release kinds join the generic parental-leave work entry — Bildungskarenz (AVRAG § 11, two to twelve months by agreement with the AMS-financed Weiterbildungsbeihilfe), Familienhospizkarenz for terminal accompaniment (AVRAG § 14a, three to six months), accompaniment of seriously ill children (§ 14b, five to nine months), children's rehabilitation leave (§ 14e, four weeks per year), Pflegekarenz (§ 14c, one to three months, undivided) and the Papa-Monat (VKG § 1a, one month, creditable toward seniority under § 1a Abs 7 VKG iVm § 15f MSchG while Bildungs-/Pflegekarenz is not). All are unpaid at the employer — the external bodies pay the replacement income (AK, AMS, Bundesamt, KV-Träger) — so the new negative KARENZ_ENTGELT rule stops the employer wage per working day through the shared Tagesatz helper whose exclusion list now covers EFZG, Mutterschutz and Karenz corrections. The Versichertenmeldung run emits M4 deregistrations at the end of the pay entitlement (the day before the release begins) and M3 re-registrations at the return date — omitted when the employment itself ends — with the eSV Karenzart strings logged as protocol information pending the special DM-ORG formats (GP7 track). The fictive BMSVG basis gains the § 7 Abs 4 Z 1–3 bridge: when a new maternity prohibition follows a parental-leave stretch directly or after employment of less than three months, the reference months fall before the preceding prohibition, and a re-founded employment within three months of the ended karenziert employment uses the single last full calendar month; contributions during the KBG period are FLAF-financed (§ 7 Abs 5) and during hospice/care leave Bund-financed (§ 7 Abs 6) — no employer rule, verified by test. Pflegeteilzeit and comparable reduced-hour arrangements pay the BV contribution on the pre-reduction wage via a new version field consumed by the BMSVG basis (§ 6 Abs 4). The endabrechnung wizard gains the § 23 Abs 8 AngG full-time re-rating preview (monthly salary ÷ work_time_rate, confirmable) with § 23a Abs 4a and UEL § 10 Abs 4 UrlG guidance. The Mutterschutz status now detects the § 163 ASVG Sonderwochengeld case (prohibition inside a Karenz — the KV-Träger pays the increased sickness benefit) and warns on § 166 ASVG suspension (full for >50 % continued pay, half at 50 %, activity and Pflegekarenzgeld hints). Verified against the original statute text in .ris/ (AVRAG §§ 11/11a/14a–14e, VKG § 1a, MSchG § 15f, BMSVG § 7 Abs 4–6, ASVG §§ 163/166) and the knowledge-base sources lb-kar/elt/kzs/pap/kbg; the vacation proration of leave stretches (§ 15f Abs 2 MSchG on the hr_holidays allocation side), the eSV special formats for the Karenz art block, the full Sonderwochengeld computation and the leave-overlap policy decision remain documented open points.

Version 19.0.17.0.0 (private)
This commit is contained in:
2026-09-15 14:25:48 +02:00
parent 850e99df20
commit d53e1e64a1
15 changed files with 1018 additions and 12 deletions
@@ -14,6 +14,7 @@ from . import buchungsbeleg
from . import wien_dag
from . import efzg
from . import mutterschutz
from . import karenz
from . import aeb
from . import pfaendung
from . import pfaendung_report
@@ -206,12 +206,18 @@ class HrPayslip(models.Model):
Erstfenster — 30-Tage-Monat (KB-Beispiel 4.500/30 × 17 =
2.550); Teilmonate über die Lohnsteuertage, um Doppelabzüge
zu vermeiden (das Entgelt ist für die Teilzeit bereits
aliquotiert)."""
aliquotiert). AP16 (§ 6 Abs 4 BMSVG): während einer
Arbeitszeit-Reduzierung mit gesetztem Feld
l10n_at_bv_vor_entgelt (z. B. Pflegeteilzeit § 14d AVRAG)
läuft der Beitrag auf dem Vor-Reduzierungs-Entgelt."""
self.ensure_one()
pflichtig_ab, kurz_av = self._at_bv_fenster()
if kurz_av:
return 0.0
vor_entgelt = self.version_id.l10n_at_bv_vor_entgelt
basis = self._l10n_at_sv_basis_roh(result_rules)
if vor_entgelt:
basis = max(basis, float(vor_entgelt))
if pflichtig_ab is None or pflichtig_ab <= self.date_from:
# AP4: fiktive BG während des Krankengeldbezugs (§ 7 Abs 3
# BMSVG) und des Wochengeldbezugs (§ 7 Abs 4, AP7) — nur
@@ -275,7 +275,7 @@ class HrPayslip(models.Model):
self.ensure_one()
basis = self._l10n_at_sv_basis_roh(result_rules)
for code in ('TEIL_ENTGELT_HALB', 'KRANKENTGELT_PHASE',
'MSCH_ENTGELT'):
'MSCH_ENTGELT', 'KARENZ_ENTGELT'):
if result_rules is not None and code in result_rules \
and result_rules[code]['total']:
basis -= result_rules[code]['total']
@@ -0,0 +1,135 @@
# Part of the odoo-at-payroll project. License: LGPL-3.
"""AP16: Karenz-/Familien-Freistellungen — unbezahlte Karenz-Arten
(Elternkarenz generisch, Bildungs-, Familienhospiz-, Kinderrehabilita-
tions- und Pflegekarenz, Papa-Monat) mit Entgelt-Stopp, eSV-An- und
Abmeldeereignissen und der BMSVG-§-7-Brücke.
Am Originalwortlaut verifiziert (.ris/, 8.13 freigegeben 2026-09-15):
- Alle Voll-Freistellungen sind entgeltlos (AVRAG §§ 11, 14a, 14b,
14e, 14c; VKG § 1a) — Entgelt-Stopp je Arbeitstag über die
negative Regel ``KARENZ_ENTGELT`` (Muster MSCH_ENTGELT, AP7).
- eSV: Abmeldung zum Ende des Entgeltanspruchs (Tag vor dem
Karenzbeginn), Anmeldung zum ersten Arbeitstag nach dem Ende;
Papamonat/Familienzeit: Abmeldung am Tag vor Beginn (§ 11 Abs 3
lit a ASVG, lb-pap-01). Karenzart-Strings der Sonderformate
„Familienhospizkarenz/Pflegekarenz An-/Abmeldung" (lb-kzs-05)
laufen als Protokoll-Info — erweiterte eSV-Sonderformate = GP7-Rest.
- BV: Elternkarenz/KBG zu Lasten FLAF (§ 7 Abs 5 BMSVG), Familien-
hospiz-/Pflegekarenz zu Lasten des Bundes (§ 7 Abs 6 BMSVG,
Fiktivgrundlage KBG § 5b Abs 1 KBGG idF vor BGBl I 53/2016);
Pflegeteilzeit: AG-Beitrag auf Vor-Reduzierungs-Entgelt (§ 6 Abs 4
BMSVG, Feld l10n_at_bv_vor_entgelt).
- Dienstzeit: Papamonat ist ANZURECHNEN (§ 1a Abs 7 VKG iVm § 15f
MSchG), Bildungs-/Pflegekarenz grundsätzlich NICHT (§ 11 Abs 2,
§ 14c/14d AVRAG) — Wizard-bestätigte Dienstzeiten, dokumentiert.
"""
from datetime import timedelta
from odoo import fields, models
# Unbezahlte Karenz-WETs (generisch + AP16-Spezies)
_KARENZ_WET = 'ATP_KARENZ'
_BILDUNGSKARENZ_WET = 'ATP_BILDUNGSKARENZ'
_HOSPIZKARENZ_WET = 'ATP_HOSPIZKARENZ'
_KINDER_KRANK_WET = 'ATP_KINDERKRANK'
_KINDER_REHAB_WET = 'ATP_KINDERREHAB'
_PFLEGEKARENZ_WET = 'ATP_PFLEGEKARENZ'
_PAPAMONAT_WET = 'ATP_PAPAMONAT'
KARENZ_ARTEN = {
_KARENZ_WET: 'Elternkarenz (MSchG/VKG)',
_BILDUNGSKARENZ_WET: 'Bildungskarenz (§ 11 AVRAG)',
_HOSPIZKARENZ_WET: 'Familienhospizkarenz — Sterbebegleitung '
'(§ 14a AVRAG)',
_KINDER_KRANK_WET: 'Familienhospizkarenz — Begleitung schwerst '
'erkrankter Kinder (§ 14b AVRAG)',
_KINDER_REHAB_WET: 'Freistellung Kinderrehabilitation '
'(§ 14e AVRAG)',
_PFLEGEKARENZ_WET: 'Pflegekarenz (§ 14c AVRAG)',
_PAPAMONAT_WET: 'Papa-Monat/Familienzeit (§ 1a VKG / FamZeitbG)',
}
class HrPayslip(models.Model):
_inherit = 'hr.payslip'
def _at_karenz_wet_codes(self):
"""Codes der unbezahlten Karenz-Freistellungen (inkl. generisch
und AP16-Spezies)."""
self.ensure_one()
return list(KARENZ_ARTEN)
def _at_karenz_leaves(self):
"""Validierte Karenz-Freistellungen: [(von, bis, wett_code)]
chronologisch."""
self.ensure_one()
typen = self.env['hr.leave.type'].search([
('work_entry_type_id.code', 'in', self._at_karenz_wet_codes())
])
leaves = self.env['hr.leave'].search([
('employee_id', '=', self.employee_id.id),
('holiday_status_id', 'in', typen.ids),
('state', 'in', ('validate', 'validate1')),
])
ergebnis = []
for leave in leaves:
wett = leave.holiday_status_id.work_entry_type_id.code
ergebnis.append((leave.request_date_from,
leave.request_date_to, wett))
return [(von, bis, wett) for von, bis, wett in ergebnis
if von and bis]
def _at_karenz_status(self):
"""Karenz-Tage je Abrechnungsperiode über alle unbezahlten
Karenz-Arten: {'kalendertage', 'arbeitstage', 'arten'} — None
ohne Freistellung im Zeitraum (Muster _at_msch_status)."""
self.ensure_one()
codes = set(self._at_karenz_wet_codes())
tage = {}
tag_art = {}
for von, bis, wett in self._at_karenz_leaves():
tag = fields.Date.to_date(von)
ende = fields.Date.to_date(bis)
while tag <= ende:
tage[tag] = True
tag_art[tag] = wett
tag += timedelta(days=1)
in_periode = sorted(
tag for tag in tage
if self.date_from <= tag <= self.date_to)
if not in_periode:
return None
eintraege = self.env['hr.work.entry'].search([
('employee_id', '=', self.employee_id.id),
('date', '>=', self.date_from),
('date', '<=', self.date_to),
('state', '!=', 'cancelled'),
('work_entry_type_id.code', 'in', list(codes)),
])
arten_aktuell = {tag_art[tag] for tag in in_periode}
return {
'kalendertage': in_periode,
'arbeitstage': sorted({e.date for e in eintraege}),
'arten': sorted(KARENZ_ARTEN[c] for c in arten_aktuell),
}
def _at_karenz_entgelt_tage(self, result_rules=None):
"""Arbeitstage der unbezahlten Karenz im Abrechnungszeitraum
(Entgelt-Stopp-Basis der Regel KARENZ_ENTGELT)."""
self.ensure_one()
status = self._at_karenz_status()
if not status:
return 0
return len(status['arbeitstage'])
class HrVersion(models.Model):
_inherit = 'hr.version'
l10n_at_bv_vor_entgelt = fields.Monetary(
string='BV-Basis vor Arbeitszeit-Reduktion (§ 6 Abs 4 BMSVG)',
currency_field='currency_id',
help='Monatsentgelt vor der Reduzierung (z. B. Pflegeteilzeit '
'§ 14d AVRAG): der BV-Beitrag läuft während der Maßnahme '
'auf Grundlage der Arbeitszeit vor Herabsetzung '
'(§ 6 Abs 4 BMSVG). Leer = laufende Basis.')
@@ -36,11 +36,27 @@ Fristberechnung aus dem ärztlichen Zeugnis bleibt beim Mandanten.
Urlaubsanspruch erwächst während des Wochengeldbezugs (lb-msf-03);
Sonderwochengeld (§ 163 ASVG, Günstigkeitsvergleich § 162 Abs 3b) =
dokumentierte Option.
AP16 (8.13): Karenz-Brücke nach § 7 Abs 4 Z 13 BMSVG — folgt das
neuerliche Beschäftigungsverbot unmittelbar auf eine Karenz (Z 1) oder
nach einer kürzeren als dreimonatigen Beschäftigung (Z 2), ist die
Bemessungsgrundlage die des Kalendermonats vor dem der Karenz
unmittelbar vorangegangenen Beschäftigungsverbots; Z 3 (neues DV nach
Beendigung des karenzierten DV, < 3 Monate): der letzte volle
Kalendermonat vor dem neuerlichen Verbot. BV während des KBG-Bezugs
läuft zu Lasten des FLAF (§ 7 Abs 5), in der Familienhospiz-/Pflege-
karenz zu Lasten des Bundes (§ 7 Abs 6) — keine AG-Regeln; das Ruhen
des Wochengeldes (§ 166 ASVG) und das Sonderwochengeld während
einer Karenz (§ 163 ASVG) werden als Info/Warnung ausgewiesen.
"""
from datetime import date, timedelta
from dateutil.relativedelta import relativedelta
from odoo import fields, models
from .karenz import KARENZ_ARTEN
_MSCH_WET = 'ATP_MSCH'
@@ -61,13 +77,21 @@ class HrPayslip(models.Model):
slip.l10n_at_msch_info = ''
continue
wochengeld = slip._at_wochengeld()
slip.l10n_at_msch_info = (
info = (
'%d Kalendertage Bezug · WG %.2f/Kalendertag '
'(Ø-Netto %.2f + %.0f %%)' % (
len(msch['kalendertage']),
wochengeld['tagesatz'],
wochengeld['netto_drei_monate'],
wochengeld['sz_prozent']))
if slip._at_msch_sonderwochengeld():
info += (' · Sonderwochengeld (§ 163 ASVG) statt '
'Wochengeld — ÖGK, erhöhtes Krankengeld '
'(§ 141 Abs 2, § 125 iVm § 108f)')
warnungen = slip._at_msch_ruhen_warnungen()
if warnungen:
info += ' · Ruhen: ' + '; '.join(warnungen)
slip.l10n_at_msch_info = info
def _at_msch_leaves(self):
"""Validierte Mutterschutz-Frist-Abwesenheiten (ATP_MSCH)."""
@@ -120,17 +144,109 @@ class HrPayslip(models.Model):
'episode_beginn': block,
}
def _at_msch_referenz_monate(self, episode_beginn):
"""Die drei (vollen) Kalendermonate vor dem Versicherungsfall
der Mutterschaft (§ 162 Abs 3: letzte 13 Wochen; § 7 Abs 4
BMSVG: letzte drei Kalendermonate). Versicherungsfall im Monat
X → Monate X-3, X-2, X-1 (aufsteigend)."""
def _at_msch_sonderwochengeld(self):
"""Sonderwochengeld statt Wochengeld (§ 163 ASVG, verifiziert):
die Mutterschutz-Frist fällt in eine Karenz nach dem MSchG —
kein Anspruch auf Wochengeld (§ 162), das Sonderwochengeld
zahlt der Krankenversicherungsträger (erhöhtes Krankengeld
§ 141 Abs 2, Bemessungsgrundlage § 125 aus dem Arbeits-
verdienst vor dem Ende des letzten Entgeltanspruchs, mit
§ 108f-Anpassung)."""
self.ensure_one()
msch = self._at_msch_status()
if not msch:
return False
for von, bis, _wett in self._at_karenz_leaves():
if any(von <= tag <= bis for tag in msch['kalendertage']):
return True
return False
def _at_msch_ruhen_warnungen(self):
"""Ruhen des Wochengeldes (§ 166 ASVG, verifiziert) —
Warnungen zu Fortbezug während der Frist:
Z 2 Entgeltfortzahlung 100 % → Ruhen zur Gänze, 50 %
hälftig (Urlaubs-/UEL-/KE-Zeiten gelten nicht als weiterge-
leistete Bezüge); Z 3 Erwerbstätigkeit und Z 4 Pflegekarenz-
geld sind Bezugszeitraum-Daten (AEB/ÖGK-Seite, Hinweis)."""
self.ensure_one()
msch = self._at_msch_status()
if not msch:
return []
tage = set(msch['kalendertage'])
efz = self._at_efz_status()
warnungen = []
if efz:
if any(tag in tage for tag in efz.get('voll_arbeitstage', [])):
warnungen.append('Fortbezug > 50 % (Entgeltfortzahlung) '
'— Ruhen zur Gänze (§ 166 Abs 1 Z 2)')
elif any(tag in tage for tag in efz.get('halb_arbeitstage', [])):
warnungen.append('Fortbezug = 50 % — Ruhen hälftig '
'(§ 166 Abs 1 Z 2)')
warnungen.append('Erwerbstätigkeit/Pflegekarenzgeld während der '
'Frist prüfen (§ 166 Abs 1 Z 3/4)')
return warnungen
def _at_msch_referenz_stichtag_und_anzahl(self, episode_beginn):
"""(Stichtag, Referenz-Monatsanzahl) nach § 7 Abs 4 BMSVG mit
Karenz-Brücke Z 13 (AP16):
- Z 1/Z 2: endete eine Karenz innerhalb von drei Monaten vor
dem neuerlichen Beschäftigungsverbot, gilt das der Karenz
unmittelbar vorangegangene Beschäftigungsverbot als
Bemessungsstichtag (Referenzmonate davor);
- Z 3: neues DV binnen drei Monaten nach Beendigung des
karenzierten DV (mit Karenz) → der letzte volle Kalendermonat
vor dem neuerlichen Verbot als EINZELNER Referenzmonat
(„volles Monatsentgelt");
- sonst: Versicherungsfall selbst, drei Monate."""
self.ensure_one()
stichtag = episode_beginn or self.date_from
grenze = stichtag - relativedelta(months=3)
karenz_kandidat = None
for von, bis, _wett in sorted(self._at_karenz_leaves(),
key=lambda k: k[1], reverse=True):
if grenze <= bis < stichtag:
karenz_kandidat = (von, bis)
break
if karenz_kandidat:
karenz_von = karenz_kandidat[0]
frist = max(
(m for m in self._at_msch_leaves()
if m[1] <= karenz_von),
key=lambda m: m[1], default=None)
if frist:
return frist[0], 3
version = self.version_id
vorher = self.env['hr.version'].search([
('employee_id', '=', self.employee_id.id),
('contract_date_end', '!=', False),
('id', '!=', version.id),
], order='contract_date_end desc', limit=1)
if (vorher and vorher.contract_date_end
and version.contract_date_start
and vorher.contract_date_end
<= version.contract_date_start
and (version.contract_date_start
- vorher.contract_date_end).days < 92
and any(k[1] <= vorher.contract_date_end
for k in self._at_karenz_leaves())):
erster = date(stichtag.year, stichtag.month, 1)
erster = (erster - timedelta(days=1)).replace(day=1)
return erster, 1
return stichtag, 3
def _at_msch_referenz_monate(self, episode_beginn):
"""Referenzkalendermonate der fiktiven BV (§ 7 Abs 4 BMSVG:
letzte drei Monate; Karenz-Brücke Z 13, AP16 — s.
_at_msch_referenz_stichtag_und_anzahl; § 162 Abs 3: letzte
13 Wochen). Versicherungsfall im Monat X → Monate X-3, X-2,
X-1 (aufsteigend)."""
self.ensure_one()
stichtag, anzahl = self._at_msch_referenz_stichtag_und_anzahl(
episode_beginn)
erster = date(stichtag.year, stichtag.month, 1)
monate = []
hilf = erster
for _ in range(3):
for _ in range(anzahl):
hilf = (hilf - timedelta(days=1)).replace(day=1)
monate.append(hilf)
return list(reversed(monate))
@@ -23,12 +23,15 @@ BVAB/BVJN aus dem GP5-BMSVG-Flag, VWAZ vereinbarte Wochenarbeitszeit
(Stunden ×100, neu für Meldedaten ab 01.01.2026).
Dateibasiert (Prämisse P7); Bestätigungen/Übertragung beim Mandanten."""
from datetime import date
from datetime import date, timedelta
import base64
from odoo import api, fields, models
from odoo.exceptions import UserError
from odoo.addons.l10n_at_hr_payroll_private.models.karenz import \
KARENZ_ARTEN
from odoo.addons.l10n_at_hr_payroll.models.elda import (
L10N_AT_ELDA_IDTEIL,
L10nAtEldaBestand,
@@ -199,6 +202,58 @@ class L10nAtPayrollVr(models.Model):
abmeldungen.append(version)
return sorted(abmeldungen, key=lambda v: v.contract_date_end)
def _l10n_at_offene_karenz_events(self):
"""AP16 (8.13): An-/Abmeldungen aus validierten Karenz-
Freistellungen: M4 zum Ende des Entgeltanspruchs (Tag vor dem
Karenzbeginn; Familienzeit am Tag vor Beginn, § 11 Abs 3 lit a
ASVG, lb-pap-01), M3 zum ersten Arbeitstag nach dem Karenzende
— entfällt, wenn das DV mit der Karenz endet (normale M4-
Vertragsabmeldung deckt das Ende). Karenzart-Strings für die
eSV-Sonderformate „Familienhospizkarenz/Pflegekarenz An-/
Abmeldung" (lb-kzs-05) laufen als Protokoll-Info; erweiterte
eSV-Sonderformate = GP7-Rest. Dedup über die Registry
(employee, art, adatum); keine Events nach dem Stichtag."""
self.ensure_one()
typen = self.env['hr.leave.type'].search([
('work_entry_type_id.code', 'in', list(KARENZ_ARTEN))])
if not typen:
return []
leaves = self.env['hr.leave'].search([
('company_id', 'in', self.company_id.ids),
('holiday_status_id', 'in', typen.ids),
('state', 'in', ('validate', 'validate1')),
]).sorted('request_date_from')
registry = self.env['l10n.at.payroll.vr.event'].search([
('company_id', '=', self.company_id.id),
])
gesehen = {(e.employee_id.id, e.art, e.adatum) for e in registry}
ereignisse = []
for leave in leaves:
von = leave.request_date_from
bis = leave.request_date_to
if not von or not bis:
continue
version = leave.employee_id.version_id
if not version:
continue
wett_code = leave.holiday_status_id \
.work_entry_type_id.code
karenzart = KARENZ_ARTEN.get(wett_code, 'Karenz')
abmeldetag = von - timedelta(days=1)
if abmeldetag > self.stichtag:
continue
if (leave.employee_id.id, 'M4', abmeldetag) not in gesehen:
ereignisse.append((version, 'M4', abmeldetag, karenzart))
rueckkehr = bis + timedelta(days=1)
if (version.contract_date_end
and rueckkehr >= version.contract_date_end):
continue
if rueckkehr > self.stichtag:
continue
if (leave.employee_id.id, 'M3', rueckkehr) not in gesehen:
ereignisse.append((version, 'M3', rueckkehr, karenzart))
return ereignisse
def _l10n_at_bber(self, version):
if version.l10n_at_lehrling:
return '03' if getattr(
@@ -234,6 +289,7 @@ class L10nAtPayrollVr(models.Model):
raise UserError('Beitragskontonummer (BKNR) fehlt.')
datensaetze = []
ereignisse = []
karenz_info = []
vstr = bknr[:2]
if lauf.nur_fallweise:
versionen = self.env['hr.version'].search([
@@ -366,6 +422,51 @@ class L10nAtPayrollVr(models.Model):
ereignisse.append((version, 'M4',
version.contract_date_end,
refw))
for version, art, adatum, karenzart in \
lauf._l10n_at_offene_karenz_events():
if not version.ssnid:
fehler.append(
'Karenz-Meldung %s ohne Versicherungsnummer.'
% version.employee_id.name)
continue
satz = L10nAtEldaSatz(
L10N_AT_ELDA_IDTEIL + VR_SATZ, 772,
bezeichnung='%s Karenz %s' % (
art, version.employee_id.name))
refw = '%s-K%d-%s-%d' % (
art, company.id,
adatum.strftime('%Y%m%d'),
version.employee_id.id)
satz.setze('SART', art)
satz.setze('VSTR', vstr)
satz.setze('REFW', refw)
satz.setze('BKNR', bknr)
satz.setze('DGNA', company.name[:70])
satz.setze('VSNR', version.ssnid)
satz.setze_datum(
'GEBD', version.employee_id.birthday)
familienname, vorname = l10n_at_namen(
version.employee_id)
satz.setze('FANA', familienname[:70])
satz.setze('VONA', (vorname or '')[:70])
satz.setze_datum('ADAT', adatum)
if art == 'M3':
satz.setze('BBER', lauf._l10n_at_bber(version))
satz.setze('GERF', 'N')
satz.setze('FRDV', 'N')
else:
satz.setze_datum('EBSV', adatum)
satz.setze('AGRD', '00')
kalender = version.resource_calendar_id
if kalender:
satz.setze('VWAZ', kalender.hours_per_week,
skala=2)
datensaetze.append(satz)
ereignisse.append((version, art, adatum, refw))
karenz_info.append(
'%s (ADAT %s) — %s' % (
version.employee_id.name,
adatum.strftime('%d.%m.%Y'), karenzart))
if fehler:
lauf.protokoll = 'FEHLER:\n' + '\n'.join(fehler)
raise UserError('Versichertenmeldung mit Fehlern '
@@ -395,12 +496,17 @@ class L10nAtPayrollVr(models.Model):
ereignisse = self.env['l10n.at.payroll.vr.event'].create(
ereignis_werte) if ereignis_werte else \
self.env['l10n.at.payroll.vr.event']
protokoll = 'Meldungen: %d' % len(datensaetze)
if karenz_info:
protokoll += ("\nKarenz (eSV-Sonderformate GP7-Rest; "
"Karenzart zur Übergabe):\n"
+ "\n".join(karenz_info))
lauf.write({
'datei': base64.b64encode(datei.render()),
'datei_name': 'versichertenmeldung_%s.txt' % (
fields.Date.today().strftime('%Y%m%d'),),
'event_ids': [(6, 0, ereignisse.ids)],
'state': 'done',
'protokoll': 'Meldungen: %d' % len(datensaetze),
'protokoll': protokoll,
})
return True