From 7196f2594ce765bc17130f03785b3a3ea5f2b93f Mon Sep 17 00:00:00 2001 From: Eduard Wisch Date: Wed, 13 May 2026 16:40:33 +0200 Subject: [PATCH] =?UTF-8?q?OCR=20f=C3=BCr=20Bild-PDFs=20beim=20Belege-Scan?= =?UTF-8?q?nen=20+=20Feedback-Meldung=20[deploy]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wenn pdftotext keinen Text findet, wird ocrmypdf (Tesseract OCR) auf das PDF angewendet bevor erneut nach Sendungsnummern gesucht wird. Bei leerem Ergebnis erscheint jetzt eine Hinweismeldung statt stummem Seiten-Reload. Co-Authored-By: Claude Opus 4.6 (1M context) --- card.php | 28 ++++++++++++++++++++++++++-- langs/de_DE/mahnung.lang | 1 + langs/en_US/mahnung.lang | 1 + 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/card.php b/card.php index 0dae3f5..2fa5530 100644 --- a/card.php +++ b/card.php @@ -185,7 +185,8 @@ if ($action === 'scan_belege' && $user->hasRight('mahnung', 'write')) { $patternService = new MahnungTrackingPattern($db); $suggestions = array(); - $pdftotextAvailable = null; // einmalig prüfen + $pdftotextAvailable = null; + $ocrmypdfAvailable = null; if (is_dir($scanDir)) { foreach (dol_dir_list($scanDir, 'files', 0) as $file) { @@ -203,8 +204,28 @@ if ($action === 'scan_belege' && $user->hasRight('mahnung', 'write')) { } if ($pdftotextAvailable) { + // Erst normales pdftotext versuchen $cmd = 'pdftotext -layout '.escapeshellarg($file['fullname']).' - 2>/dev/null'; - $text = (string) @shell_exec($cmd); + $text = trim((string) @shell_exec($cmd)); + + // Kein Text? → OCR via ocrmypdf (Bild-PDF lesbar machen) + if ($text === '') { + if ($ocrmypdfAvailable === null) { + $check2 = @shell_exec('command -v ocrmypdf 2>/dev/null'); + $ocrmypdfAvailable = !empty(trim((string) $check2)); + } + if ($ocrmypdfAvailable) { + $ocrTmp = $file['fullname'].'.ocr.pdf'; + $ocrCmd = 'ocrmypdf --skip-text -l deu+eng --jobs 2 ' + .escapeshellarg($file['fullname']).' ' + .escapeshellarg($ocrTmp).' 2>/dev/null'; + @shell_exec($ocrCmd); + if (file_exists($ocrTmp)) { + $text = trim((string) @shell_exec('pdftotext -layout '.escapeshellarg($ocrTmp).' - 2>/dev/null')); + @unlink($ocrTmp); + } + } + } } } if ($text === '') { @@ -224,6 +245,9 @@ if ($action === 'scan_belege' && $user->hasRight('mahnung', 'write')) { } $_SESSION['mahnung_tracking_suggestions_'.((int) $mahnung->id)] = $suggestions; + if (empty($suggestions)) { + setEventMessages($langs->trans('MahnungKeineSendungsnummerErkannt'), null, 'warnings'); + } if ($pdftotextAvailable === false) { setEventMessages($langs->trans('MahnungPdftotextMissing'), null, 'warnings'); } diff --git a/langs/de_DE/mahnung.lang b/langs/de_DE/mahnung.lang index a381c76..ea46e8a 100644 --- a/langs/de_DE/mahnung.lang +++ b/langs/de_DE/mahnung.lang @@ -373,3 +373,4 @@ MahnungEmailDefaultSubject = Mahnung {stufe} zu Rechnung {rechnung} MahnungEmailDefaultBody1 = Sehr geehrter Kunde,\n\nanbei senden wir Ihnen eine freundliche Zahlungserinnerung zu Rechnung {rechnung}.\nOffener Betrag inkl. evtl. Zinsen: {summe}.\nWir bitten um Begleichung bis spätestens {frist}.\n\nMit freundlichen Grüßen MahnungEmailDefaultBody2 = Sehr geehrter Kunde,\n\nanbei die 1. Mahnung zur Rechnung {rechnung}.\nBitte überweisen Sie {summe} bis zum {frist}.\n\nMit freundlichen Grüßen MahnungEmailDefaultBody3 = Sehr geehrter Kunde,\n\nanbei die letzte Mahnung zur Rechnung {rechnung}.\nFalls der Betrag von {summe} nicht bis zum {frist} eingeht, leiten wir gerichtliche Schritte ein.\n\nMit freundlichen Grüßen +MahnungKeineSendungsnummerErkannt = Keine Sendungsnummer in den Belegen erkannt. Bild-PDFs werden per OCR verarbeitet — falls trotzdem nichts gefunden wurde, enthält der Beleg evtl. keine Tracking-Nummer. diff --git a/langs/en_US/mahnung.lang b/langs/en_US/mahnung.lang index d4ba4db..bfa2460 100644 --- a/langs/en_US/mahnung.lang +++ b/langs/en_US/mahnung.lang @@ -361,3 +361,4 @@ MahnungEmailDefaultSubject = Dunning notice {stufe} for invoice {rechnung} MahnungEmailDefaultBody1 = Dear Customer,\n\nplease find attached a friendly payment reminder for invoice {rechnung}.\nOutstanding amount incl. interest: {summe}.\nWe kindly ask for settlement by {frist} at the latest.\n\nKind regards MahnungEmailDefaultBody2 = Dear Customer,\n\nplease find attached the 1st dunning notice for invoice {rechnung}.\nPlease transfer {summe} by {frist}.\n\nKind regards MahnungEmailDefaultBody3 = Dear Customer,\n\nplease find attached the final dunning notice for invoice {rechnung}.\nIf the amount of {summe} is not received by {frist}, we will initiate legal proceedings.\n\nKind regards +MahnungKeineSendungsnummerErkannt = No tracking number found in receipts. Image PDFs are processed via OCR — if still nothing was found, the receipt may not contain a tracking number.