2.3 KiB
2.3 KiB
Copilot Plan: Attendance PDF Generator
Ziel
Kombiniertes Python-CLI-Tool, das Anwesenheitsdaten aus einer Excel-Datei liest und für jeden Teilnehmer eine ausgefüllte PDF-Datei erzeugt.
Architektur
generate.py # Click CLI entry point
config.json # Konfiguration (antragsnummer, ort, month_mapping, ...)
schema.json # JSON-Schema der Konfiguration (Dokumentation)
requirements.txt # openpyxl, pypdf, click
requirements-dev.txt # + pytest
src/
__init__.py
exceptions.py # Custom Exception-Hierarchie
models.py # Datenklassen: Person, AttendanceDate, MonthlyAttendance
config_loader.py # config.json laden & validieren
excel_reader.py # Excel → MonthlyAttendance-Objekte
pdf_filler.py # MonthlyAttendance → ausgefüllte PDF
validators.py # Pre-Generation Validierung + Konsolenvorschau
template/ # PDF-Template (sab.pdf, wird separat bereitgestellt)
output/ # Ausgabeverzeichnis für generierte PDFs
tests/
__init__.py
test_excel_reader.py
test_pdf_filler.py
test_validators.py
Datenfluss
Excel-Datei → excel_reader → MonthlyAttendance → pdf_filler → PDF-Datei
Entwurfsentscheidungen
plan.N= immer"6"(mind. 6h), unabhängig von tatsächlichen Stunden- Sheet-Auswahl: manuell via
--sheet <name>(z.B.--sheet Feb) - Output-Benennung:
(n) Nachname, Vorname.pdf(n = lfd. Nummer aus Spalte A) pauschale.N="8,60"wenn anwesend (X), sonst leer- PDF-Template liegt in
./template/sab.pdf
Excel-Struktur
- Spalte A (Index 0): lfd. Nummer
- Spalte B (Index 1): Name (Format: "Nachname, Vorname")
- Spalten J–AN (Index 9–39): Tageswerte (Tag 1–31)
- Numerischer Wert → anwesend (X), Wert = Ist-Stunden
- "K" → Krank
- "KK" → Kindkrank
- "F" → unentschuldigtes Fehlen
- "E" → entschuldigtes Fehlen
- "P" → Praktikum
- "U" → Urlaub
- Leer → Zeile überspringen
PDF-Feld-Mapping (pro Zeile N, max 23 Zeilen)
| Excel-Zelle | datum.N | anwesend.N | ist.N | plan.N | pauschale.N |
|---|---|---|---|---|---|
| Numerisch | DD.MM.YYYY | X | Wert (dt. Format) | "6" | "8,60" |
| "K"/"KK"/etc | DD.MM.YYYY | Code | leer | leer | leer |
| Leer | (überspringen) | — | — | — | — |