OCR für Bild-PDFs beim Belege-Scannen + Feedback-Meldung [deploy]
All checks were successful
Deploy mahnung / deploy (push) Successful in 13s

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) <noreply@anthropic.com>
This commit is contained in:
Eduard Wisch 2026-05-13 16:40:33 +02:00
parent e785e53d8c
commit 7196f2594c
3 changed files with 28 additions and 2 deletions

View file

@ -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');
}

View file

@ -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.

View file

@ -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.