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>
50 lines
3 KiB
SQL
50 lines
3 KiB
SQL
-- Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
|
|
--
|
|
-- This program is free software: you can redistribute it and/or modify
|
|
-- it under the terms of the GNU General Public License as published by
|
|
-- the Free Software Foundation, either version 3 of the License, or
|
|
-- (at your option) any later version.
|
|
|
|
-- Mahnstufen-Konfiguration (frei konfigurierbar, Basis BGB §288)
|
|
-- Stufe 0 = kostenlose Zahlungserinnerung (ist_erinnerung = 1)
|
|
|
|
CREATE TABLE llx_mahnung_stufe (
|
|
rowid INTEGER AUTO_INCREMENT PRIMARY KEY,
|
|
entity INTEGER DEFAULT 1 NOT NULL,
|
|
stufe TINYINT NOT NULL,
|
|
label VARCHAR(60) NOT NULL,
|
|
frist_tage INTEGER DEFAULT 0 NOT NULL,
|
|
neue_frist_tage INTEGER DEFAULT 7 NOT NULL,
|
|
mahngebuehr_b2c DOUBLE(10,2) DEFAULT 0,
|
|
mahngebuehr_b2b DOUBLE(10,2) DEFAULT 0,
|
|
pauschale_b2b_einmalig TINYINT DEFAULT 0,
|
|
-- DECIMAL(6,3): der B2B-Satz (Basiszins + 9 %) liegt ueber 9,9999 und passte
|
|
-- nicht mehr in das alte DECIMAL(5,4).
|
|
zinssatz_b2c_uebersteuern DECIMAL(6,3),
|
|
zinssatz_b2b_uebersteuern DECIMAL(6,3),
|
|
versandart_default VARCHAR(20) DEFAULT 'pdf',
|
|
email_subject VARCHAR(255),
|
|
email_body TEXT,
|
|
pdf_intro TEXT,
|
|
-- 1 = kostenlose Zahlungserinnerung: keine Mahngebuehr, keine Pauschale,
|
|
-- keine Verzugszinsen, Anhang ist die Original-Rechnungs-PDF.
|
|
-- Massgeblich ist dieses Flag, NICHT die Stufennummer.
|
|
ist_erinnerung TINYINT DEFAULT 0 NOT NULL,
|
|
active TINYINT DEFAULT 1 NOT NULL,
|
|
datec DATETIME,
|
|
tms TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB;
|
|
|
|
-- Default-Stufen (idempotent: INSERT IGNORE wegen UNIQUE entity+stufe)
|
|
-- Die Labels muessen eindeutig sein: 'Zahlungserinnerung' ist ausschliesslich der
|
|
-- kostenlosen Stufe 0 vorbehalten, damit im Vorschlag/Sammelbrief/PDF sofort klar
|
|
-- ist, ob eine kostenlose Erinnerung oder eine kostenpflichtige Mahnung gemeint ist.
|
|
INSERT IGNORE INTO llx_mahnung_stufe (entity, stufe, label, frist_tage, neue_frist_tage, mahngebuehr_b2c, mahngebuehr_b2b, pauschale_b2b_einmalig, versandart_default, datec) VALUES
|
|
(1, 1, '1. Mahnung', 7, 14, 0.00, 0.00, 1, 'pdf', NOW()),
|
|
(1, 2, '2. Mahnung', 14, 10, 5.00, 5.00, 0, 'pdf', NOW()),
|
|
(1, 3, 'Letzte Mahnung', 10, 7, 10.00, 10.00, 0, 'pdf', NOW());
|
|
|
|
-- Stufe 0: kostenlose Zahlungserinnerung vor der ersten echten Mahnstufe.
|
|
-- frist_tage = 0 -> sofort ab Faelligkeit, Versand per E-Mail mit Original-Rechnung.
|
|
INSERT IGNORE INTO llx_mahnung_stufe (entity, stufe, label, frist_tage, neue_frist_tage, mahngebuehr_b2c, mahngebuehr_b2b, pauschale_b2b_einmalig, zinssatz_b2c_uebersteuern, zinssatz_b2b_uebersteuern, versandart_default, ist_erinnerung, active, datec) VALUES
|
|
(1, 0, 'Zahlungserinnerung', 0, 7, 0.00, 0.00, 0, 0.000, 0.000, 'mail', 1, 1, NOW());
|