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>
111 lines
4 KiB
PHP
111 lines
4 KiB
PHP
<?php
|
|
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
|
|
*
|
|
* GPL v3 (siehe COPYING).
|
|
*/
|
|
|
|
/**
|
|
* \file htdocs/custom/mahnung/lib/mahnung_ui.lib.php
|
|
* \ingroup mahnung
|
|
* \brief Gemeinsame Anzeige-Bausteine des Moduls.
|
|
*
|
|
* Hier liegt die EINE Darstellung einer Mahnstufe. Vorher gab es sie
|
|
* dreimal — auf der Mahnungskarte, in der Vorschlagsliste und im Widget
|
|
* — jeweils mit eigener Farbskala. Dadurch stand die Stufe an zwei
|
|
* Stellen doppelt da (farbiger Badge UND derselbe Text daneben), und die
|
|
* Farben wären beim nächsten Eingriff auseinandergelaufen.
|
|
*/
|
|
|
|
|
|
/**
|
|
* Zahnrad-Link in die Modul-Einstellungen — für den Kopf einer Modulseite.
|
|
*
|
|
* Gedacht für den Parameter $morehtmlright von load_fiche_titre(), damit das Icon
|
|
* rechts neben dem Seitentitel steht (Dolibarr-Konvention).
|
|
*
|
|
* Sichtbar nur mit dem Recht mahnung.setup oder für Administratoren. Wer die
|
|
* Einstellungen ohnehin nicht öffnen darf, bekommt kein Icon zu sehen, das ihn in
|
|
* eine "Zugriff verweigert"-Meldung laufen lässt.
|
|
*
|
|
* @return string HTML ('' = kein Recht)
|
|
*/
|
|
function mahnungSetupLink()
|
|
{
|
|
global $langs, $user;
|
|
|
|
if (!$user->hasRight('mahnung', 'setup') && empty($user->admin)) {
|
|
return '';
|
|
}
|
|
|
|
return '<a class="butActionNew" href="'.DOL_URL_ROOT.'/custom/mahnung/admin/setup.php"'
|
|
.' title="'.dol_escape_htmltag($langs->trans('MahnungSetupOeffnen')).'">'
|
|
.img_picto($langs->trans('MahnungSetupOeffnen'), 'setup', 'class="pictofixedwidth"')
|
|
.'</a>';
|
|
}
|
|
|
|
/**
|
|
* Farbe einer Mahnstufe.
|
|
*
|
|
* Maßgeblich ist das Flag ist_erinnerung der Stufe, NICHT die Stufennummer: eine
|
|
* kostenlose Zahlungserinnerung ist keine Eskalationsstufe und bleibt deshalb
|
|
* neutral grau. Stufennummern oberhalb der Standardskala sind frei konfigurierte
|
|
* Eskalationen und werden dunkelrot — sonst sähen sie harmloser aus als Stufe 3.
|
|
*
|
|
* @param int $stufe Stufennummer
|
|
* @param bool $istErinnerung true = kostenlose Zahlungserinnerung
|
|
* @return string CSS-Farbwert
|
|
*/
|
|
function mahnungStufeFarbe($stufe, $istErinnerung)
|
|
{
|
|
if ($istErinnerung) {
|
|
return '#7a7a7a';
|
|
}
|
|
|
|
// Eintrag für 0 ist nötig, weil die Stufennummer 0 auch eine echte
|
|
// (kostenpflichtige) Mahnstufe sein kann — die kostenlose Erinnerung hängt am
|
|
// Flag, nicht an der Nummer, und ist oben schon abgehandelt. Gedecktes
|
|
// Blaugrau = mildeste Eskalation; bewusst nicht heller als Stufe 1, sonst
|
|
// leidet der Kontrast zur weißen Badge-Schrift.
|
|
$colors = array(0 => '#5b7fa6', 1 => '#4a90d9', 2 => '#e68a00', 3 => '#cc3333');
|
|
if (isset($colors[(int) $stufe])) {
|
|
return $colors[(int) $stufe];
|
|
}
|
|
return ((int) $stufe > 3) ? '#a32020' : '#666';
|
|
}
|
|
|
|
/**
|
|
* Badge einer Mahnstufe — Nummer und Bezeichnung in EINEM Element.
|
|
*
|
|
* Bewusst keine zweite Textausgabe daneben: die Bezeichnung der Stufe ist frei
|
|
* konfigurierbar und heißt in der Praxis "Zahlungserinnerung", "1. Mahnung" usw.
|
|
* Ein zusätzliches Typ-Etikett würde damit nur dasselbe Wort wiederholen. Welcher
|
|
* Art die Stufe ist, transportieren Farbe und Tooltip.
|
|
*
|
|
* @param int $stufe Stufennummer
|
|
* @param string $label Bezeichnung der Stufe ('' = nur Nummer)
|
|
* @param bool $istErinnerung true = kostenlose Zahlungserinnerung
|
|
* @param string $tooltip Zusatztext für das title-Attribut ('' = Standard)
|
|
* @return string HTML
|
|
*/
|
|
function mahnungStufeBadge($stufe, $label, $istErinnerung, $tooltip = '')
|
|
{
|
|
global $langs;
|
|
|
|
$stufe = (int) $stufe;
|
|
$label = trim((string) $label);
|
|
|
|
if ($tooltip === '') {
|
|
$tooltip = $istErinnerung
|
|
? $langs->transnoentities('MahnungErinnerungKostenfrei')
|
|
: $langs->transnoentities('MahnungVorschlagBadgeMahnungHelp');
|
|
}
|
|
|
|
$text = (string) $stufe;
|
|
if ($label !== '') {
|
|
$text .= ' — '.$label;
|
|
}
|
|
|
|
$out = '<span class="badge" style="background-color:'.mahnungStufeFarbe($stufe, $istErinnerung).';color:#fff;"';
|
|
$out .= ' title="'.dol_escape_htmltag($tooltip).'">'.dol_escape_htmltag($text).'</span>';
|
|
return $out;
|
|
}
|