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>
This commit is contained in:
Guido
2026-08-21 06:30:22 +02:00
co-authored by Claude Opus 4.8
parent 01059b2bb2
commit d725f5cf57
5 changed files with 117 additions and 11 deletions
+21 -7
View File
@@ -248,6 +248,12 @@ export default function Import() {
{r.payee || r.purpose || ""}
{r.is_duplicate && <span className="badge" style={{ marginLeft: 6 }}>{t("import.duplicate")}</span>}
{r.is_counterpart && <span className="badge" style={{ marginLeft: 6 }}>{t("import.counterpart")}</span>}
{r.skip_reason === "state" && (
<span className="badge" style={{ marginLeft: 6 }}>{r.state || t("import.skipState")}</span>
)}
{r.skip_reason === "currency" && (
<span className="badge" style={{ marginLeft: 6 }}>{r.row_currency || t("import.skipCurrency")}</span>
)}
</span>
),
},
@@ -484,14 +490,22 @@ export default function Import() {
<summary className="muted small">{t("import.moreColumns")}</summary>
<p className="muted small">{t("import.ibanHint")}</p>
<div className="map-grid">
<label>
<span>{t("import.colIban")}</span>
<select value={config.column_map.counterparty_iban ?? ""} onChange={(e) => setCol("counterparty_iban", e.target.value)}>
<option value="">—</option>
{colOptions.map((c) => <option key={c.i} value={c.i}>{c.label}</option>)}
</select>
</label>
{[
["counterparty_iban", t("import.colIban")],
["fee", t("import.colFee")],
["currency", t("import.colCurrency")],
["state", t("import.colState")],
].map(([field, label]) => (
<label key={field}>
<span>{label}</span>
<select value={config.column_map[field] ?? ""} onChange={(e) => setCol(field, e.target.value)}>
<option value="">—</option>
{colOptions.map((c) => <option key={c.i} value={c.i}>{c.label}</option>)}
</select>
</label>
))}
</div>
<p className="muted small">{t("import.extraColsHint")}</p>
</details>
<div className="field-inline" style={{ marginTop: "var(--sp-3)" }}>