Der PDF-Export war bisher immer zweiseitig (Vieltrinker-/Wenigtrinker)
mit fester Mindestzeilenzahl, unabhängig von der tatsächlichen
Mitgliederzahl. Umgestellt auf:
- Bis 49 aktive Mitglieder: eine Seite ohne Trennung.
- Ab 50 Mitgliedern: weiterhin zwei Seiten (Vorder-/Rückseite).
- Zeilenhöhe richtet sich nach der Mitgliederzahl (16-40px), statt fest
16px für alle.
- Neue Mandanten-Einstellungen: freie Zeilen für neue Mitglieder an/aus,
Trennmodus bei zwei Seiten (Trinkverhalten oder alphabetisch).
Migration 0015 ergänzt die dafür nötigen tenant_settings-Spalten.
Gegen die Dev-DB verifiziert: 8 Mitglieder -> einseitiges PDF,
53 Mitglieder (temporäre Testdaten) -> zweiseitiges PDF, Einstellungen
inkl. Validierung geprüft.
jahresauswertung.php verband sich bisher mit fest codierten (kaputten)
Zugangsdaten selbst zur Datenbank statt ueber config.php, hatte keine
Zugriffskontrolle und kein CSRF, und verteilte bei jedem Aufruf sofort
einen hart codierten Bonus-Topf (490 Striche a 0,20 Euro) per PHPMailer
(dessen Quelldateien im Repo fehlen) mit AOK-spezifischem Mailtext.
Nach Abstimmung mit dem Kunden als generisches, mandantenfaehiges Feature
neu gebaut statt nur deaktiviert oder rein lesend umgesetzt:
- Admin gibt einen frei waehlbaren Gesamtbetrag ein, das System verteilt
ihn proportional zu den Jahresstrichen auf alle aktiven Mitglieder.
- Standardmaessig aktive Dry-Run-Checkbox zeigt die Verteilung, ohne zu
buchen oder Mails zu verschicken.
- Bestaetigter Lauf bucht ueber dasselbe Zweig-Muster wie ueberall
(Default-Mandant Dual-Write, andere Mandanten ledger_record_payment)
und verschickt personalisierte Mails ueber saas_send_mail(), protokolliert
im outbound_emails-Versandlog.
- Zugriffskontrolle ergaenzt (owner/admin/treasurer + Legacy-Fallback).
- http-smoke.php: jahresauswertung.php jetzt regulaerer Check statt
uebersprungenem unsicherem Aufruf; damit sind keine Seiten mehr
uebersprungen oder als bekannter offener Punkt markiert (26/26 gruen).
Live getestet: Dry-Run mit korrekter proportionaler Verteilung (Summe
ergibt exakt den Gesamtbetrag), Live-Lauf bucht und versendet korrekt,
Testdaten anschliessend vollstaendig entfernt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
mailversenden.php hatte keine Zugriffskontrolle, versendete bei jedem
GET-Request sofort echte Mails und nutzte PHPMailer, dessen Quelldateien
im Repo gar nicht vorhanden waren (nur composer.json/Lizenz) - der Aufruf
waere also ohnehin mit Fatal Error abgebrochen. Zusaetzlich waren SMTP-
Host, Absender, PayPal-Link und FAQ-URL fest auf einen Alt-Kunden (AOK)
codiert.
- Ersetzt PHPMailer durch die bestehende saas_send_mail()-Abstraktion aus
M3 (Transport log/mail je nach APP_MAIL_TRANSPORT) statt eine fehlende
Abhaengigkeit nachzuvendoren.
- Neue Tabelle outbound_emails protokolliert jeden Versandversuch:
Mandant, Mitglied, Vorlage, Betreff, Status, Fehler - das Versandlog.
- Formular hat eine standardmaessig aktive Dry-Run-Checkbox; im Dry-Run
wird nur geloggt, saas_send_mail() nicht aufgerufen.
- Mailtext ist jetzt tenant-generisch (Saldo, optionaler PayPal-Link nur
wenn der Mandant PayPal aktiviert hat, eigener Dashboard-Link) statt
hartcodierter Alt-Kunden-Inhalte.
- Zugriffskontrolle ergaenzt (owner/admin/treasurer + Legacy-Fallback).
- http-smoke.php: mailversenden.php ist jetzt reguel</EOF>
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>
csvupload.php verarbeitete CSV-Zeilen bisher sofort beim Upload, ohne
Vorschau, ohne Zugriffskontrolle (nur CSRF) und schrieb ausschliesslich in
die global unscoped kl_Einzahlungen-Tabelle.
- Neue Tabellen payment_import_batches/payment_import_rows protokollieren
jeden Import: Datei, Pruefsumme, jede Zeile mit Rohwerten, erkanntem
Mitglied, Status und erzeugter Ledger-Zeile.
- Zweistufiger Ablauf: Hochladen zeigt nur eine Vorschau (matched/
duplicate/unmatched/invalid), erst "Import bestaetigen" bucht.
- Zuordnung per paypal_name oder display_name (tenant-scoped), Dubletten-
pruefung gegen bestehende nicht-stornierte Ledger-Zahlungen.
- Buchung folgt dem etablierten Zweig-Muster: Default-Mandant per
Dual-Write nach kl_Einzahlungen plus Spiegelung, alle anderen Mandanten
direkt ueber ledger_record_payment().
- Zugriffskontrolle ergaenzt (owner/admin/treasurer + Legacy-Fallback).
- Live getestet: Treffer, unbekannter Name, ungueltiger Betrag korrekt
klassifiziert; Import bestaetigt mit korrektem Dual-Write; erneuter
Upload derselben Datei erkennt die Zeile korrekt als Dublette.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>