init with task and a plan
This commit is contained in:
commit
6cf31eb391
12 files changed
+513
No files matched your search
@@ -0,0 +1,322 @@
|
||||
---
|
||||
description: "Use when implementing, extending, or reviewing the application. Contains the full application masterplan, data sources, workbook mapping rules, and generation logic for SAB Tätigkeitsnachweise."
|
||||
applyTo: "**/*.py"
|
||||
---
|
||||
|
||||
# Application Masterplan: SAB Taetigkeitsnachweis Generator
|
||||
|
||||
## Purpose
|
||||
|
||||
A Python program that reads personnel allocation data from two Excel workbooks and generates monthly SAB Taetigkeitsnachweise as Excel files based on a dedicated template workbook.
|
||||
|
||||
The application exists to replace a manual process that currently causes two recurring problems:
|
||||
|
||||
1. Incomplete monthly Taetigkeitsnachweise because employees submit them late or not at all.
|
||||
2. Incorrect entries because staffing shares, project assignments, and role changes vary over time and are no longer reliable to maintain manually.
|
||||
|
||||
The system must therefore produce monthly, auditable, and consistent output from a central data basis.
|
||||
|
||||
## Project Scope and Paths
|
||||
|
||||
The tool must operate exclusively below `Tool/`.
|
||||
|
||||
- Input files are read only from `Tool/input/`.
|
||||
- Template files are read only from `Tool/template/`.
|
||||
- Generated files are written only to `Tool/output/`.
|
||||
- No runtime reads/writes are allowed outside `Tool/`.
|
||||
|
||||
## Source Workbooks
|
||||
|
||||
The implementation is based on three concrete Excel files.
|
||||
|
||||
### 1. Allocation Overview: `PS_PW.xlsx`
|
||||
|
||||
This workbook is the monthly allocation matrix that determines how many funded hours a person has in each project for each month.
|
||||
|
||||
Observed structure in `Tabelle1`:
|
||||
|
||||
- Column `A`: Employee name in `Last name, First name` format.
|
||||
- Column `B`: Contracted weekly hours / AV.
|
||||
- Column `C`: Project or assignment key, e.g. `PS`, `PW`, `BeWo`, `NB`, `PS / NB`.
|
||||
- Columns `D` to at least `H`: One funded-hours column per month.
|
||||
- Row `2`: Month markers per column, e.g. `ab 01.01.2026`, `ab 01.02.2026`, `ab 01.03.2026`, `ab 01.04.2026`, `ab 01.05.2026`.
|
||||
- Column `I` (or next free column after month values): Free-text remarks describing assignment changes.
|
||||
|
||||
Interpretation rules:
|
||||
|
||||
- Each person can span multiple consecutive rows when they have multiple project shares.
|
||||
- The first row of a person contains the name and total weekly hours.
|
||||
- Following rows without a name belong to the same person and describe additional project shares.
|
||||
- Numeric values in the month columns are funded weekly hours for the respective month.
|
||||
- zero (0) or `-` means no funded share in that project for that month.
|
||||
- Free-text remarks may contain clarifying timing details and must be surfaced in validation output, but the primary logic is driven by the structured columns, not by parsing remarks.
|
||||
|
||||
### 2. Central Master Data: `Stellenbeschreibungen.xlsx`
|
||||
|
||||
This workbook is the central basis data source for descriptive person/project content used to fill the SAB form.
|
||||
|
||||
Observed structure in `Tabelle1`:
|
||||
|
||||
| Column | Meaning |
|
||||
|---|---|
|
||||
| `A` | `ID` |
|
||||
| `B` | `Antragsnummer` |
|
||||
| `C` | `Name` |
|
||||
| `D` | `Qualifikation` |
|
||||
| `E` | `Stellenanteil` |
|
||||
| `F` | `Funktion` |
|
||||
| `G` | `Taetigkeit` |
|
||||
|
||||
Interpretation rules:
|
||||
|
||||
- One employee can appear multiple times with different `Stellenanteil` and `Funktion` values.
|
||||
- `Stellenanteil` is stored as a percentage-like value such as `25,00` or `75,00`.
|
||||
- `Tätigkeit` contains multi-line free text that must be written into the SAB template unchanged except for Excel-compatible line break handling.
|
||||
- `Antragsnummer` is sourced from this workbook when a matching employee/function combination exists.
|
||||
|
||||
### 3. SAB Output Template: `Tätigkeitsnachweis Stellenförderung.xlsx`
|
||||
|
||||
This workbook is the Excel output format mandated by SAB and is the dedicated template base for generated files.
|
||||
|
||||
Template rule:
|
||||
|
||||
- The template workbook contains exactly one sheet.
|
||||
- This one sheet is the blueprint that must be copied for generated sheets.
|
||||
|
||||
Observed content blocks in the workbook:
|
||||
|
||||
- `Antragsnummer`
|
||||
- `Name, Vorname`
|
||||
- `Qualifikation`
|
||||
- `Funktion`
|
||||
- `Taetigkeiten inkl. Angaben zu Dienstreisen fuer das Projekt im Abrechnungszeitraum`
|
||||
- final declaration / signature section
|
||||
|
||||
The generator must treat this workbook as the authoritative structure for the output file. Placeholder values in the template, if present, are ignored and overwritten during generation. Exact target cells or named ranges are implementation details and must be externalized in configuration once confirmed.
|
||||
|
||||
## Core Business Goal
|
||||
|
||||
For a requested reporting month, generate one SAB Taetigkeitsnachweis per active employee assignment so that the document shows the correct funded staff share for that month.
|
||||
|
||||
The generated workbook must combine:
|
||||
|
||||
- allocation hours from `PS_PW.xlsx`
|
||||
- descriptive employee master data from `Stellenbeschreibungen.xlsx`
|
||||
- layout and target cells from `Tätigkeitsnachweis Stellenförderung.xlsx`
|
||||
|
||||
## Reporting Model
|
||||
|
||||
### Reporting Period
|
||||
|
||||
The CLI works on a single target month and year, for example `04/2026`.
|
||||
|
||||
The application must determine the single month column from `PS_PW.xlsx` that matches the requested month.
|
||||
|
||||
### Monthly Column Resolution
|
||||
|
||||
The date markers in row `2` of `PS_PW.xlsx` define one column per month. For a target month:
|
||||
|
||||
1. Read all month markers from row `2`.
|
||||
2. Parse each marker as first day of month (`ab 01.MM.YYYY`).
|
||||
3. Select the column whose parsed date exactly matches the requested month and year.
|
||||
4. Use this single column value as the funded weekly hours for that employee/project row.
|
||||
5. If the value is `-`, `0`, or empty, the employee/project combination is not active for that month.
|
||||
|
||||
### Employee Grouping in `PS_PW.xlsx`
|
||||
|
||||
Because some rows omit the employee name, the parser must normalize the sheet into records with an inherited person context.
|
||||
|
||||
Normalized record shape:
|
||||
|
||||
| Field | Source |
|
||||
|---|---|
|
||||
| `employee_name` | current non-empty value from column `A` |
|
||||
| `contract_hours_weekly` | current non-empty value from column `B` |
|
||||
| `project_key` | column `C` |
|
||||
| `monthly_hours` | single month column selected from `D+` via row `2` |
|
||||
| `notes` | remarks column when present |
|
||||
|
||||
Rows without a project key are ignored.
|
||||
|
||||
## Matching Logic Across Workbooks
|
||||
|
||||
The generator must join records across the two source workbooks.
|
||||
|
||||
### Primary Match Key
|
||||
|
||||
- `Name` in `Stellenbeschreibungen.xlsx` matches `employee_name` from normalized `PS_PW.xlsx` records.
|
||||
|
||||
### Secondary Disambiguation
|
||||
|
||||
If one person has multiple master-data rows in `Stellenbeschreibungen.xlsx`, choose the row whose `Stellenanteil` best matches the funded share derived from `PS_PW.xlsx` for the requested month.
|
||||
|
||||
Derived funded share formula:
|
||||
|
||||
$$
|
||||
Foerderquote = (funded_weekly_hours / contract_weekly_hours) * 100
|
||||
$$
|
||||
|
||||
Example:
|
||||
|
||||
- contract weekly hours = `20`
|
||||
- funded weekly hours = `10`
|
||||
- Foerderquote = `50 %`
|
||||
|
||||
Matching rule:
|
||||
|
||||
- Convert `Stellenbeschreibungen.xlsx`.`Stellenanteil` from German decimal text to a numeric percentage.
|
||||
- Choose the row whose percentage equals the derived Foerderquote.
|
||||
- If several rows match, prefer the one whose `Funktion` best matches the assignment context or require explicit disambiguation in validation output.
|
||||
|
||||
### Missing Match Handling
|
||||
|
||||
If no master-data row can be matched for an active allocation record:
|
||||
|
||||
- log a validation error
|
||||
- do not silently invent qualification, function, or activity text
|
||||
- depending on CLI mode, either skip that record or abort the full generation run
|
||||
|
||||
## Output Workbook Structure
|
||||
|
||||
Each generated file is an Excel workbook derived from the SAB template. One file corresponds to one employee for one reporting month.
|
||||
|
||||
Sheet rule for multiple assignments:
|
||||
|
||||
- If an employee has one active assignment in the month, the output workbook contains one sheet.
|
||||
- If an employee has multiple active assignments (multiple Stellen/Funktionen) in the month, the output workbook must contain one separate sheet per assignment.
|
||||
- Every generated sheet is a copy of the single template sheet and is then filled with the assignment-specific data.
|
||||
|
||||
Required logical output fields:
|
||||
|
||||
| Output field | Source |
|
||||
|---|---|
|
||||
| `Antragsnummer` | `Stellenbeschreibungen.xlsx`.`Antragsnummer` |
|
||||
| `Name, Vorname` | matched employee name |
|
||||
| `Qualifikation` | `Stellenbeschreibungen.xlsx`.`Qualifikation` |
|
||||
| `Funktion` | `Stellenbeschreibungen.xlsx`.`Funktion` |
|
||||
| `Taetigkeiten ...` | `Stellenbeschreibungen.xlsx`.`Taetigkeit` |
|
||||
| reporting month label | derived from CLI month/year |
|
||||
| Foerderquote / Stellenanteil for the month | derived from `PS_PW.xlsx` and contract hours |
|
||||
| generated-on date | current system date |
|
||||
|
||||
If the SAB sheet requires additional header or footer fields that are not yet represented in the example extraction, those mappings must be added to configuration, not hardcoded into business logic.
|
||||
|
||||
## File Generation Strategy
|
||||
|
||||
- The generator creates one output workbook per employee and month.
|
||||
- The generator copies the single configured template sheet as many times as needed.
|
||||
- It writes the matched values into configured target cells.
|
||||
- It saves one output file per employee for the target month.
|
||||
|
||||
Recommended default filename pattern:
|
||||
|
||||
`Tätigkeitsnachweis_<YYYY>_<MM>_<FirstName>_<LastName>.xlsx`
|
||||
|
||||
If an employee has multiple active assignments in the same month, the resulting Excel file contains one separate sheet per assignment.
|
||||
|
||||
## Validation Rules
|
||||
|
||||
Before any workbook is written, the application must run a full validation phase.
|
||||
|
||||
### Source Validation
|
||||
|
||||
| Check | Description |
|
||||
|---|---|
|
||||
| Source files exist | `Tool/input/PS_PW.xlsx`, `Tool/input/Stellenbeschreibungen.xlsx`, and `Tool/template/Tätigkeitsnachweis Stellenförderung.xlsx` are readable |
|
||||
| Required sheets exist | `Tabelle1` exists in both source workbooks; configured template sheet exists |
|
||||
| Month-marker row valid | Row `2` in `PS_PW.xlsx` contains parseable monthly markers `ab 01.MM.YYYY` |
|
||||
| Requested month exists | Exactly one month column in `PS_PW.xlsx` matches the requested month/year |
|
||||
| Required columns exist | all configured columns are present in both source workbooks |
|
||||
| Hour values valid | resolved funded hour values are numeric, `0`, or `-` |
|
||||
| Contract hours valid | total weekly hours are numeric and greater than `0` |
|
||||
| Share values valid | derived Förderquote is between `0` and `100` unless explicitly allowed otherwise |
|
||||
| Master-data match exists | every active record can be matched to one descriptive row or is reported as ambiguous/missing |
|
||||
|
||||
### Business Validation
|
||||
|
||||
| Check | Description |
|
||||
|---|---|
|
||||
| Active assignment exists | at least one normalized allocation record resolves to funded hours > `0` in the requested month |
|
||||
| Match uniqueness | each generated output uses exactly one master-data row |
|
||||
| Template has one sheet | configured template workbook contains exactly one source sheet to clone |
|
||||
| Output filename unique | no two generated files resolve to the same path |
|
||||
| Required template targets configured | all mandatory target cells are configured before writing |
|
||||
|
||||
Validation errors are logged and summarized. They must never be silently ignored.
|
||||
|
||||
## Console Preview and Confirmation
|
||||
|
||||
After validation and before writing files, show a preview similar to:
|
||||
|
||||
```text
|
||||
=== Vorschau der ermittelten Werte ===
|
||||
Berichtsmonat : 04/2026
|
||||
PS_PW-Datei : PS_PW.xlsx
|
||||
Stammdaten : Stellenbeschreibungen.xlsx
|
||||
Vorlage : Tätigkeitsnachweis Stellenförderung.xlsx
|
||||
Aktive Faelle : 8
|
||||
Fehler : 0
|
||||
|
||||
--- Zu erzeugende Taetigkeitsnachweise ---
|
||||
Mitarbeitende(r) Projekt Funktion Stunden Quote
|
||||
Meyer, Johannes PS Produktionsschulleiter 10 / 40 25,00 %
|
||||
Meyer, Johannes PW Soz. Paed 30 / 40 75,00 %
|
||||
...
|
||||
|
||||
Moechten Sie die Dateien erzeugen? [j/N]
|
||||
```
|
||||
|
||||
- If validation errors exist, print them before the prompt.
|
||||
- Continue only if the user explicitly confirms with `j`.
|
||||
- Any other input aborts the run without writing output files.
|
||||
|
||||
## Configuration Rules
|
||||
|
||||
All environment-specific details must be stored in `config.json`.
|
||||
|
||||
Configuration must include at least:
|
||||
|
||||
- path to `Tool/input/PS_PW.xlsx`
|
||||
- path to `Tool/input/Stellenbeschreibungen.xlsx`
|
||||
- path to `Tool/template/Tätigkeitsnachweis Stellenförderung.xlsx`
|
||||
- source sheet names
|
||||
- source column mappings
|
||||
- row number for month markers in `PS_PW.xlsx`
|
||||
- template sheet selection strategy
|
||||
- output cell mappings
|
||||
- output directory (`Tool/output/`)
|
||||
- filename pattern
|
||||
|
||||
No workbook-specific coordinates may be buried directly inside business logic.
|
||||
|
||||
## CLI Requirements
|
||||
|
||||
The CLI entry point is `generate.py` using Click.
|
||||
|
||||
Required arguments:
|
||||
|
||||
- `--month` target month as `MM`
|
||||
- `--year` target year as `YYYY`
|
||||
|
||||
Optional arguments:
|
||||
|
||||
- `--employee` limit generation to one employee name
|
||||
- `--project` limit generation to one project key
|
||||
- `--dry-run` run validation and preview without writing files
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
All business logic must be covered by tests in `tests/`.
|
||||
|
||||
At minimum, tests must cover:
|
||||
|
||||
- inheritance of employee context across multiple `PS_PW.xlsx` rows
|
||||
- resolution of the correct month column for a requested month
|
||||
- conversion of German decimal percentages such as `25,00`
|
||||
- Foerderquote calculation
|
||||
- matching of one employee to multiple master-data rows by `Stellenanteil`
|
||||
- skipping inactive `-` assignments
|
||||
- validation for missing and ambiguous matches
|
||||
- generation of collision-free output filenames
|
||||
|
||||
Tests must not depend on real employee names or on the exact attached workbooks.
|
||||
Reference in new issue
Block a user