*
* 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 '| '.$langs->trans('MahnungRef').' | '.dol_escape_htmltag($mahnung->ref).' |
';
print '| '.$langs->trans('MahnungStufe').' | '.((int) $mahnung->stufe).' |
';
print '| '.$langs->trans('MahnungDatum').' | '.dol_print_date($mahnung->date_mahnung, 'day').' |
';
print '| '.$langs->trans('MahnungFaelligkeitAlt').' | '.dol_print_date($mahnung->date_lim_reglement_alt, 'day').' |
';
print '| '.$langs->trans('MahnungFaelligkeitNeu').' | '.dol_print_date($mahnung->date_lim_reglement_neu, 'day').' |
';
// Rechnung
$facture = new Facture($db);
if ($facture->fetch((int) $mahnung->fk_facture) > 0) {
print '| '.$langs->trans('MahnungRechnung').' | ';
print ''.dol_escape_htmltag($facture->ref).' |
';
}
// Kunde
$societe = new Societe($db);
if ($societe->fetch((int) $mahnung->fk_soc) > 0) {
print '| '.$langs->trans('MahnungKunde').' | ';
print ''.dol_escape_htmltag($societe->name).' ('.dol_escape_htmltag((string) $mahnung->customertype).') |
';
}
print '| '.$langs->trans('MahnungBetragOffen').' | '.price($mahnung->betrag_offen).' |
';
print '| '.$langs->trans('MahnungGebuehr').' | '.price($mahnung->mahngebuehr).' |
';
if ((float) $mahnung->pauschale_b2b > 0) {
print '| '.$langs->trans('MahnungPauschaleB2B').' | '.price($mahnung->pauschale_b2b).' |
';
}
print '| '.$langs->trans('MahnungVerzugszinsen').' | '.price($mahnung->verzugszinsen).' (Basiszins '.number_format((float) $mahnung->basiszins_snapshot, 2, ',', '.').' %) |
';
print '| '.$langs->trans('MahnungSumme').' | '.price($mahnung->summe_mahnung).' |
';
print '| '.$langs->trans('Status').' | '.dol_escape_htmltag($mahnung->getStatusLabel()).' |
';
print '
';
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 '| '.$langs->trans('Document').' | ';
print ''.$langs->trans('Size').' | ';
print ''.$langs->trans('Date').' | ';
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 '| ';
print '';
print img_picto('', $icon, 'class="pictofixedwidth"');
print dol_escape_htmltag($fname);
print '';
if ($ext === 'pdf') {
print ' '.img_picto($langs->trans('Preview'), 'search').'';
}
print ' | ';
// Groesse
print ''.dol_print_size($filesize, 0, 0).' | ';
// Datum
print ''.dol_print_date($filedate, 'dayhour').' | ';
// Aktionen: Download + Löschen
print '';
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 ' | ';
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 '| '.$langs->trans('MahnungVersanddatum').' | '.dol_print_date($mahnung->date_versand, 'day').' |
';
print '| '.$langs->trans('MahnungVersandweg').' | '
.($mahnung->versandweg && isset($versandwege[$mahnung->versandweg]) ? dol_escape_htmltag($versandwege[$mahnung->versandweg]) : dol_escape_htmltag((string) $mahnung->versandweg))
.' |
';
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 '| '.$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 ' |
';
}
print '
';
if ($canWrite) {
print '
';
}
} elseif ($canWrite) {
// Versand-Formular (Erfassung oder Bearbeitung)
$dateInit = !empty($mahnung->date_versand) ? $mahnung->date_versand : dol_now();
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 '| '.img_picto('', 'pdf', 'class="pictofixedwidth"').dol_escape_htmltag($sg['file']).' | ';
print ''.dol_escape_htmltag($sg['label']).' | ';
print ''.dol_escape_htmltag($sg['nr']).' | ';
print ''.img_picto('', 'fa-external-link-alt').' | ';
print '';
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 ' | ';
print '
';
}
print '
';
if ($canWrite) {
print '
';
}
print '
';
}
// Scan-Button (Belege durchsuchen)
if ($canWrite) {
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();