From 4fcd356972eeb48e4fda538ffd0b27ab9c2bc4fd Mon Sep 17 00:00:00 2001 From: Eduard Wisch Date: Mon, 17 Aug 2026 17:13:41 +0200 Subject: [PATCH] PDF-Zweig und Feldtabelle fuer den Geraete-Vergleich netdiagPdfGeraeteDiff() gibt die Listen getrennt aus: neu, nicht mehr erreichbar, mit neuer IP-Adresse, gleiche Adresse mit anderen offenen Ports. Beim Wiederholungstermin zaehlt, WELCHES Geraet neu ist, nicht nur wie viele. An jeder Zeile steht, worueber das Geraet wiedererkannt wurde - "erkannt ueber IP und Portmuster" ist eine schwaechere Aussage als "ueber Netzwerkname", und der Unterschied gehoert ins Dokument statt in eine Fussnote. Geprueft im Durchstich: in der App gegen echte Serverdaten gemessen (ND2026-0016 gegen ND2026-0006), synchronisiert, PDF erzeugt und angesehen. Co-Authored-By: Claude Opus 5 (1M context) --- ChangeLog.md | 24 +++++++++ core/modules/modNetDiag.class.php | 2 +- lib/netdiag.lib.php | 9 ++++ lib/netdiag_pdf.lib.php | 86 +++++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 624989b..bbc7f57 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,29 @@ # Changelog NetDiag +## 1.1.7 — 2026-08-17 + +### PDF-Zweig und Feldtabelle für den Geräte-Vergleich + +`netdiagPdfGeraeteDiff()` gibt die drei Listen getrennt aus: neu hinzugekommen, +nicht mehr erreichbar, mit neuer IP-Adresse — plus „Gleiche Adresse, andere +offene Ports". Beim Wiederholungstermin zählt, WELCHES Gerät neu ist, nicht nur +wie viele; als `|`-Kette in einer Zelle wäre das vorhanden, aber nicht lesbar. + +An jeder Zeile steht, worüber das Gerät wiedererkannt wurde. „Erkannt über IP +und Portmuster" ist eine schwächere Aussage als „über Netzwerkname", und dieser +Unterschied gehört ins Dokument statt in eine Fußnote — die Wiedererkennung +läuft bewusst nicht über MAC-Adressen, die Android seit Version 10 nicht mehr +herausgibt. + +Neu in der Whitelist: `verglichenMit`, `geraeteVorher`, `geraeteJetzt`, +`mitNeuerAdresse`, `andereOffenePorts`, `unveraendert`; Werkzeugname +`geraetediff` → „Geräte-Vergleich". `neu` und `nichtMehrErreichbar` standen +bereits drin (der IP-Scan nutzt dieselben Schlüssel). + +Geprüft im Durchstich: in der App gegen echte Serverdaten gemessen +(Vergleich ND2026-0016 gegen ND2026-0006), synchronisiert, PDF erzeugt und +angesehen. + ## 1.1.6 — 2026-08-17 ### PDF-Zweig für die DNS-Prüfung diff --git a/core/modules/modNetDiag.class.php b/core/modules/modNetDiag.class.php index 727fee3..2e80371 100644 --- a/core/modules/modNetDiag.class.php +++ b/core/modules/modNetDiag.class.php @@ -67,7 +67,7 @@ class modNetDiag extends DolibarrModules $this->editor_url = ''; $this->editor_squarred_logo = ''; - $this->version = '1.1.6'; + $this->version = '1.1.7'; // Konstanten-Name in llx_const für Modul-Status $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); diff --git a/lib/netdiag.lib.php b/lib/netdiag.lib.php index 2102690..2cf51bb 100644 --- a/lib/netdiag.lib.php +++ b/lib/netdiag.lib.php @@ -358,6 +358,14 @@ function netdiagKundenfelder() // eigentliche Aussage — welcher Server antwortet und welcher nicht. 'gefragteServer' => array('Befragte DNS-Server', ''), 'antworten' => array('Antworten der Server', ''), + // Geräte-Vergleich zweier Protokolle. `neu` und `nichtMehrErreichbar` + // stehen schon weiter oben (IP-Scan nutzt dieselben Schlüssel). + 'verglichenMit' => array('Verglichen mit', ''), + 'geraeteVorher' => array('Geräte beim letzten Besuch', ''), + 'geraeteJetzt' => array('Geräte jetzt', ''), + 'mitNeuerAdresse' => array('Mit neuer IP-Adresse', ''), + 'andereOffenePorts' => array('Gleiche Adresse, andere offene Ports', ''), + 'unveraendert' => array('Unverändert', ''), // Netz/DHCP 'server' => array('DHCP-Server', ''), 'lease' => array('Lease-Dauer', 's'), @@ -652,6 +660,7 @@ function netdiagToolName($tool) 'iptest' => 'IP-Test (Dose)', 'wifitrack' => 'WLAN-Empfang', 'dnscheck' => 'DNS-Prüfung', + 'geraetediff' => 'Geräte-Vergleich', // nicht mehr vorhandene Werkzeuge, aber in Altprotokollen enthalten 'dhcpcheck' => 'DHCP-Prüfung', 'wifiscan' => 'WLAN-Scan', diff --git a/lib/netdiag_pdf.lib.php b/lib/netdiag_pdf.lib.php index 214411f..8dee02c 100644 --- a/lib/netdiag_pdf.lib.php +++ b/lib/netdiag_pdf.lib.php @@ -222,6 +222,8 @@ function netdiagGeneratePdf($db, $protocol, $outputlangs) netdiagPdfKette($pdf, $m->result); } elseif ($m->tool === 'dnscheck') { netdiagPdfDns($pdf, $m->result); + } elseif ($m->tool === 'geraetediff') { + netdiagPdfGeraeteDiff($pdf, $m->result); } else { $pdf->MultiCell(180, 5, netdiagPdfFlattenResult($m->result), 1, 'L'); } @@ -437,6 +439,90 @@ function netdiagPdfStressTest($pdf, $json) } } +/** + * Geräte-Vergleich ins PDF schreiben: drei getrennte Listen. + * + * „Was hat sich seit dem letzten Besuch geändert" ist beim Wiederholungstermin + * die erste Frage des Kunden. Als `|`-Kette in einer Zelle wäre die Antwort + * vorhanden, aber nicht lesbar — und gerade hier zählt, WELCHES Gerät neu ist + * und welches fehlt, nicht nur wie viele. + * + * Die Angabe, worüber ein Gerät wiedererkannt wurde, bleibt bewusst an jeder + * Zeile stehen: „erkannt über IP und Portmuster" ist eine schwächere Aussage + * als „erkannt über Netzwerkname", und der Unterschied gehört ins Dokument + * statt in eine Fußnote. + * + * @param TCPDF $pdf PDF-Objekt (Cursor steht direkt hinter der Titelzeile) + * @param string $json result-JSON der Messung + * @return void + */ +function netdiagPdfGeraeteDiff($pdf, $json) +{ + $data = json_decode((string) $json, true); + if (!is_array($data)) { + $pdf->MultiCell(180, 5, netdiagPdfFlattenResult($json), 1, 'L'); + return; + } + + $sum = array(); + if (!empty($data['verglichenMit'])) { + $sum[] = 'Verglichen mit '.$data['verglichenMit']; + } + if (isset($data['geraeteVorher'])) { + $sum[] = 'damals '.$data['geraeteVorher'].' Geräte'; + } + if (isset($data['geraeteJetzt'])) { + $sum[] = 'jetzt '.$data['geraeteJetzt']; + } + if (isset($data['unveraendert'])) { + $sum[] = $data['unveraendert'].' unverändert'; + } + if (!empty($sum)) { + $pdf->MultiCell(180, 5, netdiagPdfText(implode(' | ', $sum)), 1, 'L'); + } + + $listen = array( + 'neu' => 'Neu hinzugekommen', + 'nichtMehrErreichbar' => 'Nicht mehr erreichbar', + 'mitNeuerAdresse' => 'Mit neuer IP-Adresse', + 'andereOffenePorts' => 'Gleiche Adresse, andere offene Ports', + ); + $etwasGefunden = false; + foreach ($listen as $feld => $titel) { + $eintraege = (isset($data[$feld]) && is_array($data[$feld])) ? $data[$feld] : array(); + if (empty($eintraege)) { + continue; + } + $etwasGefunden = true; + netdiagPdfEnsureSpace($pdf, 10); + $pdf->SetFont('', 'B', 8); + $pdf->Cell(180, 5, $titel.' ('.count($eintraege).')', 1, 1, 'L'); + $pdf->SetFont('', '', 8); + foreach ($eintraege as $line) { + netdiagPdfEnsureSpace($pdf, 5, function ($p) use ($titel) { + $p->SetFont('', 'B', 8); + $p->Cell(180, 5, $titel.' — Fortsetzung', 1, 1, 'L'); + $p->SetFont('', '', 8); + }); + $pdf->MultiCell(180, 5, netdiagPdfText(netdiagKundentext((string) $line)), 1, 'L'); + } + } + if (!$etwasGefunden) { + $pdf->SetFont('', 'I', 8); + $pdf->Cell(180, 5, 'Keine Veränderung gegenüber dem letzten Protokoll.', 1, 1, 'L'); + $pdf->SetFont('', '', 8); + } + + foreach (array('hinweis', 'verfahren') as $feld) { + if (!empty($data[$feld])) { + netdiagPdfEnsureSpace($pdf, 8); + $pdf->SetFont('', 'I', 7); + $pdf->MultiCell(180, 4, netdiagPdfText(netdiagKundentext((string) $data[$feld])), 1, 'L'); + $pdf->SetFont('', '', 8); + } + } +} + /** * DNS-Prüfung ins PDF schreiben: je Server eine eigene Zeile. *