Commit Graph
16 Commits
Author SHA1 Message Date
GuidoandClaude Opus 5 d05f4915ad fix: Saldo-Abgleich erklaert die Abweichung verstaendlich
Die Meldung nannte nur Zahlen ("Laut Datei / errechnet / Differenz") und
sagte nicht, was zu tun ist. Sie beschreibt jetzt in Worten, was nicht
aufgeht und ab welcher Zeile beide auseinanderlaufen.

Dazu ein Hinweis auf die haeufigste Ursache, wenn kein Zeilenfilter
gesetzt ist: Revolut legt Giro, Erspartes und Anlagekonto in EINE Datei,
jedes mit eigener Kontostand-Spalte. Ohne Filter springt die Spalte
zwischen den Produkten und der Abgleich kann gar nicht aufgehen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 18:27:14 +02:00
GuidoandClaude Opus 4.8 af865a5c7b fix: neutrale Kategorien gelten für Ausgabe UND Einnahme
Kategorien erben ihre Art von der Gruppe, und die ist entweder Ausgabe oder
Einnahme. Für einen Kontoübertrag passt beides nicht: Auf dem einen Konto geht
Geld raus, auf dem anderen kommt es rein – man musste also zwei Kategorien in
zwei Gruppen anlegen.

Als „nicht in Auswertungen einrechnen" markierte Kategorien werden jetzt in
beiden Richtungen angeboten (Buchungsformular und Import-Prüfansicht), und ihre
Schlagwörter greifen unabhängig vom Vorzeichen. Eine Kategorie „Kontoübertrag"
in einer Ausgabe-Gruppe genügt damit für beide Seiten.

Test für beide Richtungen; 94 grün.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-21 14:09:54 +02:00
GuidoandClaude Opus 4.8 8d767e728a feat: Buchen-Knopf auch unter der Prüfliste + Verlauf aufräumen
- Bei mehreren hundert Zeilen ist der Knopf oben längst aus dem Bild gescrollt;
  unter der Liste steht jetzt derselbe.
- Rückgängig gemachte Importe lassen sich aus dem Verlauf entfernen. Nur diese:
  solange ein Import steht, ist sein Eintrag die einzige Möglichkeit, seine
  Buchungen wieder loszuwerden – der Server lehnt das sonst ab.

Test für beide Fälle des neuen Endpunkts; 92 grün.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-21 09:20:29 +02:00
GuidoandClaude Opus 4.8 4a6f7a0814 feat: Zeilenfilter für Auszüge mit mehreren Pockets + Gebühren-Richtung
Der Revolut-Auszug enthält ALLE Produkte in einer Datei – im CHF-Export stehen
533 Giro-Zeilen und 255 Zeilen des Ersparten, jedes mit eigenem Kontostand-
Verlauf. Ohne Trennung landeten beide auf demselben Konto und die Pocket-
Bewegungen zählten doppelt.

- Import-Vorlage kennt einen Zeilenfilter („nur Zeilen aus Spalte X mit Wert Y"),
  Migration 0012; damit bekommt jedes Pocket sein eigenes Konto
- Gebührenzeilen (Betrag 0.00) können Belastung ODER Erstattung sein – beide
  sehen identisch aus. Die Richtung kommt jetzt aus der Kontostand-Spalte;
  ohne sie bleibt die Belastung der Normalfall
- Tests für beides; 90 grün

Nachgerechnet an den echten Auszügen: Raiffeisen 223.37, Revolut CHF 61.88,
Erspartes 6.71, Revolut EUR 0.68 – alle vier stimmen zeilengenau mit der
Kontostand-Spalte überein.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-21 09:01:07 +02:00
GuidoandClaude Opus 4.8 62eab06bdc feat: Gegenseite eines Übertrags braucht keine eigene Transfer-Regel
Bisher musste die Regel auf BEIDEN Auszügen ein fremdes Gegenkonto liefern. Beim
Empfangs-Auszug zeigt sie aber auf das Konto, das gerade importiert wird – damit
blieb die Zeile ohne Gegenkonto und wurde still als Einnahme gebucht.

- Gegenbuchungen werden über die Konto-Seite bestehender Transfers gesucht, nicht
  über das Konto-Paar. Der Empfangs-Auszug braucht damit keine Regel mehr; eine
  Regel auf der abgehenden Seite genügt für beide Dateien.
- Trifft eine Transfer-Regel, ohne dass ein Gegenkonto feststeht, wird die Zeile
  nicht mehr als Einnahme/Ausgabe gebucht, sondern in der Prüfansicht mit
  „Gegenkonto wählen" markiert – sonst zählt die Bewegung je nach Import-
  Reihenfolge doppelt.
- Tests für beide Reihenfolgen; 86 grün.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-21 08:20:13 +02:00
GuidoandClaude Opus 4.8 d97e08e913 fix: Datumsspalten mit Uhrzeit werden auch ohne passendes Format erkannt
Der Revolut-Export führt "2026-01-06 23:11:14" in der Datumsspalte. Wählte man
im Dropdown JJJJ-MM-TT, scheiterte das Parsen an der Uhrzeit – jede Zeile hatte
kein Datum und galt als ungültig ("137 Zeilen erkannt, 0 werden gebucht"),
obwohl die Auswahl richtig aussah.

- parse_date schneidet eine überzählige Uhrzeit ab und kommt auch damit klar,
  wenn das Format eine Uhrzeit erwartet, der Wert aber keine hat (ISO-T ebenso)
- Dropdown um die Varianten mit Uhrzeit ergänzt, damit die Bank-Vorlagen ihren
  echten Eintrag zeigen statt eines leeren Feldes
- Test: reines Datumsformat auf Datei mit Uhrzeit -> alle Zeilen erkannt, 84 grün

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-21 08:02:18 +02:00
GuidoandClaude Opus 4.8 5a747fbef4 feat: Saldo-Abgleich beim CSV-Import gegen die Kontostand-Spalte
Bisher merkte man einen Importfehler erst am falschen Endsaldo, ohne Hinweis auf
die Ursache. Enthält der Auszug eine laufende Kontostand-Spalte, gleicht der
Import jetzt jede Zeile dagegen ab: Die Spalte sagt, wie sich der Saldo
tatsächlich verändert hat, unsere Erkennung muss dazu passen.

- neue Spaltenzuordnung "Kontostand (laufend)"; Presets Raiffeisen/Revolut ergänzt
- Prüfansicht zeigt: stimmt überein ODER Differenz + erste abweichende Zeile
  (Datum, Empfänger, Betrag laut Bank vs. erkannt)
- meldet zusätzlich den Anfangssaldo laut Datei – häufigste Fehlerquelle
- rechnet mit dem tatsächlich gebuchten Betrag, damit auch nicht gebuchte Zeilen
  auffallen (z. B. nicht zugeordnete Gebührenspalte); Fremdwährungs-Zeilen
  gehören zu einem anderen Saldo-Verlauf und bleiben außen vor
- erkennt absteigend sortierte Auszüge
- Tests: stimmiger Auszug (ok) und fehlende Gebührenspalte (zeigt genau die
  Zeile). 83 grün.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-21 06:58:33 +02:00
GuidoandClaude Opus 4.8 d725f5cf57 fix: Revolut-Import wertet Gebühr, Status und Währung aus
Das Revolut-Preset kannte die Spalten Gebühr/Währung/Status laut Kommentar,
der Parser hat sie aber nie gelesen. Folgen: Gebühren fehlten im Saldo,
stornierte (REVERTED) und schwebende Zeilen wurden mitgebucht, und Zeilen
fremder Währungs-Pockets landeten 1:1 im Konto – der Saldo lief dadurch zu hoch.

- Gebührenspalte mindert den Betrag (immer als Kosten)
- nur Zeilen mit Status COMPLETED (oder ohne Statusspalte) sind buchbar
- Zeilen in anderer Währung als das Zielkonto werden nicht gebucht
- Grund wird in der Prüfansicht als Badge angezeigt (storniert / Währung)
- Gebühr/Währung/Status in der Spaltenzuordnung wählbar; Revolut-Preset ergänzt
- Test mit echtem Revolut-Format (Gebühr, Storno, Fremdwährung), 80 grün

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-21 06:30:22 +02:00
GuidoandClaude Opus 4.8 338c21935b feat: Transfer-Erkennung symmetrisch (Eingänge) + Gegenbuchungs-Erkennung
- Enthält der Buchungstext den Erkennungs-Text (Art „Text") eines ANDEREN
  Kontos, wird auch ein Eingang als Transfer VON diesem Konto gesetzt – nicht
  nur die Ausgabe. Richtung ergibt sich aus dem Vorzeichen.
- Gegenbuchungs-Erkennung: existiert schon ein Transfer zwischen denselben
  Konten mit passendem Betrag (±5 Tage), wird die Gegenseite als „Gegenbuchung"
  markiert und nicht angehakt – so zählt dieselbe Bewegung beim Import beider
  Auszüge nicht doppelt (überschreibbar in der Prüfansicht).
- Tests: Eingang übers Konto-Tag, Gegenbuchung übersprungen (78 grün)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-20 20:52:31 +02:00
GuidoandClaude Opus 4.8 39bf7ea11c feat: Import-UX runder + PDF-Seiten als Bild
- Bank-Vorlagen und eigene Vorlagen in EINEM Dropdown (optgroups, typ-getaggte
  Werte preset:/tpl:)
- Speichern überschreibt bei gleichem Namen (Rückfrage); geladene Vorlage belegt
  den Namen vor
- Spaltenvorschau wird automatisch erzeugt (kein „Datei einlesen"-Klick mehr)
- Gegen-IBAN in „Weitere Spalten (optional)" verschoben + erklärt; Grundzuordnung
  zeigt nur Datum/Betrag/Empfänger/Zweck
- Beleg-Modus zeigt die hochgeladenen PDF-Seiten als Bild + extrahierten Text

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-20 17:22:00 +02:00
GuidoandClaude Opus 4.8 1d5b23c127 feat: Excel-artige DataTable (Spaltenbreite/Sortieren/Filtern) für alle Tabellen
- Portierte DataTable-Komponente (aus Vorrania): Spalten per Drag breiter ziehen
  und verschieben, Klick-Sortierung, Filterzeile je Spalte, Spalten ein-/ausblenden;
  Breiten/Reihenfolge/Filter pro Tabelle im Browser gemerkt (localStorage)
- Zu langer Zellinhalt wird mit „…" abgeschnitten (Titel bleibt sichtbar, Excel-artig)
- Umgestellt: Buchungen, Import-Prüfansicht (inkl. interaktiver Zellen), Import-
  Verlauf, Benutzer
- Neue Skeleton-Komponente für den Ladezustand

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-19 22:58:01 +02:00
GuidoandClaude Opus 4.8 37f64999cd feat: Schlagwörter je Kategorie + auf-/zuklappbares Kategorie-Dropdown
- Manuelle Schlagwörter je Kategorie (Popup mit Chips, Doppelklick zum Bearbeiten)
- Treffer über Empfänger ODER Verwendungszweck; längstes Schlagwort gewinnt;
  Kind-Filter (Ausgabe/Einnahme); wirken nur bei künftigen Importen
- Lernende Korrektur-Erkennung: ab 5 Anwendungen und >= 1/3 Korrekturen
  erscheint eine Prüf-Meldung in den Einstellungen (Behalten/Entfernen)
- Neue CategorySelect-Komponente (Baum + Suche, per Portal) ersetzt die
  nativen optgroup-Selects in Buchungen und Import-Prüfansicht
- Migration 0006 (source/applied_count/overridden_count/confirmed, match_field any)
- Endpunkte, i18n DE/EN, Tests (test_keywords: 7 neu, gesamt 27 grün)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-19 21:31:29 +02:00
GuidoandClaude Opus 4.8 f375fc5eaa feat: Backup/Export + Import-UX klarer + Raiffeisen-Preset-Fix
Backup & Export:
- routers/backup: /backup/db (Admin, konsistentes SQLite-Online-Backup),
  /export/transactions.csv|json und /export/all.json (owner-gescoped).
- Einstellungen: Bereich „Backup & Export" mit Download-Buttons. docs/BACKUP.md
  (Wiederherstellung + LXC-Sicherung). pytest für Export + Admin-Schutz.

Import-Verbesserungen (Nutzer-Feedback zum Ablauf):
- Klarer Hinweis, dass die Zuordnungstabelle nur Beispielzeilen zeigt und
  „Vorschau erstellen" die vollständige Prüfliste + Buchen-Button erzeugt.
- Zusammenfassung (erkannt/gebucht) und Warnung, wenn keine gültige Zeile erkannt
  wurde (Hinweis auf Format/Bank-Vorlage).
- Fix: Raiffeisen-Preset hat has_header=true (der Export hat eine Kopfzeile).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-19 20:35:02 +02:00
GuidoandClaude Opus 4.8 7461fddb7a feat: Phase 5 – PDF/Bild-Beleg-Import (lokal, Tesseract-OCR)
Backend:
- services/ocr: PDF-Text via PyMuPDF, OCR (Tesseract) für Scans/Bilder,
  heuristischer Parser (Datum + Betrag je Zeile, CH/DE/US-Beträge).
- routers/documents: /documents/preview (Upload -> Text -> Kandidaten ->
  gemeinsame Prüf-/Buchungslogik des CSV-Imports). csv_import refaktoriert:
  detect_rows() von CSV und Beleg gemeinsam genutzt.
- requirements: PyMuPDF, pytesseract, pillow; install.sh installiert tesseract-ocr
  (+ deu). pytest: Heuristik-Parser und PDF-Vorschau.

Frontend:
- Import-Seite: CSV/PDF-Umschalter; PDF-Modus mit Beleg-Auslesen, extrahiertem
  Text zur Kontrolle und Best-Effort-Hinweis; gleiche Prüfansicht + Buchen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-19 20:25:32 +02:00
GuidoandClaude Opus 4.8 ddf4f1f5ed feat: vorgefertigte Import-Presets für Raiffeisen (CH) und Revolut
- services/csv_import: PRESETS-Liste (aus echten Beispiel-Exporten des Nutzers),
  GET /imports/presets.
- Frontend: Preset-Auswahl im Import füllt Format/Spalten automatisch.
Beide Presets per TestClient gegen echte Zeilenformate verifiziert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-19 20:14:39 +02:00
GuidoandClaude Opus 4.8 1381967aae feat: Phase 4 – CSV-Import (Templates, Prüfansicht, Duplikat/Transfer-Erkennung, Undo)
Backend:
- Modelle + Migration 0005: import_templates, import_batches, categorization_rules;
  transactions um import_batch_id + import_hash erweitert.
- services/csv_import: Datei parsen (Trennzeichen, Dezimal-/Datumsformat, Kodierung,
  Header/Skip, Vorzeichen vs. Soll/Haben), Vorschau mit Duplikat-Erkennung (Hash),
  interner-Transfer-Erkennung via IBAN, lernender Auto-Kategorisierung; Buchen mit
  Batch und Undo.
- routers/imports: Templates (CRUD), Roh-Vorschau, Prüf-Vorschau, Buchen, Verlauf,
  Rückgängig. pytest: Parsing, Duplikate, Transfer, Buchen, Undo, Lernen.

Frontend:
- Import-Seite: Konto+Datei, Format/Spaltenzuordnung (mit Roh-Vorschau),
  editierbare Prüfansicht (Kategorie/Typ/Zielkonto, Duplikate markiert),
  Buchen, Import-Verlauf mit Undo; Vorlagen speichern; i18n DE/EN.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-19 20:06:50 +02:00