feat(sprint10): Phase 4+5 — Frontend import wizard + integration testing
Phase 4 — Frontend Import Wizard:
- bank-import.ts service: types (BankImportSession, BankTransaction,
CsvColumnMapping, ImportSessionStatus, MatchStatus) + 12 React Query hooks
(sessions, transactions, mappings, upload/confirm/skip/assign/complete)
- /finance/import page: 4-step wizard (Upload -> Map -> Review -> Confirm)
* Drag-and-drop upload with bank format auto-detect (MT940/CAMT.053/CSV)
* CSV column mapping editor (saves as reusable mapping)
* Review table with color-coded MATCHED/SUGGESTED/UNMATCHED/CONFIRMED rows,
confidence % badges, member-assign Combobox, skip/confirm/bulk-confirm
* Completion summary + import history table with resume action
- de.json + en.json: full bankImport.* namespace (steps, upload, map, review,
complete, history, status, sessionStatus, actions, errors)
- Navigation: Finanzen converted to nested submenu (Uebersicht + Import)
Phase 5 — Integration Testing:
- docker compose down -v + up -d --build (clean rebuild)
- Playwright e2e/sprint10-system-test.spec.ts: verifies /finance/import
unauthenticated -> /login?callbackUrl=%2Ffinance%2Fimport (PASS)
- Backend health + frontend route registration verified
Bugfix bundled (blocked backend startup):
- PaymentRepository: countOverdueByClubId* queries referenced non-existent
Payment.dueDate column (regression from Sprint 9 Phase 6, commit 57f418f).
Switched to Payment.periodTo (the implicit due date for billing periods).
This commit is contained in:
@@ -958,6 +958,108 @@
|
||||
"noPayments": "Noch keine Zahlungen vorhanden"
|
||||
}
|
||||
},
|
||||
"bankImport": {
|
||||
"title": "Kontoauszug-Import",
|
||||
"subtitle": "Bankauszüge hochladen und automatisch Mitgliedsbeiträgen zuordnen",
|
||||
"default": "Standard",
|
||||
"steps": {
|
||||
"upload": "Hochladen",
|
||||
"map": "Spalten zuordnen",
|
||||
"review": "Treffer prüfen",
|
||||
"complete": "Abschließen"
|
||||
},
|
||||
"upload": {
|
||||
"title": "Kontoauszug hochladen",
|
||||
"help": "Unterstützte Formate: MT940 (.sta, .mt940, .txt), CAMT.053 (.xml), CSV (.csv). Maximale Dateigröße: 10 MB.",
|
||||
"dropzone": "Datei hierher ziehen oder klicken zum Auswählen",
|
||||
"formats": "MT940 • CAMT.053 • CSV",
|
||||
"useMapping": "Gespeicherte CSV-Vorlage verwenden",
|
||||
"autoDetect": "Automatisch erkennen"
|
||||
},
|
||||
"map": {
|
||||
"title": "CSV-Spalten zuordnen",
|
||||
"help": "Geben Sie an, welche Spalte welche Information enthält (0-basiert). Vorlage kann für künftige Imports gespeichert werden.",
|
||||
"templateName": "Vorlagenname",
|
||||
"templateNamePlaceholder": "z.B. Sparkasse Köln Export",
|
||||
"dateColumn": "Datums-Spalte",
|
||||
"amountColumn": "Betrags-Spalte",
|
||||
"referenceColumn": "Verwendungszweck-Spalte",
|
||||
"counterpartyColumn": "Empfänger-Spalte",
|
||||
"delimiter": "Trennzeichen",
|
||||
"dateFormat": "Datumsformat",
|
||||
"saveAsDefault": "Als Standard-Vorlage speichern"
|
||||
},
|
||||
"review": {
|
||||
"title": "Treffer prüfen",
|
||||
"transactions": "Transaktionen",
|
||||
"resumed": "Fortgesetzt",
|
||||
"progress": "Bearbeitungsfortschritt",
|
||||
"sortByConfidence": "Sortieren: Konfidenz",
|
||||
"sortByAmount": "Sortieren: Betrag",
|
||||
"sortByDate": "Sortieren: Datum",
|
||||
"autoMatchedReady": "automatische Treffer bereit zur Bestätigung",
|
||||
"date": "Datum",
|
||||
"counterparty": "Empfänger",
|
||||
"reference": "Verwendungszweck",
|
||||
"amount": "Betrag",
|
||||
"matchStatus": "Status",
|
||||
"actions": "Aktionen",
|
||||
"searchMembers": "Mitglied suchen…",
|
||||
"noMembersFound": "Keine Mitglieder gefunden",
|
||||
"noTransactions": "Keine Transaktionen vorhanden",
|
||||
"expenseSkipReason": "Ausgabe — kein Mitgliedsbeitrag"
|
||||
},
|
||||
"complete": {
|
||||
"title": "Import abschließen",
|
||||
"help": "Nach Versiegeln können keine Änderungen mehr vorgenommen werden (GoBD §147 AO).",
|
||||
"totalTransactions": "Gesamt",
|
||||
"confirmed": "Bestätigt",
|
||||
"skipped": "Übersprungen",
|
||||
"remaining": "Verbleibend",
|
||||
"warning": "Verbleibende Transaktionen werden automatisch als übersprungen markiert.",
|
||||
"sealedMessage": "Sitzung wurde versiegelt. Buchungen sind unveränderlich."
|
||||
},
|
||||
"history": {
|
||||
"title": "Import-Historie",
|
||||
"date": "Datum",
|
||||
"file": "Datei",
|
||||
"format": "Format",
|
||||
"status": "Status",
|
||||
"transactions": "Bestätigt",
|
||||
"actions": "Aktionen"
|
||||
},
|
||||
"status": {
|
||||
"MATCHED": "Übereinstimmung",
|
||||
"SUGGESTED": "Vorschlag",
|
||||
"UNMATCHED": "Kein Treffer",
|
||||
"CONFIRMED": "Bestätigt",
|
||||
"SKIPPED": "Übersprungen"
|
||||
},
|
||||
"sessionStatus": {
|
||||
"PENDING": "Ausstehend",
|
||||
"IN_REVIEW": "In Prüfung",
|
||||
"COMPLETED": "Abgeschlossen",
|
||||
"FAILED": "Fehlgeschlagen",
|
||||
"CANCELLED": "Abgebrochen"
|
||||
},
|
||||
"actions": {
|
||||
"remove": "Entfernen",
|
||||
"uploadAndParse": "Hochladen & analysieren",
|
||||
"saveAndContinue": "Speichern & weiter",
|
||||
"skip": "Überspringen",
|
||||
"skipExpense": "Als Ausgabe überspringen",
|
||||
"confirm": "Bestätigen",
|
||||
"confirmAll": "Alle bestätigen",
|
||||
"assignMember": "Mitglied zuweisen",
|
||||
"proceedToComplete": "Weiter zum Abschluss",
|
||||
"sealSession": "Sitzung versiegeln",
|
||||
"newImport": "Neuer Import",
|
||||
"resume": "Fortsetzen"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "Upload fehlgeschlagen. Bitte erneut versuchen."
|
||||
}
|
||||
},
|
||||
"documents": {
|
||||
"title": "Dokumentenarchiv",
|
||||
"description": "Vereinsdokumente verwalten und archivieren",
|
||||
|
||||
Reference in New Issue
Block a user