Dolibarr Modul: Mahnwesen (3-stufig nach BGB §288)
Find a file
Eduard Wisch 98f3f1a04b
All checks were successful
Deploy mahnung / deploy (push) Successful in 13s
Übernehmen setzt Versanddatum + Versandweg automatisch [deploy]
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>
2026-05-13 17:03:21 +02:00
.forgejo/workflows Pipeline-Fix: Commit-Message als ENV-Variable durchreichen statt String-Interpolation [deploy] 2026-05-11 12:28:30 +02:00
admin i18n: Alle Texte über $langs->trans() — ~100 neue Sprachschlüssel de_DE + en_US [deploy] 2026-05-13 16:25:50 +02:00
ajax i18n: Alle Texte über $langs->trans() — ~100 neue Sprachschlüssel de_DE + en_US [deploy] 2026-05-13 16:25:50 +02:00
class Fix: Tabellen-Layout fichehalfleft + Einschreiben-Pattern für OCR [deploy] 2026-05-13 16:45:56 +02:00
core i18n: Alle Texte über $langs->trans() — ~100 neue Sprachschlüssel de_DE + en_US [deploy] 2026-05-13 16:25:50 +02:00
langs OCR für Bild-PDFs beim Belege-Scannen + Feedback-Meldung [deploy] 2026-05-13 16:40:33 +02:00
sql Konfigurierbare Tracking-Patterns mit Live-Vorschau [deploy] 2026-05-11 12:04:42 +02:00
card.php Übernehmen setzt Versanddatum + Versandweg automatisch [deploy] 2026-05-13 17:03:21 +02:00
CHANGELOG.md Bonitaets-Workflow: Warnbox Kundenkarte + Uneinbringlich-Button Stufe 3 [deploy] 2026-05-11 13:17:44 +02:00
CLAUDE.md Docs: README + CLAUDE.md auf Stand nach Phasen 1-6 bringen 2026-05-11 13:28:36 +02:00
list.php i18n: Alle Texte über $langs->trans() — ~100 neue Sprachschlüssel de_DE + en_US [deploy] 2026-05-13 16:25:50 +02:00
README.md Docs: README + CLAUDE.md auf Stand nach Phasen 1-6 bringen 2026-05-11 13:28:36 +02:00

Modul Mahnung — 3-stufiges Mahnwesen für Dolibarr

Mahnwesen-Modul für Dolibarr ERP: tägliche Vorschlagsliste überfälliger Rechnungen, 3-stufiger Workflow (Erinnerung → Mahnung → Letzte Mahnung), Mahngebühren + tagesgenaue Verzugszinsen nach BGB §288, PDF- und ODT-Mahnschreiben, E-Mail-Versand, Sammelbrief, Trigger auf Zahlungseingang.

Status

Version 0.2.0 + Phasen 1-6 (Unreleased) — UX-Vorschlagsliste, Versand-Erfassung, Sendebeleg-Upload, konfigurierbare Tracking-Patterns mit Live-Vorschau, Beleg-Scan via pdftotext, Versand-Reminder, Bonitäts-Workflow + Uneinbringlich-Klassifikation.

Features

Feature Implementierung
Tägliche Vorschlagsliste überfälliger Rechnungen Cron MahnungCronBuildVorschlag
Push-Benachrichtigung mit Anzahl je Stufe Ntfy + GlobalNotify
3 Stufen pflegbar (Frist, neue Frist, Gebühr B2C/B2B, Versandart, E-Mail-Template, PDF-Intro) admin/setup.php
B2C / B2B-Erkennung über llx_societe.tva_intra
Verzugszinsen tagesgenau, B2C: Basiszins +5 %, B2B: +9 %; Override pro Stufe möglich
§288 Abs. 5 Pauschale 40 € nur bei B2B, einmalig pro Rechnung
PDF-Mahnschreiben (DIN 5008) Standard-TCPDF-Generator pdf_standard_mahnung
ODT-Mahnschreiben (je Stufe) ODT-Template-Generator doc_generic_mahnung_odt mit Stufen-Auswahl
Dokumentenmodell-Verwaltung Setup-Seite: Modelle aktivieren, Default wählen, ODT-Templates hochladen
Template-Variablen-Referenz admin/templatevars.php — alle verfügbaren ODT-Variablen
Dokumentenliste auf Mahnungs-Karte Vorschau (Lupe), Download, Modellauswahl
Bulk-Erstellung + Sammelbrief TCPDI-basiert
E-Mail-Versand mit PDF-Anhang CMailFile, Subject/Body mit Platzhaltern
Auto-Erledigung bei Zahlungseingang Trigger BILL_PAYED + PAYMENT_CUSTOMER_CREATE
Tab "Mahnungen (n)" auf Rechnungs- + Kundenkarte Hook completeTabsHead (filtert auf add/external)
Widget: Offene Rechnungen mit Mahnstufe box_mahnung_offen
Vorschlagsliste-Filter (Mahnstufe, Tage Verzug, Mindestbetrag, Kundentyp B2B/B2C, Kunden-Select2 mit Ajax) list.php — Kundentyp-Wechsel filtert das Kunden-Dropdown sofort per Auto-Submit
Kontakt-Spalte in Vorschlagsliste (Telefon-/Mail-Icons mit Direktlink) tel:/mailto: aus llx_societe.phone/email
Versand-Erfassung pro Mahnung (Datum, Versandweg, Sendungsnummer, Tracking-Provider) card.php Versand-Block; setzt automatisch Status auf VERSENDET
Tracking-Deep-Links für DHL, DPAG, DPD, Hermes, UPS konfigurierbar via Tracking-Pattern-Tabelle
Sendebeleg-Upload pro Mahnung Dolibarrs formfile->showdocuments('mahnung', ...)DOL_DATA_ROOT/mahnung/<MAHN-Ref>/
Konfigurierbare Tracking-Patterns (Regex + URL-Template, Priorität, Aktivierung) admin/tracking_patterns.php CRUD + Live-Vorschau
Live-Regex-Vorschau (Treffer + URL-Preview während Eingabe) ajax/regex_preview.php (debounced 300ms, ReDoS-Schutz)
Beleg-Scan (pdftotext + Pattern-Matching → Sendungsnummer-Vorschlag) Button "Belege scannen" auf card.php
Versand-Reminder (Mahnung > N Tage unversendet → Ntfy-Push) Cron MahnungCronVersandReminder, Schwellenwert via MAHNUNG_VERSAND_REMINDER_DAYS
Bonitäts-Box auf Kundenkarte (Anzahl + Summe + letztes Datum der badcustomer abandoned Rechnungen) Hook tabContentViewThirdparty
Bonitäts-Warning bei Auftrag-/Rechnungs-Karte Hook formObjectOptions (invoicecard + ordercard)
"Als uneinbringlich klassifizieren"-Button auf Mahnung Stufe 3 Bestätigungs-Dialog mit Begründung → Facture::setCanceled($user, CommonInvoice::CLOSECODE_BADDEBT, $note)

Voraussetzungen

  • Dolibarr ≥ 19
  • PHP ≥ 7.4
  • TCPDF (Dolibarr-Standard) für PDF
  • Optional: ODTPHP (Dolibarr-Standard) für ODT-Templates
  • Optional: TCPDI (Dolibarr includes/tcpdf/tcpdi.php) für Sammelbrief-Konkatenation
  • Optional: GlobalNotify für In-App-Notification-Badges
  • Empfohlen: BankImport (automatischer Zahlungseingang via FinTS triggert die Mahnungs-Erledigung sauber)

Installation

git clone https://git.data-it-solution.de/data/mahnung.git \
  /pfad/zu/dolibarr/htdocs/custom/mahnung

Dann Startseite → Setup → Module → Finanzwesen → Mahnung aktivieren.

Bei Aktivierung werden llx_mahnung_mahnung und llx_mahnung_stufe angelegt; drei Default-Stufen werden idempotent eingefügt. Dokumentenmodelle (standard_mahnung, generic_mahnung_odt) werden in llx_document_model registriert.

Nach Aktivierung in Setup → Mahnwesen Einstellungen:

  1. Basiszins prüfen
  2. Stufen-Texte (PDF-Intro, E-Mail-Body) anpassen
  3. Dokumentenmodell wählen und ggf. ODT-Templates hochladen
  4. Cron-Job MahnungCronBuildVorschlag aktivieren

ODT-Templates

Templates werden unter Setup → Mahnwesen Einstellungen → Dokumentenmodelle hochgeladen.

Dateinamen-Konvention

Dateiname Verwendung
mahnung_stufe1.odt Zahlungserinnerung (Stufe 1)
mahnung_stufe2.odt 1. Mahnung (Stufe 2)
mahnung_stufe3.odt Letzte Mahnung (Stufe 3)
mahnung.odt Fallback für alle Stufen

Verfügbare Template-Variablen (Auswahl)

Variable Beispiel
{mahnung_ref} MAHN2026-0001
{mahnung_stufe} 1
{mahnung_stufe_label} Zahlungserinnerung
{mahnung_date} 10.05.2026
{mahnung_betrag_offen} 131,34
{mahnung_mahngebuehr} 5,00
{mahnung_verzugszinsen} 1,23
{mahnung_summe} 137,57
{mahnung_kundentyp} B2C
{facture_ref} IN2604-0036
{facture_total_ttc} 131,34
{company_name} Kundenname
{mycompany_name} Eigene Firma
{mahnung_bank_iban} DE89...

Vollständige Liste: Setup → Mahnwesen → Verfügbare Template-Variablen

Rechte

Recht Standard Bedeutung
mahnung.read aktiv Mahnungen einsehen
mahnung.write inaktiv Mahnungen erstellen / bearbeiten
mahnung.send inaktiv Mahnungen versenden (E-Mail / Druck)
mahnung.delete inaktiv Mahnungen stornieren
mahnung.setup inaktiv Stufen, Basiszins, Versand konfigurieren

Modul-Konstanten

Name Default Bedeutung
MAHNUNG_BASISZINS 1.27 BGB-Basiszins (%) — halbjährlich pflegen (1.1./1.7.)
MAHNUNG_AUFSCHLAG_B2C 5.0 Verzugszins-Aufschlag B2C (BGB §288 Abs. 1)
MAHNUNG_AUFSCHLAG_B2B 9.0 Verzugszins-Aufschlag B2B (BGB §288 Abs. 2)
MAHNUNG_PAUSCHALE_B2B 40.00 Pauschale B2B (EUR, BGB §288 Abs. 5, einmalig)
MAHNUNG_ADDON_PDF standard_mahnung Standard-Dokumentenmodell
MAHNUNG_ADDON_PDF_ODT_PATH DOL_DATA_ROOT/doctemplates/mahnung ODT-Template-Verzeichnis
MAHNUNG_NTFY_TOPIC vk-builds Ntfy-Topic für Vorschlags-Push
MAHNUNG_VERSAND_REMINDER_DAYS 2 Schwelle (Tage) für Versand-Reminder Ntfy-Push

Datenbank

Tabelle Zweck
llx_mahnung_mahnung Mahnvorgänge — inkl. Versand-Felder date_versand, versandweg, tracking_nr, tracking_provider (idempotente Migration via migrateVersandFelder() beim Setup-Aufruf)
llx_mahnung_stufe Stufen-Konfiguration (Stufe 1/2/3 mit Fristen, Gebühren, Templates)
llx_mahnung_trackingpattern Konfigurierbare Tracking-Regex + URL-Template pro Provider, Default-Seed mit DHL/DPAG/DPD/Hermes/UPS

AJAX-Endpoints

Endpoint Zweck Parameter Auth
ajax/createmahnung.php Bulk-Mahnung-Erzeugung facture_ids[], stufe, token mahnung.write
ajax/sammelbrief.php Sammelbrief-PDF facture_ids[], token mahnung.send
ajax/sendmail.php E-Mail-Versand mahnung_id, token mahnung.send
ajax/regex_preview.php Live-Vorschau für Tracking-Patterns regex, sample, url_template (POST) mahnung.setup oder Admin

Hooks & Trigger

Hook-Klasse: class/actions_mahnung.class.php — registriert für invoicecard, thirdpartycard, ordercard.

Hook Zweck
addMoreActionsButtons "Mahnung erstellen"-Button auf Rechnungs-Karte
completeTabsHead Tab "Mahnungen (n)" — filtert auf mode=add + filterorigmodule=external (sonst doppelter Tab, siehe KB #601)
tabContentViewThirdparty Bonitäts-Warnbox auf Kundenkarte wenn badcustomer abandoned Rechnungen existieren
formObjectOptions Bonitäts-Warning bei Auftrag-/Rechnungs-Karten

Trigger: core/triggers/interface_99_modMahnung_MahnungTriggers.class.php

  • BILL_PAYED + BILL_VALIDATE + PAYMENT_CUSTOMER_CREATE → setzt offene Mahnungen auf STATUS_ERLEDIGT

Cron-Jobs:

  • MahnungCronBuildVorschlag — täglich, Vorschlagsliste aufbauen + Ntfy-Push
  • MahnungCronVersandReminder — täglich, Reminder für unversendete Mahnungen

Workflow

Cron 06:00 (MahnungCronBuildVorschlag)
   |
   |--> ueberfaellige Rechnungen einsammeln
   |--> Stufe ermitteln (Stufe 1 ab frist_tage Verzug,
   |                     Folgestufen nach neue_frist_tage seit Vor-Mahnung)
   |--> Ntfy-Push mit Anzahl je Stufe + Gesamt-EUR
   |--> GlobalNotify "actionRequired" (wenn Modul aktiv)
   |
   v
list.php (Vorschlagsliste)
   |    Filter: Mahnstufe, min. Verzug, min. Betrag, Kundentyp (B2B/B2C), Kunde (Select2)
   |    Spalten: Rechnung, Kunde, Kontakt (tel/mail), Typ, Faelligkeit, Verzug,
   |             Betrag, letzte Mahnung, vorgeschlagene Stufe
   |
   |--> User waehlt aus + klickt "Mahnungen erzeugen"
   |    -> ajax/createmahnung.php berechnet Gebuehr + Verzugszinsen,
   |       persistiert llx_mahnung_mahnung, generiert PDF/ODT
   |
   |--> Alternativ "Sammelbrief erzeugen"
   |    -> ajax/sammelbrief.php generiert + konkateniert PDFs
   |
   v
card.php (Mahnung-Detailansicht)
   |    Documents: generierte PDFs + Modellauswahl + Regenerate
   |    Versand: Datum, Versandweg, Sendungsnummer, Tracking-Provider -> Deep-Link
   |    Sendebelege: Upload (formfile->showdocuments), Scan-Button
   |    Aktionen: Stornieren | Als uneinbringlich klassifizieren (nur Stufe 3)
   |
Cron 06:00 (MahnungCronVersandReminder)
   |--> Mahnungen mit Status=ERSTELLT > N Tage unversendet -> Ntfy-Push
   |
Zahlungseingang (BankImport / Manual)
   |
   v Trigger BILL_PAYED / PAYMENT_CUSTOMER_CREATE
   |--> alle offenen Mahnvorgaenge zur Rechnung -> status=erledigt
   |
Endgueltig uneinbringlich (Mahnbescheid + Vollstreckung erfolglos)
   |
   v Stufe-3-Mahnung -> Button "Als uneinbringlich klassifizieren"
   |--> Facture::setCanceled($user, CLOSECODE_BADDEBT, $note)
   |    -> fk_statut=3 (ABANDONED), close_code='badcustomer'
   |    -> Mahnung wird storniert, Begruendung in note_private
   |--> Auf Kundenkarte erscheint rote Bonitaets-Warnbox
   |--> Beim Anlegen neuer Auftraege/Rechnungen: Warning-Banner
   |
Steuerlich (Steuer-Modul):
   |--> EÜR ignoriert (liest llx_paiement, keine Zahlung = keine Einnahme)
   |--> UStVA filtert fk_statut IN (1,2) -> abandoned automatisch ausgeschlossen

Dateibaum

mahnung/
├── core/modules/modMahnung.class.php           Descriptor, Rechte, Cron, Hooks, Models
│                                               (migrateVersandFelder + Pattern-Seed)
├── core/modules/mahnung/
│   ├── modules_mahnung.php                     Abstrakte Basis ModelePDFMahnung
│   └── doc/
│       ├── pdf_standard_mahnung.modules.php    TCPDF-Generator (DIN 5008)
│       └── doc_generic_mahnung_odt.modules.php ODT-Template-Generator
├── core/triggers/interface_99_modMahnung_MahnungTriggers.class.php
├── core/boxes/box_mahnung_offen.php            Widget: Offene Rechnungen + Mahnstufe
├── class/mahnung.class.php                     CRUD Mahnvorgang + generateDocument()
│                                               + setVersand + trackingUrl + defaultProviderForWeg
├── class/mahnungstufe.class.php                CRUD Stufen-Konfig
├── class/mahnungvorschlag.class.php            Vorschlags-Service (Stufenermittlung,
│                                               kundentyp/min_betrag-Filter, soc_phone/email)
├── class/mahnungtrackingpattern.class.php      CRUD Tracking-Patterns + detectFromText
├── class/mahnungcron.class.php                 buildVorschlagsliste + versandReminder
├── class/mahnungntfy.class.php                 Ntfy-Wrapper
├── class/actions_mahnung.class.php             Hook-Klasse:
│                                               - addMoreActionsButtons (invoicecard)
│                                               - completeTabsHead (invoice+thirdparty)
│                                               - tabContentViewThirdparty (Bonitaets-Box)
│                                               - formObjectOptions (invoice+ordercard Warning)
├── admin/setup.php                             Setup + Dokumentenmodell + Auto-Migration
├── admin/templatevars.php                      Template-Variablen-Referenz
├── admin/tracking_patterns.php                 CRUD + Live-Vorschau fuer Tracking-Patterns
├── ajax/createmahnung.php                      Bulk-Mahnung-Erzeugung
├── ajax/sammelbrief.php                        Sammelbrief-PDF-Konkatenation
├── ajax/sendmail.php                           E-Mail-Versand
├── ajax/regex_preview.php                      Live-Vorschau-Endpoint fuer Pattern-Setup
├── list.php                                    Vorschlagsliste / Archiv (Select2-Filter)
├── card.php                                    Detailansicht: Versand, Belege, Tracking,
│                                               Uneinbringlich-Workflow
├── sql/llx_mahnung_*.sql                       Schema + Seed
└── langs/{de_DE,en_US}/mahnung.lang

Lizenz

GPL-3.0