prepare("SELECT o.*, c.name as client_name, c.email as client_email, c.language as client_language FROM orders o JOIN clients c ON o.client_id = c.id WHERE o.id = ?"); $stmt->execute([$order_id]); $order = $stmt->fetch(PDO::FETCH_ASSOC); if (!$order) { die('Order not found.'); } $stmt = db()->prepare("SELECT oi.*, p.name as product_name FROM order_items oi JOIN products p ON oi.product_id = p.id WHERE oi.order_id = ?"); $stmt->execute([$order_id]); $order_items = $stmt->fetchAll(PDO::FETCH_ASSOC); class PDF extends tFPDF { function Header() { $this->Image('assets/pasted-20260109-102314-972f2719.jpg', 10, 6, 60); $this->SetFont('DejaVu', 'B', 15); $this->SetY(30); $this->Cell(80); $this->Cell(30, 10, t('pdf_order_details_title'), 0, 0, 'C'); $this->Ln(20); } function Footer() { $this->SetY(-15); $this->SetFont('DejaVu', 'I', 8); $this->Cell(0, 10, 'Page ' . $this->PageNo() . '/{nb}', 0, 0, 'C'); } } $pdf = new PDF(); $pdf->AliasNbPages(); $pdf->AddFont('DejaVu','','DejaVuSansCondensed.ttf',true); $pdf->AddFont('DejaVu','B','DejaVuSansCondensed-Bold.ttf',true); $pdf->AddFont('DejaVu','I','DejaVuSansCondensed-Oblique.ttf',true); $pdf->AddFont('DejaVu','BI','DejaVuSansCondensed-BoldOblique.ttf',true); $pdf->AddPage(); $pdf->SetFont('DejaVu', '', 12); $pdf->Cell(0, 10, t('pdf_order_id') . ': ' . $order['id'], 0, 1); $pdf->Cell(0, 10, t('pdf_client') . ': ' . $order['client_name'], 0, 1); $pdf->Cell(0, 10, t('pdf_email') . ': ' . $order['client_email'], 0, 1); $pdf->Cell(0, 10, t('status') . ': ' . t_status($order['status']), 0, 1); $pdf->Cell(0, 10, t('payment_method') . ': ' . t_status($order['payment_method']), 0, 1); $pdf->Cell(0, 10, t('total_gross') . ': ' . format_money($order['total_amount'], $_SESSION['lang'] ?? 'pl', db()), 0, 1); $pdf->MultiCell(0, 10, t('notes') . ': ' . $order['notes'], 0, 1); $pdf->Cell(0, 10, t('pdf_created_at') . ': ' . $order['created_at'], 0, 1); $pdf->Ln(10); $pdf->SetFont('DejaVu', 'B', 12); $lineHeight = 5; // Headers $headers = [ ['width' => 70, 'text' => t('product')], ['width' => 30, 'text' => t('quantity')], ['width' => 30, 'text' => t('unit_price_net')], ['width' => 30, 'text' => t('unit_price_gross')], ['width' => 30, 'text' => t('total_gross')], ]; $padding = 2; // Calculate maximum header height without drawing text (by using a temporary white text color) $pdf->SetTextColor(255, 255, 255); $maxHeight = 0; $x = $pdf->GetX(); $y = $pdf->GetY(); $cellHeights = []; foreach ($headers as $header) { $startY = $y; // We need to clone the object to avoid moving the cursor on the main object $tempPdf = clone $pdf; $tempPdf->SetXY($x + $padding, $y); $tempPdf->MultiCell($header['width'] - $padding * 2, $lineHeight, $header['text'], 0, 'L'); $cellHeight = $tempPdf->GetY() - $startY; $cellHeights[] = $cellHeight; $x += $header['width']; } $headerContentHeight = max($cellHeights); $headerRowHeight = $headerContentHeight + $padding * 2; // Restore text color and position $pdf->SetTextColor(0, 0, 0); $pdf->SetXY($pdf->GetX(), $y); // Draw headers with calculated height $x = $pdf->GetX(); $y = $pdf->GetY(); foreach ($headers as $header) { $pdf->Rect($x, $y, $header['width'], $headerRowHeight); $pdf->SetXY($x + $padding, $y + $padding); $pdf->MultiCell($header['width'] - $padding * 2, $lineHeight, $header['text'], 0, 'L'); $x += $header['width']; $pdf->SetXY($x, $y); } $pdf->Ln($headerRowHeight); $pdf->SetFont('DejaVu', '', 12); $vatRate = 1.23; foreach ($order_items as $item) { $client_language = $order['client_language']; $vatRate = 1.23; if ($client_language === 'en') { $unit_price_net = (float)$item['unit_price']; $unit_price_gross = $unit_price_net * $vatRate; } else { $unit_price_gross = (float)$item['unit_price']; $unit_price_net = $unit_price_gross / $vatRate; } // --- Cell data --- $widths = [70, 30, 30, 30, 30]; $data = [ $item['product_name'], $item['quantity'], format_money($unit_price_net, $_SESSION['lang'] ?? 'pl', db()), format_money($unit_price_gross, $_SESSION['lang'] ?? 'pl', db()), format_money($item['line_total'], $_SESSION['lang'] ?? 'pl', db()), ]; // --- Calculate Row Height --- $y1 = $pdf->GetY(); $x1 = $pdf->GetX(); $tempPdf = clone $pdf; $tempPdf->SetXY($x1 + $padding, $y1); $tempPdf->MultiCell($widths[0] - $padding*2, $lineHeight, $data[0], 0, 'L'); $contentHeight = $tempPdf->GetY() - $y1; if ($contentHeight < $lineHeight) { $contentHeight = $lineHeight; } $rowHeight = $contentHeight + $padding * 2; // --- Draw Row --- $current_x = $x1; for ($i = 0; $i < count($data); $i++) { // Draw border $pdf->Rect($current_x, $y1, $widths[$i], $rowHeight); // Set text position $pdf->SetXY($current_x + $padding, $y1 + $padding); // Draw text if ($i === 0) { // MultiCell for product name $pdf->MultiCell($widths[0] - $padding*2, $lineHeight, $data[0], 0, 'L'); } else { // Cell for others $pdf->Cell($widths[$i] - $padding*2, $lineHeight, $data[$i], 0, 0, 'L'); } // Move to next cell start $current_x += $widths[$i]; $pdf->SetXY($current_x, $y1); } $pdf->Ln($rowHeight); } $pdf->Output('D', 'order_' . $order['id'] . '.pdf');