deepseek den plan umsetzen lassen
This commit is contained in:
1 parent
6c60a72e0f
commit
044e4df783
16 files changed
+971
-55
No files matched your search
@@ -0,0 +1,136 @@
|
||||
"""Validierung von Input-Dateien und Templates."""
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from openpyxl import load_workbook
|
||||
from openpyxl.utils import column_index_from_string
|
||||
|
||||
from .models import FieldSchema, OutputMapping, ValidationResult
|
||||
|
||||
|
||||
def validate_input_file(
|
||||
filepath: Path,
|
||||
schema: list[FieldSchema],
|
||||
) -> ValidationResult:
|
||||
"""
|
||||
Validiert eine Input-Datei:
|
||||
- Datei existiert
|
||||
- Erwartete Spalten sind vorhanden (Header in Zeile 1)
|
||||
- Mindestens ein Daten-Sheet enthält Daten
|
||||
"""
|
||||
errors: list[str] = []
|
||||
warnings: list[str] = []
|
||||
info: dict = {}
|
||||
|
||||
if not filepath.exists():
|
||||
errors.append(f"Input-Datei nicht gefunden: {filepath}")
|
||||
return ValidationResult(is_valid=False, errors=errors)
|
||||
|
||||
try:
|
||||
wb = load_workbook(filepath, data_only=True)
|
||||
except Exception as e:
|
||||
errors.append(f"Datei konnte nicht geöffnet werden: {e}")
|
||||
return ValidationResult(is_valid=False, errors=errors)
|
||||
|
||||
sheet_count = len(wb.sheetnames)
|
||||
info["sheet_count"] = sheet_count
|
||||
info["sheet_names"] = wb.sheetnames
|
||||
|
||||
# Prüfe, ob mindestens ein Sheet die erwarteten Spalten hat
|
||||
sheets_with_data = 0
|
||||
for sheet_name in wb.sheetnames:
|
||||
ws = wb[sheet_name]
|
||||
if ws.max_row < 2:
|
||||
continue # Kein Header + Daten
|
||||
|
||||
header_row = list(ws.iter_rows(min_row=1, max_row=1, values_only=True))[0]
|
||||
missing_cols = []
|
||||
for field in schema:
|
||||
col_idx = column_index_from_string(field.column) - 1
|
||||
if col_idx >= len(header_row):
|
||||
missing_cols.append(f"{field.column} ({field.field_name})")
|
||||
continue
|
||||
header_val = str(header_row[col_idx]).strip() if header_row[col_idx] is not None else ""
|
||||
if header_val != field.field_name:
|
||||
warnings.append(
|
||||
f"Sheet '{sheet_name}', Spalte {field.column}: "
|
||||
f"Erwartet '{field.field_name}', gefunden '{header_val}'"
|
||||
)
|
||||
|
||||
if not missing_cols:
|
||||
sheets_with_data += 1
|
||||
|
||||
# Zähle Datenzeilen
|
||||
data_rows = ws.max_row - 1
|
||||
info[f"rows_{sheet_name}"] = data_rows
|
||||
|
||||
info["sheets_with_data"] = sheets_with_data
|
||||
wb.close()
|
||||
|
||||
if sheets_with_data == 0:
|
||||
errors.append("Kein Sheet mit den erwarteten Spalten gefunden.")
|
||||
|
||||
return ValidationResult(
|
||||
is_valid=len(errors) == 0,
|
||||
errors=errors,
|
||||
warnings=warnings,
|
||||
info=info,
|
||||
)
|
||||
|
||||
|
||||
def validate_template(
|
||||
template_path: Path,
|
||||
mapping: list[OutputMapping],
|
||||
) -> ValidationResult:
|
||||
"""
|
||||
Validiert ein Template:
|
||||
- Datei existiert
|
||||
- Alle target_cells aus dem Mapping sind im Template vorhanden
|
||||
"""
|
||||
errors: list[str] = []
|
||||
warnings: list[str] = []
|
||||
info: dict = {}
|
||||
|
||||
if not template_path.exists():
|
||||
errors.append(f"Template-Datei nicht gefunden: {template_path}")
|
||||
return ValidationResult(is_valid=False, errors=errors)
|
||||
|
||||
try:
|
||||
wb = load_workbook(template_path, data_only=True)
|
||||
except Exception as e:
|
||||
errors.append(f"Template konnte nicht geöffnet werden: {e}")
|
||||
return ValidationResult(is_valid=False, errors=errors)
|
||||
|
||||
info["sheet_names"] = wb.sheetnames
|
||||
|
||||
# Wir validieren gegen das erste Sheet (üblicherweise das Haupt-Template)
|
||||
if not wb.sheetnames:
|
||||
errors.append("Template enthält keine Sheets.")
|
||||
wb.close()
|
||||
return ValidationResult(is_valid=False, errors=errors)
|
||||
|
||||
ws = wb[wb.sheetnames[0]]
|
||||
|
||||
found_cells = 0
|
||||
missing_cells = []
|
||||
for m in mapping:
|
||||
try:
|
||||
cell = ws[m.target_cell]
|
||||
found_cells += 1
|
||||
except (ValueError, KeyError):
|
||||
missing_cells.append(m.target_cell)
|
||||
|
||||
info["found_target_cells"] = found_cells
|
||||
info["total_target_cells"] = len(mapping)
|
||||
|
||||
if missing_cells:
|
||||
errors.append(f"Zielfelder nicht im Template gefunden: {', '.join(missing_cells)}")
|
||||
|
||||
wb.close()
|
||||
return ValidationResult(
|
||||
is_valid=len(errors) == 0,
|
||||
errors=errors,
|
||||
warnings=warnings,
|
||||
info=info,
|
||||
)
|
||||
Reference in new issue
Block a user