feat: CSV-Format automatisch erkennen

Bisher musste man bei jedem Import Trennzeichen, Datumsformat und
Spaltenzuordnung von Hand eintragen – die haeufigste Fehlerquelle ueberhaupt:
Ein falsches Datumsformat liess alle Zeilen durchfallen, ein falscher
Dezimaltrenner verzehnfachte Betraege.

Zuerst wird gegen die Bank-Vorlagen geprueft (Kopfzeilen-Signatur); alle vier
echten Ausaege des Nutzers werden so sicher erkannt. Sonst inhaltsbasiert:
welche Spalte enthaelt Daten, welche Betraege, welche den laengsten Text.

Zwei Fallen, die dabei aufgefallen sind und getestet werden:
- Deutsche Datumsangaben stecken voller Punkte, und viele Auszuege fuehren
  Buchungs- UND Valutadatum. Ohne sie herauszurechnen kaeme "." als
  Dezimalzeichen heraus und aus 1.204,70 wuerden 1.20.
- parse_date ist absichtlich nachsichtig; beim Erkennen darf es das nicht
  sein, sonst gewinnt ein Format mit Uhrzeit gegen das richtige ohne.

Ganzzahlen ohne Vorzeichen zaehlen nur halb, damit Referenznummern und Kurse
nicht als Betragsspalte durchgehen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-08-22 21:17:37 +02:00
co-authored by Claude Opus 5
parent c47525ff7e
commit e6801b0474
3 changed files with 282 additions and 0 deletions
+11
View File
@@ -90,6 +90,17 @@ def _transient(user_id: int, **fields) -> ImportTemplate:
return ImportTemplate(owner_id=user_id, name="_transient", **fields)
@router.post("/detect")
async def detect_format(
file: UploadFile = File(...),
encoding: str = Form("utf-8"),
_: User = Depends(get_current_user),
) -> dict:
"""Format der Datei erkennen, damit niemand mehr Spalten von Hand zuordnet."""
daten = await file.read()
return csv_import.erkenne_format(daten, encoding)
@router.post("/raw")
async def raw_preview(
file: UploadFile = File(...),