First version, for githup; UNSTABLE, DO NOT USE!

This commit is contained in:
Fabio Herzig
2026-04-12 21:25:44 +02:00
commit a51fd9dbeb
423 changed files with 58560 additions and 0 deletions

View File

@@ -0,0 +1,424 @@
<?php
use Sprain\SwissQrBill\PaymentPart\Output\DisplayOptions;
use Sprain\SwissQrBill\PaymentPart\Output\TcPdfOutput\TcPdfOutput;
use TCPDF;
if (!isset($baseDir)) $baseDir = $_SERVER['DOCUMENT_ROOT'];
require $baseDir . '/../composer/vendor/autoload.php';
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
// Show all errors except deprecation notices (these come from vendor libraries
// that aren't yet typed for newer PHP versions). Long-term fix: update
// dependencies to versions compatible with your PHP runtime.
error_reporting(E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED);
// Add a higher memory limit
ini_set('memory_limit', '256M'); // Start with 256M, increase if needed
session_start();
if (empty($_SESSION['access_granted_trainer']) || $_SESSION['access_granted_trainer'] !== true || empty($_SESSION['passcodetrainer_id']) || $_SESSION['passcodetrainer_id'] < 1) {
http_response_code(403);
header("Location: /intern/trainer");
exit;
}
if (!isset($_SESSION['order_id']) || !isset($_SESSION['order_preis'])) {
http_response_code(403);
exit;
}
if (!isset($_POST['order_id']) || !isset($_POST['preis']) || !isset($_POST['name']) || !isset($_POST['vorname']) || !isset($_POST['strasse']) || !isset($_POST['plz']) || !isset($_POST['ort'])) {
http_response_code(422);
exit;
}
if (intval($_SESSION['order_id']) !== intval($_POST['order_id']) || intval($_SESSION['order_preis']) !== intval($_POST['preis'])) {
http_response_code(401);
exit;
}
$type = 'tr';
$data = include $baseDir. '/../scripts/db/db-verbindung-script.php';
if ($data['success'] === false){
echo json_encode(['success' => false, 'message' => $data['message']]);
exit;
}
require $baseDir. '/../scripts/db/db-functions.php';
require $baseDir . '/../scripts/db/db-tables.php';
$dbresult = db_select($mysqli, $tableOrders, '*', 'order_id = ?', [$_POST['order_id']]);
if ($dbresult === false || count($dbresult) === 0) {
echo json_encode(['success' => false, 'message' => 'Order not found']);
exit;
} elseif (count($dbresult) > 1) {
echo json_encode(['success' => false, 'message' => 'Error: Multiple orders found with the same ID']);
exit;
}
$wkName = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['wkName']);
$rechnungenName = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenName']);
$rechnungenVorname = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenVorname']);
$rechnungenStrasse = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenStrasse']);
$rechnungenHausnummer = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenHausnummer']);
$rechnungenPostleitzahl = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenPostleitzahl']);
$rechnungenOrt = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenOrt']);
$rechnungenIBAN = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenIBAN']);
$linkWebseite = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['linkWebseite']);
$dbresult = $dbresult[0];
$orderStatus = (floatval($_SESSION['order_preis']) === 0.0 && !isset($_POST['postversand'])) ? 2 : 1 ;
$orderId = intval($_POST['order_id']);
$current_year = date('Y');
$monat = date('n');
if ($monat > 6) $current_year++;
class MYPDF extends TCPDF
{
public $columns;
public $headerBottomY = 0;
public $firstPageDone = false; // track first page
public $printfooter;
public function Header()
{
// Logo always
$image_file = $_SERVER['DOCUMENT_ROOT'] . '/intern/img/logo-normal.png';
$this->Image($image_file, 180, 15, 15);
// Table header only for subsequent pages
if ($this->firstPageDone && !empty($this->columns)) {
// Use same top margin as table
$this->SetY(35); // or another fixed Y
$this->SetX(15);
$this->SetFont('GoogleSansFlex-Regular', '', 11);
$this->setCellPaddings(2, 0, 2, 0);
foreach ($this->columns as $c) {
$this->Cell($c['max_width'], 10, $c['header'], 0, 0, 'L');
}
$this->Ln();
$this->headerBottomY = $this->GetY();
$this->SetLineWidth(0.6);
$this->Line(15, $this->GetY(), 210 - 15, $this->GetY());
$this->SetLineWidth(0.2);
}
}
public function Footer()
{
}
}
// --- Create PDF ---
$pdf = new MYPDF('P', 'mm', 'A4', true, 'UTF-8', false);
$pdf->current_year = (date('n') > 6) ? date('Y') + 1 : date('Y');
$pdf->wkp_name = $rechnungenVorname . ' ' . $rechnungenName;
$pdf->wkp_adresse = $rechnungenStrasse . ' ' . $rechnungenHausnummer;
$pdf->wkp_plz_ort = $rechnungenPostleitzahl . ' ' . $rechnungenOrt;
$pdf->wkp_url = $linkWebseite;
$pdf->wk_name = $wkName;
$pdf->pers_name = $_POST['vorname'] . ' ' . $_POST['name'];
$pdf->pers_adresse = $_POST['strasse'] . ' ' . $_POST['hausnummer'];
$pdf->pers_plz_ort = $_POST['plz'] . ' ' . $_POST['ort'];
$pdf->printfooter = true;
// Mark first page done so Header() prints table headers on subsequent pages
$pdf->firstPageDone = false;
$pdf->setCellPaddings(2, 0, 2, 0);
$pdf->SetMargins(15, 35, 15);
// Fonts
$pdf->AddFont('GoogleSansFlex9pt-Bold', '', $_SERVER['DOCUMENT_ROOT'] . '/../private-files/tcpdf-fonts/googlesansflex_9ptb.php');
$pdf->AddFont('GoogleSansFlex-Regular', '', $_SERVER['DOCUMENT_ROOT'] . '/../private-files/tcpdf-fonts/gsf.php');
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('WKVS');
$pdf->SetAutoPageBreak(TRUE, 10);
$pdf->SetFont('GoogleSansFlex-Regular', '', 11);
// --- Add a page ---
$pdf->AddPage();
// --- Sender block (left) ---
$pdf->SetX(15);
$pdf->Cell(0, 0, $pdf->wkp_name, 0, 1);
$pdf->Cell(0, 0, $pdf->wkp_adresse, 0, 1);
$pdf->Cell(0, 0, $pdf->wkp_plz_ort, 0, 1);
$pdf->Ln(7);
$pdf->Cell(0, 0, $pdf->wkp_url, 0, 1);
// --- Recipient block (right / window) ---
$x = 110; // X coordinate for right window
$y = 50; // Y coordinate
$w = 80; // Width of recipient block
$address = implode("\n", [
$pdf->pers_name,
$pdf->pers_adresse,
$pdf->pers_plz_ort
]);
$pdf->MultiCell($w, 5, $address, 0, 'L', false, 1, $x, $y, true);
date_default_timezone_set('UTC');
// --- Invoice title ---
$pdf->Ln(20); // space below recipient
$pdf->SetFont('GoogleSansFlex9pt-Bold', '', 15);
$pdf->Cell(0, 10, 'Startgebührenrechnung ' . $pdf->wk_name . ' ' . $pdf->current_year, 0, 1, 'L');
$pdf->SetFont('GoogleSansFlex-Regular', '', 10);
$pdf->Cell(0, 9, "Rechnungsnummer: " . $orderId, 0, 1, 'L');
$pdf->SetFont('GoogleSansFlex-Regular', '', 7);
$pdf->Cell(0, 0, "Ausstellungsdatum: " . date("d.m.y"), 0, 1, 'L');
$pdf->Ln(10); // space below title
$pdf->SetFont('GoogleSansFlex9pt-Bold', '', 13);
//$turnerinnnenIds = [];
$turnerinnnenIds = explode(',', str_replace(['[', ']','"'], '', $dbresult['item_ids']));
$columns = ['name' => ['header' => 'Name'],
'programm' => ['header' => 'Programm'],
'verein' => ['header' => 'Verein'],
'preis' => ['header' => 'Startgebühr']];
foreach ($columns as $key => $column){
$columns[$key]['max_width'] = $pdf->GetStringWidth($column['header']);
}
$totalPreis = 0.00;
$dbdata = [];
foreach ($turnerinnnenIds as $singleid){
$newdbresult = db_select($mysqli, $tableTurnerinnen, 'name, vorname, programm, verein', 'id = ?', [$singleid]);
if ($newdbresult && count($newdbresult) === 1){
$dbdata[$singleid] = $newdbresult;
$pdf->SetFont('', '', 10);
$text = 'Startgebühr '.$newdbresult[0]['name'].' '.$newdbresult[0]['vorname'];
if ($pdf->GetStringWidth($text) > $columns['name']['max_width'] ?? 0){
$columns['name']['max_width'] = $pdf->GetStringWidth($text);
}
if ($pdf->GetStringWidth($newdbresult[0]['programm']) > $columns['programm']['max_width'] ?? 0){
$columns['programm']['max_width'] = $pdf->GetStringWidth($newdbresult[0]['programm']);
}
if ($pdf->GetStringWidth($newdbresult[0]['verein']) > $columns['verein']['max_width'] ?? 0){
$columns['verein']['max_width'] = $pdf->GetStringWidth($newdbresult[0]['verein']);
}
if (isset($newdbresult[0]['programm'])){
$dbpreis = db_select($mysqli, $tableProgramme, 'preis', 'programm = ?', [$newdbresult[0]['programm']]);
if ($newdbresult && count($newdbresult) === 1 && isset($dbpreis[0]['preis'])){
$preis = $dbpreis[0]['preis'];
$totalPreis += floatval($dbpreis[0]['preis']);
} else {
$preis = 'ERROR';
}
if ($pdf->GetStringWidth('CHF '.$preis) > $columns['preis']['max_width'] ?? 0){
$columns['preis']['max_width'] = $pdf->GetStringWidth('CHF '.$preis);
}
}
}
}
foreach ($columns as $key => $column){
$columns[$key]['max_width'] += 2; // Add some padding
}
$maxWidth = 210 - 30; // A4 width minus margins
$totalColumnWidth = 0;
foreach ($columns as $column){
$totalColumnWidth += $column['max_width'];
}
if ($totalColumnWidth < $maxWidth){
$scalingFactor = $maxWidth / $totalColumnWidth;
foreach ($columns as $key => $column){
$columns[$key]['max_width'] = $column['max_width'] * $scalingFactor;
}
}
foreach ($columns as $c) {
$pdf->Cell($c['max_width'], 10, $c['header'], 0, 0, 'L');
}
$pdf->Ln();
$pdf->SetLineWidth(0.6);
$pdf->Line(15, $pdf->GetY(), 210 - 15, $pdf->GetY());
$pdf->SetLineWidth(0.2);
$pdf->headerBottomY = $pdf->GetY();
// --- Set top margin for table below title ---
// Mark first page done so Header() prints table headers on subsequent pages
$pdf->firstPageDone = true;
$pdf->SetFont('GoogleSansFlex-Regular', '', 11);
$pdf->columns = $columns;
$margin_top = $pdf->headerBottomY;
$pdf->SetMargins(15, 45, 15); // +5 mm padding below header
$pdf->SetY($margin_top); // Move cursor below header manually
foreach ($dbdata as $singleid => $newdbresult){
$pdf->SetFont('', '', 10);
$text = 'Startgebühr '.$newdbresult[0]['name'].' '.$newdbresult[0]['vorname'];
$pdf->Cell($columns['name']['max_width'], 10, $text, 0, 0, 'L');
$pdf->Cell($columns['programm']['max_width'], 10, $newdbresult[0]['programm'], 0, 0, 'L');
$pdf->Cell($columns['verein']['max_width'], 10, $newdbresult[0]['verein'], 0, 0, 'L');
$pdf->SetFillColor(100, 100, 100);
if (isset($newdbresult[0]['programm'])){
$dbpreis = db_select($mysqli, $tableProgramme, 'preis', 'programm = ?', [$newdbresult[0]['programm']]);
if ($newdbresult && count($newdbresult) === 1 && isset($dbpreis[0]['preis'])){
$preis = $dbpreis[0]['preis'];
} else {
$preis = 'ERROR';
}
$pdf->Cell($columns['preis']['max_width'], 10, 'CHF ' . $preis, 0, 1, 'C');
}
$pdf->SetDrawColor(100, 100, 100);
$pdf->Line(15, $pdf->getY(), 210 - 15, $pdf->getY());
$pdf->SetDrawColor(0, 0, 0);
}
/*
if (isset($_POST['postversand'])) {
$pdf->SetFont('', '', 10);
$text = 'Postversand der Rechnung durch WKVS';
$pdf->Cell($columns['name']['max_width'], 10, $text, 0, 0, 'L');
$pdf->Cell($columns['programm']['max_width'], 10, '', 0, 0, 'L');
$pdf->Cell($columns['verein']['max_width'], 10, '', 0, 0, 'L');
$pdf->SetFillColor(100, 100, 100);
$pdf->Cell($columns['preis']['max_width'], 10, 'CHF 2.50', 0, 1, 'C');
$pdf->SetDrawColor(100, 100, 100);
$pdf->Line(15, $pdf->getY(), 210 - 15, $pdf->getY());
$pdf->SetDrawColor(0, 0, 0);
$totalPreis += 2.5;
}
*/
if ($totalPreis !== 0) {
require __DIR__ . '/ajax-neu_qr_rechnung.php';
}
$pdf->Ln(3);
$pdf->SetFont('GoogleSansFlex9pt-Bold', '', 10);
$pdf->Cell(100, 10, "Gesamt:", 0, 0, 'L');
$pdf->SetX($columns['name']['max_width'] + $columns['programm']['max_width'] + $columns['verein']['max_width'] + 15);
$pdf->Cell($columns['preis']['max_width'], 10, 'CHF ' . number_format($totalPreis, 2), 0, 1, 'C');
$pdf->SetFont('GoogleSansFlex-Regular', '', 10);
if ($totalPreis !== 0) {
$pdf->Ln(10);
$pdf->SetTextColor(90, 103, 39);
$pdf->MultiCell(0, 8, 'Diese Rechnung wurde als bezahlt eigetragen, da der Betrag 0 CHF beträgt', 0, 'L');
$pdf->SetTextColor(0, 0, 0);
} else {
// 3. Create a full payment part for TcPDF
$output = new TcPdfOutput($qrBill, 'de', $pdf);
// 4. Optional, set layout options
if (class_exists(\Sprain\SwissQrBill\PaymentPart\Output\DisplayOptions::class)) {
$displayOptions = new \Sprain\SwissQrBill\PaymentPart\Output\DisplayOptions();
$displayOptions
->setPrintable(false) // true to remove lines for printing on a perforated stationery
->setDisplayTextDownArrows(false) // true to show arrows next to separation text, if shown
->setDisplayScissors(false) // true to show scissors instead of separation text
->setPositionScissorsAtBottom(false) // true to place scissors at the bottom, if shown
;
// 5. Generate the output, applying display options when supported
if (method_exists($output, 'setDisplayOptions')) {
$output->setDisplayOptions($displayOptions);
}
} else {
// DisplayOptions class is not available in the installed package version.
// We proceed without custom display options.
}
// Generate the payment part (always call)
if ($pdf->getY() > 297 - 120) {
$pdf->firstPageDone = false;
$pdf->printfooter = false;
$pdf->addPage();
}
$output->getPaymentPart();
}
if (isset($_SESSION['order_id'])) unset($_SESSION['order_id']);
if (isset($_SESSION['order_preis'])) unset($_SESSION['order_preis']);
$filename = 'Rechnung Startgebuehren '.$wkName.' '.$current_year.' '.date('YmdHis').'.pdf';
$pdf->SetTitle($filename);
$savePath = $baseDir . '/../private-files/rechnungen/' . $orderId . '.pdf';
// Save PDF to disk
$pdf->Output($savePath, 'F');
$sql = "UPDATE $tableOrders SET order_status = ? WHERE order_id = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("ii", $orderStatus, $orderId);
$stmt->execute();
$stmt->close();
// 2. DELETE basket items
db_delete($mysqli, $tableBasketItems, ['user_id' => intval($_SESSION['passcodetrainer_id'])]);
$mysqli->close();
// Send headers manually
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . $dirFileName . '"');
header('Content-Length: ' . filesize($savePath));
// Send file contents
readfile($savePath);
exit;