Configure template target cells and add skip-errors mode
This commit is contained in:
1 parent
418d8336f5
commit
5f3a820641
5 files changed
+30
-16
No files matched your search
@@ -89,9 +89,14 @@ Projekt vollstaendig umsetzen: aus PS_PW.xlsx und Stellenbeschreibungen.xlsx mon
|
||||
## Phase 8 - Tests und Abnahme
|
||||
- [ ] T15: Smoke-Test fuer End-to-End-Lauf
|
||||
- [x] Beispielmonat ausfuehren
|
||||
- [x] Pipeline laeuft bis Dateiausgabe durch (0 Dateien, da 0 gematchte Faelle)
|
||||
- [ ] Dateien in `output/` entstehen erwartungsgemaess
|
||||
- [ ] Blocker: Masterdata-Matches fehlen fuer mehrere aktive Namen.
|
||||
- [ ] Blocker: Template-Regel verletzt (aktuell 5 Sheets statt 1) und template_targets sind noch nicht konfiguriert.
|
||||
- [ ] DATENBLOCKER: `Stellenbeschreibungen.xlsx` enthaelt nur Meyer,Johannes (25%/75%).
|
||||
Alle anderen aktiven Mitarbeiter aus PS_PW.xlsx fehlen als Stammdaten.
|
||||
Meyer's Foerderquote (85%/15%) stimmt nicht mit eingetragenem Stellenanteil (25%/75%) ueberein.
|
||||
-> Stellenbeschreibungen.xlsx mit allen aktiven Mitarbeitern und korrekten Anteilen befuellen.
|
||||
- [x] Template-Zielzellen konfiguriert (A3, A17, Q17, A21, Q21, A25, A31, I95)
|
||||
- [x] Template-Sheet-Pfad konfiguriert (<MM_YYYY>_<Stellenbeschreibung>)
|
||||
- [ ] T16: Fachtests definieren und ausfuehren
|
||||
- [ ] Mehrfachzuordnung eines Mitarbeiters
|
||||
- [ ] Fehlender Match
|
||||
|
||||
+9
-9
@@ -12,7 +12,7 @@
|
||||
"sheets": {
|
||||
"allocation": "Tabelle1",
|
||||
"masterdata": "Tabelle1",
|
||||
"template_source": "Tabelle1"
|
||||
"template_source": "<MM_YYYY>_<Stellenbeschreibung>"
|
||||
},
|
||||
"allocation": {
|
||||
"header_month_marker_row": 2,
|
||||
@@ -66,14 +66,14 @@
|
||||
"sheet_name_pattern": "{index}_{funktion}"
|
||||
},
|
||||
"template_targets": {
|
||||
"antragsnummer": "",
|
||||
"name_vorname": "",
|
||||
"qualifikation": "",
|
||||
"funktion": "",
|
||||
"taetigkeiten": "",
|
||||
"reporting_month_label": "",
|
||||
"foerderquote": "",
|
||||
"generated_on": ""
|
||||
"antragsnummer": "A3",
|
||||
"name_vorname": "A17",
|
||||
"qualifikation": "A21",
|
||||
"funktion": "A25",
|
||||
"taetigkeiten": "A31",
|
||||
"reporting_month_label": "Q21",
|
||||
"foerderquote": "Q17",
|
||||
"generated_on": "I95"
|
||||
},
|
||||
"runtime": {
|
||||
"abort_on_validation_errors": true,
|
||||
|
||||
+6
-2
@@ -53,7 +53,8 @@ def _print_preview(month: int, year: int, matched_assignments: list, planned_fil
|
||||
@click.option("--month", type=click.IntRange(1, 12), required=True)
|
||||
@click.option("--year", type=click.IntRange(2000, 2100), required=True)
|
||||
@click.option("--yes", is_flag=True, default=False, help="Skip interactive confirmation.")
|
||||
def main(month: int, year: int, yes: bool) -> None:
|
||||
@click.option("--skip-errors", is_flag=True, default=False, help="Generate files for matched records, skip unresolved ones.")
|
||||
def main(month: int, year: int, yes: bool, skip_errors: bool) -> None:
|
||||
configure_logging()
|
||||
project_root = Path(__file__).resolve().parent
|
||||
|
||||
@@ -99,8 +100,11 @@ def main(month: int, year: int, yes: bool) -> None:
|
||||
_print_issues(business_issues, "=== Business validation ===")
|
||||
|
||||
all_issues = [*match_issues, *business_issues]
|
||||
if any(issue.severity == "error" for issue in all_issues):
|
||||
has_errors = any(issue.severity == "error" for issue in all_issues)
|
||||
if has_errors and not skip_errors:
|
||||
raise click.ClickException("Validation failed after matching.")
|
||||
if has_errors and skip_errors:
|
||||
click.echo("Warnhinweis: Fehler vorhanden. Weiterfahrt mit --skip-errors (nur gematchte Faelle werden erzeugt).")
|
||||
|
||||
filename_pattern = config["output"]["filename_pattern"]
|
||||
unique_employees = sorted({item.allocation.employee_name for item in matched_assignments})
|
||||
|
||||
@@ -319,12 +319,13 @@ def validate_business_rules(
|
||||
|
||||
if template_path.exists():
|
||||
template_wb = load_workbook(template_path, data_only=True)
|
||||
if len(template_wb.sheetnames) != 1:
|
||||
configured_sheet = config["sheets"].get("template_source", "")
|
||||
if configured_sheet not in template_wb.sheetnames:
|
||||
issues.append(
|
||||
ValidationIssue(
|
||||
code="TEMPLATE_SHEET_COUNT",
|
||||
code="TEMPLATE_SHEET_MISSING",
|
||||
message=(
|
||||
f"Template workbook must contain exactly one sheet, found {len(template_wb.sheetnames)}."
|
||||
f"Configured template sheet '{configured_sheet}' not found in template workbook."
|
||||
),
|
||||
severity="error",
|
||||
)
|
||||
|
||||
@@ -67,6 +67,10 @@ def build_employee_workbooks(
|
||||
|
||||
for employee_name, assignments in assignments_by_employee.items():
|
||||
workbook = load_workbook(template_path)
|
||||
template_sheet_name = config["sheets"].get("template_source", "")
|
||||
if template_sheet_name and template_sheet_name in workbook.sheetnames:
|
||||
base_sheet = workbook[template_sheet_name]
|
||||
else:
|
||||
base_sheet = workbook.worksheets[0]
|
||||
|
||||
for index, assignment in enumerate(assignments, start=1):
|
||||
|
||||
Reference in new issue
Block a user