From e7375ac5593742c3a2ba732126378f53b0e1a7b4 Mon Sep 17 00:00:00 2001 From: Eduard Wisch Date: Thu, 14 May 2026 10:29:50 +0200 Subject: [PATCH] fix(mahnung): Button "Mahnung erstellen" nur bei freigegebener + offener Rechnung, in zweiter Zeile [deploy] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Vorher: Button wurde immer gezeigt — auch bei Entwurf, bezahlt, storniert (zwar disabled mit Tooltip, aber sichtbar). Jetzt: Hook gibt nichts aus wenn: - Entwurf (statut == 0) - Bezahlt (paye != 0) - Storniert / abandoned (statut == 2 / 3) Nur bei statut >= 1 UND paye === 0 erscheint der Button. Überfällig-Logik entscheidet danach nur noch ob aktiv (mit URL) oder disabled (mit Tooltip). Zusätzlich: Flex-Spacer (flex-basis:100%) wird DIREKT vor den Button gestellt → Button landet in eigener zweiter Zeile unterhalb der primären Aktionen, neben "Import Zeilen / Löschen / Auf anderen Kunden übertragen". Output via \$this->resprints statt direktem print — verhindert HTML-Layoutbruch bei Hook-Aufrufen mitten in Tabellen. Co-Authored-By: Claude Opus 4.7 (1M context) --- class/actions_mahnung.class.php | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/class/actions_mahnung.class.php b/class/actions_mahnung.class.php index e426aeb..7b251e4 100644 --- a/class/actions_mahnung.class.php +++ b/class/actions_mahnung.class.php @@ -49,27 +49,43 @@ class ActionsMahnung return 0; } - $paye = (int) ($object->paye ?? 0); + $paye = (int) ($object->paye ?? 0); $statut = (int) ($object->statut ?? ($object->status ?? 0)); - $dateLim = !empty($object->date_lim_reglement) ? (int) $object->date_lim_reglement : 0; - $ueberfaellig = ($statut === 1 && $paye === 0 && $dateLim > 0 && $dateLim < dol_now()); - $langs->load('mahnung@mahnung'); + // Button nur bei FREIGEGEBENER (statut >= 1) und NOCH OFFENER (paye === 0) Rechnung. + // Entwurf, bezahlt, storniert, abandoned → gar kein Button. + if ($statut < 1 || $paye !== 0) { + return 0; + } if (!$user->hasRight('mahnung', 'write')) { return 0; } + $langs->load('mahnung@mahnung'); + + $dateLim = !empty($object->date_lim_reglement) ? (int) $object->date_lim_reglement : 0; + $ueberfaellig = ($dateLim > 0 && $dateLim < dol_now()); + $label = $langs->trans('MahnungErstellen'); if ($ueberfaellig) { $url = DOL_URL_ROOT.'/custom/mahnung/list.php?mainmenu=billing&leftmenu=mahnung&mode=vorschlag&search_socid='.((int) $object->socid); - print dolGetButtonAction($label, '', 'default', $url, 'btn-mahnung-create', 1); + $btn = dolGetButtonAction($label, '', 'default', $url, 'btn-mahnung-create', 1); } else { $attr = array('title' => $langs->trans('MahnungKeineUeberfaelligen')); - print dolGetButtonAction($label, '', 'default', '#', 'btn-mahnung-create', 0, array('attr' => $attr)); + $btn = dolGetButtonAction($label, '', 'default', '#', 'btn-mahnung-create', 0, array('attr' => $attr)); } + // In die zweite Zeile zwingen: Flex-Spacer mit voller Breite und 0 Höhe DIREKT + // vor dem Button. Wirkt nur bei flex-wrap-Layouts (Standard in .tabsAction) — + // sonst harmlos. So landet "Mahnung" optisch unter den Standard-Aktionen, neben + // Import Zeilen / Löschen / Auf anderen Kunden übertragen. + $spacer = '
'; + + // Über $this->resprints zurückgeben statt direktem print — sonst kann der Output + // mitten in HTML-Fragmenten landen. Dolibarr printet danach $hookmanager->resPrint. + $this->resprints = $spacer.$btn; return 0; }