3.9 KiB
3.9 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
--month <name>(z.B.--month Feb) - Output-Benennung:
(n) Nachname, Vorname.pdf(n = lfd. Nummer aus Spalte A) pauschale_5.N= Dropdown-Wert"1"(= 8,60 €) wenn anwesend (X), sonst"0"- PDF-Template liegt in
./template/sab.pdf - PDF-Felder für Ort und Datum:
unterschrift.ort/unterschrift.datum
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
- "V" → Vorstellungsgespräch
- "A" → aus Projekt ausgeschieden
- Leer → Zeile überspringen
PDF-Feld-Mapping (pro Zeile N, max 23 Zeilen)
| Excel-Zelle | datum.N | anwesend.N | ist.N | plan.N | pauschale_5.N |
|---|---|---|---|---|---|
| Numerisch | DD.MM.YYYY | X | Wert (dt. Format) | "6" | "1" |
| "K"/"KK"/etc | DD.MM.YYYY | Code | leer | leer | "0" |
| Leer | (überspringen) | — | — | — | — |
Windows-Installer (Inno Setup)
Ziel
Installer-EXE erstellen, die:
- Von einem Windows SMB-Share aus gestartet werden kann (self-contained .exe)
- Das Programm lokal unter
%ProgramFiles%\AnwesenheitPDF\installiert - Einen Startmenü-Eintrag anlegt (optional: Desktop-Verknüpfung)
- Einen Uninstaller registriert (Programme und Features)
Tool: Inno Setup 6
- Free, open-source, weit verbreitet
- Erzeugt eine einzelne selbstextrahierende .exe (ideal für SMB-Share)
- Unterstützt German.isl (deutschsprachiger Wizard)
- ISCC.exe (Compiler) muss auf Build-Maschine installiert sein
- Installation:
winget install --id JRSoftware.InnoSetup -e -s winget -i
Dateien
installer\AnwesenheitPDF.iss— Inno Setup Scriptbuild.bat— um Installer-Schritt erweitert (ruft ISCC auf)- Ausgabe:
dist\AnwesenheitPDF-Setup-x.y.z.exe
Ablauf build.bat (neu: Schritt 4)
- pip install
- update_version.py (liest Version aus config.json)
- PyInstaller → dist\AnwesenheitPDF\
- Version aus config.json extrahieren → ISCC aufrufen → dist\AnwesenheitPDF-Setup-x.y.z.exe
Install-Ziel
{autopf}\AnwesenheitPDF\(= Program Files, UAC-geschützt)- Requires admin (PrivilegesRequired=admin)
- Startmenü:
{group}\AnwesenheitPDF
Release Notes
- Aktuelle Versionsnummer aus config.json bestaetigen.
- Release-Notes-Dokument im Projekt-Root anlegen.
- Release-Notes-Datei zusaetzlich zum Installer in
update_check_pathkopieren.