Files
odoo-at-payroll/addons/l10n_at_hr_payroll_private/models/versichertenmeldung.py
T
fegger d53e1e64a1 [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)
2026-09-15 14:25:48 +02:00

512 lines
23 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Part of the odoo-at-payroll project. License: LGPL-3.
"""Versichertenmeldung reduziert (GP7/AP5) — DM-ORG 42.7.0 Kapitel
E.29 (BEST ``VR``, Version 03, Satzlänge 772; PDF-verifizierte
Feldtabelle 2026-09-12): Anmeldung M3 (vor Arbeitsantritt), Abmeldung
M4 (7 Kalendertage ab PV-Ende), Änderungsmeldung M6 nur für
Ausnahmefälle (Inhaltsänderungen laufen über die mBGM; lb-mel-08).
Fallweise Anmeldung (BEST ``MA``, SART 32/33, Länge 450): je
Beschäftigungstag vor Arbeitsantritt (§ 33 Abs 1a Z 1 ASVG).
Event-Modell deklarativ (Dimona-auto-Muster, ohne write-diff):
offene Anmeldungen = älteste Version eines Beschäftigungsspannen-
Beginns ohne M3-Eintrag in der Meldungs-Registry; offene Abmeldungen
= beendete Versionen ohne M4-Eintrag. Die Registry
(``l10n.at.payroll.vr.event``) protokolliert gesendete Meldungen
(REFW/ADAT), damit erneute Läufe idempotent bleiben.
Felder: BBER 01 Arbeiter/02 Angestellte(r)/0304 Lehrling (D.39),
GERF geringfügig (J/N), FRDV freies Dienstverhältnis, ADAT An-/
Abmeldedatum, EBSV arbeitsrechtliches Ende vs ADAT (UEL/KE-Verlänger
ung der PV sind nicht modelliert → ADAT = contract_date_end),
AGRD eSV-Abmeldegrund (Mapping am hr.departure.reason, Standard 00),
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, 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,
L10nAtEldaDatei,
L10nAtEldaSatz,
)
from odoo.addons.l10n_at_hr_payroll.models.lohnzettel_l16 import \
l10n_at_namen
# Versichertenmeldung (E.29, Version 03) — nach IDTEIL, Länge 772.
VR_SATZ = [
(2, 'REFW', 21, 40, 'a'),
(3, 'REFU', 61, 40, 'a'),
(4, 'BKNR', 101, 10, 'a'),
(5, 'DGNA', 111, 70, 'a'),
(6, 'DTEL', 181, 50, 'a'),
(7, 'MAIL', 231, 60, 'a'),
(8, 'INF1', 291, 12, 'a'),
(9, 'INF2', 303, 12, 'a'),
(10, 'VSNR', 315, 10, 'n'),
(11, 'GEBD', 325, 8, 'n'), # TTMMJJJJ
(12, 'REFV', 333, 40, 'a'),
(13, 'FANA', 373, 70, 'a'),
(14, 'VONA', 443, 70, 'a'),
(15, 'ADAT', 513, 8, 'n'), # TTMMJJJJ
(16, 'BDAT', 521, 8, 'n'),
(17, 'RDAT', 529, 8, 'n'),
(18, 'BBER', 537, 2, 'a'), # Beschäftigungsbereich (D.39)
(19, 'GERF', 539, 1, 'a'), # geringfügig J/N
(20, 'FRDV', 540, 1, 'a'), # freier Dienstvertrag J/N
(21, 'EBSV', 541, 8, 'n'), # Ende des Beschäftigungsverhältnisses
(22, 'AGRD', 549, 2, 'a'), # Abmeldegrund (D.22)
(23, 'SAGR', 551, 20, 'a'),
(24, 'KEAB', 571, 8, 'n'),
(25, 'KEBI', 579, 8, 'n'),
(26, 'UEAB', 587, 8, 'n'),
(27, 'UEBI', 595, 8, 'n'),
(28, 'BVAB', 603, 8, 'n'), # BV-Beitrag ab
(29, 'BVEN', 611, 8, 'n'),
(30, 'BVJN', 619, 1, 'a'), # Betriebliche Vorsorge J/N
(31, 'UMDA', 620, 8, 'n'),
(32, 'RUMD', 628, 8, 'n'),
(33, 'SOUM', 636, 1, 'a'),
(34, 'ZTUM', 637, 2, 'a'),
(35, 'ZKUM', 639, 10, 'a'),
(36, 'RWUM', 649, 40, 'a'),
(37, 'RUUM', 689, 40, 'a'),
(38, 'BKUM', 729, 40, 'a'),
(39, 'VWAZ', 769, 4, 'n'), # Stunden ×100
]
# Fallweise Anmeldung (E.18, Version 07) — nach IDTEIL, Länge 450.
FALLWEISE_SATZ = [
(2, 'BKNR', 21, 10, 'a'),
(3, 'DGNA', 31, 70, 'a'),
(4, 'VSNR', 101, 10, 'n'),
(5, 'GEBD', 111, 8, 'n'),
(6, 'FANA', 119, 70, 'a'),
(7, 'VONA', 189, 70, 'a'),
(8, 'GESL', 259, 1, 'n'), # 1 männlich/2 weiblich …
(9, 'ADAT', 260, 8, 'n'), # Tag der fallweisen Beschäftigung
(10, 'BKFZ', 268, 3, 'a'),
(11, 'BPLZ', 271, 9, 'a'),
(12, 'BORT', 280, 40, 'a'),
(14, 'WOBD', 321, 12, 'a'),
(15, 'ZOBD', 333, 15, 'a'),
(17, 'REFN', 410, 30, 'a'),
(18, 'VTAZ', 440, 4, 'n'), # Stunden ×100
]
class L10nAtPayrollVrEvent(models.Model):
"""Meldungs-Registry: je gesendeter Meldung ein Eintrag (Art,
ADAT, REFW) — Grundlage für die deklarative Event-Erkennung der
offenen An-/Abmeldungen."""
_name = 'l10n.at.payroll.vr.event'
_description = 'Versichertenmeldung — gesendete Meldungen'
_order = 'adatum, id'
company_id = fields.Many2one('res.company', required=True,
default=lambda self: self.env.company)
employee_id = fields.Many2one('hr.employee', required=True,
index=True, ondelete='cascade')
version_id = fields.Many2one('hr.version', required=True,
ondelete='cascade')
art = fields.Selection(
[('M3', 'Anmeldung'), ('M4', 'Abmeldung'), ('M6', 'Änderung'),
('MA', 'Fallweise Anmeldung')],
required=True)
adatum = fields.Date(required=True)
refw = fields.Char(required=True)
class L10nAtPayrollVr(models.Model):
_name = 'l10n.at.payroll.vr'
_description = 'Versichertenmeldung (An-/Abmeldung) — ELDA-Lauf'
_inherit = ['mail.thread']
_order = 'id desc'
company_id = fields.Many2one(
'res.company', required=True,
default=lambda self: self.env.company)
stichtag = fields.Date(
default=fields.Date.today,
help='Anmeldungen bis zu diesem Tag (M3 ist eigentlich VOR '
'Arbeitsantritt zu übermitteln — der Lauf meldet '
'beginnende Beschäftigungsverhältnisse).')
nur_fallweise = fields.Boolean(
string='Nur fallweise Anmeldungen (BEST MA)',
help='Erzeugt ausschließlich Anmeldungen fallweise '
'Beschäftigter (je Beschäftigungstag, SART 32).')
datei = fields.Binary(attachment=True, copy=False)
datei_name = fields.Char(copy=False)
protokoll = fields.Text(string='Prüfprotokoll')
state = fields.Selection(
[('draft', 'Entwurf'), ('done', 'Erzeugt')], default='draft',
required=True, tracking=True)
event_ids = fields.Many2many(
'l10n.at.payroll.vr.event', string='Gesendete Meldungen',
copy=False)
def _l10n_at_offene_anmeldungen(self):
"""Älteste aktive Version je AN ohne M3-Eintrag: Beginn eines
Beschäftigungsverhältnisses (früheste contract_date_start)."""
self.ensure_one()
offene = []
versionen = self.env['hr.version'].search([
('company_id', '=', self.company_id.id),
('contract_date_start', '!=', False),
('active', '=', True),
]).with_company(self.company_id)
nach_an = {}
for version in versionen:
nach_an.setdefault(version.employee_id, version)
if version.contract_date_start \
< nach_an[version.employee_id].contract_date_start:
nach_an[version.employee_id] = version
registry = self.env['l10n.at.payroll.vr.event'].search([
('company_id', '=', self.company_id.id),
('art', 'in', ('M3', 'MA')),
])
gesehen = {(e.employee_id.id, e.adatum) for e in registry}
for employee, version in nach_an.items():
if (employee.id, version.contract_date_start) in gesehen:
continue
if version.contract_date_start > self.stichtag:
continue
offene.append(version)
return sorted(offene, key=lambda v: v.contract_date_start)
def _l10n_at_offene_abmeldungen(self):
self.ensure_one()
abmeldungen = []
versionen = self.env['hr.version'].search([
('company_id', '=', self.company_id.id),
('contract_date_end', '!=', False),
]).with_company(self.company_id)
registry = self.env['l10n.at.payroll.vr.event'].search([
('company_id', '=', self.company_id.id),
('art', '=', 'M4'),
])
gesehen = {(e.employee_id.id, e.adatum) for e in registry}
for version in versionen:
if (version.employee_id.id, version.contract_date_end) \
in gesehen:
continue
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(
version, 'l10n_at_personalgruppe', '') == 'arbeiter' \
else '04'
return '01' if getattr(
version, 'l10n_at_personalgruppe', '') == 'arbeiter' \
else '02'
def _l10n_at_geringfuegig(self, version):
"""Vorausschauende Geringfügigkeits-Einschätzung zur Anmeldung:
Kataloggehalt/Überzahlung gegen die GFG (§ 5 Abs 2 ASVG); die
endgültige Bewertung läuft monatlich über den GP4-Kern."""
gfg = float(self.env['hr.rule.parameter']
._get_parameter_from_code(
'at_sv_gfg_monatlich', version.contract_date_start,
raise_if_not_found=False) or 0.0)
gehalt = version.wage \
or (version.kv_gruppe_id._get_gehalt(
version.erfahrungsstufe, version.contract_date_start)
if getattr(version, 'kv_gruppe_id', False) else 0.0)
ueberzahlung = getattr(version, 'ueberzahlung', 0.0) or 0.0
if ueberzahlung:
gehalt = ueberzahlung
return bool(gfg and gehalt and gehalt <= gfg)
def action_erzeugen(self):
for lauf in self:
fehler = []
company = lauf.company_id
bknr = company.l10n_at_beitragskontonummer
if not bknr:
raise UserError('Beitragskontonummer (BKNR) fehlt.')
datensaetze = []
ereignisse = []
karenz_info = []
vstr = bknr[:2]
if lauf.nur_fallweise:
versionen = self.env['hr.version'].search([
('company_id', '=', company.id),
('l10n_at_fallweise', '=', True),
('active', '=', True),
])
registry = self.env['l10n.at.payroll.vr.event'].search([
('company_id', '=', company.id),
('art', '=', 'MA'),
])
gesehen = {(e.employee_id.id, e.adatum)
for e in registry}
for version in versionen:
if not version.ssnid:
fehler.append('%s ohne Versicherungsnummer.'
% version.employee_id.name)
continue
# MVP: je AN ein Anmeldetag (der Vertragsbeginn);
# tagesgenaue Einsatztage = documented Rest
# (Work-Entry-Auswertung).
adat = version.contract_date_start
if not adat or (version.employee_id.id, adat) \
in gesehen:
continue
satz = L10nAtEldaSatz(
L10N_AT_ELDA_IDTEIL + FALLWEISE_SATZ, 450,
bezeichnung='Fallweise %s'
% version.employee_id.name)
satz.setze('SART', '32')
satz.setze('VSTR', vstr)
satz.setze('BKNR', bknr)
satz.setze('DGNA', company.name[:70])
satz.setze('VSNR', version.ssnid)
satz.setze_datum('GEBD', version.employee_id.birthday)
satz.setze('FANA', (version.private_last_name
or '')[:70])
satz.setze('VONA', (version.private_first_name
or '')[:70])
satz.setze('GESL', '2'
if version.sex == 'female' else '1')
satz.setze_datum('ADAT', adat)
kalender = version.resource_calendar_id
if kalender:
satz.setze('VTAZ', kalender.hours_per_day,
skala=2)
refn = 'MA-%d-%s-%d' % (
company.id, adat.strftime('%Y%m%d'),
version.employee_id.id)
satz.setze('REFN', refn)
datensaetze.append(satz)
ereignisse.append((version, 'MA', adat, refn))
else:
for version in lauf._l10n_at_offene_anmeldungen():
if not version.ssnid:
fehler.append(
'Anmeldung %s ohne Versicherungsnummer.'
% version.employee_id.name)
continue
satz = L10nAtEldaSatz(
L10N_AT_ELDA_IDTEIL + VR_SATZ, 772,
bezeichnung='M3 %s' % version.employee_id.name)
refw = 'M3-%d-%s-%d' % (
company.id,
version.contract_date_start.strftime('%Y%m%d'),
version.employee_id.id)
satz.setze('SART', 'M3')
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', version.contract_date_start)
satz.setze('BBER', lauf._l10n_at_bber(version))
satz.setze('GERF', 'J' if lauf
._l10n_at_geringfuegig(version) else 'N')
satz.setze('FRDV', 'N')
if getattr(version, 'l10n_at_abfertigung_neu',
False):
satz.setze('BVAB',
version.contract_date_start
.strftime('%d%m%Y'))
satz.setze('BVJN', 'J')
kalender = version.resource_calendar_id
if kalender:
satz.setze('VWAZ', kalender.hours_per_week,
skala=2)
datensaetze.append(satz)
ereignisse.append((version, 'M3',
version.contract_date_start,
refw))
for version in lauf._l10n_at_offene_abmeldungen():
if not version.ssnid:
fehler.append(
'Abmeldung %s ohne Versicherungsnummer.'
% version.employee_id.name)
continue
satz = L10nAtEldaSatz(
L10N_AT_ELDA_IDTEIL + VR_SATZ, 772,
bezeichnung='M4 %s' % version.employee_id.name)
refw = 'M4-%d-%s-%d' % (
company.id,
version.contract_date_end.strftime('%Y%m%d'),
version.employee_id.id)
agrd = getattr(
version.departure_reason_id, 'l10n_at_agrd',
False) or '00'
satz.setze('SART', 'M4')
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', version.contract_date_end)
satz.setze_datum('EBSV', version.contract_date_end)
satz.setze('AGRD', agrd)
datensaetze.append(satz)
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 '
'abgebrochen:\n' + '\n'.join(fehler))
if not datensaetze:
raise UserError('Keine offenen Meldungen zum '
'Stichtag %s.' % lauf.stichtag)
bestand = L10nAtEldaBestand(
'MA' if lauf.nur_fallweise else 'VR', vstr, '07'
if lauf.nur_fallweise else '03',
hersteller={'name': 'odoo-at-payroll', 'kfz': 'A',
'plz': company.partner_id.zip,
'ort': company.partner_id.city,
'strasse': company.partner_id.street},
datensaetze=datensaetze)
datei = L10nAtEldaDatei([bestand])
ereignis_werte = []
for version, art, adatum, refw in ereignisse:
ereignis_werte.append({
'company_id': company.id,
'employee_id': version.employee_id.id,
'version_id': version.id,
'art': art,
'adatum': adatum,
'refw': refw,
})
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': protokoll,
})
return True