Some checks failed
Deploy mahnung / deploy (push) Failing after 4s
Neuer Cron-Job MahnungCronVersandReminder (taeglich):
- Sucht in llx_mahnung_mahnung Status=ERSTELLT (1) + date_versand IS NULL
+ datec < NOW() - INTERVAL N DAY.
- N steht in der Konstante MAHNUNG_VERSAND_REMINDER_DAYS (Default 2).
- Bei Treffern: Ntfy-Push (Topic MAHNUNG_NTFY_TOPIC) mit Titel + Liste
der bis zu 8 Mahnungen ("MAHN2026-0042 (Stufe 2, 3 Tage alt) — Kunde").
- Optional GlobalNotify-Badge "mahnung_versand" wenn GlobalNotify aktiv.
Modul-Descriptor:
- Cronjobs-Array um Reminder ergaenzt (frequency 1d, priority 55, status 1).
Lang-Keys: 2x (de_DE + en_US) fuer Cron-Label + Description.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
135 lines
9.4 KiB
Markdown
135 lines
9.4 KiB
Markdown
# Changelog
|
||
|
||
## [Unreleased]
|
||
|
||
### Versand-Reminder (Cron + Ntfy)
|
||
- Neuer Cron-Job `MahnungCronVersandReminder` (taeglich): sucht Mahnungen mit Status `ERSTELLT` deren PDF seit > N Tagen erstellt aber noch nicht versendet wurde, schickt Ntfy-Push und (falls aktiv) GlobalNotify-Badge.
|
||
- Schwellenwert konfigurierbar via Konstante `MAHNUNG_VERSAND_REMINDER_DAYS` (Default 2).
|
||
- Nachricht listet bis zu 8 Mahnungen (Ref + Stufe + Alter in Tagen + Kunde); Rest als "+N weitere".
|
||
|
||
### Beleg-Scan mit Sendungsnummer-Erkennung
|
||
- Neuer Button "Belege scannen" im Versand-Block der Mahnungs-Karte.
|
||
- Beim Klick werden alle hochgeladenen Belege (PDF via `pdftotext`, sonst txt/html) durchsucht und gegen die konfigurierten Tracking-Patterns gematcht.
|
||
- Erkannte Sendungsnummern werden als Vorschlag ueber dem Beleg-Bereich angezeigt (mit Dateiname, Provider-Label, Sendungsnummer + Deep-Link).
|
||
- Per "Uebernehmen"-Button werden `tracking_nr` + `tracking_provider` in einem Klick gespeichert. "Verwerfen" entfernt den Vorschlag aus der Session.
|
||
- Fallback: wenn `pdftotext` im Container fehlt, wird das im UI klar gemeldet — txt/html werden trotzdem durchsucht.
|
||
- OCR (Tesseract fuer Bilder) bewusst noch nicht enthalten — kommt separat falls gewuenscht, ist Container-Aufwand.
|
||
|
||
### Konfigurierbare Tracking-Patterns (Setup-Seite)
|
||
- Neue Tabelle `llx_mahnung_trackingpattern` (Pro Eintrag: provider, label, regex, url_template, priority, active). Auto-Migration + Default-Seed beim Setup-Aufruf.
|
||
- Default-Patterns: DHL Paket (20-stellig), DPAG Einschreiben (`RR123456789DE`), UPS (1Z…), DHL 11-stellig, Hermes 14-stellig, DPD 14-stellig — Prioritaeten so gesetzt dass spezifischere Patterns zuerst greifen.
|
||
- Neue Setup-Seite `admin/tracking_patterns.php` mit CRUD: Pattern anlegen/bearbeiten/aktivieren-deaktivieren/loeschen.
|
||
- **Live-Vorschau**: Beim Tippen von Regex/URL/Beispieltext wird via AJAX-Endpoint `ajax/regex_preview.php` direkt gezeigt ob der Regex syntaktisch gueltig ist, was er aus dem Beispieltext matcht und wie die finale Tracking-URL aussieht.
|
||
- ReDoS-Schutz im AJAX-Endpoint: max 10 KB Sample, `pcre.backtrack_limit=100k`, Whitelist Delimiter `/ # ~`.
|
||
- `Mahnung::trackingUrl()` (hardcoded Fallback) bleibt — primaer wird `MahnungTrackingPattern::urlFor()` aus DB-Patterns benutzt.
|
||
- Setup-Page-Link: Button "Tracking-Muster (Regex)" oben rechts auf der Modul-Setup-Seite.
|
||
|
||
### Versand & Belege (Mahnungs-Karte)
|
||
- Neue Felder `date_versand`, `versandweg`, `tracking_nr`, `tracking_provider` an `llx_mahnung_mahnung` — idempotente Migration laeuft beim ersten Setup-Aufruf nach dem Deploy.
|
||
- Neuer Block "Versand & Belege" auf der Mahnungs-Karte:
|
||
- Erfassung Versanddatum + Versandweg (Brief/Einschreiben/DHL/DPD/Hermes/UPS/Fax/Mail/Persoenlich/Eigen).
|
||
- Optionale Sendungsnummer + Anbieter — Mahnung-Klasse liefert Deep-Link zur Sendungsverfolgung (DHL, Deutsche Post, DPD, Hermes, UPS).
|
||
- "Sendung verfolgen"-Button oeffnet die Provider-Seite mit eingesetzter Sendungsnummer.
|
||
- Beleg-Upload via Dolibarrs `formfile->showdocuments()` — Dateien landen in `DOL_DATA_ROOT/mahnung/<MAHN-Ref>/`, voll integriert mit ECM/document.php.
|
||
- Status springt automatisch auf `STATUS_VERSENDET` sobald ein Versanddatum gesetzt wird (sofern vorher <= ERSTELLT).
|
||
- Neue Methoden `Mahnung::setVersand()`, `Mahnung::trackingUrl()`, `Mahnung::defaultProviderForWeg()`, `Mahnung::getVersandwegLabel()`.
|
||
|
||
### Vorschlagsliste — UX
|
||
- Kunden-Filter: rowid-Input ersetzt durch Dolibarr-Standard `select_company()` (Ajax-Suche bzw. klassisches Dropdown, je nach Dolibarr-Konfiguration). Direkt-Links `?search_socid=74` bleiben funktional.
|
||
- Neuer Filter "Mindestbetrag" (in EUR, Komma erlaubt).
|
||
- Neuer Filter "Kundentyp" (B2B / B2C).
|
||
- Neue Spalte "Kontakt" mit Telefon- und Mail-Direktlink-Icons.
|
||
|
||
### Fixes
|
||
- Kundenkarte: Tab "Mahnwesen" erschien doppelt, weil `complete_head_from_modules()` pro Karte mehrfach (core + external + remove) feuert. Hook filtert jetzt auf `mode=add` + `filterorigmodule=external`.
|
||
|
||
## [0.2.0] — 2026-05-10 — ODT-Template-System, Widget, Dokumentenmodelle
|
||
|
||
### ODT-Template-System
|
||
- Abstrakte Basis-Klasse `ModelePDFMahnung extends CommonDocGenerator` (`core/modules/mahnung/modules_mahnung.php`)
|
||
- ODT-Generator `doc_generic_mahnung_odt` mit Stufen-spezifischer Template-Auswahl (mahnung_stufe1/2/3.odt, Fallback mahnung.odt)
|
||
- TCPDF-Generator `pdf_standard_mahnung` (refactored aus `mahnungpdf.class.php`)
|
||
- `mahnung.class.php`: `generateDocument()` Methode via `commonGenerateDocument()`
|
||
- Template-Variablen: Mahnung, Rechnung, Kunde, Bankverbindung, Dolibarr-Standard
|
||
- ODT-Template-Upload auf Setup-Seite mit Benennungskonvention-Hinweis
|
||
|
||
### Widget
|
||
- `box_mahnung_offen`: Offene Kundenrechnungen mit Mahnstufe-Badge (basiert auf box_factures_imp)
|
||
- Alle offenen Rechnungen (nicht nur überfällige), Status-Icon wie Original
|
||
- Farbige Mahnstufe-Badges (blau/orange/rot) mit Link zur Mahnung-Detailseite
|
||
- Strich (—) bei Rechnungen ohne Mahnung
|
||
|
||
### Dokumentenliste auf card.php
|
||
- Generierte Dokumente zur Mahnung auflisten (aus Rechnungsordner)
|
||
- PDF-Vorschau (Lupe), Download-Button
|
||
- Modellauswahl-Dropdown bei mehreren aktiven Dokumentenmodellen
|
||
|
||
### Setup-Erweiterungen
|
||
- Dokumentenmodell-Verwaltung (aktivieren/deaktivieren, Default setzen)
|
||
- `admin/templatevars.php`: Referenzseite aller verfügbaren ODT-Template-Variablen
|
||
- Link von Setup zur Variablen-Referenz
|
||
|
||
### Modul-Descriptor
|
||
- `module_parts['models'] = 1`
|
||
- Neue Konstanten: `MAHNUNG_ADDON_PDF`, `MAHNUNG_ADDON_PDF_ODT_PATH`
|
||
- Document-Model-Registrierung in `init()` (standard_mahnung + generic_mahnung_odt)
|
||
- Widget `box_mahnung_offen@mahnung` registriert
|
||
- Picto korrigiert: `fa-envelope-open-text` (FA5-Free)
|
||
|
||
### Bugfixes
|
||
- numero 500037 → 500038 (Kollision mit Eplan behoben)
|
||
- `verifCsrf()` entfernt (existiert nicht in Dolibarr, CSRF via `newToken()`)
|
||
- `f.statut` → `f.fk_statut` (Dolibarr 22.x Spaltenname)
|
||
- `actions_setmoduleoptions.inc.php` vor `llxHeader()` verschoben (ODT-Upload)
|
||
- Widget: `require_once mahnung.class.php` an Dateianfang (Fatal Error bei Klassen-Konstanten in SQL)
|
||
|
||
### Entfernt
|
||
- `class/mahnungpdf.class.php` — Logik in `core/modules/mahnung/doc/pdf_standard_mahnung.modules.php`
|
||
|
||
---
|
||
|
||
## [0.1.0] — 2026-05-07 — Erstveröffentlichung (Phase 1–10)
|
||
|
||
### DB-Schema (Phase 1)
|
||
- `llx_mahnung_mahnung` — Mahnvorgänge mit Stufe, Beträgen, Zinsen, Status, Snapshot des Basiszinses für Reproduzierbarkeit
|
||
- `llx_mahnung_stufe` — pro Stufe konfigurierbar: Frist, neue Frist, Gebühren B2C/B2B, optional Zinssatz-Override, Versandart, E-Mail-/PDF-Templates
|
||
- 3 Default-Stufen werden bei Aktivierung idempotent eingefügt
|
||
|
||
### Modul-Descriptor (Phase 1)
|
||
- numero `500038`, family `financial`, FA-Picto `fa-envelope-open-text`
|
||
- Modul-Konstanten: `MAHNUNG_BASISZINS`, `MAHNUNG_AUFSCHLAG_B2C`, `MAHNUNG_AUFSCHLAG_B2B`, `MAHNUNG_PAUSCHALE_B2B`, `MAHNUNG_NTFY_TOPIC`
|
||
- Rechte: `read`, `write`, `send`, `delete`, `setup`
|
||
- Cron-Job `MahnungCronBuildVorschlag` (täglich, default deaktiviert)
|
||
- Linkes Menü unter „Rechnungen" (mainmenu=billing) mit Vorschlagsliste / Archiv
|
||
|
||
### CRUD + Setup (Phase 2)
|
||
- `class/mahnung.class.php` — CRUD, Status-Konstanten, Verzugszinsen-Berechnung nach BGB §288
|
||
- `class/mahnungstufe.class.php` — Stufen-Konfiguration, Override-Helfer für Zinsen/Gebühren
|
||
- `admin/setup.php` — Stufen-Tabelle vollständig pflegbar, Konstanten persistent
|
||
|
||
### Vorschlagsliste + Cron (Phase 3)
|
||
- `class/mahnungvorschlag.class.php` — gemeinsamer Service: ermittelt pro überfälliger Rechnung die nächste vorgeschlagene Stufe, B2C/B2B-Erkennung via `tva_intra`, offener Betrag aus `paiement_facture`
|
||
- `class/mahnungcron.class.php` — Cron sammelt Vorschläge, sendet Ntfy-Push (Topic aus Setup), schreibt zusätzlich GlobalNotify-Action wenn aktiv
|
||
- `class/mahnungntfy.class.php` — schmaler Ntfy-Push-Wrapper
|
||
- `list.php` — Vorschlagsliste-UI mit Multi-Select, Filter nach Stufe / Verzugstagen / Kunde, Buttons „Mahnungen erzeugen" und „Sammelbrief"
|
||
|
||
### PDF-Generator + Erstellen (Phase 4)
|
||
- TCPDF-basierter Generator (DIN-5008 Form A): Adressfenster, Bezugszeichenzeile, Tabelle, Gebührenblock, Verzugszinsen mit Snapshot-Zinssatz, neue Frist, Bankverbindungs-Footer
|
||
- PDFs landen in `documents/facture/{ref}/` und erscheinen automatisch im Dokumente-Tab der Rechnung
|
||
- `ajax/createmahnung.php` — Bulk-Endpoint mit CSRF + Permission-Check, erzeugt Mahnung + PDF, behandelt §288 Abs. 5 Pauschale einmalig pro Rechnung
|
||
|
||
### Hooks + Trigger (Phase 5)
|
||
- `core/triggers/interface_99_modMahnung_MahnungTriggers.class.php` — `BILL_PAYED` und `PAYMENT_CUSTOMER_CREATE` setzen offene Mahnungen auf erledigt
|
||
- `class/actions_mahnung.class.php` — Hook auf Rechnungs- und Kundenkarte: Tab „Mahnungen (n)" mit Badge, Button „Mahnung erstellen" wenn überfällig
|
||
- `card.php` — Detailansicht eines Mahnvorgangs mit Storno-Aktion (`formconfirm`-Modal)
|
||
|
||
### E-Mail + Sammelbrief (Phase 6)
|
||
- `ajax/sendmail.php` — sendet Mahnung-PDF via `CMailFile` an die Kunden-Mail; Subject/Body mit Platzhaltern aus Stufen-Konfig
|
||
- `ajax/sammelbrief.php` — erzeugt Mahnungen für Auswahl, konkateniert ihre PDFs via TCPDI in eine Datei, liefert Download
|
||
|
||
### Integrationen (Phase 7 + 8)
|
||
- GlobalNotify: Cron sendet zusätzlich `actionRequired`-Notification ins Dolibarr-UI (wenn Modul aktiv)
|
||
- Tab „Mahnungen" auf Kundenkarte (`thirdpartycard`) zusätzlich zur Rechnungskarte
|
||
|
||
### Pipeline (Phase 10)
|
||
- `.forgejo/workflows/deploy.yml` — Deploy auf `/mnt/appdata/firma/dolibarr-202509/modules/mahnung` bei Push auf `main` mit `[deploy]` oder Tag `v*`, Ntfy-Notify auf Topic `vk-builds`
|