diff --git a/.gitignore b/.gitignore index 695a574..f08b553 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ __pycache__/ .DS_Store .~lock.*# *.xlsx# -~*.xlsx \ No newline at end of file +~*.xlsx +/versions diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..55a7788 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,72 @@ +# Changelog + +Alle nennenswerten Änderungen an diesem Projekt werden in dieser Datei dokumentiert. + +Das Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), +und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/). + +--- + +## [1.1] – 2026-06-24 + +### Hinzugefügt + +- **Streamlit-Web-UI** (`app.py`) mit: + - Dropdown zur Auswahl der Input-Datei (`.xlsx`) aus dem `input/`-Ordner – mit Sofort-Validierung und Anzeige von Mitarbeiteranzahl, Antragsnummern und Einträgen pro Monat + - Dropdown zur Auswahl des PDF-Templates aus dem `template/`-Ordner – mit Sofort-Validierung und Anzeige gefundener `_Field`-Platzhalter + - Mitarbeiter-Multiselect-Liste mit „Alle auswählen“ / „Keine auswählen“-Buttons + - „Tätigkeitsnachweise generieren“-Button mit Fortschrittsanzeige + - Session-State-Caching für Validierung und Parsing (kein erneutes Einlesen bei UI-Reruns) + - Erfolgsmeldung mit Liste generierter Dateien und Button zum Öffnen des Output-Ordners + +- **PDF-basierte Generierung** (`src/writer.py`) via PyMuPDF (fitz): + - Pre-Scan aller `_Field`-Platzhalter im Template-PDF über **alle Seiten** + - Automatische Erkennung von Position (Bounding Box) und Schriftgröße jedes Platzhalters + - Redact + Insert-Text-Verfahren: Platzhalter werden geschwärzt und durch echte Daten ersetzt + - Unterstützung für **mehrseitige Templates** (z. B. 2 Seiten pro Monat) + - **Mehrzeilige Textboxen** (`Tätigkeiten_Field`, `Dienstreisen_Field`) mit automatischem Wortumbruch + - **Automatische Schriftgrößen-Anpassung** bei langen Texten in Qualifikation und Funktion (Autoscale) + - Prozentwerte werden als Ganzzahl ohne `%`-Zeichen ausgegeben + - Datumsformat `dd.mm.yyyy` wird automatisch aus dem Monatsfeld (`MM.JJ`) berechnet + - Ort standardmäßig „Dresden“ + - Dateiname: `{Nachname}_{Vorname}_Tätigkeitsnachweis.pdf` + +- **Input-Parsing** (`src/parser.py`): + - Einlesen von `.xlsx`-Dateien mit openpyxl – ein Sheet pro Monat + - Monats-Sheet-Erkennung per Wildcard-Pattern (`* 20??`) + - Prozentwert-Konvertierung: Excel-Prozentwerte (0.5 → 50) oder Ganzzahlen (50 → 50) + - Automatisches Überspringen leerer Zeilen (Name oder Antragsnummer fehlt) + - Gruppierung der Records nach Mitarbeitername (`group_by_employee`) + - Hilfsfunktionen: `get_unique_antragsnummern`, `get_unique_employees` + +- **Validierung** (`src/validator.py`): + - Input-Datei: Prüft Existenz, Spaltenüberschriften (gegen `input-fields.json`), Datenzeilen pro Monats-Sheet + - Input-Daten: Erkennt leere Pflichtfelder pro Person und meldet betroffene Namen + - PDF-Template: Sucht alle `_Field`-Platzhalter im PDF und meldet fehlende + - Nicht-Monats-Sheets (z. B. „Alle Rollen“) werden ignoriert + +- **Konfigurationsdateien** (`config/`): + - `settings.ini`: Pfade für Input/Template/Output, Dateinamen-Pattern, Monats-Sheet-Pattern, Skip-Optionen + - `input-fields.json`: Spaltenschema der Input-Tabelle (9 Felder: ID, Kommentar, Antragsnummer, Name, Qualifikation, Funktion, Stellenanteil in %, Monat, Tätigkeit) + - `output-fields.json`: Mapping Input-Feld → `_Field`-Platzhalter im PDF (8 Felder) + +- **Datenmodell** (`src/models.py`): + - `EmployeeRecord`: Dataclass für eine Mitarbeiter-Zeile mit `month_index`- und `year`-Properties + - `FieldSchema`, `OutputMapping`, `AppConfig`, `ValidationResult` + +- **Cold Run** (`coldrun.py`): Headless-Generierung für die erste Person ohne GUI, automatisch mit erster Input- und Template-Datei + +- **Start-Skripte**: `start.bat` (Windows), `start.sh` / `start.command` (macOS/Linux) + +- **End-to-End-Tests** (`tests/test_e2e.py`): + - pytest-basiert mit realer Input-Datei (`2025 JM.xlsx`) und realem PDF-Template + - Prüft: 168 Datensätze, 19 Personen, 12 Monate + - Validiert Output-PDF: Seitenanzahl (24 Seiten = 12 × 2), Inhalte (Antragsnummer, Name, Stellenanteil, Qualifikation, Monat, Funktion, Tätigkeit), keine verbliebenen `_Field`-Platzhalter + +- **README.md**: Vollständige Dokumentation zu Setup, Bedienung, Konfiguration, Cold Run und Tests + +### Geändert + +- Template-Format von `.xlsx` auf **PDF** umgestellt (ursprüngliches Excel-Template war schreibgeschützt) +- `config/output-fields.json`: `target_cell` entfernt – Mapping erfolgt jetzt über `_Field`-Platzhalter im PDF +- `src/config.py`: `get_available_templates` filtert jetzt `.pdf`-Dateien