Configure template target cells and add skip-errors mode
This commit is contained in:
1 parent
418d8336f5
commit
5f3a820641
5 files changed
+31
-17
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
|
## Phase 8 - Tests und Abnahme
|
||||||
- [ ] T15: Smoke-Test fuer End-to-End-Lauf
|
- [ ] T15: Smoke-Test fuer End-to-End-Lauf
|
||||||
- [x] Beispielmonat ausfuehren
|
- [x] Beispielmonat ausfuehren
|
||||||
|
- [x] Pipeline laeuft bis Dateiausgabe durch (0 Dateien, da 0 gematchte Faelle)
|
||||||
- [ ] Dateien in `output/` entstehen erwartungsgemaess
|
- [ ] Dateien in `output/` entstehen erwartungsgemaess
|
||||||
- [ ] Blocker: Masterdata-Matches fehlen fuer mehrere aktive Namen.
|
- [ ] DATENBLOCKER: `Stellenbeschreibungen.xlsx` enthaelt nur Meyer,Johannes (25%/75%).
|
||||||
- [ ] Blocker: Template-Regel verletzt (aktuell 5 Sheets statt 1) und template_targets sind noch nicht konfiguriert.
|
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
|
- [ ] T16: Fachtests definieren und ausfuehren
|
||||||
- [ ] Mehrfachzuordnung eines Mitarbeiters
|
- [ ] Mehrfachzuordnung eines Mitarbeiters
|
||||||
- [ ] Fehlender Match
|
- [ ] Fehlender Match
|
||||||
|
|||||||
+9
-9
@@ -12,7 +12,7 @@
|
|||||||
"sheets": {
|
"sheets": {
|
||||||
"allocation": "Tabelle1",
|
"allocation": "Tabelle1",
|
||||||
"masterdata": "Tabelle1",
|
"masterdata": "Tabelle1",
|
||||||
"template_source": "Tabelle1"
|
"template_source": "<MM_YYYY>_<Stellenbeschreibung>"
|
||||||
},
|
},
|
||||||
"allocation": {
|
"allocation": {
|
||||||
"header_month_marker_row": 2,
|
"header_month_marker_row": 2,
|
||||||
@@ -66,14 +66,14 @@
|
|||||||
"sheet_name_pattern": "{index}_{funktion}"
|
"sheet_name_pattern": "{index}_{funktion}"
|
||||||
},
|
},
|
||||||
"template_targets": {
|
"template_targets": {
|
||||||
"antragsnummer": "",
|
"antragsnummer": "A3",
|
||||||
"name_vorname": "",
|
"name_vorname": "A17",
|
||||||
"qualifikation": "",
|
"qualifikation": "A21",
|
||||||
"funktion": "",
|
"funktion": "A25",
|
||||||
"taetigkeiten": "",
|
"taetigkeiten": "A31",
|
||||||
"reporting_month_label": "",
|
"reporting_month_label": "Q21",
|
||||||
"foerderquote": "",
|
"foerderquote": "Q17",
|
||||||
"generated_on": ""
|
"generated_on": "I95"
|
||||||
},
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"abort_on_validation_errors": true,
|
"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("--month", type=click.IntRange(1, 12), required=True)
|
||||||
@click.option("--year", type=click.IntRange(2000, 2100), required=True)
|
@click.option("--year", type=click.IntRange(2000, 2100), required=True)
|
||||||
@click.option("--yes", is_flag=True, default=False, help="Skip interactive confirmation.")
|
@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()
|
configure_logging()
|
||||||
project_root = Path(__file__).resolve().parent
|
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 ===")
|
_print_issues(business_issues, "=== Business validation ===")
|
||||||
|
|
||||||
all_issues = [*match_issues, *business_issues]
|
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.")
|
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"]
|
filename_pattern = config["output"]["filename_pattern"]
|
||||||
unique_employees = sorted({item.allocation.employee_name for item in matched_assignments})
|
unique_employees = sorted({item.allocation.employee_name for item in matched_assignments})
|
||||||
|
|||||||
@@ -319,12 +319,13 @@ def validate_business_rules(
|
|||||||
|
|
||||||
if template_path.exists():
|
if template_path.exists():
|
||||||
template_wb = load_workbook(template_path, data_only=True)
|
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(
|
issues.append(
|
||||||
ValidationIssue(
|
ValidationIssue(
|
||||||
code="TEMPLATE_SHEET_COUNT",
|
code="TEMPLATE_SHEET_MISSING",
|
||||||
message=(
|
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",
|
severity="error",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -67,7 +67,11 @@ def build_employee_workbooks(
|
|||||||
|
|
||||||
for employee_name, assignments in assignments_by_employee.items():
|
for employee_name, assignments in assignments_by_employee.items():
|
||||||
workbook = load_workbook(template_path)
|
workbook = load_workbook(template_path)
|
||||||
base_sheet = workbook.worksheets[0]
|
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):
|
for index, assignment in enumerate(assignments, start=1):
|
||||||
if index == 1:
|
if index == 1:
|
||||||
|
|||||||
Reference in new issue
Block a user