feat(reports): DATEV-Monatsblatt-Export (Blanko-Vorlage) für Steuerberater

Neuer PDF-Export GET /reports/datev-monthly/export: ein Blatt pro
Mitarbeiter/Monat im Layout der DATEV-Stundenaufzeichnungs-Vorlage
(Beginn/Pause/Ende/Dauer + K/U/UU/F/SA/SU-Kürzel + Bemerkungen +
Summe + Unterschriftsfelder). Führt time_entries, Absences und
Feiertage pro Kalendertag zusammen.

Außerdem: Mustervorlagen für neue Backend-Module (Model/Schema/Router/
Migration/Test) und eine Frontend-Page-Vorlage, abgeleitet vom
hours_payouts-Modul als aktuellstem sauberen Muster.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CviFgc739S89xS97pvjszj
This commit is contained in:
2026-08-06 22:19:54 +02:00
co-authored by Claude Sonnet 5
parent f3ed234e56
commit 1dcc04ae07
10 changed files with 901 additions and 2 deletions
+26
View File
@@ -188,3 +188,29 @@ class OvertimeReportDetailed(BaseModel):
total_employees: int
total_overtime: float
rows: list[OvertimeReportRowDetailed]
# ── DATEV-Monatsblatt ──────────────────────────────────────────────────────────
# Layout entspricht "Stundenaufzeichnungen Muster blanko DATEV ab 2015":
# ein Blatt pro Mitarbeiter/Monat, Zeile pro Kalendertag.
class DatevDayRow(BaseModel):
day: int # Kalendertag 1-31
weekday_label: str # "Mo".."So" für Anzeige
start_time: time | None = None
break_minutes: int | None = None
end_time: time | None = None
duration_hours: float | None = None
code: str | None = None # K/U/UU/F/SA/SU siehe DATEV_CODES
recorded_on: date | None = None # "aufgezeichnet am" (created_at des Eintrags)
note: str | None = None # Bemerkungen (Absence-Typ-Name o.ä.)
class DatevMonthlySheet(BaseModel):
company_name: str
user_name: str
personnel_number: str | None
year: int
month: int
rows: list[DatevDayRow]
total_hours: float