366 lines
12 KiB
PHP
366 lines
12 KiB
PHP
<?php
|
|
|
|
use TCPDF;
|
|
|
|
if (!isset($baseDir)) {
|
|
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
|
}
|
|
|
|
require_once $baseDir . '/../scripts/session_functions.php';
|
|
|
|
ini_wkvs_session();
|
|
|
|
check_user_permission('wk_leitung');
|
|
|
|
verify_csrf();
|
|
|
|
if (!isset($baseDir)) {
|
|
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
|
}
|
|
|
|
$type = 'kr';
|
|
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
|
|
|
if ($data['success'] === false) {
|
|
header('Content-Type: application/json');
|
|
echo json_encode(['success' => false, 'message' => $data['message']]);
|
|
exit;
|
|
}
|
|
|
|
require $baseDir . '/../scripts/db/db-tables.php';
|
|
require $baseDir . '/../scripts/db/db-functions.php';
|
|
|
|
$wkName = db_get_var($mysqli, "SELECT `value` FROM $db_tabelle_var WHERE `name` = ?", ['wkName']);
|
|
|
|
$wkName = ($wkName === null) ? 'Keinen Wettkampfname angegeben. Setzen unter: /intern/wk-leitung/einstellungen' : $wkName;
|
|
|
|
$normalFontSize = 11;
|
|
$marginSide = 10;
|
|
$marginTop = 10;
|
|
$minMarginBottomTable = 20;
|
|
$format = 'A4';
|
|
$orientation = 'L';
|
|
|
|
$svgs = [
|
|
'1' => '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M6 2h12v2a6 6 0 0 1-6 6 6 6 0 0 1-6-6V2zm0 20h12v-2a6 6 0 0 0-6-6 6 6 0 0 0-6 6v2zm6-10c1.657 0 3-1.343 3-3H9c0 1.657 1.343 3 3 3z" fill="#0073aa"/></svg>',
|
|
'2' => '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" fill="#28a745"/><path d="M7 12l3 3 7-7" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>',
|
|
'3' => '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" fill="#dc3545"/><path d="M8 8l8 8M16 8l-8 8" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>'
|
|
];
|
|
|
|
$now = trim($_POST['date'] ?? date('Y-m-d H:i:s'));
|
|
|
|
$logEntries = db_select($mysqli, $db_tabelle_verbuchte_startgebueren_log, "*");
|
|
|
|
$personen = db_select($mysqli, $db_tabelle_intern_benutzende, "`id`, `name_person`, `username`");
|
|
|
|
$indexedPersonen = array_column($personen, null, 'id');
|
|
|
|
$entriesArray = [];
|
|
|
|
foreach ($logEntries as $slE) {
|
|
|
|
// $value = ($slE['old_order_status'] !== null) ? ($svgs[$slE['old_order_status']] ?? $slE['old_order_status']) . ' ' . json_decode('"\u2192"') . ' ' . ($svgs[$slE['new_order_status'] ?? ''] ?? $slE['new_order_status'] ?? '') : ($svgs[$slE['new_order_status'] ?? ''] ?? $slE['new_order_status'] ?? '');
|
|
|
|
$valueArray = [
|
|
1 => $svgs[$slE['old_order_status'] ?? ''] ?? '',
|
|
2 => isset($svgs[$slE['old_order_status']]),
|
|
3 => $svgs[$slE['new_order_status'] ?? ''] ?? '',
|
|
4 => isset($svgs[$slE['new_order_status']])
|
|
];
|
|
|
|
$entriesArray[] = [
|
|
'order_id' => $slE['order_id'] ?? '',
|
|
'value' => $valueArray,
|
|
'edited_by' => $indexedPersonen[$slE['edited_by']]['name_person'] ?? 'Unbekannter User',
|
|
'timestamp' => new DateTime($slE['edited_at'])->format('d.m.Y H:i:s') ?? '---'
|
|
];
|
|
}
|
|
|
|
// Load TCPDF
|
|
require $baseDir . '/../composer/vendor/autoload.php';
|
|
|
|
class ProtokollPDF extends TCPDF
|
|
{
|
|
public $columns;
|
|
public $wkName;
|
|
public $marginSide;
|
|
public $marginTop;
|
|
public $pdfHeight;
|
|
public $pdfWidth;
|
|
public $headerType;
|
|
public $now;
|
|
// Page header
|
|
|
|
public $headerBottomY = 0;
|
|
|
|
|
|
public function Header()
|
|
{
|
|
$this->SetFillColor(255, 255, 255);
|
|
|
|
$this->Rect(0, 0, $this->pdfWidth, $this->pdfHeight, 'F');
|
|
|
|
$arrayTitles = [];
|
|
$image_file = $_SERVER['DOCUMENT_ROOT'] . '/intern/img/logo-normal.png';
|
|
$this->SetY($this->marginTop);
|
|
$this->SetX(($this->marginSide ?? 10));
|
|
$this->SetFont('freesans', '', 20);
|
|
|
|
$this->Cell(0, 0, 'Protokoll Rechnungen ' . $this->wkName, 0, 1, 'L', 0, '', 0, false, 'T', 'M');
|
|
$preimageX = $this->GetX();
|
|
$preimageY = $this->GetY();
|
|
$this->Image($image_file, $this->pdfWidth - 10 - $this->marginSide, $this->marginTop, '', 10, 'png', '', 'T');
|
|
|
|
$this->SetY($preimageY + 5);
|
|
$this->SetX($this->marginSide ?? 10); // Force back to left margin
|
|
$this->SetFont('freesans', '', 11);
|
|
|
|
$this->Ln(5);
|
|
|
|
$columns = $this->columns;
|
|
$startY = $this->GetY();
|
|
$this->SetFont('', 'B');
|
|
|
|
$this->SetX($this->marginSide ?? 10);
|
|
|
|
foreach ($columns as $col) {
|
|
|
|
$title = $col['header'];
|
|
|
|
if (($col['rotate'] ?? false)) {
|
|
$x = $this->GetX();
|
|
$y = $this->GetY() + 7;
|
|
|
|
$this->StartTransform();
|
|
$this->Rotate(45, $x, $y);
|
|
|
|
$lineY = $startY + 7;
|
|
if (($col['id'] ?? '') === 'gesamt') {
|
|
$this->SetLineWidth(0.6);
|
|
} else {
|
|
$this->SetLineWidth(0.2);
|
|
}
|
|
|
|
$this->Line($x, $lineY, $x + ($col['width_header'] ?? 0), $lineY);
|
|
$this->SetLineWidth(0.2);
|
|
|
|
$this->Cell($col['width_header'] ?? 0, 7, $title ?? '', 0, 0, 'C');
|
|
$this->StopTransform();
|
|
$this->SetX($x + ($col['max_width'] ?? 0));
|
|
} else {
|
|
$this->Cell($col['max_width'] ?? 0, 7, $title ?? '', 0, 0, $col['align'] ?? 'L');
|
|
}
|
|
}
|
|
|
|
$this->Ln();
|
|
$this->headerBottomY = $this->GetY();
|
|
}
|
|
|
|
|
|
// Page footer
|
|
public function Footer()
|
|
{
|
|
$this->SetLineWidth(0.6);
|
|
$this->Line($this->marginSide ?? 10, $this->headerBottomY, $this->pdfWidth - ($this->marginSide ?? 10), $this->headerBottomY);
|
|
|
|
$this->SetLineWidth(0.2);
|
|
|
|
$this->SetY(0);
|
|
$this->SetX(0);
|
|
|
|
$this->SetFillColor(255, 255, 255); // white
|
|
|
|
$this->Cell(($this->marginSide ?? 10), $this->pdfHeight, '', 0, 0, 'L', true);
|
|
|
|
$this->SetY(0);
|
|
$this->SetX($this->pdfWidth - ($this->marginSide ?? 10));
|
|
|
|
$this->Cell(($this->marginSide ?? 10), $this->pdfHeight, '', 0, 0, 'L', true);
|
|
|
|
$this->SetY(-15);
|
|
$this->SetFont('freesans', 'I', 8);
|
|
|
|
// 1. Page Number - Centered
|
|
$this->Cell(0, 10, 'Seite ' . $this->getAliasNumPage() . ' von ' . $this->getAliasNbPages(), 0, false, 'C');
|
|
|
|
// 2. Timestamp - Force to Left
|
|
$this->SetX($this->getMargins()['left']); // Reset to left margin
|
|
$this->Cell(0, 10, 'Zeitstempel: ' . $this->now, 0, false, 'L');
|
|
|
|
// 3. Host - Force to Right (Cell with width 0 and align 'R' handles this)
|
|
$this->SetX($this->getMargins()['left']); // Reset again so 'R' alignment works from the start
|
|
$this->Cell(0, 10, $_SERVER['HTTP_HOST'], 0, 0, 'R', false, 'https://'.$_SERVER['HTTP_HOST']);
|
|
}
|
|
}
|
|
|
|
$pdf = new ProtokollPDF($orientation, 'mm', $format, true, 'UTF-8', false);
|
|
|
|
$pdfHeight = $pdf->getPageHeight();
|
|
$pdfWidth = $pdf->getPageWidth();
|
|
|
|
$pdf->wkName = $wkName;
|
|
$pdf->marginSide = $marginSide;
|
|
$pdf->marginTop = $marginTop;
|
|
$pdf->pdfHeight = $pdfHeight;
|
|
$pdf->pdfWidth = $pdfWidth;
|
|
$pdf->now = $now;
|
|
|
|
$pdf->SetCreator(PDF_CREATOR);
|
|
$pdf->SetAuthor($wkName);
|
|
$pdf->SetTitle($wkName . "_Protokoll.pdf");
|
|
|
|
$pdf->SetAutoPageBreak(FALSE);
|
|
|
|
|
|
$pdf->SetFont('freesans', '', 11);
|
|
|
|
// Define columns dynamically
|
|
$columns = [
|
|
['id' => 'order_id', 'header' => 'Rechnungsnummer', 'align' => 'L', 'flex' => true, 'type' => 'link', 'field' => 'order_id'],
|
|
['id' => 'value', 'header' => 'Änderung', 'align' => 'L', 'flex' => true, 'type' => 'value', 'field' => 'value'],
|
|
['id' => 'edited_by', 'header' => 'Geändert durch', 'align' => 'C', 'flex' => true, 'type' => 'field', 'field' => 'edited_by'],
|
|
['id' => 'timestamp', 'header' => 'Zeitstempel', 'align' => 'C', 'flex' => true, 'type' => 'field', 'field' => 'timestamp'],
|
|
];
|
|
|
|
|
|
$padding = 4;
|
|
|
|
// 1. Calculate initial max widths based on headers
|
|
foreach ($columns as &$col) {
|
|
$col['width_header'] = $pdf->GetStringWidth($col['header']) + ($padding * 2);
|
|
if ($col['type'] !== 'note') {
|
|
$col['max_width'] = $col['width_header'];
|
|
} else {
|
|
$col['max_width'] = 0;
|
|
}
|
|
}
|
|
|
|
unset($col);
|
|
|
|
foreach ($entriesArray as $row) {
|
|
foreach ($columns as $col) {
|
|
$text = '';
|
|
if ($col['type'] !== 'value') {
|
|
if (isset($row[$col['field']])) {
|
|
$text = $row[$col['field']];
|
|
}
|
|
$width = $pdf->GetStringWidth($text) + ($padding * 2);
|
|
if ($width > $col['max_width']) {
|
|
$col['max_width'] = $width;
|
|
}
|
|
} else {
|
|
if (40 > $col['max_width']) {
|
|
$col['max_width'] = 40;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$fixedWidth = 0;
|
|
|
|
foreach ($columns as $col) {
|
|
if ($col['flex'] ?? false) {
|
|
$flexCols[] = $col['id'];
|
|
$fixedWidth += $col['max_width'];
|
|
} else {
|
|
$fixedWidth += $col['max_width'];
|
|
}
|
|
}
|
|
|
|
$tablew = $pdfWidth - (2 * $marginSide);
|
|
|
|
$effTableWidth = $tablew - $fixedWidth;
|
|
|
|
if (!empty($flexCols) && $effTableWidth > 0) {
|
|
$flexTotalInitial = 0;
|
|
foreach ($columns as $col) {
|
|
if ($col['flex'] ?? false) $flexTotalInitial += $col['max_width'];
|
|
}
|
|
|
|
foreach ($columns as &$col) {
|
|
if ($col['flex'] ?? false) {
|
|
$col['max_width'] += ($col['max_width'] / $flexTotalInitial) * $effTableWidth;
|
|
}
|
|
}
|
|
unset($col);
|
|
}
|
|
|
|
$pdf->columns = $columns;
|
|
|
|
$pdf->AddPage();
|
|
$margin_top = $pdf->headerBottomY;
|
|
|
|
$pdf->SetMargins($marginSide, $margin_top, $marginSide); // +5 mm padding below header
|
|
$pdf->SetY($margin_top); // Move cursor below header manually
|
|
|
|
$pdf->SetFont('', '');
|
|
|
|
foreach ($entriesArray as $row) {
|
|
|
|
$rowHeight = 10;
|
|
|
|
foreach ($columns as $col) {
|
|
|
|
$pdf->setFillColor(255, 255, 255);
|
|
|
|
if ($pdf->getY() + $rowHeight > $pdfHeight - $minMarginBottomTable) {
|
|
$pdf->addPage();
|
|
$margin_top = $pdf->headerBottomY;
|
|
$pdf->setY($margin_top);
|
|
}
|
|
|
|
$customFontSize = (isset($col['font_size']) && $col['font_size'] != 0);
|
|
|
|
if ($customFontSize) {
|
|
$pdf->SetFont('', '', $col['font_size']);
|
|
}
|
|
|
|
$startX = $pdf->GetX();
|
|
$startY = $pdf->GetY();
|
|
|
|
if ($col['type'] === 'field') {
|
|
$text = $row[$col['field']] ?? '';
|
|
|
|
$pdf->MultiCell($col['max_width'], $rowHeight, $text, 'B', $col['align'], true, 0, $startX, $startY, true, 0, false, true, $rowHeight, 'M');
|
|
} elseif ($col['type'] === 'value') {
|
|
$pdf->MultiCell($col['max_width'], $rowHeight, '', 'B', $col['align'], true, 0, $startX, $startY, true, 0, false, true, $rowHeight, 'M');
|
|
|
|
$valuesArrary = $row[$col['field']];
|
|
|
|
if (isset($valuesArrary[1]) && isset($valuesArrary[2]) && $valuesArrary[2]) {
|
|
$pdf->ImageSVG('@' . $valuesArrary[1], $startX, $startY + 2, $rowHeight - 4, $rowHeight - 4);
|
|
$pdf->MultiCell(10, $rowHeight, json_decode('"\u2192"'), '', 'C', false, 0, $startX + $rowHeight - 4, $startY, true, 0, false, true, $rowHeight, 'M');
|
|
}
|
|
|
|
if (isset($valuesArrary[3]) && isset($valuesArrary[3]) && $valuesArrary[4]) {
|
|
$pdf->ImageSVG('@' . $valuesArrary[3], $startX + $rowHeight - 4 + 10, $startY + 2, $rowHeight - 4, $rowHeight - 4);
|
|
}
|
|
|
|
$pdf->SetX($startX + $col['max_width']);
|
|
|
|
} elseif ($col['type'] === 'link') {
|
|
$text = $row[$col['field']] ?? '';
|
|
|
|
$pdf->MultiCell($col['max_width'], $rowHeight, $text, 'B', $col['align'], true, 0, $startX, $startY, true, 0, false, true, $rowHeight, 'M');
|
|
|
|
$pdf->Link($startX, $startY, $col['max_width'], $rowHeight, 'https://'.$_SERVER['HTTP_HOST'].'/intern/wk-leitung/rechnungen-viewer?order_id='.$text);
|
|
}
|
|
|
|
if ($customFontSize) {
|
|
$pdf->SetFont('', '', $normalFontSize);
|
|
}
|
|
}
|
|
|
|
$pdf->SetY($startY + $rowHeight);
|
|
}
|
|
$textanzEintaege = (count($entriesArray) > 1) ? 'Einträge': 'Eintrag';
|
|
|
|
$pdf->SetFont('', '', 7);
|
|
|
|
$pdf->Cell(20, 6, count($entriesArray).' '.$textanzEintaege, 0, 0, 'L');
|
|
|
|
$pdf->SetFont('', '', $normalFontSize);
|
|
|
|
|
|
$pdf->Output($wkName . "_Protokoll_Rechnungen.pdf", 'I');
|
|
exit; |