Implement template cloning and sheet population logic

This commit is contained in:
Rob committed 2026-04-21 15:36:42 +02:00
1 parent 7501499080
commit 10e3ec8c12
2 files changed
+100 -5

No files matched your search

+5 -5
View File
@@ -67,10 +67,10 @@ Projekt vollstaendig umsetzen: aus PS_PW.xlsx und Stellenbeschreibungen.xlsx mon
- [x] Pflicht-Zielzellen vollstaendig konfiguriert - [x] Pflicht-Zielzellen vollstaendig konfiguriert
## Phase 6 - Ausgabeerzeugung ## Phase 6 - Ausgabeerzeugung
- [ ] T11: Template-Verarbeitung bauen - [x] T11: Template-Verarbeitung bauen
- [ ] Template-Workbook laden - [x] Template-Workbook laden
- [ ] Sheet pro aktiver Zuordnung klonen - [x] Sheet pro aktiver Zuordnung klonen
- [ ] Inhalte assignment-spezifisch in Zielzellen schreiben - [x] Inhalte assignment-spezifisch in Zielzellen schreiben
- [ ] T12: Dateinamen und Speichern - [ ] T12: Dateinamen und Speichern
- [ ] Muster: `Taetigkeitsnachweis_YYYY_MM_Vorname_Nachname.xlsx` - [ ] Muster: `Taetigkeitsnachweis_YYYY_MM_Vorname_Nachname.xlsx`
- [ ] Pro Mitarbeiter genau eine Datei pro Monat erzeugen - [ ] Pro Mitarbeiter genau eine Datei pro Monat erzeugen
@@ -111,4 +111,4 @@ Projekt vollstaendig umsetzen: aus PS_PW.xlsx und Stellenbeschreibungen.xlsx mon
8. T15 -> T16 -> T17 8. T15 -> T16 -> T17
## Aktueller Startpunkt ## Aktueller Startpunkt
- [ ] Naechste aktive Aufgabe: T11 (Template-Verarbeitung bauen) - [ ] Naechste aktive Aufgabe: T12 (Dateinamen und Speichern)
+95
View File
@@ -1 +1,96 @@
"""Template-based output workbook writer.""" """Template-based output workbook writer."""
from __future__ import annotations
from collections import defaultdict
from datetime import date
from pathlib import Path
from typing import Any
from openpyxl import Workbook, load_workbook
from .models import MatchedAssignment
def _split_name_for_filename(name: str) -> tuple[str, str]:
cleaned = str(name or "").strip()
if "," in cleaned:
last_name, first_name = [part.strip() for part in cleaned.split(",", 1)]
return first_name or "Unknown", last_name or "Unknown"
parts = cleaned.split()
if len(parts) >= 2:
return parts[0], parts[-1]
if len(parts) == 1:
return parts[0], "Unknown"
return "Unknown", "Unknown"
def _normalize_sheet_title(raw_title: str, fallback_index: int) -> str:
cleaned = (raw_title or "").strip().replace("[", "(").replace("]", ")")
if not cleaned:
cleaned = f"Assignment_{fallback_index}"
return cleaned[:31]
def _set_target_value(worksheet: Any, target_cell: str, value: Any) -> None:
if not target_cell:
return
worksheet[target_cell] = value
def build_employee_workbooks(
config: dict[str, Any],
matched_assignments: list[MatchedAssignment],
report_month: int,
report_year: int,
project_root: Path,
) -> dict[str, Workbook]:
paths_cfg = config["paths"]
files_cfg = config["files"]
output_cfg = config["output"]
targets = config.get("template_targets", {})
template_path = (
project_root
/ paths_cfg["template_dir"]
/ files_cfg["template_workbook"]
)
assignments_by_employee: dict[str, list[MatchedAssignment]] = defaultdict(list)
for assignment in matched_assignments:
assignments_by_employee[assignment.allocation.employee_name].append(assignment)
workbooks: dict[str, Workbook] = {}
month_label = f"{report_month:02d}/{report_year}"
today_label = date.today().strftime("%d.%m.%Y")
for employee_name, assignments in assignments_by_employee.items():
workbook = load_workbook(template_path)
base_sheet = workbook.worksheets[0]
for index, assignment in enumerate(assignments, start=1):
if index == 1:
sheet = base_sheet
else:
sheet = workbook.copy_worksheet(base_sheet)
sheet_name_pattern = output_cfg.get("sheet_name_pattern", "{index}_{funktion}")
raw_sheet_name = sheet_name_pattern.format(
index=index,
funktion=assignment.masterdata.funktion,
)
sheet.title = _normalize_sheet_title(raw_sheet_name, index)
_set_target_value(sheet, targets.get("antragsnummer", ""), assignment.masterdata.antragsnummer)
_set_target_value(sheet, targets.get("name_vorname", ""), assignment.allocation.employee_name)
_set_target_value(sheet, targets.get("qualifikation", ""), assignment.masterdata.qualifikation)
_set_target_value(sheet, targets.get("funktion", ""), assignment.masterdata.funktion)
_set_target_value(sheet, targets.get("taetigkeiten", ""), assignment.masterdata.taetigkeit)
_set_target_value(sheet, targets.get("reporting_month_label", ""), month_label)
_set_target_value(sheet, targets.get("foerderquote", ""), f"{assignment.foerderquote_percent:.2f} %")
_set_target_value(sheet, targets.get("generated_on", ""), today_label)
workbooks[employee_name] = workbook
return workbooks