* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. */ /** * \file mahnung/card.php * \ingroup mahnung * \brief Detailansicht eines einzelnen Mahnvorgangs. */ $res = 0; if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) { $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; } $tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; } if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) { $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; } if (!$res && file_exists("../main.inc.php")) { $res = @include "../main.inc.php"; } if (!$res) { die("Include of main fails"); } require_once DOL_DOCUMENT_ROOT.'/custom/mahnung/class/mahnung.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; global $langs, $user, $db; $langs->loadLangs(array('mahnung@mahnung', 'companies', 'bills')); if (!$user->hasRight('mahnung', 'read')) { accessforbidden(); } $id = GETPOSTINT('id'); $action = GETPOST('action', 'aZ09'); $mahnung = new Mahnung($db); if ($mahnung->fetch($id) <= 0) { dol_print_error($db, $langs->trans('MahnungNichtGefunden', $id)); exit; } // Verzugszinsen für noch nicht versandte Mahnungen mit aktueller Konfiguration neu berechnen if ((int) $mahnung->status <= Mahnung::STATUS_ERSTELLT && !empty($mahnung->fk_facture)) { require_once DOL_DOCUMENT_ROOT.'/custom/mahnung/class/mahnungstufe.class.php'; $_stufe = new MahnungStufe($db); if ($_stufe->fetchByStufe((int) $mahnung->stufe) > 0) { $_basiszins = (float) getDolGlobalString('MAHNUNG_BASISZINS', '1.27'); $_override = $_stufe->getZinssatzOverride($mahnung->customertype); // Verzugstage: Differenz Mahndatum - Original-Fälligkeit $_tageVerzug = 0; if (!empty($mahnung->datec) && !empty($mahnung->date_lim_reglement_alt)) { $_tageVerzug = max(0, (int) round(($mahnung->datec - $mahnung->date_lim_reglement_alt) / 86400)); } $_neueZinsen = Mahnung::berechneVerzugszinsen( $mahnung->betrag_offen, $_tageVerzug, $mahnung->customertype, $_basiszins, $_override ); if (abs((float) $mahnung->verzugszinsen - $_neueZinsen) > 0.001) { $mahnung->verzugszinsen = $_neueZinsen; $mahnung->basiszins_snapshot = $_basiszins; $mahnung->rechneSumme(); $mahnung->update($user); } } } // Stornieren if ($action === 'storno' && $user->hasRight('mahnung', 'delete')) { $mahnung->status = Mahnung::STATUS_STORNIERT; if ($mahnung->update($user) > 0) { setEventMessages($langs->trans('MahnungStornieren').' OK', null, 'mesgs'); header('Location: '.$_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id)); exit; } setEventMessages($mahnung->error, null, 'errors'); } // Dokument neu generieren if ($action === 'regenerate_pdf' && $user->hasRight('mahnung', 'write')) { $selectedModel = GETPOST('model', 'alphanohtml'); $result = $mahnung->generateDocument($selectedModel, $langs); if ($result > 0) { setEventMessages($langs->trans('MahnungDokumentErstellt'), null, 'mesgs'); } else { setEventMessages($langs->trans('MahnungDokumentFehler').': '.$mahnung->error, null, 'errors'); } header('Location: '.$_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id)); exit; } // Generiertes Dokument löschen if ($action === 'delete_doc' && $user->hasRight('mahnung', 'write')) { $docfile = GETPOST('file', 'alphanohtml'); if (!empty($docfile) && !empty($mahnung->fk_facture)) { $facTmp = new Facture($db); if ($facTmp->fetch((int) $mahnung->fk_facture) > 0) { $baseDir = !empty($conf->facture->multidir_output[$facTmp->entity]) ? $conf->facture->multidir_output[$facTmp->entity] : $conf->facture->dir_output; $fullpath = $baseDir.'/'.dol_sanitizeFileName($facTmp->ref).'/'.dol_sanitizeFileName($docfile); // Sicherstellen dass die Datei zur Mahnung gehoert (Ref im Dateinamen) if (file_exists($fullpath) && strpos($docfile, dol_sanitizeFileName($mahnung->ref)) !== false) { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; dol_delete_file($fullpath); setEventMessages($langs->trans('FileWasRemoved'), null, 'mesgs'); } else { setEventMessages($langs->trans('MahnungDateiNichtGefunden'), null, 'errors'); } } } header('Location: '.$_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id)); exit; } // Versand-Daten speichern (Datum, Weg, optional Tracking) if ($action === 'set_versand' && $user->hasRight('mahnung', 'write')) { $y = GETPOSTINT('versand_year'); $m = GETPOSTINT('versand_month'); $d = GETPOSTINT('versand_day'); $dateVersand = ($y && $m && $d) ? dol_mktime(12, 0, 0, $m, $d, $y) : dol_now(); $weg = GETPOST('versandweg', 'aZ09'); $trackNr = trim((string) GETPOST('tracking_nr', 'alphanohtml')); $trackProv = GETPOST('tracking_provider', 'aZ09'); if (empty($trackProv) && $trackNr !== '') { $trackProv = Mahnung::defaultProviderForWeg($weg); } if ($mahnung->setVersand($user, $dateVersand, $weg, $trackNr ?: null, $trackProv ?: null) > 0) { setEventMessages($langs->trans('MahnungVersandGespeichert'), null, 'mesgs'); } else { setEventMessages($mahnung->error ?: $langs->trans('MahnungFehlerSpeichern'), null, 'errors'); } header('Location: '.$_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id)); exit; } // Rechnung als uneinbringlich klassifizieren (close_code='badcustomer') // — endgültiger Schritt nach erfolglosem Mahnverfahren / Vollstreckung. if ($action === 'confirm_uneinbringlich' && $user->hasRight('mahnung', 'delete')) { require_once DOL_DOCUMENT_ROOT.'/core/class/commoninvoice.class.php'; $note = trim((string) GETPOST('uneinbringlich_note', 'nohtml')); if ($note === '') { $note = $langs->trans('MahnungVerfahrenErfolglos').' '.dol_print_date(dol_now(), 'day'); } $facReload = new Facture($db); if ($facReload->fetch((int) $mahnung->fk_facture) > 0) { // Rechnung auf STATUS_ABANDONED (3) + close_code='badcustomer' setzen $ret = $facReload->setCanceled($user, CommonInvoice::CLOSECODE_BADDEBT, $note); if ($ret > 0) { // Mahnung mitstornieren — Vorgang ist damit fachlich abgeschlossen $mahnung->status = Mahnung::STATUS_STORNIERT; $mahnung->note_private = trim(($mahnung->note_private ? $mahnung->note_private."\n\n" : '').$langs->trans('MahnungUneinbringlichKlassifiziert').' ('.dol_print_date(dol_now(), 'day').'): '.$note); $mahnung->update($user); setEventMessages($langs->trans('MahnungUneinbringlichErfolg'), null, 'mesgs'); } else { setEventMessages($facReload->error ?: $langs->trans('MahnungFehlerKlassifizieren'), null, 'errors'); } } else { setEventMessages($langs->trans('MahnungRechnungNichtLadbar'), null, 'errors'); } header('Location: '.$_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id)); exit; } // Sendungsnummer aus erkanntem Vorschlag übernehmen if ($action === 'apply_tracking' && $user->hasRight('mahnung', 'write')) { $nr = trim((string) GETPOST('nr', 'alphanohtml')); $prov = GETPOST('provider', 'aZ09'); if ($nr !== '' && $prov !== '') { $mahnung->tracking_nr = $nr; $mahnung->tracking_provider = $prov; // Versanddaten gleich mitsetzen wenn noch leer if (empty($mahnung->date_versand)) { $mahnung->date_versand = dol_now(); } if (empty($mahnung->versandweg)) { // Provider → passender Versandweg $provToWeg = array('dpag' => 'einschreiben', 'dhl' => 'dhl', 'dpd' => 'dpd', 'hermes' => 'hermes', 'ups' => 'ups'); $mahnung->versandweg = $provToWeg[$prov] ?? 'post'; } if ($mahnung->update($user) > 0) { setEventMessages($langs->trans('MahnungTrackingUebernommen'), null, 'mesgs'); } } // Vorschlag aus Session entfernen unset($_SESSION['mahnung_tracking_suggestions_'.((int) $mahnung->id)]); header('Location: '.$_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id)); exit; } // Vorschläge verwerfen if ($action === 'dismiss_tracking' && $user->hasRight('mahnung', 'write')) { unset($_SESSION['mahnung_tracking_suggestions_'.((int) $mahnung->id)]); header('Location: '.$_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id)); exit; } // Belege scannen: pdftotext + Pattern-Matching if ($action === 'scan_belege' && $user->hasRight('mahnung', 'write')) { require_once DOL_DOCUMENT_ROOT.'/custom/mahnung/class/mahnungtrackingpattern.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $scanRef = dol_sanitizeFileName($mahnung->ref); $scanDir = (!empty($conf->mahnung->multidir_output[$mahnung->entity]) ? $conf->mahnung->multidir_output[$mahnung->entity] : $conf->mahnung->dir_output ?? (DOL_DATA_ROOT.'/mahnung')) .'/'.$scanRef; $patternService = new MahnungTrackingPattern($db); $suggestions = array(); $pdftotextAvailable = null; $ocrmypdfAvailable = null; if (is_dir($scanDir)) { foreach (dol_dir_list($scanDir, 'files', 0) as $file) { $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); $text = ''; if ($ext === 'txt' || $ext === 'html' || $ext === 'htm') { $text = @file_get_contents($file['fullname']); if ($ext === 'html' || $ext === 'htm') { $text = strip_tags((string) $text); } } elseif ($ext === 'pdf') { if ($pdftotextAvailable === null) { $check = @shell_exec('command -v pdftotext 2>/dev/null'); $pdftotextAvailable = !empty(trim((string) $check)); } if ($pdftotextAvailable) { // Erst normales pdftotext versuchen $cmd = 'pdftotext -layout '.escapeshellarg($file['fullname']).' - 2>/dev/null'; $text = trim((string) @shell_exec($cmd), " \t\n\r\0\x0B\x0C"); // 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 === '') { continue; } $hit = $patternService->detectFromText($text); if ($hit !== null) { $suggestions[] = array( 'file' => $file['name'], 'provider' => $hit['provider'], 'nr' => $hit['nr'], 'url' => $hit['url'], 'label' => $hit['label'], ); } } } $_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'); } header('Location: '.$_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id)); exit; } // Versand-Daten zurücksetzen (z.B. Korrekturmöglichkeit) if ($action === 'clear_versand' && $user->hasRight('mahnung', 'write')) { $mahnung->date_versand = null; $mahnung->versandweg = null; $mahnung->tracking_nr = null; $mahnung->tracking_provider = null; // Status nicht zurückdrehen — nur Daten löschen if ($mahnung->update($user) > 0) { setEventMessages($langs->trans('MahnungVersandGeleert'), null, 'mesgs'); } header('Location: '.$_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id)); exit; } // Upload-Verzeichnis für Sendebelege (muss VOR llxHeader stehen für actions_linkedfiles) require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $mahnungSafeRef = dol_sanitizeFileName($mahnung->ref); $upload_dir = (!empty($conf->mahnung->multidir_output[$mahnung->entity]) ? $conf->mahnung->multidir_output[$mahnung->entity] : $conf->mahnung->dir_output ?? (DOL_DATA_ROOT.'/mahnung')) .'/'.$mahnungSafeRef; if (!is_dir($upload_dir)) { dol_mkdir($upload_dir); } $permissiontoadd = $user->hasRight('mahnung', 'write'); $permissiontodelete = $user->hasRight('mahnung', 'write'); include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; llxHeader('', $langs->trans('MahnungRef').' '.$mahnung->ref); print load_fiche_titre($langs->trans('MahnungRef').' '.$mahnung->ref, '', 'fa-envelope-open-text'); print '
'; print '
'; print ''; print ''; print ''; print ''; print ''; print ''; // Rechnung $facture = new Facture($db); if ($facture->fetch((int) $mahnung->fk_facture) > 0) { print ''; print ''; } // Kunde $societe = new Societe($db); if ($societe->fetch((int) $mahnung->fk_soc) > 0) { print ''; print ''; } print ''; print ''; if ((float) $mahnung->pauschale_b2b > 0) { print ''; } print ''; print ''; print ''; print '
'.$langs->trans('MahnungRef').''.dol_escape_htmltag($mahnung->ref).'
'.$langs->trans('MahnungStufe').''.((int) $mahnung->stufe).'
'.$langs->trans('MahnungDatum').''.dol_print_date($mahnung->date_mahnung, 'day').'
'.$langs->trans('MahnungFaelligkeitAlt').''.dol_print_date($mahnung->date_lim_reglement_alt, 'day').'
'.$langs->trans('MahnungFaelligkeitNeu').''.dol_print_date($mahnung->date_lim_reglement_neu, 'day').'
'.$langs->trans('MahnungRechnung').''.dol_escape_htmltag($facture->ref).'
'.$langs->trans('MahnungKunde').''.dol_escape_htmltag($societe->name).' ('.dol_escape_htmltag((string) $mahnung->customertype).')
'.$langs->trans('MahnungBetragOffen').''.price($mahnung->betrag_offen).'
'.$langs->trans('MahnungGebuehr').''.price($mahnung->mahngebuehr).'
'.$langs->trans('MahnungPauschaleB2B').''.price($mahnung->pauschale_b2b).'
'.$langs->trans('MahnungVerzugszinsen').''.price($mahnung->verzugszinsen).' (Basiszins '.number_format((float) $mahnung->basiszins_snapshot, 2, ',', '.').' %)
'.$langs->trans('MahnungSumme').''.price($mahnung->summe_mahnung).'
'.$langs->trans('Status').''.dol_escape_htmltag($mahnung->getStatusLabel()).'
'; print '
'; // Ende fichecenter Stammdaten // --- Generierte Dokumente (wie bei Rechnungen) --- print '
'; print load_fiche_titre($langs->trans('Documents'), '', 'fa-file'); // Dokumente im Rechnungsordner suchen die zur Mahnung gehoeren $docDir = ''; if ($facture->id > 0) { $docDir = !empty($conf->facture->multidir_output[$facture->entity]) ? $conf->facture->multidir_output[$facture->entity] : $conf->facture->dir_output; $docDir .= '/'.dol_sanitizeFileName($facture->ref); } $fileList = array(); if (!empty($docDir) && is_dir($docDir)) { $allFiles = dol_dir_list($docDir, 'files', 0, preg_quote($mahnungSafeRef, '/')); foreach ($allFiles as $f) { $fileList[] = $f; } } if (!empty($fileList)) { $canDeleteDoc = $user->hasRight('mahnung', 'write'); print ''; print ''; print ''; print ''; print ''; print ''; print ''; foreach ($fileList as $f) { $fname = $f['name']; $relativePath = dol_sanitizeFileName($facture->ref).'/'.$fname; $dlUrl = DOL_URL_ROOT.'/document.php?modulepart=facture&file='.urlencode($relativePath); $viewUrl = $dlUrl.'&attachment=0'; $ext = strtolower(pathinfo($fname, PATHINFO_EXTENSION)); $icon = ($ext === 'pdf') ? 'pdf' : (($ext === 'odt') ? 'ooffice' : 'generic'); $filesize = !empty($f['size']) ? $f['size'] : filesize($f['fullname']); $filedate = !empty($f['date']) ? $f['date'] : filemtime($f['fullname']); print ''; // Dateiname mit Icon + Lupe direkt daneben print ''; // Groesse print ''; // Datum print ''; // Aktionen: Download + Löschen print ''; print ''; } print '
'.$langs->trans('Document').''.$langs->trans('Size').''.$langs->trans('Date').'
'; print ''; print img_picto('', $icon, 'class="pictofixedwidth"'); print dol_escape_htmltag($fname); print ''; if ($ext === 'pdf') { print ' '.img_picto($langs->trans('Preview'), 'search').''; } print ''.dol_print_size($filesize, 0, 0).''.dol_print_date($filedate, 'dayhour').''; print ''.img_picto($langs->trans('Download'), 'download').''; if ($canDeleteDoc) { $delUrl = $_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id).'&action=delete_doc&file='.urlencode($fname).'&token='.newToken(); print ' '; print img_picto($langs->trans('Delete'), 'delete'); print ''; } print '
'; } else { print '
'.$langs->trans('NoDocuments').'
'; } // Aktionen require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; $form = new Form($db); $formfile = new FormFile($db); // --- Versand & Belege --- print '
'; print load_fiche_titre($langs->trans('MahnungVersandBelege'), '', 'fa-truck'); print '
'; print '
'; // Versandwege (Dropdown-Optionen, Label kommt aus Lang-File MahnungVersandweg*) $versandwege = array( 'post' => $langs->trans('MahnungVersandwegPost'), 'einschreiben' => $langs->trans('MahnungVersandwegEinschreiben'), 'dhl' => $langs->trans('MahnungVersandwegDhl'), 'dpd' => $langs->trans('MahnungVersandwegDpd'), 'hermes' => $langs->trans('MahnungVersandwegHermes'), 'ups' => $langs->trans('MahnungVersandwegUps'), 'fax' => $langs->trans('MahnungVersandwegFax'), 'email' => $langs->trans('MahnungVersandwegEmail'), 'persoenlich' => $langs->trans('MahnungVersandwegPersoenlich'), 'eigen' => $langs->trans('MahnungVersandwegEigen'), ); $editVersand = ($action === 'edit_versand') || empty($mahnung->date_versand); $canWrite = $user->hasRight('mahnung', 'write'); if (!empty($mahnung->date_versand) && $action !== 'edit_versand') { // Anzeige der bereits erfassten Versanddaten print ''; print ''; print ''; if (!empty($mahnung->tracking_nr)) { require_once DOL_DOCUMENT_ROOT.'/custom/mahnung/class/mahnungtrackingpattern.class.php'; $trackUrl = (new MahnungTrackingPattern($db))->urlFor((string) $mahnung->tracking_provider, (string) $mahnung->tracking_nr); print ''; } print '
'.$langs->trans('MahnungVersanddatum').''.dol_print_date($mahnung->date_versand, 'day').'
'.$langs->trans('MahnungVersandweg').'' .($mahnung->versandweg && isset($versandwege[$mahnung->versandweg]) ? dol_escape_htmltag($versandwege[$mahnung->versandweg]) : dol_escape_htmltag((string) $mahnung->versandweg)) .'
'.$langs->trans('MahnungTrackingNr').''; print ''.dol_escape_htmltag($mahnung->tracking_nr).''; if (!empty($trackUrl)) { print ' '; print img_picto('', 'fa-external-link-alt', 'class="pictofixedwidth"'); print dol_escape_htmltag($langs->trans('MahnungSendungVerfolgen')).''; } print '
'; if ($canWrite) { print '
'; print ''.img_picto('', 'edit').' '.dol_escape_htmltag($langs->trans('MahnungVersandBearbeiten')).' '; print ''.dol_escape_htmltag($langs->trans('MahnungVersandLeeren')).''; print '
'; } } elseif ($canWrite) { // Versand-Formular (Erfassung oder Bearbeitung) $dateInit = !empty($mahnung->date_versand) ? $mahnung->date_versand : dol_now(); print '
'; print ''; print ''; print ''; // Versanddatum print ''; // Versandweg print ''; // Tracking-Nr print ''; // Optional: Tracking-Provider override print ''; print '
'.$langs->trans('MahnungVersanddatum').''; print $form->selectDate($dateInit, 'versand_', 0, 0, 0, '', 1, 0); print '
'.$langs->trans('MahnungVersandweg').''; print ''; print '
'.$langs->trans('MahnungTrackingNr').''; print ''; print ' ('.dol_escape_htmltag($langs->trans('MahnungTrackingProviderAuto')).')'; print '
'.$langs->trans('MahnungTrackingProvider').''; print ''; print '
'; print '
'; print ' '; if (!empty($mahnung->date_versand)) { print ''.dol_escape_htmltag($langs->trans('Cancel')).''; } print '
'; print '
'; } // --- Sendebelege (Beleg-Upload via Dolibarr-Standard) --- print '
'; print load_fiche_titre($langs->trans('MahnungSendebelege'), '', 'fa-paperclip'); print '
'.$langs->trans('MahnungSendebelegeHint').'
'; // Tracking-Vorschläge aus Session-Flash (vom Scan) anzeigen $suggKey = 'mahnung_tracking_suggestions_'.((int) $mahnung->id); $suggestions = $_SESSION[$suggKey] ?? null; if (is_array($suggestions) && !empty($suggestions)) { print '
'; print ''.$langs->trans('MahnungTrackingErkannt').' ('.count($suggestions).')'; print ''; foreach ($suggestions as $sg) { print ''; print ''; print ''; print ''; print ''; print ''; print ''; } print '
'.img_picto('', 'pdf', 'class="pictofixedwidth"').dol_escape_htmltag($sg['file']).''.dol_escape_htmltag($sg['label']).''.dol_escape_htmltag($sg['nr']).''.img_picto('', 'fa-external-link-alt').''; if ($canWrite) { $applyUrl = $_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id).'&action=apply_tracking' .'&nr='.urlencode((string) $sg['nr']) .'&provider='.urlencode((string) $sg['provider']) .'&token='.newToken(); print ''.dol_escape_htmltag($langs->trans('MahnungTrackingUebernehmen')).''; } print '
'; if ($canWrite) { print '
'.dol_escape_htmltag($langs->trans('MahnungTrackingVerwerfen')).'
'; } print '
'; } // Scan-Button (Belege durchsuchen) if ($canWrite) { print '
'; print ''; print img_picto('', 'fa-search', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MahnungBelegeScannen')); print ' '; print ''.$langs->trans('MahnungBelegeScannenHint').''; print '
'; } $urlSelf = $_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id); // Upload-Formular (Durchsuchen + Upload-Button) $formfile->form_attach_new_file( $urlSelf, '', // title 0, // addcancel 0, // sectionid (int) $canWrite, // perm 50, // size $mahnung, // object '', // options 1, // useajax '', // savingdocmask 0, // linkfiles 'formuserfile', // htmlname '', // accept '', // sectiondir 0, // usewithoutform 0, // capture 0 // disablemulti ); // Dateiliste der bereits hochgeladenen Belege print $formfile->showdocuments( 'mahnung', // $modulepart $mahnungSafeRef, // $modulesubdir $upload_dir, // $filedir $urlSelf, // $urlsource 0, // $genallowed (kein PDF-Gen-Button hier) (int) $canWrite, // $delallowed '', // $modelselected 0, // $allowgenifempty 0, // $forcenomultilang 0, // $iconPDF 0, // $notused 0, // $noform '', // $param '', // $title '', // $buttonlabel '', // $codelang '', // $morepicto $mahnung, // $object 0 // $hideifempty ); print '
'; // Ende fichecenter Versand & Belege if ($mahnung->status !== Mahnung::STATUS_STORNIERT && $user->hasRight('mahnung', 'delete')) { if ($action === 'confirm_storno') { print $form->formconfirm( $_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id), $langs->trans('MahnungStornieren'), $langs->trans('MahnungStornieren').' — '.dol_escape_htmltag($mahnung->ref).'?', 'storno', '', 0, 1 ); } if ($action === 'ask_uneinbringlich') { // Bestätigungsdialog mit Eingabefeld für Begründung $formquestion = array( array( 'type' => 'textarea', 'name' => 'uneinbringlich_note', 'label' => $langs->trans('MahnungUneinbringlichBegruendung'), 'value' => $langs->trans('MahnungVerfahrenErfolglos').' '.dol_print_date(dol_now(), 'day'), 'morecss' => 'minwidth500 quatrevingtpercent', ), ); print $form->formconfirm( $_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id), $langs->trans('MahnungUneinbringlichTitel'), $langs->trans('MahnungUneinbringlichWarnung').' '.dol_escape_htmltag($mahnung->ref).'?', 'confirm_uneinbringlich', $formquestion, 0, 1, 300 ); } } print '
'; if ($user->hasRight('mahnung', 'write')) { // Modellauswahl require_once DOL_DOCUMENT_ROOT.'/custom/mahnung/core/modules/mahnung/modules_mahnung.php'; $modellist = ModelePDFMahnung::liste_modeles($db); $defaultModel = getDolGlobalString('MAHNUNG_ADDON_PDF', 'standard_mahnung'); if (is_array($modellist) && count($modellist) > 1) { print ''; } print ''; print $langs->trans('MahnungGenerate'); print ' '; } // "Als uneinbringlich klassifizieren" — nur für Stufe-3-Mahnungen mit // Status >= ERSTELLT (also nicht im Entwurf) und nicht bereits storniert. // Setzt die Rechnung auf STATUS_ABANDONED mit close_code='badcustomer'. if ($mahnung->status !== Mahnung::STATUS_STORNIERT && (int) $mahnung->stufe === 3 && (int) $mahnung->status >= Mahnung::STATUS_ERSTELLT && $user->hasRight('mahnung', 'delete') ) { // Prüfen ob Rechnung schon abandoned ist — dann Button verstecken $facStatus = 0; $facRes = $db->query("SELECT fk_statut, close_code FROM ".MAIN_DB_PREFIX."facture WHERE rowid = ".((int) $mahnung->fk_facture)); if ($facRes && ($facObj = $db->fetch_object($facRes))) { $facStatus = (int) $facObj->fk_statut; $db->free($facRes); } if ($facStatus !== 3) { print ''; print img_picto('', 'warning', 'class="pictofixedwidth"'); print $langs->trans('MahnungUneinbringlich'); print ''; } else { // Rechnung ist schon als abandoned markiert — Info anzeigen print ''.dol_escape_htmltag($langs->trans('MahnungRechnungBereitsUneinbringlich')).''; } } if ($mahnung->status !== Mahnung::STATUS_STORNIERT && $user->hasRight('mahnung', 'delete')) { print ''; print $langs->trans('MahnungStornieren'); print ''; } print '
'; llxFooter(); $db->close();