All checks were successful
Deploy mahnung / deploy (push) Successful in 13s
- ODT-Template-System: Pro Mahnstufe eigenes Template (mahnung_stufe1/2/3.odt), Fallback auf generisches Template; Basis-Klasse ModelePDFMahnung, pdf_standard_mahnung (TCPDF refactored), doc_generic_mahnung_odt (ODTPHP) - Widget box_mahnung_offen: Überfällige Rechnungen mit Mahnstufe-Badge (blau/orange/rot) - card.php: Dokumentenliste mit Lupe (PDF-Vorschau), Download, Modellauswahl - admin/templatevars.php: Referenzseite aller verfügbaren ODT-Variablen - admin/setup.php: Dokumentenmodell-Verwaltung, Upload-Bereich mit Benennungskonvention - mahnung.class.php: generateDocument() + socid-Alias für commonGenerateDocument() - modMahnung.class.php: models=1, MAHNUNG_ADDON_PDF/ODT_PATH-Konstanten, document_model-Registrierung in init(), Widget registriert - mahnungpdf.class.php entfernt, Logik in pdf_standard_mahnung.modules.php Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
229 lines
9 KiB
PHP
229 lines
9 KiB
PHP
<?php
|
|
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
|
|
*
|
|
* 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, 'Mahnung nicht gefunden');
|
|
exit;
|
|
}
|
|
|
|
// 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('Dokument erstellt', null, 'mesgs');
|
|
} else {
|
|
setEventMessages('Dokument-Fehler: '.$mahnung->error, null, 'errors');
|
|
}
|
|
header('Location: '.$_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id));
|
|
exit;
|
|
}
|
|
|
|
llxHeader('', $langs->trans('MahnungRef').' '.$mahnung->ref);
|
|
|
|
print load_fiche_titre($langs->trans('MahnungRef').' '.$mahnung->ref, '', 'fa-envelope-open-text');
|
|
|
|
print '<table class="border centpercent">';
|
|
print '<tr><td class="titlefield">'.$langs->trans('MahnungRef').'</td><td>'.dol_escape_htmltag($mahnung->ref).'</td></tr>';
|
|
print '<tr><td>'.$langs->trans('MahnungStufe').'</td><td>'.((int) $mahnung->stufe).'</td></tr>';
|
|
print '<tr><td>'.$langs->trans('MahnungDatum').'</td><td>'.dol_print_date($mahnung->date_mahnung, 'day').'</td></tr>';
|
|
print '<tr><td>'.$langs->trans('MahnungFaelligkeitAlt').'</td><td>'.dol_print_date($mahnung->date_lim_reglement_alt, 'day').'</td></tr>';
|
|
print '<tr><td>'.$langs->trans('MahnungFaelligkeitNeu').'</td><td>'.dol_print_date($mahnung->date_lim_reglement_neu, 'day').'</td></tr>';
|
|
|
|
// Rechnung
|
|
$facture = new Facture($db);
|
|
if ($facture->fetch((int) $mahnung->fk_facture) > 0) {
|
|
print '<tr><td>'.$langs->trans('MahnungRechnung').'</td>';
|
|
print '<td><a href="'.DOL_URL_ROOT.'/compta/facture/card.php?id='.((int) $facture->id).'">'.dol_escape_htmltag($facture->ref).'</a></td></tr>';
|
|
}
|
|
|
|
// Kunde
|
|
$societe = new Societe($db);
|
|
if ($societe->fetch((int) $mahnung->fk_soc) > 0) {
|
|
print '<tr><td>'.$langs->trans('MahnungKunde').'</td>';
|
|
print '<td><a href="'.DOL_URL_ROOT.'/societe/card.php?socid='.((int) $societe->id).'">'.dol_escape_htmltag($societe->name).'</a> ('.dol_escape_htmltag((string) $mahnung->customertype).')</td></tr>';
|
|
}
|
|
|
|
print '<tr><td>'.$langs->trans('MahnungBetragOffen').'</td><td>'.price($mahnung->betrag_offen).'</td></tr>';
|
|
print '<tr><td>'.$langs->trans('MahnungGebuehr').'</td><td>'.price($mahnung->mahngebuehr).'</td></tr>';
|
|
if ((float) $mahnung->pauschale_b2b > 0) {
|
|
print '<tr><td>'.$langs->trans('MahnungPauschaleB2B').'</td><td>'.price($mahnung->pauschale_b2b).'</td></tr>';
|
|
}
|
|
print '<tr><td>'.$langs->trans('MahnungVerzugszinsen').'</td><td>'.price($mahnung->verzugszinsen).' (Basiszins '.number_format((float) $mahnung->basiszins_snapshot, 2, ',', '.').' %)</td></tr>';
|
|
print '<tr><td>'.$langs->trans('MahnungSumme').'</td><td><strong>'.price($mahnung->summe_mahnung).'</strong></td></tr>';
|
|
print '<tr><td>Status</td><td>'.dol_escape_htmltag($mahnung->getStatusLabel()).'</td></tr>';
|
|
print '</table>';
|
|
|
|
// --- Generierte Dokumente (wie bei Rechnungen) ---
|
|
print '<br>';
|
|
print load_fiche_titre($langs->trans('Documents'), '', 'fa-file');
|
|
|
|
// Dokumente im Rechnungsordner suchen die zur Mahnung gehoeren
|
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
|
$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);
|
|
}
|
|
|
|
$mahnungRef = dol_sanitizeFileName($mahnung->ref);
|
|
$fileList = array();
|
|
if (!empty($docDir) && is_dir($docDir)) {
|
|
$allFiles = dol_dir_list($docDir, 'files', 0, preg_quote($mahnungRef, '/'));
|
|
foreach ($allFiles as $f) {
|
|
$fileList[] = $f;
|
|
}
|
|
}
|
|
|
|
if (!empty($fileList)) {
|
|
print '<table class="noborder centpercent">';
|
|
print '<tr class="liste_titre">';
|
|
print '<th>'.$langs->trans('Document').'</th>';
|
|
print '<th class="right">'.$langs->trans('Size').'</th>';
|
|
print '<th class="center">'.$langs->trans('Date').'</th>';
|
|
print '<th class="center"></th>';
|
|
print '</tr>';
|
|
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'; // Inline-Ansicht (keine Download-Erzwingung)
|
|
$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 '<tr class="oddeven">';
|
|
// Dateiname mit Icon
|
|
print '<td class="nowraponall">';
|
|
print '<a href="'.$dlUrl.'">';
|
|
print img_picto('', $icon, 'class="pictofixedwidth"');
|
|
print dol_escape_htmltag($fname);
|
|
print '</a>';
|
|
print '</td>';
|
|
// Groesse
|
|
print '<td class="right nowraponall">'.dol_print_size($filesize, 0, 0).'</td>';
|
|
// Datum
|
|
print '<td class="center nowraponall">'.dol_print_date($filedate, 'dayhour').'</td>';
|
|
// Aktionen: Vorschau + Download
|
|
print '<td class="right nowraponall">';
|
|
if ($ext === 'pdf') {
|
|
print '<a href="'.$viewUrl.'" target="_blank" title="'.dol_escape_htmltag($langs->trans('Preview')).'">'.img_picto($langs->trans('Preview'), 'search', 'class="pictofixedwidth"').'</a> ';
|
|
}
|
|
print '<a href="'.$dlUrl.'">'.img_picto($langs->trans('Download'), 'download', 'class="pictofixedwidth"').'</a>';
|
|
print '</td>';
|
|
print '</tr>';
|
|
}
|
|
print '</table>';
|
|
} else {
|
|
print '<div class="opacitymedium">'.$langs->trans('NoDocuments').'</div>';
|
|
}
|
|
|
|
// Aktionen
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
|
|
$form = new Form($db);
|
|
|
|
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
|
|
);
|
|
}
|
|
}
|
|
|
|
print '<br><div class="tabsAction">';
|
|
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 '<select name="model" id="selectmodel" style="margin-right: 5px;">';
|
|
foreach ($modellist as $k => $v) {
|
|
print '<option value="'.dol_escape_htmltag($k).'"'.($k === $defaultModel ? ' selected' : '').'>'.dol_escape_htmltag($v).'</option>';
|
|
}
|
|
print '</select>';
|
|
}
|
|
|
|
print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id).'&action=regenerate_pdf&token='.newToken().'" onclick="if(document.getElementById(\'selectmodel\')){this.href+=\'&model=\'+document.getElementById(\'selectmodel\').value;}">';
|
|
print $langs->trans('MahnungGenerate');
|
|
print '</a> ';
|
|
}
|
|
if ($mahnung->status !== Mahnung::STATUS_STORNIERT && $user->hasRight('mahnung', 'delete')) {
|
|
print '<a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?id='.((int) $mahnung->id).'&action=confirm_storno">';
|
|
print $langs->trans('MahnungStornieren');
|
|
print '</a>';
|
|
}
|
|
print '</div>';
|
|
|
|
llxFooter();
|
|
$db->close();
|