mirror of
http://100.103.83.12:3003/fegger/odoo-at-payroll.git
synced 2026-09-17 08:52:45 +00:00
14940ac31a
mBGM/JASV (models/mbgm.py — DM-ORG 42.7.0 E.32, BEST MB, Version 02): Paket PS (BKNR/DGNA/BZRM/GSUM/ANZM) → mBGM G1 (REFW/VSNR/FANA/VONA/VSUM/VERG=1) → Tarifblock T1 (BSGR/VVON) → Verrechnungsbasis BS (VBTY/VBBT) → Verrechnungsposition V1 (VPTY/VPVZ/VPTA/RSVZ/RSUM). KEIN DN/DG-Zweig-Split: T01 = GESAMT-Prozentsatz des Tarifsystems je Beschäftigtengruppe (Parameter at_mbgm_tarif, normativ: laufend 39,05 % = KV 7,65 + PV 22,80 + AV 5,90 + UV 1,10 + WF 1,00 + IESG 0,10; SZ 37,55 % = DN KV 3,87 + PV 10,25 + AV 2,95 + DG 20,48). Abschläge als EIGENE Verrechnungspositionen je Basis: A03/A02/A01 = Minderung AV auf 0/1/2 % (§ 2a AMPFG, nur DN-AV, je Verrechnungsbasis AB UND SZ), A09 = UV-Entfall 60, A10 = AV+IE-Entfall Pensionsanspruch (Konkurrenz a4: sperrt Staffelabschlag), A15 = PV-Halbierung Bonusphase — konsistent mit der GP4-§-2a-DN-seitig-Konvention. BV (BMSVG): eigene Verrechnungsbasis BV (ungedeckelt, GP5) + Position V01 1,53 %. RSUM = Basis x Satz (mBGM-Tarifierung), Konsistenz-Check gegen GP4-Payslip-Beitragssummen ±0,10 € als Prüfwarnung. Storno: R1-Sätze mit REFU/VSUM wie Original. Fehlanzeige: Paket ohne mBGM-Sätze (ANZM 0). Geringfügige/fallweise ohne Parametrisierung: listenweiser Abbruch (keine Tarif-Erfindung; BSGR B044/B045/B010/B030 aus dem SV-Tarifsystem pflegen). Versichertenmeldung (models/versichertenmeldung.py — DM-ORG E.29, BEST VR, Version 03, Satzlänge 772): M3 vor Arbeitsantritt / M4 (7 Kalendertage ab PV-Ende) mit deklarativer Event-Erkennung über die Meldungs-Registry (l10n.at.payroll.vr.event) — idempotente Läufe, Dimona-auto-Idee ohne write-diff-Hacks. Felder: BKNR/VSNR/GEBD/FANA/VONA (Namenssplit am letzten Leerzeichen), ADAT/EBSV, BBER 01-04 aus l10n_at_personalgruppe/lehrling, GERF (Kataloggehalt vs. GFG), FRDV, BVAB/BVJN aus dem GP5-BMSVG-Flag, VWAZ (Stunden x100, neu ab 01.01.2026), AGRD aus dem hr.departure.reason-Mapping (Standard 00). Fallweise Anmeldung (BEST MA, SART 32, Version 07, Länge 450): MVP je Anmeldetag am Vertragsbeginn; tagesgenaue Einsatztage via Work-Entry-Auswertung = dokumentierter Rest. NSchAB-Branche als Company-Flag (l10n_at_nschab): B001-T01 + 3,80 % (Schlechtwetterentschädigung, ÖGK-Tarifsystem Normalbetriebe mit Schlechtwetterentschädigung). Tests: test_meldewesen_private (2 — mBGM-Satzhierarchie mit A03 je Basis aus November-Fixture + GSUM-Konsistenz; VR M3/M4 mit Registry-Idempotenz und AGRD). Rechenfälle docs/rechenfaelle/meldewesen.md. 19.0.7.0.0.
406 lines
18 KiB
Python
406 lines
18 KiB
Python
# 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)/03–04 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
|
||
import base64
|
||
|
||
from odoo import api, fields, models
|
||
from odoo.exceptions import UserError
|
||
|
||
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_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 = []
|
||
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))
|
||
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']
|
||
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),
|
||
})
|
||
return True |