Files
2026-05-21 23:51:38 +02:00

102 lines
3.9 KiB
Markdown
Raw Permalink 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.
# 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 Script
- `build.bat` — um Installer-Schritt erweitert (ruft ISCC auf)
- Ausgabe: `dist\AnwesenheitPDF-Setup-x.y.z.exe`
### Ablauf build.bat (neu: Schritt 4)
1. pip install
2. update_version.py (liest Version aus config.json)
3. PyInstaller → dist\AnwesenheitPDF\
4. 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_path` kopieren.