Phase 13/14 abgeschlossen. Der Mailversand war zuvor KAPUTT: ajax/sendmail.php
war bereits zur Funktionsbibliothek umgebaut, card.php postete aber weiterhin
per JS dagegen.
Mailformular (FormMail)
- card.php nutzt jetzt Dolibarrs Standard-Mailformular (action=presend/send):
Empfaenger (Firma + alle Ansprechpartner), Betreff, Text und Anhang sichtbar
und aenderbar. Gesendet wird ausschliesslich ueber mahnungSendeErinnerungsMail().
- Anhang = unveraenderte Original-Rechnungs-PDF, wird bei Bedarf nacherzeugt.
Eigener Parameter mailinit statt mode=init, weil get_form() bei mode=init die
Anhangsliste selbst leert.
- HTML-Mails: DolEditor im Setup + withfckeditor=-1 im Formular (folgt
FCKEDITOR_ENABLE_MAIL wie Dolibarrs eigene Mailvorlagen).
- Klartext bleibt Klartext: GETPOST('restricthtml') jagt jeden Nicht-HTML-Text
durch dol_nl2br() — mahnungBodyEntkleiden() nimmt nur dieses Artefakt zurueck
und laesst echte Formatierung unangetastet.
- Platzhalter jetzt auch in Dolibarr-Schreibweise (__REF__, __DATE_YMD__,
__AMOUNT_FORMATED__, __DATE_DUE_YMD__, __FRIST_TAGE__ ...), Liste sichtbar im Setup.
- Absender-Adresse und -Name konfigurierbar (MAHNUNG_EMAIL_SENDER[_NAME]).
- Erneuter Versand moeglich (force aus dem Status abgeleitet, nicht aus dem
Request — Doppelversand-Schutz bleibt wirksam).
Versandprotokoll (neue Tabelle llx_mahnung_mailprotokoll)
- Jede versendete Erinnerung wird mit Empfaenger, Kopie, Betreff, Text und
Anhangsnamen festgehalten, einsehbar unter Versandstatus. Historie statt
Spalten am Vorgang, weil erneut gesendet werden kann.
- Lazy-Migration legt die Tabelle an (DB_VERSION 0.4.0), kein Reaktivieren noetig.
Haertung nach Code-Review (21 bestaetigte Funde)
- Anhang liess sich nicht abwaehlen (wurde sofort wieder eingehaengt)
- Upload/Entfernen ohne Rechtepruefung; Temp-Verzeichnis pro Vorgang getrennt
- Teilzahlung zwischen Oeffnen und Senden fuehrt zurueck ins Formular
- Empfaenger: Semikolon-Trenner, keine stillen Verwerfungen, Dubletten, CR/LF
- CSRF: presend + Core-Dateiaktionen (confirm_deletefile, renamefile, sendit,
linkit) token-pflichtig
- Externe Benutzer sehen nur eigene Vorgaenge; Abschreiben verlangt facture.creer
UI
- Mahnstufe nur noch EINE Darstellung (Badge), Farbskala zentral in
lib/mahnung_ui.lib.php statt doppelt gepflegt
- Zahnrad oben rechts in die Einstellungen (nur mit Recht mahnung.setup)
- Original-Rechnung unter Verknuepfte Dokumente mit Vorschau, Groesse in KB
- PDF-Einleitungstext nur noch, wo ueberhaupt ein PDF entsteht
Sprachdateien de_DE/en_US deckungsgleich, 9 tote Keys entfernt.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mahnungen im Status "Erstellt" (noch nicht versandt) werden beim Aufruf
der card.php mit der aktuellen Stufen-Konfiguration neu berechnet.
Ändert sich der Zinssatz-Override in den Einstellungen, wirkt das
sofort auf alle offenen Mahnungen.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
apply_tracking setzt jetzt auch date_versand (heute) und
versandweg (abgeleitet vom Provider) wenn noch leer.
Kein extra Speichern-Klick mehr nötig.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
$upload_dir wird erst nach den Action-Handlern definiert.
scan_belege-Block berechnet den Pfad jetzt selbst.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pdftotext gibt bei Bild-PDFs 0x0C (Form Feed) zurück — trim() entfernt
das nicht. Dadurch wurde der OCR-Fallback nie ausgelöst.
Jetzt trim() mit expliziter Zeichenliste inkl. \x0C.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fichehalfleft entfernt — Stammdaten und Versand-Tabelle
nutzen jetzt die volle Seitenbreite statt nur 55%.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- fichehalfleft Container für korrekte Dolibarr-Rahmen bei Stammdaten + Versand
- Einschreiben-Regex in DB updated: optionale Leerzeichen (OCR-freundlich)
- detectFromText() entfernt Leerzeichen aus erkannten Nummern (OCR-Normalisierung)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wenn pdftotext keinen Text findet, wird ocrmypdf (Tesseract OCR)
auf das PDF angewendet bevor erneut nach Sendungsnummern gesucht wird.
Bei leerem Ergebnis erscheint jetzt eine Hinweismeldung statt
stummem Seiten-Reload.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dolibarr-Standard-Klassen (fichecenter, underbanner, tableforfield)
für konsistentes Card-Layout wie bei Rechnungen/Bestellungen.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
showdocuments() gibt String zurück — fehlte print davor.
Versand & Belege Bereich mit fichecenter/underbanner gerahmt.
Sendebelege-Titel als load_fiche_titre statt h3.
hideifempty=0 damit Sektion immer sichtbar.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Umlaute in allen lang-Dateien korrigiert. Alle hardcodierten deutschen Strings
in 22 PHP-Dateien durch $langs->trans('Key') ersetzt. Neue Schlüssel für
Cron-Meldungen, Dokument-Aktionen, Bonität, Vorschlag-Status, Template-Vars u.a.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bonitaets-Anzeige:
- Hook tabContentViewThirdparty rendert prominente rote Warnbox auf der
Kundenkarte wenn fk_statut=3 + close_code=badcustomer existiert. Zeigt
Anzahl, Gesamtsumme, Datum letzter Abschreibung + Link zur Detail-Liste.
- Hook formObjectOptions zeigt kompakte Warn-Zeile auf ordercard und
invoicecard wenn der Kunde Forderungsausfaelle hat.
- ordercard zum module_parts.hooks.data ergaenzt.
Uneinbringlich-Button:
- Auf Mahnung-Karten der Stufe 3, Status >= ERSTELLT, nicht storniert,
Rechnung noch nicht abandoned.
- Bestaetigungs-Dialog mit Begruendungs-Textfeld (Default-Text setzt
das aktuelle Datum ein).
- Ruft Facture::setCanceled mit CommonInvoice::CLOSECODE_BADDEBT.
- Mahnung wird storniert + Begruendung in note_private festgehalten.
Steuer-Modul kompatibel: EÜR liest nur llx_paiement (keine Zahlung =
keine Einnahme), UStVA filtert fk_statut IN (1,2) — abandoned Rechnungen
werden automatisch korrekt ausgeschlossen. Bei Ist-Versteuerung damit
buchhalterisch sauber, kein manueller Eingriff noetig.
Lang-Keys: 16 neu (de_DE + en_US) fuer Bonitaets-Box + Uneinbringlich-Workflow.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Neuer Button "Belege scannen" im Versand-Block der Mahnungs-Karte:
- Action scan_belege durchlaeuft alle Files in DOL_DATA_ROOT/mahnung/<MAHN-Ref>/
- PDFs werden via pdftotext (CLI, mit Verfuegbarkeits-Check) extrahiert
- txt/html werden direkt eingelesen (HTML mit strip_tags)
- Pro Datei wird MahnungTrackingPattern::detectFromText() angewendet —
matched gegen alle aktiven Patterns nach priority DESC
- Treffer landen in $_SESSION als Vorschlag (file, provider, nr, url, label)
UX:
- Vorschlags-Banner mit gruener Linke ueber dem Beleg-Bereich
- Pro Vorschlag: Datei-Icon, Pattern-Label, Sendungsnummer als <code>,
externer Link zur Sendungsverfolgung, "Uebernehmen"-Button
- "Uebernehmen" (action=apply_tracking) speichert tracking_nr +
tracking_provider an der Mahnung und leert Session
- "Verwerfen" (action=dismiss_tracking) entfernt nur Session-Eintrag
Fallback:
- Wenn pdftotext nicht im Container verfuegbar: Warnmeldung im UI,
txt/html werden trotzdem verarbeitet.
OCR fuer Bilder (PNG/JPG) bewusst noch nicht enthalten — separater Schritt
mit Container-Anpassung (Tesseract) wenn gewuenscht.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>