Files
kaffeekasse-saas/docs/m6-import-export-mail.md
T
clemensandClaude Sonnet 5 81dfff51a0 M6: PDF-Export tenant-nativ und TCPDF vollstaendig vendort
exportKaffeeliste.php band config.php direkt ein (keine Bootstrap-Kette)
und hatte ueberhaupt keine Zugriffskontrolle. TCPDF war im Repo nur
teilweise vorhanden (include/-Verzeichnis und Font-Definitionen fehlten
komplett), wodurch der Export bislang immer mit einem Fatal Error abbrach.

- TCPDF/include/ und die 14 PDF-Standard-Fonts (Helvetica, Courier, Times,
  Symbol, ZapfDingbats) aus dem offiziellen TCPDF-6.6.2-Release nachvendort
  (nicht die vollen ~25 MB an Unicode-Fonts, die hier nicht gebraucht
  werden).
- Zugriffskontrolle ergaenzt (owner/admin/treasurer + Legacy-Fallback wie
  bei den anderen Treasurer-Seiten).
- Vieltrinker-/Wenigtrinker-Aufteilung liest jetzt tenant-sicher ueber
  ledger_fetch_participants_by_window_marks() statt Legacy-SQL direkt
  gegen kl_Kaffeeverbrauch; Preis pro Strich kommt aus tenant_settings
  statt kl_config. N+1-Abfragen pro Zeile durch die bereits geladene
  Teilnehmerzusammenfassung ersetzt.
- scripts/http-smoke.php prueft den Export jetzt als regulaeren Check
  (gueltige PDF-Antwort) statt als bekannten offenen Punkt.
- Live getestet: gueltiges zweiseitiges PDF, Namen/Salden im Textstream
  verifiziert, Aufteilung stimmt mit Ledger-Daten ueberein.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 15:23:16 +02:00

109 lines
4.9 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.
# M6 Import, Export und Mail
Stand: 2026-07-15
M6 macht die Admin-/Treasurer-Flows produktionsreif: CSV-Import,
PDF-/Listenexport, Mailversand und Jahresprozesse laufen tenant-sicher
gegen das neue Modell statt gegen Legacy-Tabellen direkt.
## CSV-Import
Umgesetzte Dateien:
```text
database/migrations/0008_saas_payment_imports.sql
app/imports.php
csvupload.php
```
Ziel: Zahlungsimport mit echter Vorschau, Dublettenprüfung und Audit-Trail,
statt sofortiger Verarbeitung ohne Bestätigungsschritt wie im Legacy-Stand.
Umfang:
- Neue Tabellen `payment_import_batches` und `payment_import_rows` (siehe
Kernschema im Umstrukturierungsplan) protokollieren jeden Import: Datei,
Prüfsumme, Zeitpunkt, jede einzelne Zeile mit Rohwerten, erkanntem
Mitglied, Status und nach Bestätigung der erzeugten Ledger-Zeile.
- Zweistufiger Ablauf: Hochladen erzeugt eine Vorschau (`status = previewed`)
ohne jede Buchung; erst der zweite Schritt „Import bestätigen“ committet
die als `matched` erkannten Zeilen (`status = committed`).
- Zeilen werden klassifiziert: `matched` (wird gebucht), `duplicate`
(gleicher Teilnehmer, gleicher Betrag, gleicher Tag existiert bereits als
nicht-stornierte Ledger-Zahlung), `unmatched` (kein Mitglied per
`paypal_name` oder `display_name` gefunden), `invalid` (Betrag oder Datum
nicht parsebar).
- Zuordnungsregel entspricht der Legacy-Logik: Name aus der CSV wird gegen
`paypal_name` oder `display_name` verglichen (case-insensitiv).
- Buchung folgt demselben Zweig-Muster wie die übrige Sammelerfassung: Für
Teilnehmer mit `legacy_mitarbeiter_id` (Default-Mandant) wird zusätzlich
eine `kl_Einzahlungen`-Zeile geschrieben und gespiegelt; alle anderen
Mandanten werden direkt über `ledger_record_payment()` gebucht.
- Zugriffskontrolle ergänzt: Die Seite hatte zuvor gar keine Prüfung außer
CSRF. Jetzt gilt dieselbe Rollen-/Legacy-Fallback-Logik wie bei
`einzahlung.php` (`owner`, `admin`, `treasurer`).
- Upload-Härtung aus M2 (Größen-/Typprüfung, Speicherung außerhalb des
direkt erreichbaren Codes unter `var/uploads`, Löschung nach Verarbeitung)
bleibt erhalten.
Live gegen die Dev-Datenbank getestet: Upload mit drei Testzeilen (Treffer,
unbekannter Name, ungültiger Betrag), Vorschau-Klassifizierung geprüft,
Import bestätigt (Dual-Write und Ledger-Spiegelung korrekt), erneuter Upload
derselben Datei erkennt die bereits importierte Zeile korrekt als Dublette.
Testdaten anschließend entfernt.
## PDF-/Listenexport
Umgesetzte Dateien:
```text
TCPDF/include/ (neu vendort)
TCPDF/fonts/ (nur die 14 PDF-Standard-Fonts, neu vendort)
exportKaffeeliste.php
scripts/http-smoke.php
```
Ziel: Der bestehende zweiseitige Kaffeeliste-Ausdruck (Vieltrinker-/
Wenigtrinker-Seite mit Wasserzeichen) bleibt optisch erhalten, liest aber
tenant-sicher aus dem Ledger statt aus Legacy-Tabellen.
Umfang:
- TCPDF war im Repo nur teilweise vorhanden (`include/`-Verzeichnis und
Font-Definitionen fehlten komplett, siehe M0/M1). Nachvendort wurden nur
`include/` und die 14 PDF-Standard-Fonts (Helvetica, Courier, Times,
Symbol, ZapfDingbats die einzigen tatsächlich genutzten) aus dem
offiziellen TCPDF-6.6.2-Release, nicht die vollen ~25&nbsp;MB an
Unicode-Fonts, die für diesen Export nicht gebraucht werden.
- `exportKaffeeliste.php` hatte zuvor überhaupt keine Zugriffskontrolle
(nicht einmal einen `checkKaffeelisteAdmin`-Aufruf) und band `config.php`
direkt statt der gemeinsamen Bootstrap-Kette ein. Jetzt gilt dieselbe
Rollen-/Legacy-Fallback-Logik wie bei den anderen Treasurer-Seiten.
Zusätzlich nutzt die Seite bewusst keine Ledger-native Fensterprüfung
mit dem alten Legacy-Anker (jüngstes Datum in `kl_Kaffeeverbrauch`)
mehr, sondern durchgängig `ledger_fetch_participants_by_window_marks()`
mit `tenant_settings.sheet_window_days` für alle Mandanten einheitlich,
da es sich um einen reinen Lesereport ohne Schreibpfad handelt (siehe
Cutover-Notiz: keine Notwendigkeit, hier Legacy-Verhalten 1:1 zu
bewahren).
- Guthaben kommt direkt aus der vorab geladenen Teilnehmerzusammenfassung
(`balance_cents`) statt aus zwei separaten Datenbankabfragen pro Zeile
(N+1-Muster im Original).
- Preis pro Strich kommt aus `tenant_settings.mark_price_cents` statt aus
`kl_config`.
- `scripts/http-smoke.php` prüft den PDF-Export jetzt als regulären Check
(gültige PDF-Antwort) statt als bekannten offenen Punkt.
Live getestet: gültiges zweiseitiges PDF (58&nbsp;KB) mit korrektem
`Content-Type: application/pdf`, Namen und Salden im PDF-Textstream
stichprobenartig verifiziert (unkomprimierte Testausgabe), Vieltrinker-/
Wenigtrinker-Aufteilung stimmt mit den Ledger-Daten überein.
## Prüfstatus
- Golden Master: grün mit 104 Assertions.
- M4 Ledger-Migration: grün mit 73 Assertions.
- M4 Ledger-Service: grün mit 115 Assertions.
- HTTP-Smoke: grün mit 24 geprüften Seiten (PDF-Export jetzt regulär statt
bekannter offener Punkt).