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;