Finanzmanager/docs/qif-import.md
fds2610-bot 1e3227ce83 Phase 1: Stammdaten und QIF-Stammdatenimport
Konten, Kontengruppen, Kategorien und Klassen samt Übernahme aus dem
QIF-Export des Lexware FinanzManagers.

Kontenübersicht nach Kontengruppen gebündelt, mit Gruppensummen und
Gesamtsumme; die drei Saldospalten (Online-Saldo, aktueller und erwarteter
Saldo) sind angelegt und werden bis Phase 2 aus dem Anfangssaldo gespeist.

Kategorien sind hierarchisch mit ":" als Trenner. Der vollständige Pfad
steht redundant in der Tabelle, weil jede Anzeige und der gesamte Import
darüber laufen; Umbenennen und Verschieben schreiben den Teilbaum neu. Die
Art (Einnahme/Ausgabe) gilt für den ganzen Ast. Register wie im Original:
Alle, Einnahmen, Ausgaben, Umbuchungskonten.

QifParser liest zustandsbehaftet und sequenziell, wandelt ISO-8859-1 nach
UTF-8 und versteht US-Beträge sowie das Datumsformat aus der Kopfzeile.
QifStammdatenImport ist idempotent und bietet Trockenlauf und Protokoll -
im Dialog unter Verwaltung sowie über scripts/qif-import.php. Am echten
Export geprüft: 17 Klassen, 105 Kategorien, 37 Konten.

Enthält außerdem die Korrektur der englischen Monatsnamen im
Einstellungsdialog: date('F') ist sprachlich nicht umschaltbar, deshalb
liegen die Namen jetzt zentral als View::MONATE vor. Die Änderung ließ
sich nicht als eigener Commit trennen, weil sie dieselben Dateien berührt
wie Phase 1.

Tests: 227 PHP-Prüfungen und 14 Playwright-Tests, alle grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 21:33:40 +02:00

102 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# QIF-Import
Der Lexware FinanzManager exportiert erweitertes Quicken-QIF. Die `.QDF`-Datei ist
verschlüsselt und damit keine Migrationsquelle – der QIF-Export ist der einzige Weg.
Stand: Klassen, Kategorien und Konten werden übernommen (Phase 1). Buchungen, Splits,
Umbuchungen und Wertpapierbuchungen folgen in Phase 2 und 6.
## Aufbau der Datei
```
!Option:MDY Datumsformat für die gesamte Datei
!Type:Class Klassen
!Type:Cat Kategorien
!Option:AutoSwitch Beginn der Kontenliste
!Account ein Konto je Eintrag
!Clear:AutoSwitch Ende der Kontenliste
!Account / !Type:… ab hier abwechselnd Konto und dessen Buchungen
```
Ein Eintrag endet mit `^`. Jede Zeile beginnt mit einem Feldbuchstaben, der Rest ist der
Wert. Felder dürfen mehrfach auftreten (Splitzeilen, Adresszeilen), deshalb hält
`QifParser` jeden Eintrag als Liste von Paaren und bietet `feld()`, `felder()` und
`hatFeld()`.
**Die Datei ist zustandsbehaftet.** Der Kontobezug einer Buchung steckt allein darin,
welcher `!Account`-Abschnitt zuletzt kam – nach Sektionstypen gruppiert gelesen wäre er
verloren. Der Parser liefert daher eine flache Liste in Dateireihenfolge, jeder Eintrag mit
Sektionstyp und aktuellem Konto.
Jeder Kontoeintrag setzt zugleich das aktuelle Konto. In der Kontenliste folgen mehrere
aufeinander, ohne dass Buchungen dazwischenstehen; das schadet nicht und deckt zugleich die
zweite Schreibweise ab, bei der ein einzelner `!Account` den Kontowechsel bedeutet.
## Felder der Stammdaten
| Sektion | Feld | Bedeutung |
|---|---|---|
| `!Type:Class` | `N` / `D` | Name, Beschreibung |
| `!Type:Cat` | `N` | vollständiger Pfad mit `:` |
| | `D` | Beschreibung |
| | `I` / `E` | Einnahme bzw. Ausgabe (Marker ohne Wert) |
| | `T` | steuerrelevant (Marker ohne Wert) |
| | `R` | Kennziffer des Steuerformulars |
| `!Account` | `N` / `T` | Name, Kontotyp (siehe `docs/stammdaten.md`) |
| | `D` | Beschreibung; `Kontonr. 12345` wird als Kontonummer übernommen |
| | `L` | Kreditlimit im US-Format |
## Fallstricke
1. **Zeichensatz ISO-8859-1, Zeilenenden CRLF.** `QifParser::nachUtf8()` prüft erst, ob
schon UTF-8 vorliegt – eine zweite Konvertierung zerstörte die Umlaute.
2. **Beträge im US-Format**: `-1,241.04`. Das Komma ist Tausendertrenner.
3. **Datum laut Kopfzeile**, meist `MDY` mit zweistelligem Jahr: `D3.18.26` ist der
18.03.2026. Jahreszahlen ab 70 gelten als 19xx.
4. **Kategorie und Klasse in einer Zeile**: `L400 - Leben:B-Essen alleine/Privat`.
5. **Unterkategorien ohne genannte Elternkategorie.** Der Import legt fehlende
Zwischenstufen selbst an (`Kategorie::findenOderAnlegenNachPfad()`).
6. **Konten stehen zweimal in der Datei** – einmal in der Kontenliste, einmal als Kopf
ihrer Buchungen. Der zweite Treffer ist keine Dublette.
7. **Umbuchungen erscheinen doppelt**, einmal je beteiligtem Konto, und müssen in Phase 2
zu einer Buchung zusammengeführt werden.
8. **Anfangssalden fehlen im Export** und werden je Konto nachgetragen.
## Arbeitsweise des Importeurs
`QifStammdatenImport` ist **idempotent**: Was es schon gibt, wird gezählt und übersprungen,
nie doppelt angelegt. Ein zweiter Lauf derselben Datei ändert nichts.
Der echte Lauf liegt in einer Transaktion – ein Abbruch mitten in der Kategorieliste
hinterließe sonst einen halben Baum. Der **Trockenlauf** schreibt gar nicht, sondern zählt
mit einer Menge bereits bekannter Pfade mit; auch die Zwischenstufen, die der Import selbst
anlegen würde, erscheinen dort in der Vorschau.
## Bedienung
Im Dialog unter *Verwaltung → QIF-Import*: Datei hochladen, Trockenlauf, dann übernehmen.
Hochgeladene Dateien bleiben im Importverzeichnis (`data/import`), damit derselbe Export
erst geprüft und dann übernommen werden kann.
Auf der Kommandozeile:
```bash
docker compose exec -u www-data php php scripts/qif-import.php data/import/Export.QIF
docker compose exec -u www-data php php scripts/qif-import.php --uebernehmen data/import/Export.QIF
```
Ohne `--uebernehmen` läuft nur der Trockenlauf. `--benutzer=NAME` wählt den Mandanten,
sonst gilt der erste aktive Benutzer.
## Prüfung gegen den echten Export
Der Trockenlauf gegen `Export-Migration-Beispiel.QIF` liefert die Zahlen der Voranalyse:
```
Datei enthält Class: 17 · Cat: 105 · Account: 73 · Bank: 572 · Cash: 61 ·
Oth T: 31 · Oth A: 154 · Invst: 16 · Memorized: 579
Klassen 17 neu
Kategorien 105 neu
Konten 37 neu, 36 vorhanden (die Zweitnennung je Konto)
```