7.7 KiB
description, applyTo
| description | applyTo |
|---|---|
| Use when implementing, extending, or reviewing the attendance PDF generator application. Contains the full application masterplan, Excel data model, PDF field mapping rules, and attendance status logic. | **/*.py |
Application Masterplan: Attendance PDF Generator
Purpose
A Python program that reads attendance data from an Excel file and generates personalized PDF reports for each participant. The program must correctly map all daily attendance values from Excel into the corresponding PDF form fields.
Excel File Structure
- One Excel file = one full year of attendance data.
- One sheet = one calendar month.
- Column A: Sequential participant number (1 to n).
- Column B: Participant name in
Last name, First nameformat. - Following columns: Additional data columns, including one column per calendar day of the month.
Each row represents one participant. Each day column contains the attendance value for that participant on that specific day.
PDF Output Structure
Each PDF is generated per participant, per month. The PDF contains a table with one row per working day.
| PDF Field | Description | Source |
|---|---|---|
person.name |
Full name of the participant | Excel column B |
monat_jahr |
Month and year in MM/YYYY format |
Derived from sheet name + filename |
antragsnummer |
Application number | config.json (hardcoded) |
ort |
Location/city | config.json (hardcoded) |
erstellungsdatum |
Creation date (DD.MM.YYYY) |
Current system date at generation time |
datum.0 – datum.22 |
Date per row in DD.MM.YYYY format (max 23 rows) |
Derived from sheet name + year |
anwesend.0 – anwesend.22 |
Attendance status dropdown (see mapping below) | Excel day cell |
ist.0 – ist.22 |
Actual attendance in hours (Ist-Stand Anwesenheit (in h)) |
Excel day cell (numeric) |
plan.0 – plan.22 |
Planned attendance in hours (Geplante Anwesenheit lt. Konzeption (in h)) |
Derived from ist value |
pauschale.0 – pauschale.22 |
Flat rate Pauschale 8,60 € (mind. 6 h anwesend) |
Set to 8,60 if present (X), else empty |
Header Field Derivation Rules
Year
- Extracted from the Excel filename using a regex pattern (e.g.,
Anwesenheit_2026.xlsx→2026). - The filename pattern must be configurable in
config.json.
Month
- Derived from the sheet name in the Excel file.
- German abbreviated month names are mapped to month numbers:
| Sheet Name | Month |
|---|---|
Jan |
01 |
Feb |
02 |
Mär |
03 |
Apr |
04 |
Mai |
05 |
Jun |
06 |
Jul |
07 |
Aug |
08 |
Sep |
09 |
Okt |
10 |
Nov |
11 |
Dez |
12 |
- This mapping is stored in
config.json.
Application Number (antragsnummer)
- Hardcoded static value stored in
config.json. Never derived from Excel.
Location (ort)
- Hardcoded static value stored in
config.json. Never derived from Excel.
Creation Date (erstellungsdatum)
- Always the current system date at the time of PDF generation, formatted as
DD.MM.YYYY.
Excel-to-PDF Field Mapping Rules
Rule 1: Present — Numeric value (hours)
Condition: The Excel cell for a participant on a given day contains a numeric value (integer or decimal, representing hours worked).
PDF actions:
datum.N→ Set to the date inDD.MM.YYYYformat.anwesend.N→ SelectX = anwesend.ist.N→ Set to the exact numeric value from Excel (actual hours worked).plan.N→ Select the nearest applicable planned value:3(for sessions up to 3h) or6(for sessions above 3h). The threshold logic must be consistently applied and configurable.
Rule 2: Sick — Value "K"
Condition: The Excel cell contains the string K.
PDF actions:
datum.N→ Set to the date inDD.MM.YYYYformat.anwesend.N→ SelectK = Krank.ist.N→ Leave empty.plan.N→ Leave empty.
Rule 3: Child Sick — Value "KK"
Condition: The Excel cell contains the string KK.
PDF actions:
datum.N→ Set to the date inDD.MM.YYYYformat.anwesend.N→ SelectKK = Kindkrank.ist.N→ Leave empty.plan.N→ Leave empty.
Rule 4: Unexcused Absence — Value "F"
Condition: The Excel cell contains the string F.
PDF actions:
datum.N→ Set to the date inDD.MM.YYYYformat.anwesend.N→ SelectF = unentschuldigtes Fehlen.ist.N→ Leave empty (no hours entered).plan.N→ Leave empty (no planned hours entered).
Rule 5: Flat Rate — pauschale.N
Condition: Applied for every row where attendance is present (X).
PDF actions:
pauschale.N→ Set to8,60ifanwesend.NisX = anwesend.pauschale.N→ Leave empty for all other statuses (K, KK, F, etc.).
Rule 6: No Entry / Empty Cell
Condition: The Excel cell for a given day is empty or the day does not exist in the month (e.g., February has fewer than 31 days).
PDF actions:
- Skip this row entirely. Do not add a date entry for this day.
Attendance Status Dropdown Values
The anwesend field is a dropdown. Valid selectable values:
| Code | Meaning |
|---|---|
X |
X = anwesend (present) |
K |
K = Krank (sick) |
KK |
KK = Kindkrank (child sick) |
E |
E = Entschuldigt (excused absence) |
F |
F = unentschuldigtes Fehlen (unexcused absence) |
P |
P = Praktikum (internship) |
U |
U = Urlaub (vacation) |
Planned Hours Logic (plan.N)
When a participant is present (X), the planned hours dropdown must be set always to the value mind. 6h.
General Implementation Rules
- All configuration, thresholds, field mappings, static values (
antragsnummer,ort), and the month-name mapping must be stored in aconfig.jsonfile at the project root. - The CLI entry point is
generate.pyusing Click. - All business logic must be covered by tests in
tests/. Tests must not depend on specific real participant names or file names.
Pre-Generation Validation & Confirmation Workflow
Before any PDF is written, the program must execute a full validation and preview phase:
1. Validation Checks
All of the following must be verified. Errors are logged (not silently ignored) and summarized at the end:
| Check | Description |
|---|---|
| Excel file exists | The given file path resolves to a readable .xlsx file |
| Year extractable from filename | The filename matches the configured pattern and yields a 4-digit year |
| Sheet name valid | The sheet name exists and maps to a known German month abbreviation |
| Column A present | Sequential number column exists |
| Column B present | Name column exists |
| Day columns present | At least one day column is detected |
| Attendance values valid | Each non-empty cell contains either a numeric value or a known status code (K, KK, F, E, P, U) |
config.json present and complete |
All required keys (antragsnummer, ort, month mapping, filename pattern) exist |
| PDF template accessible | The PDF template file exists and is readable |
2. Console Preview
After validation, display a structured summary on the console showing all derived values:
=== Vorschau der ermittelten Werte ===
Excel-Datei : Anwesenheit_2026.xlsx
Jahr : 2026
Monat : März (03)
Antragsnummer : <value from config>
Ort : <value from config>
Erstelldatum : 27.03.2026
Teilnehmer : 12
Fehler : 0
Möchten Sie die PDF-Generierung starten? [j/N]
- If there are validation errors, list each one clearly before the prompt.
- The process only continues if the user explicitly confirms with
j(ja). - If the user enters anything else or presses Enter, the process is aborted without creating any files.